spy16 / parens

Parens is a highly flexible and embeddable LISP toolkit. :computer:
33 stars 3 forks source link

Implement builtin special forms #26

Open spy16 opened 4 years ago

spy16 commented 4 years ago
lthibault commented 4 years ago

Quick note about the if expression: I'm unable to use it or to replicate it in Wetware because

  1. parseIf is not exported (so I can't reuse it in my own Analyzer type)
  2. 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.

spy16 commented 4 years ago

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.

lthibault commented 4 years ago

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.

lthibault commented 3 years ago

@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?

spy16 commented 3 years ago

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)
}