In response to some comments from Nikhil:
| Thomas says:
| > AN ASIDE: Actually, in this example, what I *really* wanted was a
| > definitional list comprension (Kevin, was that what you called it?
| > You wrote a note about this ages ago):
| > So that a qualifier can also be a let or where definition,
| > perhaps like:
| >
| > [ .. | ..... (lsy, l, s:r)|isNonterm s = all_kernel_item_tab ! kno ]
| >
| > The problem with this syntax is that = looks too much like ==.
|
| We've always had these in Id list comprehensions. A qualifier can
| either be pat <- listexp (pat drawn from list) or pat = exp (for
| binding names to parts of exp). We've found this to be extremely
| useful. They're used all the time, and to my knowledge there's never
| been any confusion with == (in Id, also, == is the symbol for
| equality).
This subject came up on the mailing list a few years ago but there was no
clear concensus about what the precise syntax and semantics should be. Some
were worried about the confusion between = and ==, some thought that pat=exp
generators should be defined by an equation like:
[ e | pat = exp ] = [ let pat = exp in e ]
allowing recursive bindings, others felt that pat=exp should have the
same semantics as pat <- [exp].
Gofer has supported definitional list comprehensions (using the recursive
binding semantics) since its very first release. It was my hope that this
would give people, myself included, a better chance to experiment with them.
>From what I've seen so far, I certainly would like to see something like this
in a future version of Haskell. Definitional list comprehensions are not
essential -- we can always carry out the translations ourselves using nested
comprehensions and let expressions -- but I have found a number of places
where they provided a convenient, concise and natural way to write my
programs.
On the other hand, I think that the pat=expr syntax was something of a
design error and it may not be supported in future releases. Judging from
email that I've received, the similarity of == and = does cause confusion.
In fact, it has also caught me on at least one occassion! (So yes, my
experience is somewhat at odds with Nikhil's here.) As a result, Gofer 2.28
supports an alternative (and more general) syntax, with qualifiers of the
form let {decls} and a semantics given by:
[ e | let { decls } ] = [ let { decls } in e ]
Parsing this doesn't cause any conflicts with standard Haskell syntax (as far
as I can tell), and the braces can usually be omitted so there isn't a big
syntactic overhead.
Finally, as Thomas hinted in his message, let me mention that Kevin Hammond
also made similar proposals for definitional list comprehensions several
years ago. In fact, if I remember correctly, Kevin's proposals were more
general because he showed that the same approach also works very nicely with
arbitrary monad comprehensions, not just list comprehensions.
Mark