Three language changes
Sunday, August 24, 2008
There are three language changes coming up as a result of the new high-level optimizer being merged in. All are minor, and I have already updated most code in the repository, however they’re worth pointing out.
Recursive declarations
Words (combinators) which are declared inline
and recursive must also
be declared recursive
. Most combinators are not recursive, but instead
are built in terms of other combinators, such as curry
, map
, and so
on. However the fundamental ones are recursive, and they need to be
declared as such. Furthermore, input parameters which are quotations
must have their stack effect annotated with a nested stack effect
declaration. For now, this is only a requirement for inline recursive
words; in the future, Factor might require such annotations on all
quotation parameters. Here is an example; the loop
combinator calls a
quotation until it returns false:
: loop ( pred: ( -- ? ) -- )
dup slip swap [ loop ] [ drop ] if ; inline recursive
Note the nested stack effect, and the recursive
declaration. If you
find this too verbose, then consider building your combinator from other
combinators, such as loop
and while
, instead of using explicit
recursion.
The rationale for this change is that it simplifies the compiler front-end. Inline words which are recursive and those which are not are constructed differently in the compiler’s IR, but the decision must be made before the word definition is inspected for recursive calls. The old compiler front-end would back-track and throw away the partially constructed IR upon encountering a recursive call, but this lead to poor performance for code with deeply nested calls to recursive combinators. The new approach simplifies the front-end and only requires a little bit of effort from the programmer.
Stricter retain stack operation checking
Before, the compiler would tolerate code such as the following:
: foo ( a b -- c ) >r [ r> 1 + ] [ r> drop 0 ] if ;
Here the retain stack usage was balanced within the entire word, but not
in individual quotations. Again, this lead to complications; the
compiler IR had to express not only data stack but retain stack values
at control flow merge points, and with my move toward an SSA
IR, the
bookkeeping became a pain. Since this type of code is harder to
understand and doesn’t come up very often anyway, I decided to simplify
the compiler and prohibit it. Now, usages of >r
and r>
must be
balanced within every quotation, not just the entire word.
Old-style delegation has been removed
I implemented inheritance in April this year; so delegation has been deprecated for four months now, and its finally out. Most libraries have been updated to either use inheritance, or the more powerful delegation library by Daniel Ehrenberg.