((lambda (f0 f1 f2...) <body>) x.f0 x.f1 x.f2)
Something like that might be generated for a vcase expression like this:
((:nil) (error "stack underflow"))
((:elem item _ tail)
(set! stack tail)
I then made the inliner recognize ((lambda () ...) ...) applications and inline them when it could. This revealed a major problem with my inliner, most easily demonstrated like this:
(let ((n 10))
((lambda (x) (set! n 5) x) n))
This should return 10, not 5. In the stack example above, instead of returning the popped item, it returns the new top of the stack.
Some kind of assignment analysis is needed.
While digging around for a good reference on the subject, I found a really good paper on inlining that seems to cover this and several other issues. It looks pretty straightforward to implement, so there may be another pause-to-work-on-irken phase.