2 ms·
Every Lisp has syntax. But the code is actual data and there is a separate syntax for this data, called s-expressions. Source code is actually simple nested li
by lispm 4y ago
Every Lisp has syntax. But the code is actual data and there is a separate syntax for this data, called s-expressions.
Source code is actually simple nested list data. For example the following snippet, which binds two variables A and B, defines a local function and then calls this local function. This is just an s-expression, which consists of symbols, numbers and lists.
Even though s-expressions have a syntax with numbers, parentheses, symbols, ... - they can not only be written in a text editor, one can also directly compute with them using the typical Lisp operators for lists, numbers, strings, symbols, ...
The following enters literal data, which is not executed as code.
CL-USER 5 > '(let ((a (+ 1 2))
(b (* 2 3)))
(flet ((add3 (a b)
(+ 3 a b)))
(add3 a b)))
(LET ((A (+ 1 2))
(B (* 2 3)))
(FLET ((ADD3 (A B)
(+ 3 A B)))
(ADD3 A B)))
We can substitute the symbol * with the symbol expt in this s-expression - the variable * just holds the last evaluation result:
CL-USER 6 > (subst 'expt '* *)
(LET ((A (+ 1 2))
(B (EXPT 2 3)))
(FLET ((ADD3 (A B)
(+ 3 A B)))
(ADD3 A B)))
Then this can be evaluated:
CL-USER 7 > (eval *)
14
Now, even though the program is written as a data structure, the Lisp program itself has syntax. Only function calls have the simple (operator args...) syntax. But there are also special forms and macro forms.
LET is a syntactic form and expects a list of (variable value) pairs as its first sub-expression. Then follows a body of subexpressions, where the variables can be used.
FLET is a another syntactic form: it expects a list of function definitions and a body. The function definition starts with a name, followed by an arglist and then by a body.
In reality this is more complex, since LET and FLET allow declarations, functions allow complex argument lists, declarations, documentations, etc.
So for FLET the top-level EBNF syntax would be like:
flet ((function-name lambda-list
[[local-declaration* | local-documentation]]
local-form*)*)
declaration*
form*
With more syntax for lambda-list, declaration, documentation and form.