(This is a really early version, which assumes you know some Lisp.)
Adder is a Lisp-1, meaning that function names are variable names,
as in Scheme. By contrast, in a Lisp-2, such as Common Lisp or Emacs
Lisp, function names are a separate namespace, so that, in the
(foo foo), the two
unrelated. (Python also has a single namespace, while Ruby has two.
I sometimes think of Python as a Perl-1, and Ruby as a Perl-2.) All
names must be defined before being used; setting a variable without
defining it is an error. There are no Common Lisp-style packages; a
symbol is purely a name.
Adder supports object field access via Python syntax: foo.bar.baz, for example. There is also a Lispy syntax, as in (. foo bar baz), which you'll need when you want to access a field of an object that's not in a variable. In addition, .bar.baz is a function, so that (.bar.baz foo) is equivalent to foo.bar.baz. This is so you can write functional code without having to write quite so many trivial lambdas. The equivalent Lispy syntax is (.. bar baz).
All Python builtins are available as members of the object
python; so, for example, (python.sum '(1 2 3)) is
Adder supports Common Lisp-style (defmacro).
from. For example,
(import foo bar)is equivalent to Python's
import foo,bar. Note that modules written in Adder can be imported, too—in fact, they can even be imported into Python. See Modules, below.
(class ClassName (...ParentNames...) ...code...). As in Python, the class definition encloses a block of code which is executed in class scope. For example:
(import math) (class Point () (define __init__ (self x y) (:= (. self x) x) (:= (. self y) y)) (define (dist self other) (math.sqrt (+ (* (- other.x self.x) (- other.x self.x)) (* (- other.y self.y) (- other.y self.y))))) )
(begin), but introduces a new lexical scope. You probably want
(extern foo)declares that the runtime environment will contain a variable named
foo. Used for code which is run dynamically, relying on variables set externally (e.g., HTML templates). Returns the value of
(begin (defvar x 9) (exec-py "x=7") x)will return 9, not 7, since the
xin Adder is actually
x-1, which gets translated into
(.. bar baz)is equivalent to
(lambda (x) (. x bar baz)).
(define (f x) (* x x))or
(define y 9).
for bar in foo: yield bar(For example, if you're recursing down a tree.) In Adder, this would be
(yield* foo): yield all the elements which foo would yield. In Adder,
yield*is a simple macro; in Python, it's impossible.
Modules can be written in Adder, and can be imported into Adder and
into Python. To make sure the Adder modules
in the directory
/foo/bar/baz are available, put
sys.path (aka the
PYTHONPATH). If the
/foo/bar/+baz+ actually exists, this won't work.
If you have a Python program, and you want to import an Adder
module, you'll need to
import adder before you import
the first Adder module; that inserts the
used to load Adder modules.
When you import an Adder module,
it gets compiled to Python; if the Adder module's source was
Python code is cached in
/foo/bar/baz/quux.py. At this
/foo/bar/baz/quux.pyc does not get created; that
might be a nice little speedup.