On Tuesday, August 28, 2012 1:01:32 PM UTC-7, Nelson Morris wrote:
> On Tue, Aug 28, 2012 at 1:08 PM, Armando Blancas <abm2...@gmail.com<javascript:>>
> 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.