"er" words
Monday, August 6, 2007
Take a look at the new implementation of subset
:
: pusher ( quot -- quot accum )
V{ } clone [ [ push-if ] 2curry ] keep ; inline
: subset ( seq quot -- subseq )
over >r pusher >r each r> r> like ; inline
The idea of having a pusher
word was originally suggested by Eduardo
Cavazos. This word takes a predicate quotation and yields two values,
the first being a quotation taking an object as input, and the second
being a vector. If you call the quotation with an object for which the
predicate yields true, the object is pushed on the vector. The generated
quotation “closes over” the vector. Now the only thing subset
has to
do is pass the pusher quotation to each
, and hide the pusher vector on
the retain stack until after the iteration is done. When iteration has
completed, the pusher vector contains all elements which passed the
predicate.
I think there is a very interesting idiom here, and it is worth exploring this idea more.
Also, note that while from the outside, subset
is referentially
transparent, it uses mutable state internally. While it may be possible
to write something just as simple without mutation, I think in many
cases, being able to mutate considerably simplifies code; certain
algorithms are just more naturally expressed with mutation, at least in
a stack language, and integrating abstractions such as monads or
uniqueness types into a stack language is still an open research problem
(but Christopher Diggins is working on
it…)
There is something to be said for allowing different programming styles
in a language, instead of forcing a single style on the programmer (as
in Haskell and other purely functional languages, or even Smalltalk’s
“everything-is-message-passing-OOP”.)