You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

34 KiB

The Slime 1.0 Manual

abstract

\tableofcontents

Lisp languages

Lisp is not one language but rather a family of programming languages. The family is devided by some characteristics. There are Lisp-1 and Lisp-2 dialects and there is a difference between a Lisp with lexical scoping as opposed to dynamic scoping. These differences will be explained in later sections.

Like most Lisps, Slime is dynamically typed. That means that like in statically typed Languages Slime has different data types, but they are associated not with variables but with the Lisp objects themselves. Variables can be assigend Lisp objects of any internal type.

The Lisp language family is known to be highly flexible and applicable in all areas by creating domain specific languages in Lisp itself through a powerful macro system. The central data structure in Lisp is the list. The reason why lisp is so powerful is because the program source code itself is represented as lists. The nested lists make up the syntax tree of the lisp program. It is therfore computationally easy to parse lisp programs as the source code itself is already structured in the form of the syntax tree; allowing for parsing in linear time.

The macro system in Slime works by recognizing macros at parse-time and running them, and replacing the macro call in the program code with the return value of the macro and then checking if further macros have to be expanded in the replaced code. Therefore the macros can be used to pre-compute values or rewrite expressions (creating syntactic sugar) or themselves define macros.

Lists

As mentioned in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Lisp%20%20languages, the central data structure in all Lisps is the list. Lists are implemented as singly linked lists, made up of pairs (historically called cons-cells), each pair has two slots, the first and the rest (historically car and cdr). A linked lsit ist then constructed by the convention that the first field of a pair points to the first element of the list and the rest field points to the rest of the list. Following this description, the list is a recursive data structure. For the end of the list a special value nil is used in the rest field.

A helpful way to visualize lists made up of pairs is using box diagrams. A simple box diagram can be seen in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/simpleBoxDiagram. Each rectangle is divided in two. The left part represents the first field, the right part represents the rest. The arrows point to the values in these fields.

The diagram in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/simpleBoxDiagram shows a simple list containing the values 1, 2 and 3. The first pair stores the number 1 its first field and the rest points to the rest of the list. The last pair points to the special value nil in its rest to denote the end of the list.

{{{ditaa_header}}}

  +-----+-----+    +-----+-----+    +-----+-----+
  |     |     |    |     |     |    |     |     |
  |     |     |--->|     |     |--->|     |  /  |
  |     |     |    |     |     |    |     |     |
  +-----+-----+    +-----+-----+    +-----+-----+
     |                |                |
     |                |                |
     V                V                V
     1                2                3

/felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/diagrams/list123.esp

However the rest of a pair needs not to be a pair or nil, it could also point to any other value. By doing this the list is no longer "well formed" but rather "ill formed". Ill formed lsits can be used as an optimization when using the list for storing data. In /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/illFormedList an ill formed list can be seen, that also contains the values 1, 2 and 3 but stores them using only two pairs instead of 3.

{{{ditaa_header}}}

  +-----+-----+    +-----+-----+
  |     |     |    |     |     |
  |     |     |--->|     |     |--->3
  |     |     |    |     |     |
  +-----+-----+    +-----+-----+
     |                |
     |                |
     V                V
     1                2

/felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/diagrams/list12.3.eps

representing lists in Lisp

In Slime and in most Lisps, lists are represented using round parenthesis where ( denotes the start of the list and ) denotes the end. Eeach element inside these parenthesis separated by one or more spaces will be interpreted as an element of that list. For example the list from /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/simpleBoxDiagram would be represented as (1 2 3). During parse time, the Lisp parser transforms the parenthesised list into the pairs that are in the end stored in memory.

To also be able to represent ill formed lists in Lisp there is a special syntax using the . (dot symbol). If the parser encounters a . inside of a list, it will treat the next element as the rest. If there is no or more than one element after the . an parsing error will be thrown. Using this syntax we can represent the ill formed list from /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/illFormedList as (1 2 . 3). We can also write well formed lists using the dot notation if we point the rest to another list. So the well formed list from /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/simpleBoxDiagram can also be written as \[\texttt{(1 . (2 . (3)))}\]

representing function calls in Lisp

