Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Final Design #7

Merged
merged 10 commits into from
Oct 24, 2020
Merged

WIP: Final Design #7

merged 10 commits into from
Oct 24, 2020

Conversation

spy16
Copy link
Owner

@spy16 spy16 commented Oct 17, 2020

I think I finally found a satisfactory design for this. Some highlights:

  1. Env is an interface and only represents the context of evaluation. It does not do the evaluation. This allows custom Expr same set of facilties available for builtin Exprs.
  2. Env provides a Child(name string, vars map[string]core.Any) Env method that allows us to create a stack for a single thread execution. This is also necessary for supporting closures since we need to extend the closing environment for creating the func.
  3. Analyzer and Env are separate allowing us to independently customize. This also means, we can have an Interpreter type of struct that composes a reader, analyzer and env to give a single executor that can expose things like ReadEval, Eval etc. and also stacktrace generation etc.

Note: This PR only has the final overall architecture model. But still needs some changes to be the final repo structure.

  1. builtin.NewAnalyzer does not let you set custom special-form parsers for now..
  2. All the value types are dumped inside builtin package ( i did that to have some separation from already existing types during experimenting) - may be we should have it in the root slurp package itself.

@spy16 spy16 requested a review from lthibault October 17, 2020 07:04
@spy16 spy16 added this to the v1.0 milestone Oct 17, 2020
@spy16 spy16 changed the title Final Design WIP: Final Design Oct 17, 2020
@spy16
Copy link
Owner Author

spy16 commented Oct 17, 2020

🎉 Added support for closures.

;; notice that the parameters are specified in pure-LISP form since we 
;; don't have vectors yet.
(def foo (fn f1 (a) 
                 (fn f2 (b) 
                     (fn f3 (c) 
                         (+ a b c)))))

(((foo 1) 2) 3) 
;; returns 6 as expected,

(def adds3 ((foo 1) 2))
(adds3 10)
;; returns 13 as expected.

🎉 Added support for macro (with no syntax-quote/unquote support yet) (Refer #4)

(def foo (macro (a) ''a))

(foo 10)
;; returns a as expected

@spy16 spy16 marked this pull request as draft October 17, 2020 17:17
@spy16 spy16 marked this pull request as ready for review October 18, 2020 14:25
@spy16
Copy link
Owner Author

spy16 commented Oct 18, 2020

@lthibault This project has been stuck at the same incomplete/unstable state for a while now 😅. I think this PR finally has the base that we can build on.​ I would like to finalize a repo structure and make a release with these changes. Bit confused about what structure to go with.. Let me know if you any suggestions here.

Approach 1

  • core package with only the core primitives (interfaces like Env, Analyzer, Any , Expr etc. and their errors, functions that build on them such as Eval, Root etc.)..

  • All the built-in value types, default analyzer etc. in a bultins pakage. slurp only wires all of them to provide a usable interpreter setup. slurp.New() should return a working interpreter.

  • Pros: Very thin & clear core package, Clear separation of what is essential to using slurp (i.e., core) and what is only the default and can be replaced (builtins)..

  • Cons: Too many packages, Users need to use builtin.Int64, builtin.NewList etc. opposed to more clearer slurp.Int64 etc.

Approach 2

  • core package contains core primitives as defined above along with built-in value types.

  • default analyzer can be in core or can be in slurp root package.

  • Pros: Less packages, more complete and functional core package I think.

  • Cons: Fat core. Users need to use core.Int64 etc. which doesn't exactly say Int64 is coming from slurp core. (as in slurp.New())

Approach 3

  • core package with only the core primitives (interfaces like Env, Analyzer, Any , Expr etc. and their errors, functions that build on them such as Eval, Root etc.)..

  • all built-in value types and default analyzer in slurp root pacakge.

  • Pros: Less packages, verythin & clear core package

  • Cons: Fat slurp package.

Approach 4

  • core package with only the core primitives (interfaces like Env, Analyzer, Any , Expr etc. and their errors, functions that build on them such as Eval, Root etc.)..
  • all built-in value types and default analyzer in slurp root pacakge.
  • Pros: Less packages, verythin & clear core package
  • Cons: Fat slurp package.

Or just everything in slurp root package which will make the slurp fat but is the simplest approach.

README.md Outdated Show resolved Hide resolved
slurp.go Outdated Show resolved Hide resolved
slurp.go Outdated Show resolved Hide resolved
@lthibault
Copy link
Collaborator

@spy16 This is really great!!! 🎉 🚀 🔥 Thanks for doing this!

I flagged a couple of minor issues, but I think this is pretty much ready to merge at your convenience.

In terms of package structure, I'm most favorable to approach 1. My reasoning is that since we're aiming for a build-your-own-lisp toolkit, a clear separation between core functionality (core) and "included batteries" (builtins, etc.) is more important than keeping the number of packages small. I tend to think of package names as part of the documentation, so fewer packages is not necessarily better, IMHO. Lastly, I really like the ease of entry that slurp.New() provides.

Minor suggestion: I would go with builtin instead of the plural builtins. I think it reads better, and shortens a package name that is near the upper bound of "acceptably short".

Anyway, 👍. Merge when ready!

P.S. I'm still using parens for now, so feel free to merge this in an incomplete state and add the remaining features in separate PRs, if that's easier.

@spy16 spy16 merged commit 9ac97fc into master Oct 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants