On Tue, Aug 28, 2012 at 1:08 PM, Armando Blancas <abm221...@gmail.com> wrote: > I'm playing around with a parser combinator library from the paper Monadic > Parser Combinators by Hutton and Meijer [1] and came up with this: > > https://gist.github.com/3501273 > > That's just enough to show the error I'm getting when (expr) calls (factor): > > Clojure 1.4.0 > user=> (load-file "expr.clj") > #'user/expr > user=> (run expr "(5)") > IllegalStateException Attempting to call unbound fn: #'user/expr > clojure.lang.Var$Unbound.throwArity (Var.java:43) > > To avoid this error, I coded a new version of the parser (factor) but in > this case I use inline calls to (bind) instead of using parser (between), > which makes it work: > > Now using (parser*) inside the definition of (expr): (def expr (bind facfor* > ...) > > Clojure 1.4.0 > user=> (load-file "expr.clj") > #'user/expr > user=> (run expr "(5)") > 5 > > I thought it was a bug but this may have to do with the forward declaration > of "expr" and when is deref'ed. After much trying I can't see why this won't > work: > > (def factor > (choice (between (match \() (match \)) expr) > integer))
(def factor ...) immediately gets the value of the body to assign to the var #'factor. (choice ...) is a function, so has to get the values of it's arguments before invoking. This means it gets the value of expr, which unbound and uses that. > > But this will: > > (def factor* > (choice (bind (match \() (fn [_] > (bind expr (fn [e] > (bind (match \)) (fn [_] (result e))))))) > integer)) This occurs similar to the above, except it hits a fn. fn is a "special form" defined to wait to get the value of its body until it is executed. By that time the (def expr ...) has occurred and #'expr has a bound value. A similar effect can be achieved with (def factor (choice (between (match \() (match \)) (fn [x] (expr x))) integer)) I ran into the same thing re-exploring that paper in clojure. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en