Friday, August 6, 2010

Fat Arrows

Update: I found out that the extra/pair-rocket vocabulary implements this functionality, apparently named after Ruby's hash-rockets.

Today, I saw a blog post about adding "fat arrows" (syntactic sugar to support dictionaries) to the efene programming language.

One of Factor's strengths is defining new syntax to make certain problems more possible or more elegant. In this post, I will show what it takes to add "fat arrows" to Factor.

First, what is a "fat arrow"? It appears to be simple syntax to create two-element arrays, but without using "array syntax". Assuming we had already defined it, it would work something like this:

( scratchpad ) 1 => 2 .
{ 1 2 }

( scratchpad ) t => "some text" .
{ t "some text" }

So, how do we implement it? The documentation is pretty detailed and includes an article about the parser and, in particular, parsing words.

The basic strategy is:

  1. get the last object parsed
  2. parse ahead to read the next object
  3. wrap both elements into an array
  4. place the array back onto the parse sequence

The core to this is reading ahead to parse the next object. This can be accomplished with the scan-object word. Once we know that, it's pretty straightforward to implement:

SYNTAX: =>
    unclip-last scan-object 2array suffix! ;

I'm not a huge fan of this syntax (since it is very close to <=>, one of the comparative words), but it does make case statements look prettier. Here's one from the examples:

SYMBOL: yes  SYMBOL: no  SYMBOL: maybe
maybe {
    yes   => [ ] ! Do nothing
    no    => [ "No way!" throw ]
    maybe => [ "Make up your mind!" print ]
    [ "Invalid input; try again." print ]
} case ;

1 comment: