This document will help us rewrite Carp's dynamic evaluator (defined in Eval.hs) to make it behave in a more principled and non-surprising way.
- Fix the various bugs related to dynamic evaluation that has been found (see "Relevant issues" below).
- Add missing features that are to be expected in a dynamic Lisp (see below).
- Make it easy to extend the dynamic evaluator with new features in the future.
- carp-lang/Carp#560
- carp-lang/Carp#555
- carp-lang/Carp#545
- carp-lang/Carp#476
- carp-lang/Carp#556
- carp-lang/Carp#659
- carp-lang/Carp#660
- carp-lang/Carp#453
- Documentation on how to use the dynamic language and the macro system
- Complete macro facilities (quasiquoting, splicing, complete error reporting, etc)
- Dynamic stack traces
- Auto completion of user-defined names
[TODO]
- form : Any valid Carp data struture as represented in text.
- top level : Any form that isn't embedded in another form.
- Static Carp : The compiled version of the Carp language.
- Dynamic Carp : The interpreted, functional, GC'ed version of the Carp language.
Related issues:
Questions:
Lexical scoping (look in the current scope, then any enclosing scope, up until global scope). Things that create scopes:
- function definitions (defn, defndynamic, fn)
- let
- modules
(set! <symbol> <value>)
Yes (see the Parsing module for more info)
- defn
- def
- do
- while
- fn
- let
- break
- if
- match
- true
- false
- address
- set!
- the
- ref
- deref
- with
More things should be moved to the reserved list, actually.
The :rest
token in defmacro is also reserved.
There are no keywords. Maybe will be in the macros, see this implementation https://gist.github.com/sdilts/73a811a633bb0ef3dd7e31b84a138a5a.
They use the same modules but dynamic lookup will only find dynamic functions, and static lookup will only find static functions.
Questions:
Yes.
Using set!
. The mutation comes into effect immedately (using IORefs internally).
Lexical (no dynamic scope for anything).
Questions:
Yup.
Lexical scoping rules, functions and let create new variables.
No captured variables are mutable.
The dynamic lambdas captures the whole environment at the time the closure is created (when the (fn ...)
form is evaluated).
Questions:
Using .
, Foo.a and Bar.a.
By using (use <module name>)
you can avoid having to specify the module.
Runtime error when looking up the symbol.
Neither, unless any single one of the modules (Foo/Bar) is imported with use
. If both are imported the lookup is an error since it can't be resolved to a single value.
Yes. Types live in a different namespace.
Questions:
Dynamic context:
- defndynamic (creates dynamic functions)
- defdynamic (creates dynamic global variables)
- defmacro (creates macros)
Static context:
- defn (creates static functions)
- def (creates static global variables)
- deftype (for defining product- and sumtypes)
- register (for making external functions available)
All contexts:
- defmodule
Related issues:
Questions:
Questions:
- What is a macro?
- What functions are available at macro-expansion time?
- What is quasi-quoting and what is its syntax?
- What is splicing, and what is its syntax?
Questions:
- How does the REPL know when to evalutate something in the dynamic or static context?
- When does it decide to run the given code in the dynamic or static context?
Issues:
Questions:
- What types are available?
- When is a form typechecked?
- How do you refer to a specific type? Are types first class citizens?