Many ways to skin a FAt CaT OR …
Sunday, April 27th, 2008Some people go to church on Sundays and some find time to divulge to the non-urgent ie. play with Factor a little. Well, I am not playing, I started making something concrete in Factor. Something that was cooking in my head for 6 whole years, and if no one made it in this time I might just step out and do it.
Well the concept is still not fully cooked, but I decided it’s time to stop boiling it and put it out on a pan and burn it a little and see what we get. So today I made few more words and a bunch of unit tests for it. Ok, so I am coding a very concrete thing in Factor for the first time. I like when I see that the Forth philosophy about re-FACTORing (yeah, hence the name I think) words to smaller and smaller independent words showed it’s beauty.
My main words with very rich functionality basically needed very very little stack shuffling ( just a dup, swap or over here and there - and I didn’t use cleave combinators) but then I came to one very simple utility word that because of few specifics used them noticeably more.
It was no problem to write but because Factor is so versatile I was sure there are other more elegant solutions. So I pasted that word on Factor’s paste and asked on IRC and so far I have 4 solutions that used very different concepts each, so I think it’s an interesting example of Factor.
This is my original, made in the “primitive” way with just stack shuffling… The code takes assoc. array, extracts/processes few values from it and leaves 3 values on stack. Basically very simple unimportant stuff…
: unpack-answer-to-me ( array -- type_subj answer id )
"type" over at "subject" pick at " " prepend append
"answer" pick at
"id" roll at ;
#! Example of use..
{ { "type" "typ" } { "subject" "subj" } { "id" 12 } { "answer" "ans" } }
unpack-answer-to-me .s
! returns
"typ subj"
"ans"
12
Itvar on IRC came to this solution, he used locals. I think it’s much more readable than mine..
:: unpack-answer-to-me ( array -- type_subj answer id )
"type" array at
"subject" array at " " prepend append
"answer" array at
"id" array at ;
Then Itvar made a word using the new cleave combinators. Cleave combinators are new “invention” (I think) in stack based world and I didn’t see them in action until this. This code looks very good to me and nicely reflects the logical structure of code.. The cleave stuff is that bi and tri
: rev-at swap at ;
: cleave-unpack-answer ( array -- type_subj answer id )
[ [ "type" rev-at ] [ "subject" rev-at ] bi " " prepend append ]
[ "answer" rev-at ]
[ "id" rev-at ] tri ;
Before Itvar showed this code I was thinking that I could make some sort of “extract” combinator myself that could be useful in all such cases. I made modify-values combinator before and really liked what it allowed. Well it was too interesting to-not-do it so I made it and this is the usage..
: unpack-answer-to-me ( array -- type_subj answer id )
{ { { "type" "subject" } [ " " prepend append ] }
{ { "answer" } [ ] }
{ { "id" } [ ] }
} extract-values+ ;
Well I am biased and I don’t know Factor well yet, but I like this solution the most
. Cleave is cool too. I will post the code for this and some other combinators soon-ish. This post is getting too long already.
update
johnnowak , a guy who is making his own stack based language Fifth (5th — website should be coming soon) came up with yet another solution. I like this one because it creates/uses 2 very general purpose and useful combinators to get a very straightforward solution.
: 2dip -rot 2slip ;
: extract swap [ at ] curry each ;
: unpack-extract
{ "type" "subject" "answer" "id" } extract
[ " " prepend append ] 2dip
;
The page and app is in Slovene language for now, but it is already being translated to English and some other languages. It’s an application that photo-studios can use to offer their customers fast and simple way to upload photos for printing. I made such web-app for one studio like 7 years ago (with PHP and REBOL), I later made better one for another studio few years back, but this solution is made for “them all” and brings big improvements to the previous two. FotoLOAD mini is a mini and is somewhat limited but also free. There is also a non-mini which won’t be free 

