Skip to content

Instantly share code, notes, and snippets.

@crcx
Created December 13, 2009 14:56
Show Gist options
  • Save crcx/255446 to your computer and use it in GitHub Desktop.
Save crcx/255446 to your computer and use it in GitHub Desktop.
On the use of later

One of the more interesting flow control words in Retro is later. This is a word that returns control to the caller, then regains control when the caller is finished.

A simple example:

: test ( - ) 1 . later 2 . ;
: b ( - ) test 3 . ;

Run b, and you should see:

1 3 2

What happens here:

b:
  call test
    test displays 1
    test returns to b
  display 3
  execution of b ends
    control passes back to test
    test displays 2
    and returns
back to the interpreter

later can be very useful in cases where you need to ensure cleanups are done later. For example, when parsing, you may want to disable the whitespace filter, but restore it when your word is done. The simple way:

: foo ( "- ) whitespace off 32 accept whitespace on ;

Or, factoring out the filter:

: no-ws  ( - ) whitespace off ;
: yes-ws ( - ) whitespace on ;
: foo ( "- ) no-ws 32 accept yes-ws ;

But it's cleaner with later added:

: disable-ws ( - ) whitespace off later whitespace on ;
: foo ( "- ) disable-ws 32 accept ;

The use of later also allows passing control back and forth between two words:

: foo ( - ) 1 . later 2 . later 3 . later 4 . ;
: bar ( - ) foo 5 . later 6 . later 7 . ;

When "bar" is run:

1 5 2 6 3 7 4

Play with later and see what kind of interesting bits of flow control you can achieve with it. It's a powerful word, and definitely worth study.

@darius
Copy link

darius commented Sep 13, 2010

CLU's iterators worked like this. (The syntax for 'value later' was something like 'yield(value)' and it had to pass just one value each time, of the declared type, but it was otherwise like this, and unlike e.g. Python's yield, which makes the Python frontend rewrite the whole function as an object with a .next() method.)

@kragen
Copy link

kragen commented Mar 27, 2012

I suppose the implementation of later is something like

: later r> r> swap >r >r ;

no? That's dramatically, dramatically simpler than the iterator implementations I was discussing in higher-order programming and concurrency in low-level languages. On the other hand, it doesn't seem to support the iterator deciding when to terminate the loop, or nested loops.

@darius
Copy link

darius commented Mar 27, 2012

My previous comment was wrong about just one value in CLU -- it could be any number of values, just subject to static typing. For the record.

@crcx
Copy link
Author

crcx commented Apr 9, 2012

Kragen: yes, that's how I define it in Retro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment