Sunday, August 24, 2008

Three language changes

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.

No comments: