[racket] Pattern matching define macro

From: Alexander D. Knauth (alexander at knauth.org)
Date: Tue Jul 15 18:22:00 EDT 2014

On Jul 15, 2014, at 5:40 PM, Stephen Chang <stchang at ccs.neu.edu> wrote:

>> Is there any reason why you can’t just use match-patterns instead of using ($ match-pattern) ?
> 
> The idea was to support a generic interface so different instances
> could be defined, but thus each instance needs it's own name. For
> example, I need to differentiate when I'm binding a match pattern vs
> binding multiple values.
> 
> I tried to define shortcuts for some match patterns like $list and I
> suppose you could rename them to be the same as racket but I didnt
> want to clash with racket's names. There's also define-match-bind to
> create your own shortcuts.

Ok that makes sense.  

> 
> 
>> And is there anything like a “generic-binding-expander” that would act sort of like a match-expander?
> 
> No there isnt. It was a todo but I never got around to it. Did you
> have something specific in mind?

No, I just thought that it would be really useful and wanted to know if it was there.  
Also I was thinking I could use it to make gen-bind expanders for match-patterns if I need them.  

> 
> 
>> And is there some kind of "generic-bind/renamed” module or something that provides everything from generic-bind except without the ~ in front?
> 
> Good idea. Yes, in hindsight my choice of names was probably
> suboptimal. I've incorporated your suggestion so now you can do
> (require generic-bind/as-rkt-names), which drops all ~-prefixes
> (except for ~vs). Thanks!
> 
> 
>> 
>> 
>> On Jul 15, 2014, at 3:02 PM, Stephen Chang <stchang at ccs.neu.edu> wrote:
>> 
>>>> I just found this, which has a lot of forms for just about everything I can think of (and more) that support things like match-patterns:
>>>> https://github.com/stchang/generic-bind
>>>> 
>>>> I haven’t tried it yet, but It looks pretty amazing.
>>>> 
>>>> It probably has everything you want.
>>> 
>>> Thanks for the kind words. :)
>>> 
>>> This was an experiment that tried to address a few questions that
>>> repeatedly get asked on the mailing list:
>>> 
>>> 1) that you can't destructure data structures at the binding site, and
>>> 2) that you need to manually define many different versions of each
>>> binding construct (eg define, match-define, match-define-values, etc),
>>> which inevitably means that some binding forms don't exist (eg
>>> match-for/X forms)
>>> 
>>> Something like the expressivity problem for binding forms.
>>> 
>>> I tried to implement one "generic" version of each binding form that
>>> would accept many different "binding instances", so every binding form
>>> would be extensible by implementing the appropriate instance (eg, a
>>> matching instance, a values instance)
>>> 
>>> Every Racket binding form should have a ~-prefixed version in my
>>> library and my version should work as a drop-in replacement for its
>>> Racket counterpart if you want to try it out.
>>> 
>>> Here's a link to the docs if you're interested in reading more:
>>> http://stchang.github.io/generic-bind/generic-bind.html
>>> 
>>> (You can tell that it hasn't been updated in a while from the old css.)
>>> 
>>> Caveat: my macro-fu hasn't quite reached expert level so I'd love for
>>> anyone to tell me where my code is bad.
>>> 
>>> That being said, I ran a large part of the Racket test suite using my
>>> binding forms instead of the Racket ones so they should be usable in
>>> most scenarios.
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>>> 
>>>> On Jul 13, 2014, at 12:41 AM, Alexander D. Knauth <alexander at knauth.org> wrote:
>>>> 
>>>>> 
>>>>> On Jul 12, 2014, at 10:17 PM, Alexander D. Knauth <alexander at knauth.org> wrote:
>>>>> 
>>>>>> 
>>>>>> On Jul 12, 2014, at 6:43 PM, Brian Adkins <racketusers at lojic.com> wrote:
>>>>>> 
>>>>>>> I probably won't keep my defpat macro, at least not in its present form (for one, it only handles a single arg); there's probably a balance between being concise and being general/flexible.
>>>>>> 
>>>>>> Although define/match is definitely more powerful, if you want it, this would probably be a good version of what you want that would handle multiple arguments:  (I’ll reply again if I get one to work with optional and/or keyword-arguments)
>>>>>> (define-syntax defpat
>>>>>> (syntax-rules ()
>>>>>> [(defpat (f arg-pat ...) body ...)
>>>>>>  (defpat f (match-lambda** [(arg-pat ...) body ...]))]
>>>>>> [(defpat id expr)
>>>>>>  (define id expr)]))
>>>>> 
>>>>> Ok I just made a version of defpat that can handle multiple arguments, optional arguments, keyword-arguments, and optional keyword-arguments.
>>>>> I also made a form called my-match-lambda that defpat uses to do this.
>>>>> https://github.com/AlexKnauth/defpat
>>>>> Also to do this I had to make it so that you have to use square brackets to specify optional arguments, otherwise it couldn’t tell between an optional argument and a match pattern.
>>>>> 
>>>> 
>>>> 
>>>> ____________________
>>>> Racket Users list:
>>>> http://lists.racket-lang.org/users
>> 



Posted on the users mailing list.