[racket-dev] binding clause transformers (was: generic binding forms)

From: Stephen Chang (stchang at ccs.neu.edu)
Date: Thu Aug 29 02:19:28 EDT 2013

Hi Jens,

Your binding clause transformers looks very useful. I've definitely hacked
together a subset of your functionality in the past so I will be using your
library in the future.

And I can see the similar goals. We should compare notes. One question,
have you tried to make your def form work with function definitions? It
seems like it should be able to, by wrapping the function body with your
let-syntax. Would that not work?



On Mon, Aug 26, 2013 at 2:14 AM, Jens Axel Søgaard <jensaxel at soegaard.net>wrote:

> Hi Stephen,
>
> > As an educational side project, I've been toying around with a
> > different way of organizing all the binding forms. What I wanted to do
> > is remove the need to manually combine current (and future) binding
> > forms by moving the binding "logic" to the binding site itself.
>
> Your goals seem similar to the ones I had for "bind".
> The different binding forms all have binding clauses.
> I introduced binding clause transformers that decide what
> to do with a given binding clause.
>
> The binding clause transformer :delay can for example
> be used like this (where bind is my name for a let that understands
> binding clause transformers).
>
>  (bind<http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html&https://github.com/soegaard/bind/blob/master/scribblings/bind.html=false#%28form._%28%28lib._bind%2Fmain..rkt%29._bind%29%29>
>  ([x :delay<http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html&https://github.com/soegaard/bind/blob/master/scribblings/bind.html=false#%28form._%28%28lib._bind%2Fmain..rkt%29._~3adelay%29%29>
>  1]   (+<http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html&https://github.com/soegaard/bind/blob/master/scribblings/bind.html=false#%28def._%28%28quote._~23~25kernel%29._%2B%29%29>
>  x x)))
>
> At macro expansion time this is expanded into
>
> (let<http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html&https://github.com/soegaard/bind/blob/master/scribblings/bind.html=false#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let%29%29>
>  ([x (delay<http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html&https://github.com/soegaard/bind/blob/master/scribblings/bind.html=false#%28form._%28%28lib._racket%2Fpromise..rkt%29._delay%29%29>
>  1)])   (let-syntax<http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html&https://github.com/soegaard/bind/blob/master/scribblings/bind.html=false#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._let-syntax%29%29>
>  ([clause ...<http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html&https://github.com/soegaard/bind/blob/master/scribblings/bind.html=false#%28form._%28%28lib._racket%2Fprivate%2Fstxcase-scheme..rkt%29._......%29%29>
> ])     (+<http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html&https://github.com/soegaard/bind/blob/master/scribblings/bind.html=false#%28def._%28%28quote._~23~25kernel%29._%2B%29%29>
>  x x)))
>
> where clause ... introduce a syntax binding such that x in the body
> expands to a use of x.
>
> This is just an example though. The key concept is the binding clause
> transformer.
> Here is the documentation for bind and def (let and define):
>
> http://htmlpreview.github.io/?https://github.com/soegaard/bind/blob/master/scribblings/bind.html
>
> Here is the Github repository:  https://github.com/soegaard/bind
>
> Another small example:
>
> Example:                                                       > (bind ([v :vector (for/vector ([i 5]) (random 10))])
>     (displayln (~a "The vector " v " contains " v))
>     (displayln (~a "The first element is: " (v 0)))
>     (v! 0 42)
>     (displayln (~a "The first element is now: " (v 0)))
>     (displayln (~a "The middle three elements are: " (v 1 4))))
>
>
> This expands into uses of vector-ref and vector-set! so there is no
> runtime penalty
> for using this shorthand.
>
> /Jens Axel
>
>
> 2013/8/26 Stephen Chang <stchang at ccs.neu.edu>
>
>> Hi dev,
>>
>> I've noticed that Racket has a lot of convenient binding forms but
>> they don't fit together unless someone does it manually (for example
>> there's match-let and match-let-values, but no match-for).
>>
>> As an educational side project, I've been toying around with a
>> different way of organizing all the binding forms. What I wanted to do
>> is remove the need to manually combine current (and future) binding
>> forms by moving the binding "logic" to the binding site itself.
>>
>> Inspired by the in-vogue generics movement in the Racket world, I've
>> hacked together a sort of "generic interface" for bindings (in
>> reality, it's just a bunch of syntax properties right now), and
>> implemented alternate versions of some of the main binding forms that
>> support "instances" of these generic bindings.
>>
>> To illustrate, here are some test cases for a generic define I
>> implemented (~define). I also implemented binding "instances" for
>> match and values (which I arbitrarily named $ and ~v below) and I can
>> use these forms in (mostly) any binding position that supports generic
>> bindings.
>>
>> ;; functions
>> > (~define (f1 x y) (+ x y))
>> > (f1 10 20)
>> 30
>> > (~define (f2 ($ (list x y))) (+ x y))
>> > (f2 (list 10 20))
>> 30
>>
>> ;; non-functions
>> > (~define a1 100)
>> > a1
>> 100
>> > (~define (~v a2 a3) (values 134 456))
>> > a2
>> 134
>> > a3
>> 456
>>
>> You can nest bind instances too:
>>
>> > (~define (~v ($ (list b1 b2)) b3) (values (list 22 33) 44))
>> > b1
>> 22
>> > b2
>> 33
>> > b3
>> 44
>>
>> Does anyone think this is useful? Or is it just a lot of work to save
>> a little bit of typing? Has anyone tried something like this before?
>>
>> It's still very much a work in progress but I figure I would ask for
>> some feedback earlier rather than too later, in case there is
>> something that makes this infeasible.
>>
>> Brave souls can look at the hackery here:
>> https://github.com/stchang/generic-bind/blob/master/generic-bind.rkt
>> (Warning: I'm still trying to figure out all the toys in the Racket
>> macro toolbox. For the most part, everything still looks like a
>> syntax-rule/case/parse/->datum nail to my hammer.)
>>
>> Technical question: I couldn't figure out a nice way to implement
>> ~let. Essentially, I want a let form where some clauses are let-values
>> and some are match-let, but I need to bind them all at the same time,
>> like let. I can't define a ~lambda that works with values because
>> functions in racket can't receive values. Anyone have any ideas?
>>
>> Side observation: Trying to get things to work with multiple return
>> values was a pain because they don't compose (as in, functions can
>> produce them but can't receive them). Not sure if anything can be done
>> about this though.
>> _________________________
>>   Racket Developers list:
>>   http://lists.racket-lang.org/dev
>>
>
>
>
> --
> --
> Jens Axel Søgaard
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20130829/97da2e08/attachment-0001.html>

Posted on the dev mailing list.