VISITOR: ++ ! acts like +, coercing string arguments to a number, unless both arguments are strings, in which case it appends them
V: number string ++
string>number + ;
V: string number ++
>r string>number r> + ;
V: number number ++
+ ;
V: string string ++
append ;
It would compile it to a form sort of like this:
GENERIC: ++
GENERIC: ++-string
GENERIC: ++-number
M: string ++ swap ++-string ;
M: number ++ swap ++-number ;
M: number ++-string
swap string>number + ;
M: string ++-number
swap >r string>number r> + ;
M: number ++-number
swap + ;
M: string ++-string
swap append ;
As it turned out, it wasn't much of a challenge, and the resulting code is about 24 lines long. The main problem with it is that the visitor pattern lends itself to a rather naive method order, but I don't think that's much of an issue in practice. Without further ado, here's the visitor pattern in Factor:
USING: kernel generic syntax words parser hashtables sequences ;
IN: visitor
: define-visitor ( word -- )
dup dup reset-word define-generic
H{ } clone "visitors" set-word-prop ;
: VISITOR:
CREATE define-visitor ; parsing
: connect-method ( top-class generic method-word -- )
[ swap ] swap add -rot define-method ;
: record-visitor ( top-class generic method-word -- )
swap "visitors" word-prop swapd set-hash ;
: new-vmethod ( method bottom-class top-class generic -- )
gensym dup define-generic
3dup connect-method
[ record-visitor ] keep
define-method ;
: define-visitor-method ( method bottom-class top-class generic -- )
>r >r >r \ swap add* r> r> r>
2dup "visitors" word-prop hash
[ nip define-method ] [ new-vmethod ] ?if ;
: V:
! syntax: V: bottom-class top-class generic body... ;
f set-word scan-word scan-word scan-word
parse-definition -roll define-visitor-method ; parsing
Enjoy! The full module can be found in the Factor repository. The great thing about Factor here is that, whereas you'd have to repeat this pattern every time you use it in Java, Factor lets you write it only once. But then again, comparing Factor to Java to prove Factor is good is somewhat of a straw-man fallacy.
1 comment:
Post a Comment