[racket-dev] racket/match is broken

From: Sam Tobin-Hochstadt (samth at ccs.neu.edu)
Date: Thu Oct 6 07:45:09 EDT 2011

On Thu, Oct 6, 2011 at 12:34 AM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
> Sure you COULD do that, but app is so cool, I just like the way it looks.

Unlike, say, `syntax-parse', `match' isn't designed for the use-case
of building ASTs while matching.  If you wanted that, you'd need to
definitely think harder about a bunch of the guarantees that you might
need there -- for example, data structure construction might be
expensive and you wouldn't want to repeat it.  As a result of these
considerations, `syntax-parse' matches left-to-right, in each pattern,
before going on to the next, IIRC. That's the right choice for what
it's doing, but `match' is intended to be a simpler tool, allowing it
to optimize in ways that something with more goals couldn't.

> Also, Sam, I've thought more about this and I've definitely made the
> assumption that the "and" pattern evaluates left to right. For
> example, in the bidirectional matchers that are underneath the URL
> dispatch library, I assume that to protect usages of 'app' from
> getting the right typed arguments.

I think that `and' should match left to right -- the expansion of (?
f? p) into (and (? f?) p) definitely relies on that, so I'll add some
tests to ensure that's the case.

> Jay
>
> On Wed, Oct 5, 2011 at 8:55 PM, Robby Findler
> <robby at eecs.northwestern.edu> wrote:
>> Why wouldn't you write that match like this:
>>
>> (match ..
>>  [`(+ ,lhs ,rhs) (make-plus (parse lhs) (parse rhs))]
>>  [`(fun (,(? symbol arg) ...) ,body) (make-fun arg (parse body))])
>>
>> Robby
>>
>> On Wed, Oct 5, 2011 at 9:48 PM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>>> Okay. I think it is strange, but feel free to do that and revert my
>>> change. Apologies for the confusion.
>>>
>>> The use case I was actually doing was like this:
>>>
>>> [(list '+ (app parse lhs) (app parse rhs))
>>>  ...]
>>> [(list 'fun (list (? symbol? arg) ...) (app parse body))
>>>  ...]
>>>
>>> And when you gave it a '(fun () ...) it would try to parse the '() in
>>> the fun as the lhs of a + and then throw an exception and crash the
>>> whole match.
>>>
>>> Jay
>>>
>>> On Wed, Oct 5, 2011 at 7:39 PM, Sam Tobin-Hochstadt <samth at ccs.neu.edu> wrote:
>>>> On Wed, Oct 5, 2011 at 5:13 PM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>>>>>
>>>>> Basically, it calls the app function on the second element of the list
>>>>> even though the head of the list has failed to pattern match.
>>>>
>>>> This is not a bug.  `match' makes no guarantee about the order in
>>>> which it checks elements of the pattern.  If it were to try to support
>>>> this kind of use case, it would have to specify how many times it
>>>> would call each function that might be embedded in a match, which
>>>> requires a detailed semantics of backtracking in the matcher, and lock
>>>> in a particular implementation.
>>>>
>>>> I will clarify the documentation to say that you shouldn't use
>>>> functions that aren't safe to call 0, 1, or more times, in various
>>>> orders, inside `match' patterns.
>>>> --
>>>> sam th
>>>> samth at ccs.neu.edu
>>>>
>>>
>>>
>>>
>>> --
>>> Jay McCarthy <jay at cs.byu.edu>
>>> Assistant Professor / Brigham Young University
>>> http://faculty.cs.byu.edu/~jay
>>>
>>> "The glory of God is Intelligence" - D&C 93
>>>
>>> _________________________________________________
>>>  For list-related administrative tasks:
>>>  http://lists.racket-lang.org/listinfo/dev
>>
>
>
>
> --
> Jay McCarthy <jay at cs.byu.edu>
> Assistant Professor / Brigham Young University
> http://faculty.cs.byu.edu/~jay
>
> "The glory of God is Intelligence" - D&C 93
>



-- 
sam th
samth at ccs.neu.edu



Posted on the dev mailing list.