If we tried to enter the Lisp representation of the lists like (1 2 3) discussed in [[representing lists in Lisp]] directly into an Lisp interpreter we would get an error. That doesn't mean that the explanation given in the section is wrong, it is in fact correct: the lisp parser will transform the lisp syntax into the pairs in memory. The reason we would get an error is, that when reading Lisp code, the Lisp interpreter first parses the code and then tries to evaluate it and return the result back to the user.

In Lisp by default, a list corresponds to a function call. As mentioned in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Lisp%20%20languages Lisp represents lists and Lisp programms as lists. If a list is treated as a function call, the first element will be treated as the function and the rest of the elements will be the arguments to that function. If we would wnter (1 2 3) directly into the Lisp interpreter we would get an error saying it cannot find the function 1.

If we would want to compute the sum of the numbers 5 and 3 we could do this by invoking the + function with 5 and 3 as its arguments. (+ 5 3) will evaluate to 8. We can also nest functions calls and use the return values as parameters to other functions: (+ (- 12 4) (/ 24 4)) will evaluate to 14. The box diagramm showing the internal structure of that computation can be seen in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/moreComplexBoxDiagram.

{{{ditaa_header}}}

  +-----+-----+    +-----+-----+                                        +-----+-----+
  |     |     |    |     |     |                                        |     |     |
  |     |     |--->|     |     |--------------------------------------->|     |  /  |
  |     |     |    |     |     |                                        |     |     |
  +-----+-----+    +-----+-----+                                        +-----+-----+
     |                |                                                    |
     |                |                                                    |
     V                V                                                    V
     +             +-----+-----+    +-----+-----+    +-----+-----+      +-----+-----+    +-----+-----+    +-----+-----+
                   |     |     |    |     |     |    |     |     |      |     |     |    |     |     |    |     |     |
                   |     |     |--->|     |     |--->|     |  /  |      |     |     |--->|     |     |--->|     |  /  |
                   |     |     |    |     |     |    |     |     |      |     |     |    |     |     |    |     |     |
                   +-----+-----+    +-----+-----+    +-----+-----+      +-----+-----+    +-----+-----+    +-----+-----+
                      |                |                |                  |                |                |
                      |                |                |                  |                |                |
                      V                V                V                  V                V                V
                      -               12                4                  /               24                4

/felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/diagrams/simpleMath.eps

Evaluation order

As a first step of evaluation of a regular function, all its arguments are getting evaluated, and then the function is applied to the evaluated arguments. For example when evaluating the nested expression in code:complex-math the outermost function is the + function with three arguments: (* 3 4), (- 100 (+ 12 13 14 15)) and 2. So before the outhermost + gets invoked, the three arguments are getting evaluated recursively.

{{{slime_header}}}

  (print (+ (* 3 4)
            (- 100 (+ 12 13 14 15))
            2))
A more complex nested arithmetic expression. Nested expressions can be written more readable by aligning subsequent arguments vertically underneeth each other
evaluates to =>
60

Special forms

The given evaluation rule – to evaluate all the arguments first and then allpying them to the funciton – as described in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Evaluation%20order is only valid for regular functions. There is a class of functions that do not follow this evaluation rule called special forms. Special forms are needed when you do not wish to evaluate all arguments. For example the built-in if function should only evaluate the "then-expression" if the condition evaluates to a truthy value and not otherwise. Consider the example in code:special-forms. The if expression only evaluates the then-expression. If the if function would follow the evaluation order of regular functions, first all three arguments (< 1 2), (print "I knew it!!\n") but also (print "Oh, it is not?!\n") could get evaluated and so both messages would be printed. In the given if expression, the condition evaluates to a truthy value and only I knew it!! will be printed.

{{{slime_header}}}

  (if (< 1 2)
      (print "I knew it!!\n")
    (print "Oh, it is not?!\n"))
The if function is a special form because it does not evaluate all of its arguments
evaluates to =>
I knew it!!

The programmer can also define their own special forms using special-lambda and macros, which will be explained in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Special%20lambdas and /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Macros.

Symbols and keywords

Truthyness

Lambdas

