Should BitC incorporate comprehensions?/ I'm embarrassed to say that the notion of "comprehensions" confused me for a long time. It's a big word suggesting something complicated to me that turns out to mean something very simple. For allocation-sensitive applications, many comprehensions will turn out not to be usable, but they are still a useful syntactic construct for application purposes. Actually, I haven't thought very hard about which comprehension-driven allocations can be eliminated, so maybe my concern isn't yet justified.
My personal opinion is that comprehensions are useful even if we only do them for a few commonly used types (e.g. lists, vectors, lazy sequences). My concern is that by introducing comprehensions for these types, we effectively move the convenience syntax for these types back into the language core. Right now, nearly all of that convenience syntax is handled with predefined rules in the mixfix engine, which simplifies parsing quite a lot by handling it all in a uniform way. Questions: 1. Do we feel that comprehensions are useful enough to warrant inclusion? 2. Do we agree that comprehensions seem prone to entail allocation, in which case there are some kinds of codes that may need to avoid them? 3. Is there some way to generalize our handling of convenience syntax in order to generalize our handling of comprehensions? In particular, is there some trick similar to "mixfix wrapping a type constructor is both a type expression and a pattern expression" that we can adopt in this case to allow more generalized extensions to convenience construction syntax? F# has a somewhat interesting take on extensible comprehensions in the form of "Computation Expresions": http://research.microsoft.com/pubs/217375/computation-zoo.pdf I'm planning to read that paper again while asking myself "how much of this wouldn't be necessary if F# had mixfix?" I'm very clear that computation expressions introduce some new constructs (notably some syntactic support for incrementally generated sequences via co-routines). What I'm not clear about is how to think about the types in something like the following list comprehension: [ toUpper c | c <- (s : String) ] Here's what makes me unhappy about this construct: it's syntax driven rather than type driven. It seems to me that the right reading of this construct ought to be something like someConstructor (generator yielding BoundedList 'nat 'a) -> someType 'a and in this case the generator is something like: map (fn (c) = toUppser c) (c <- (s : String)) Where: c-> (s : String) is itself a generator producing a result of type BoundedList 'nat char, and we can readily imagine a map that maps from one bounded list to another. So far so good, but then we are left with something of the form [ e : BoundedList 'Nat char ] which is presumably a mixfix wrapper of list (e:BoundedList 'Nar char) And hello! What's that? Is that really a distinguished constructor? If the output here has type BoundedList 'a, that's not so bad. We just need to define it somewhere, and it can certainly be something built-in for those types that are internally variadic. Offhand, it seems to me that the comprehension notion really only works for types having some distinguished constructor with the signature (BoundedList 'nat 'a) -> type [optional type arguments including 'a] Does that seem about right? If so, then I suspect our mixfix support may need some tweaks, but I think we may be close to generalizing comprehensions... shap
_______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
