Open spy16 opened 4 years ago
Quick note about the if
expression: I'm unable to use it or to replicate it in Wetware because
parseIf
is not exported (so I can't reuse it in my own Analyzer
type)env.analyzer
is not exported (so I can't re-implement it)In this particular case, I could embed BuiltinAnalyzer
into my custom implementation, but I think that would miss the larger point: it feels wrong to have certain special forms only be implementable in parens itself.
Yes, I am aware of this issue but yet to decide on a solution. (Like I had mentioned on the other thread, I am always skeptical of making things public unless they are absolutely needed 😅). Do let me know if you have any other suggestions on this.
Yup, makes sense! BTW I share your skepticism on the issue of exporting symbols, so 👍.
I don’t have a solution in mind either — just wanted to flag the issue. I’ll let you know if I come up with anything.
@spy16 The latest commit breaks Wetware's def
special form since parens.DefExpr
now depends on env.analyzer
under the hood.
I've given this a bit of thought and haven't been able to come up with a solution other than exporting Analyze()
from Env
, so I'm going to open a PR with this straightforward fix. If we come up with a better approach, we can integrate it later (ideally before the 1.0 release).
Have you had any breakthroughs on your end?
Ohh. Yea, def
was previously invoking Eval(env)
during analyse which was a bug. So i had to change it to only analyse the form provided for binding.
I haven't come up with any solution too (probably because exposing Analyse is the right solution).. Go ahead with the PR.
Another problem to keep in mind (while implementing your custom analyser/exprs for example):
currently Analyse
takes an Env argument. And also the Expr.Eval(env)
takes an env argument. Env should actually be bound to the expr at analyse time and Eval()
should simply use that. Which means, all the Expr types would need to keep the env
used during analyse inside them. So the Expr
contract will probably change to:
type Expr interface {
Eval() (Any, error)
}
(do <expr>*)
(if test then else?)
(def sym value)
(quote expr)
(let ( binding* ) expr*)
(fn name? ( param* ) expr*)