Arc Forumnew | comments | leaders | submitlogin
3 points by Jesin 6146 days ago | link | parent

I am new to Factor, but I know enough to explain some of the basics. Factor, like Lisp, can do anything to a code block that it can do to a sequence. Observe:

  : until ( pred body tail -- )
      rot \ not add -rot
      while
  ; inline
Now, a line-by-line explanation (not that end-of-line means any more in Factor than it does in Lisp).

  : until ( pred body tail -- )
This starts the definition of until, and then says that it takes three values from the top of the stack (pred, body, and tail from bottom to top) and leaves none of them on the stack at the end. This particular word assumes that the 3 arguments it takes are quotations (although it does not state that; it's dynamically typed) (quotation is Factor's name for a code block).

  rot \ not add -rot
rot is a "shuffle word" with this stack effect: ( x y z -- y z x ), in this case that means ( pred body tail -- body tail pred ).

\ not pushes the word not rather than executing it, roughly equivalent to 'no in Arc.

add appends the not we just pushed to the sequence immediately underneath it, pred.

-rot has the stack effect ( x y z -- z x y ), in this case ( body tail pred -- pred body tail ).

  while
This is just a call to the built-in word while, which happens to have the same stack effect we use for until.

  ; inline
This ends the declaration, and tags the word as inline for the benefit of any optimizing compilers.

Whew. That was a lot harder to explain in English than it was to think about in Factor. Of course, anyone explaining Lisp code to a non-Lisper will have the same sort of difficulty. The point here is that you can modify blocks of code as instruction sequences and then execute them. Sound familiar?

  (mac my-until (test . body)
      `(while (no ,test) ,@body))