Slime allows for creating anonymous functions called lambdas. We did not talk about binding variables, we will do this in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Define, but we can still use lambdas now. Remember that Lisp interpretes the first argument of a list in the source code as a function and the rest as the arguments. The lambda special form evaluates to a regular function object that can then stand in the first position of the function call list. The basic syntax for the lambda special form is: \[\texttt{(lambda (arg1 arg2 ...) (body1) ...)}\] the first arguemnt to lambda is a list of the arguments. All the following arguments will be the body of the lambda. They will be executed when the lambda is invoked. The return value of a lambda is the value of the last evaluated expression in the body.

Probably the simplest function to write as a lambda is the identity function. It takes one argument and returns it. The identity lambda and a few other simple examples of lambdas can be seen in code:simple-lambdas.

{{{slime_header}}}

  (printf ((lambda (x) x) 1))
  (printf ((lambda (x y) (+ x y)) 3 5))
  (printf ((lambda (x y z) (list x y z)) 1 2 3))
Some simle lambdas
evaluates to =>
1
8
(1 2 3)

Additionally Slime lambdas have the possibility to take optional arguments in the form of keyword arguemnts as well as a rest argument which allows for accepting any number of arguments. Since these concepts are most useful when the function is actually bound to a variable, they will be introduced when we learned how to do that in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Define.

Special lambdas

The lambda special form creates a function object that represents a regular function. So the basic evaluation rules count: when the lambda is invoked all it's arguments are evaluated and then the lambda is applied to the evaluated arguments. If this is not wanted in some rare cases, the programmer also has the possibility to define a special form using special-lambda, which, when invoked does not evaluare any argument. The programmer has to evaluate the arguments in the body themselves using eval. The rest of the syntax between lambda and special-lambda are the same.

{{{slime_header}}}

  ((lambda         (x) (printf x)) (+ 1 2))
  ((special-lambda (x) (printf x)) (+ 1 2))

  ;; Special lambdas make it possible to write
  ;; code that inspects code
  ((special-lambda (expr)
       (printf "The function to be called is"
               (first expr)
               "and the result is"
               (eval expr)))
   (+ 1 2))
Special lambdas do not evaluate their arguments
evaluates to =>
3
(+ 1 2)
The function to be called is + and the result is 3.

Define

To assign a value to a symbol you can use the define built-in special form. The syntax for define is: \[\texttt{(define symbol value)}\] and some usages can be seen in code:variable-defines.

{{{slime_header}}}

(define var1 1)
(define var2 "Hello World")
(define var3 (+ 1 2))

(printf var1 var2 var3)
Simple definition of variables
evaluates to =>
1 Hello World 3

Defining functions

In /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Lambdas we learned how to create function objects using the lambda built-in form. Using define every Lisp Object can be assigned to a symbol making no exception for the function objects. In code:lambda-defines you can see what that would look like.

{{{slime_header}}}

  (define hypothenuse
    (lambda (a b)
      (** (+ (* a a) (* b b)) 0.5)))

  (printf (hypothenuse 3 4))
Definition of functions using lambdas
evaluates to =>
5

Since defining functions is so common, there is a syntactic shorthand that does not require to write out the whole lambda definition. In this case the first argument to the call to define is a list. The frist element of the list is the name of the function to define and the other elemens are the arguments to that function. An example can be seen in code:function-defines. Note that the definition looks like a call to the function we are constructing, making it easier to see what a call to that function will look like.

{{{slime_header}}}

  (define (hypothenuse a b)
    (** (+ (* a a) (* b b)) 0.5))

  (printf (hypothenuse 3 4))
Definition of functions using the shorthand syntax of define
evaluates to =>
5

Functions with keyword arguments

A sometimes more convenient way of passing arguments to a function is using keyword arguments. Using keyword arguments a function call could look like this: \[\texttt{(function :arg1 value1 :arg2 value2)}\] here the function accepts two arguments named arg1 and arg2. The user of this function can see more clearly excatly which argument will be assigned wich value. This notation also allows for switching the argument order. The following function call is equivalent to the call above. \[\texttt{(function :arg2 value2 :arg1 value1)}\].

