24 March 2011

Kernel Suggestions

Kernel Suggestions

Having gotten neck-deep in coding Klink, most recently listloop, I've found a few small areas where IMHO the Kernel specification might be improved.

for-each should cycle like $sequence

John Shutt clearly considered this (6.9.1) and decided the other way: Terminating on circular lists is more important than in-order behavior.

I'm tempted by his rationale. But `for-each' is not like `map', it is very nearly the `apply' counterpart of `$sequence'. The parallel between them persuades me that they should behave the same way on cycles.

Let finders return (found? . value)

Again, John considered this with `assoc' (6.3.6) and decided the other way. But `assoc's case doesn't generalize. Successful `assoc' results can't be nil because they are pairs, but in general, `nil' is a possible object to find.

Already I find myself writing code that wants to use a (bool . value) return, like:

($define! (found . obj) (some-finder))
($if (and? 
        (not? found)
        (some-check))
   ($define! (found . obj) (another-finder))
   #inert)

It's very convenient. This regular form also makes it easy to wrap finders in control constructs that easily understand whether the result of a finder is available.

I would ask that finders in general return a (bool . value) pair, including:

  • assoc, or a reserved name associated with assoc.
  • assq, or again a reserved name associated with it
  • $binds? + (eval SYM ENV)
    • Provided in Klink as `find-binding'
  • The accessors built by make-keyed-dynamic-variable and make-keyed-static-variable. With this, it is easier to determine whether a known keyed variable is bound or not, but raising an error if it's not requires an extra step. Ie, the reverse of the current definition. Either could be defined in terms of the other.

No comments:

Post a Comment