It all depends on what you want to do: As Joe suggested, handling packets one at a time with a combinator is better than reading the whole stream and then writing the whole result. Your each-window combinator should implement the increasing index logix. However this won't work if you want to implement the optionnal shuffle feature (maybe that's why you were reading the whole input before proceeding).
However, if you do want to read the whole input, here's a more idiomatic way of writing read-chunks (didn't test, but should work): USING: grouping : read-chunks ( -- seq ) contents WINDOW group ; Even with the old structure of a loop with reads, you could make it clearer by using "generalized booleans" (pretty name to say that everything except f is true) : read-chunks ( -- seq ) [ [ WINDOW read dup [ , t ] [ ] if ] loop ] { } make ! or this : read-chunks ( -- seq ) [ [ WINDOW read [ , t ] [ f ] if* ] loop ] { } make ! There was also a solution with the word produce : read-chunks ( -- seq ) [ WINDOW read dup ] [ ] produce nip ; Also, the docs recommend to use http://docs.factorcode.org/content/word-read-partial,io.html in your case. Finally, as a general rule, I prefer shorter functions without comments to long function with comments. So you could break down format-packets in smaller words. Keep in mind that this is easy in concatenative languages. The comment of format-packet even shows that you think of this words as 2 operations ("Do A. Also do B"), so I would define A and B and define format-packets as A B without comments. Overall it was already pretty readable though.. Hope this helps. Cheers, Jon On Mon, Feb 20, 2012 at 1:59 PM, Tim Allen <screwt...@froup.com> wrote: > (this is a resend of a message that got caught in the moderation queue) > > I have a friend who occasionally runs programming competitions for kids, > and when he's putting together exercises he sometimes runs them by us > just to see what we'll come up with. The other day he posted > a description of a simple task and I thought I'd have a go. I got it > working in Python very neatly, but then I decided I'd see if I could > figure out how to do the same in Factor. > > Here's the problem description: > > Code Golf Challenge #1 > ====================== > > Write something that will: > > * Encode stdin into chunks like so: > 01 1 octet SOH > xxxx 2 octets chunk number (monotonically increasing) > xx 1 octet chunk length > ... <256 octets up to 255 bytes of data > xx 1 octet checksum (8-bit sum of all data bytes) > > with an "end of transmission" marker of: > 04 1 octet EOT > xxxx 2 octets chunk number > 00 1 octet length 0 > > * optionally shuffle chunks > * base64-encode output > > Your entry should be *readable*. Use any standard libraries you want. > > Par 78 SLOC (ANSI C). It relies on standard Unix tools and pipes. > > For what it's worth, I'm told this algorithm is very similar to the > ancient XMODEM file-transfer protocol. Yes, 'readable' conflicts with > 'code golf'; at least for the Factor version I'm trying to prefer > readability over brevity. Also, comparing my implementation to the > sample ANSI C implementation, it turns out there are extra rules: > > - chunk length is actually capped at 128 bytes > - the uint16 chunk length should be stored in big-endian order > > Here's my Factor implementation. It works (that is, it produces > identical output to the reference implementation), but it's not very > pretty (note that I've ignored the 'shuffle' feature, and base64 > encoding is done with an external tool, same as the reference > implementation): > > USING: arrays io io.encodings io.encodings.binary kernel locals > make math pack sequences syntax ; > IN: bmodem > > CONSTANT: WINDOW 128 > > ! Splits stdin into an array of WINDOW-sized byte-arrays. > : read-chunks ( -- seq ) > [ [ WINDOW read dup f = [ ] [ , t ] if ] loop ] { } make > ; > > ! Takes a sequence of payload byte-arrays and frames each one > ! with a packet-header and check-sum. > ! Also adds the trailer ("EOT") packet. > : format-packets ( seq -- seq' ) > [ > [ > [| payload index | > 1 index payload length 3array "CSC" pack-be % > payload % > payload sum 256 mod , > ] B{ } make > ] map-index > ] > [ length 4 swap 0 3array "CSC" pack-be ] bi > suffix > ; > > ! Slurp bytes from stdin, spit packets to stdout. > : main ( -- ) > binary decode-input read-chunks > binary encode-output format-packets [ write ] each > ; > > MAIN: main > > In particular, the way read-chunks breaks out of the loop when it's hit > EOF strikes me as ugly, what with the if word's quotations having > different stack signatures. Also, there's still a few stack-shuffling > words lurking about in there. I'm not sure if that's within standard > tolerances, or if I'm doing something wrong. > > Any hints or suggestions? > > ------------------------------------------------------------------------------ > Try before you buy = See our experts in action! > The most comprehensive online learning library for Microsoft developers > is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, > Metro Style Apps, more. Free future releases when you subscribe now! > http://p.sf.net/sfu/learndevnow-dev2 > _______________________________________________ > Factor-talk mailing list > Factor-talk@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/factor-talk ------------------------------------------------------------------------------ Try before you buy = See our experts in action! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-dev2 _______________________________________________ Factor-talk mailing list Factor-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/factor-talk