On Sun, Feb 22, 2009 at 6:01 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote: > At Sun, 22 Feb 2009 17:44:42 -0500, Sam TH wrote: >> I'd like to write a sequence syntax that uses `match'-style pattern >> matching. Unfortunately, this doesn't seem to be currently possible, >> but it's close. >> >> First, something like this is ruled straight out: >> >> (for/list ([(? (lambda (x) #t) x) (:match (list 1 2 3))]) x) >> >> since (lambda (x) #t) is not an identifier. This is ruled out >> *before* the `:match' expander is given control. >> >> Second, it's not possible to distinguish between the client writing this: >> >> (for/list ([x (:match e)]) ...) >> >> and this: >> >> (for/list ([(x) (:match e)]) ...) >> >> which, while they have the same semantics for `in-list', would have >> very different semantics for `:match'. >> >> I think the easiest solution would be to (1) accept any pattern in the >> binding position, and have individual sequence-syntax forms rule them >> out (perhaps `define-sequence-syntax' could make this easy), and (2) >> provide a lower-level form which is given the raw pattern, without any >> transformation. >> >> I'll write up a patch, provided anyone is interested. > > It sounds worth trying, but I'm not sure it will work easily. > > The existing `for' forms were designed with the idea that the > right-hand side of a binding is always an expression. If the expression > has a certain shape, then you might get better performance, but the > shape of the expression doesn't affect the binding. > > A benefit of that design is that you can derive new `for'-like forms > that wrap some right-hand sides with sequence converters. For example, > a derived form might wrap a right-hand side with `stop-before'. If I > remember correctly, then some of the `for' forms (perhaps `for/or' or > `for/and') are implemented that way. > > In other words, the constraint that the right-hand side is always an > expression might be built deep enough into the design that it's > difficult to change. But I'm not sure.
Attached is my initial effort. 'for.diff' is a diff for 'scheme/private/for.ss', implementing `define-raw-sequence-syntax'. Then 'test.ss' uses that to implement `:match' and `:match*', which match single- and multiple-value generators, respectively. I've tried out a bunch of examples (included in the file), and they all seem to work as intended, including the ones using `for/and' and `for/or'. Do you think this is a reasonable strategy? Is there something I've overlooked? Thanks, -- sam th samth at ccs.neu.edu -------------- next part -------------- A non-text attachment was scrubbed... Name: test.ss Type: application/octet-stream Size: 2148 bytes Desc: not available URL: <http://lists.racket-lang.org/archive/dev/attachments/20090222/e620f91d/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: for.diff Type: text/x-diff Size: 4528 bytes Desc: not available URL: <http://lists.racket-lang.org/archive/dev/attachments/20090222/e620f91d/attachment.bin>