For this to work however, the function must be defined to accept these keyword arguments. To do this the special marker :keys has to be inserted into the argument list of a lambda or a function define. All following arguments must be supplied as keyword arguments, unless they are also supplied with a default value, in which case they do not need to be supplied. To attach a default value to a keyword argument, insert :defaults-to <value> after the keyword argument name. An example of all of this can be seen in code:keyword-args. Important note: keyword arguments must be defined and supplied after all the regular arguments.

{{{slime_header}}}

  (define (complex required1 required2 :keys
                   key1
                   key2 :defaults-to 3
                   key3)
    (* (+ required1 required2)
       key1
       key2
       key3))

  (printf (complex 1 2 :key1 2 :key2 2 :key3 3))
  (printf (complex 1 2 :key1 2 :key3 3))
  (printf (complex 1 2 :key3 3 :key1 2))
A more complex functoin definition using keyword arguments
evaluates to =>
36
54
54

Functions with rest arguments

If the programmer wants to create a function that can accept any number of arguments, they can use the rest argument. It is defined after the special marker :rest and after the rest argument, no other arguments can be defined. In the execution of the fuction, the rest arguent will be assigned to a list containing all the supplied values. The rest argument can be used in conjunction with the other argument types, regular arguments and keyword arguments.

{{{slime_header}}}

  (define (execute-operation operation
                             :keys
                             do-logging :defaults-to ()
                             :rest values)
    (define result (apply operation values))
    (when do-logging
      (printf "Executing operation"
              operation
              "agains the values"
              values
              "yielded:"
              result))
    result)

  (printf (execute-operation '+ 1 2 3))
  (printf (execute-operation '*
                             :do-logging t
                             10 11))
A more complex functoin definition using keyword arguments
evaluates to =>
6
Executing operation * agains values (10 11) yielded: 110
110

Environments

Macros

Built-in functions

COMMENT Built-in functions

This section provides a comprehensive list of the built in functions for Slime. Some of them are defined in C++ source code, some are themselves written in Slime. The cool thing about Slime is that it is really easy to extend and adapt it for many purposes by writing new functions in C++ that for example communicate with an already existing software system, so Slime can be used as an embedded scripting language.

Arithmetic functions

+

(regular function [C++]) Takes 0 or more numbers as arguments and returns the sum of all the numbers.

{{{slime_header}}}

(printf (+))
(printf (+ 3))
(printf (+ 1 3 2))
(printf (+ 1 (+ 3 4)))
evaluates to =>
0
3
6
8
-

(regular function [C++]) Takes 0 or more numbers as arguments. If only one number is supplied, its negation is returned, otherwise the difference of the first argument and the sum of the remaining arguments is returned: \[\texttt{(- 10 2 1)} \Rightarrow 10 - 2 - 1 = 10 - (2 + 1) = 7\]

{{{slime_header}}}

(printf (-))
(printf (- 3))
(printf (- 5 3 1))
(printf (- 5 (+ 3 1)))
evaluates to =>
0
-3
1
1
*

(regular function [C++]) Takes 0 or more numbers as arguments and returns the product of all the numbers.

{{{slime_header}}}

(printf (*))
(printf (* 2))
(printf (* 5 3 2))
(printf (* 2 (+ 3 1)))
evaluates to =>
1
2
30
8
/

(regular function [C++]) Takes 0 or more numbers as arguments. If only one number is supplied, it is returned, otherwise the quotient of the first argument and the product of the remaining arguments is returned: \[\texttt{(/ 100 2 5)} \Rightarrow \frac{100}{\frac{2}{5}} = \frac{100}{2 \cdot 5} = 10\]

{{{slime_header}}}

(printf (/))
(printf (/ 3))
(printf (/ 1 2))
(printf (/ 2 (+ 3 2 1)))
evaluates to =>
1
3
0.500000
0.333333
**

(regular function [C++]) Takes 2 number arguments and returns the the first argument taken to the power of the second argument.

{{{slime_header}}}

(printf (** 1 200))
(printf (** 2 6))
(printf (** 25 0.5))
(printf (** 27 (/ 1 3)))
evaluates to =>
1
64
5
3
%

(regular function [C++]) Takes 2 number arguments and rounds them down to integer values and then returns the remainder of the division of the first argument by the second.

{{{slime_header}}}

(printf (% 10 3))
(printf (% (+ 3 (* 12 15)) 15))
evaluates to =>
1
3
not

(regular function [C++])

{{{slime_header}}}

(printf (not 10))
(printf (not ()))
(printf (not (> 10 1)))
(printf (not (< 10 1)))
evaluates to =>
()
t
()
t
and

(regular function [C++])

{{{slime_header}}}

(printf (and))
(printf (and 1 2  3 4))
(printf (and 1 2 () 4))
(printf (and (> 3 1) (< 3 10)))
evaluates to =>
t
t
()
t
or

(regular function [C++])

{{{slime_header}}}

(printf (or))
(printf (or 1 2  3 4))
(printf (or 1 2 () 4))
(printf (or (> 1 3) (< 3 10)))
evaluates to =>
()
t
t
t
increment

(regular function [Slime])

{{{slime_header}}}

  (printf (increment 11))
evaluates to =>
12
decrement

(regular function [Slime])

{{{slime_header}}}

  (printf (decrement 12))
evaluates to =>
11

Comparison functions

=

(regular function [C++]) Takes 0 or more arguments and returns t iff \[\forall\ \text{arg}_i \in \text{arguments}: \text{arg}_i = \text{arg}_{i+1}\] ∈dent and () otherwise.

{{{slime_header}}}

;; numbers
(pe (= 1 (+ -1 2)))
(pe (= 0  (** 3 0)))
;; strings
(pe (= "abc" "abc"))
(pe (= "abc" "abs"))
;; symbols & keywords
(pe (= 'sym1 'sym2))
(pe (= :key1 :key1))
evaluates to =>
(= 1 (+ -1 2)) evaluates to t
(= 0 (** 3 0)) evaluates to ()
(= abc abc) evaluates to t
(= abc abs) evaluates to ()
(= 'sym1 'sym2) evaluates to ()
(= :key1 :key1) evaluates to t
>

(regular function [C++]) Takes 0 or more arguments and returns t iff \[\forall\ \text{arg}_i \in \text{arguments}: \text{arg}_i > \text{arg}_{i+1}\] ∈dent and () otherwise.

>=

(regular function [C++]) Takes 0 or more arguments and returns t iff \[\forall\ \text{arg}_i \in \text{arguments}: \text{arg}_i \ge \text{arg}_{i+1}\] ∈dent and () otherwise.

<

(regular function [C++]) Takes 0 or more arguments and returns t iff \[\forall\ \text{arg}_i \in \text{arguments}: \text{arg}_i < \text{arg}_{i+1}\] ∈dent and () otherwise.

<=

(regular function [C++]) Takes 0 or more arguments and returns t iff \[\forall\ \text{arg}_i \in \text{arguments}: \text{arg}_i \le \text{arg}_{i+1}\] ∈dent and () otherwise.

Controlflow

if

(special form [C++]) Takes 2 or more arguments. If the first argument (the condition) evaluates to a truthy value, the second argument is evaluated and returned. Else if more arguemnts are supplied, they will be evaluated and the last result will be returned, if the condition was falsy and no further arguments were supplied, then nil will be returned.

{{{slime_header}}}

(printf (if 1 1 2))
(printf (if () 1 2))
(printf (if () 1 ))
evaluates to =>
1
2
()
cond

(special form [Slime])

{{{slime_header}}}

  (define (fib n)
    (cond ((<= n 0) 0)
          ((=  n 1) 1)
          (else (+ (fib (- n 1))
                   (fib (- n 2))))))

  (printf (fib 6))
evaluates to =>
8
while

(special form [C++])

{{{slime_header}}}

  (define animals '("Bird" "Dolphin" "Giraffe"))

  (while animals
    (printf (first animals) "is an animal")
    (define animals (rest animals))
    )
evaluates to =>
Bird is an animal
Dolphin is an animal
Giraffe is an animal
n-times

(special form [Slime])

{{{slime_header}}}

(n-times 3 (printf "Three time's a charm"))
evaluates to =>
Three time's a charm
Three time's a charm
Three time's a charm
when

(special form [Slime])

{{{slime_header}}}

(printf (when 1 2 3))
(printf (when () 2 3))
evaluates to =>
3
()
unless

(special form [Slime])

{{{slime_header}}}

(printf (unless 1 2 3))
(printf (unless () 2 3))
evaluates to =>
()
3

Functions for lists

pair

(regular function [C++]) Takes 2 arguments of any type and return a pair which first field points to the first argument and the rest field points to the second argument.

{{{slime_header}}}

(printf (pair 1 "yes"))
(printf (pair '+ ()))
(printf (pair '+ (pair 1 (pair 3 ()))))
(printf (eval (pair '+ '(1  3))))
evaluates to =>
(1 . yes)
(+)
(+ 1 3)
4
first

(regular function [C++]) Takes a list as argument and returns the contents of its first field.

{{{slime_header}}}

(printf (first (pair 1 3)))
(printf (first (list 2 3)))
(printf (first '("hello" "world")))
evaluates to =>
1
2
hello
rest

(regular function [C++]) Takes a list as argument and returns the contents of its rest field.

{{{slime_header}}}

(printf (rest (pair 1 3)))
(printf (rest (list 2 3)))
(printf (rest '("hello" "world")))
list

(regular function [C++]) Takes any number of arguments, evaluates each and returns a list containing the results.

{{{slime_header}}}

  (printf (list))
  (printf (list 1 2 3))
  (printf (list (pair 1 2)
                '(3 4)
                (list 5 6)))
evaluates to =>
()
(1 2 3)
((1 . 2) (3 4) (5 6))
length

(regular function [Slime]) Takes a list as argument and returns the number of elements in that list.

{{{slime_header}}}

  (printf (length ()))
  (printf (length '(1 2 3)))
  (printf (length '(+ 1 4 (+ 2 3))))
evaluates to =>
0
3
4
end

(regular function [Slime]) Takes a list as argument. Returns the last pair in the list.

{{{slime_header}}}

  (printf (end ()))
  (printf (end '(1 2 3)))
  (printf (end '(+ 1 4 (+ 2 3))))
evaluates to =>
()
(3)
((+ 2 3))
last

(regular function [Slime]) Takes a list as argument. Returns the last element in the list.

{{{slime_header}}}

  (printf (last ()))
  (printf (last '(1 2 3)))
  (printf (last '(+ 1 4 (+ 2 3))))
evaluates to =>
()
3
(+ 2 3)
extend

(regular function [Slime]) Takes a list and any

append

(regular function [Slime])

range

(regular function [Slime])

range-while

(regular function [Slime])

zip

(regular function [Slime])

enumerate

(regular function [Slime])

map

(regular function [Slime])

filter

(regular function [Slime])

reduce

(regular function [Slime])

reduce-binary

(regular function [Slime])

Functions on types

type

(regular function [C++])

set-type

(regular function [C++])

delete-type

(regular function [C++])

symbol->keyword

(regular function [C++])

string->symbol

(regular function [C++])

symbol->string

(regular function [C++])

Help and debugging

break

(regular function [C++])

memstat

(regular function [C++])

info

(regular function [C++])

show

(regular function [C++])

pe

(special form [Slime])

I/O

print

(regular function [C++])

read

(regular function [C++])

printf

(regular function [Slime])

Errors

try

(regular function [C++])

error

(regular function [C++])

no category

eval

(regular function [C++])

apply

(regular function [C++])

lambda

(special form [C++]) See the section about Lambdas in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Lambdas.

special-lambda

(special form [C++]) See the section about Lambdas in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Lambdas.

copy

(regular function [C++])

import

(regular function [C++])

load

(regular function [C++])

exit

(regular function [C++])

let

(regular function [C++])

quote

(regular function [C++])

quasiquote

(regular function [C++])

unquote

(regular function [C++])

mutate

(regular function [C++])

define

(special form [C++]) See the section about define in /felix/slime/src/commit/a442d2ecec63bcf90c51c642fb452e032fa93997/manual/Define.

assert

(regular function [C++])

COMMENT testbox