Michael Bevilacqua-Linn on 3 Feb 2011 11:02:48 -0800


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: let substitution in clojure?


Ah,

Well, if you don't have to write it yourself then the cleanest thing to do is probably to just define an alias to let.

match.core=> (require 'clojure.contrib.def)
nil
match.core=> (clojure.contrib.def/defalias sub let)
#'match.core/sub
match.core=> (sub [x 1 y 2] (+ x y))
3
match.core=>

Thanks,
MBL

On Thu, Feb 3, 2011 at 1:40 PM, Dan Mead <d.w.mead@gmail.com> wrote:
Thanks guys, that makes sense.

I had assumed that macros would still evaluate their arguments at runtime.

It would be easier to use contrib.match (I had looked at that when it
was called matchure)
but this pattern matcher is part of the backend I'm working on for my
Haskell to Clojure translator.
The translator is written in Haskell, but still has to support pattern
matching and _expression_ rewriting at runtime.
So when some code gets translated the pattern matcher and some other
stuff gets included with the generated code.

Clojure's built in matcher works on the forms I'm translating now, but
later on I'll need to do algebraic data types and such
so finer control over the matcher is required.

Phil: if it were for a class, then yes.  =p



Dan



On Thu, Feb 3, 2011 at 11:58 AM, Philip Fominykh <philip@glyf.org> wrote:
> dan are you making internet do your homework for you again? --philip
>
> On Thu, Feb 3, 2011 at 06:02, Dan Mead <d.w.mead@gmail.com> wrote:
>>
>> Hi guys, I'm having trouble figuring out the proper way to do some
>> macro stuff for my project.
>>
>> I've got a pattern matcher that works as you'd expect. I can take
>> patterns which are quoted s-expressions and match them to actual
>> values. This returns a set of bindings, which I want to use to rewrite
>> a corresponding _expression_.
>>
>> it's working with a regular dumb function that crawls down a quoted
>> _expression_ and does replacement with the bindings list. This is pretty
>> bad as it runs in theta(n) time, and is really brittle when it comes
>> to scoping issues.
>>
>>
>> So, I'm trying to get a macro that will splice the bindings list as a
>> vector and the target _expression_ into a let statement. That way
>> scoping should be less of an issue and it should run in constant time
>> (or whatever let run in etc etc)
>>
>>
>> so, to match some pattern to a set of values we can do
>>
>> user=> (match '(x y z) '(1 2 3))
>> ((x 1) (y 2) (z 3))
>>
>> If that call to the matcher is wrapped in some stuff to convert to a
>> vector, we can do
>>
>> user=> (domatch '(x y z) '(1 2 3))
>> [x 1 y 2 z 3]
>>
>> and clojure agrees that it's a vector
>>
>> user=> (vector? (domatch '(x y z) '(1 2 3)))
>> true
>>
>> if i have a macro like this
>>
>> (defmacro sub [binds expr]
>>  `(let ~binds ~expr))
>>
>> which works fine, if you give it a literal vector
>>
>> user=> (sub [x 1 y 1] (+ x y))
>> 2
>>
>> then why doesn't it work with my call to the matcher?
>>
>> user=> (sub (domatch '(x y z) '(1 2 3)) (+ x y z))
>> java.lang.IllegalArgumentException: let requires a vector for its
>> binding (NO_SOURCE_FILE:0)
>>
>>
>> I'm afraid I've lost the plot here. Any insight you guys could give
>> would be helpful
>>
>> Here is my newbie and entirely too verbose code.
>>
>> http://taz.cs.wcupa.edu/~dmead/patternmatch.clj
>>
>> Dan
>>
>> sorry if you get this post twice
>
>