#+title: The Slime 1.0 Manual

#+begin_abstract
abstract
#+end_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 [[Lisp  languages]], 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  [[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 [[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}}}
#+begin_src ditaa :file diagrams/list123.eps
  +-----+-----+    +-----+-----+    +-----+-----+
  |     |     |    |     |     |    |     |     |
  |     |     |--->|     |     |--->|     |  /  |
  |     |     |    |     |     |    |     |     |
  +-----+-----+    +-----+-----+    +-----+-----+
     |                |                |
     |                |                |
     V                V                V
     1                2                3
#+end_src

#+name: simpleBoxDiagram
#+caption: Box diagram showing the internal structure of a list containing the values 1, 2 and 3
#+RESULTS:
[[file: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 [[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}}}
#+begin_src ditaa :file diagrams/list12.3.eps
  +-----+-----+    +-----+-----+
  |     |     |    |     |     |
  |     |     |--->|     |     |--->3
  |     |     |    |     |     |
  +-----+-----+    +-----+-----+
     |                |
     |                |
     V                V
     1                2
#+end_src

#+name: illFormedList
#+caption: The internal structure of an ill formed list where the last pair points to the value 3
#+RESULTS:
[[file: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
[[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 [[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 [[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 [[Lisp  languages]] 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
[[moreComplexBoxDiagram]].

{{{ditaa_header}}}
#+begin_src ditaa :file diagrams/simpleMath.eps
  +-----+-----+    +-----+-----+                                        +-----+-----+
  |     |     |    |     |     |                                        |     |     |
  |     |     |--->|     |     |--------------------------------------->|     |  /  |
  |     |     |    |     |     |                                        |     |     |
  +-----+-----+    +-----+-----+                                        +-----+-----+
     |                |                                                    |
     |                |                                                    |
     V                V                                                    V
     +             +-----+-----+    +-----+-----+    +-----+-----+      +-----+-----+    +-----+-----+    +-----+-----+
                   |     |     |    |     |     |    |     |     |      |     |     |    |     |     |    |     |     |
                   |     |     |--->|     |     |--->|     |  /  |      |     |     |--->|     |     |--->|     |  /  |
                   |     |     |    |     |     |    |     |     |      |     |     |    |     |     |    |     |     |
                   +-----+-----+    +-----+-----+    +-----+-----+      +-----+-----+    +-----+-----+    +-----+-----+
                      |                |                |                  |                |                |
                      |                |                |                  |                |                |
                      V                V                V                  V                V                V
                      -               12                4                  /               24                4



#+end_src

#+name: moreComplexBoxDiagram
#+caption: The internal structure of the expression =(+ (- 12 4) (/ 24 4))=
#+RESULTS:
[[file: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}}}
#+name: code:complex-math
#+caption: A more complex nested arithmetic expression. Nested  expressions can  be written  more
#+caption: readable by aligning  subsequent arguments vertically underneeth each other
#+begin_src slime
  (print (+ (* 3 4)
            (- 100 (+ 12 13 14 15))
            2))
#+end_src

#+RESULTS: code:complex-math
: 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 [[Evaluation order]] 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}}}
#+name: code:special-forms
#+caption: The =if= function is a special form because it does not evaluate all of its arguments
#+begin_src slime
  (if (< 1 2)
      (print "I knew it!!\n")
    (print "Oh, it is not?!\n"))
#+end_src

#+RESULTS: code:special-forms
: evaluates to =>
: I knew it!!

The programmer can also define their own special forms using =special-lambda= and macros, which will
be explained in [[Special lambdas]] and [[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  [[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}}}
#+name: code:simple-lambdas
#+caption: Some simle lambdas
#+begin_src slime
  (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))
#+end_src

#+RESULTS: code:simple-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 [[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}}}
#+name: code:special-lambdas
#+caption: Special lambdas do not evaluate their arguments
#+begin_src slime
  ((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))
#+end_src

#+RESULTS: code:special-lambdas
: 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}}}
#+name: code:variable-defines
#+caption: Simple definition of variables
#+begin_src slime
(define var1 1)
(define var2 "Hello World")
(define var3 (+ 1 2))

(printf var1 var2 var3)
#+end_src

#+RESULTS: code:variable-defines
: evaluates to =>
: 1 Hello World 3

** Defining functions
In  [[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}}}
#+name: code:lambda-defines
#+caption: Definition of functions using lambdas
#+begin_src slime
  (define hypothenuse
    (lambda (a b)
      (** (+ (* a a) (* b b)) 0.5)))

  (printf (hypothenuse 3 4))
#+end_src

#+RESULTS: code:lambda-defines
: 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}}}
#+name: code:function-defines
#+caption: Definition of functions using the shorthand syntax of define
#+begin_src slime
  (define (hypothenuse a b)
    (** (+ (* a a) (* b b)) 0.5))

  (printf (hypothenuse 3 4))
#+end_src

#+RESULTS: code:function-defines
: 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}}}
#+name: code:keyword-args
#+caption: A more complex functoin definition using keyword arguments
#+begin_src slime
  (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))
#+end_src

#+RESULTS: code:keyword-args
: 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}}}
#+name: code:rest-args
#+caption: A more complex functoin definition using keyword arguments
#+begin_src slime
  (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))
#+end_src

#+RESULTS: code:rest-args
: evaluates to =>
: 6
: Executing operation * agains values (10 11) yielded: 110
: 110

* Environments
* Macros
* 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}}}
#+name: code:built-in-=
#+begin_src slime
(printf (+))
(printf (+ 3))
(printf (+ 1 3 2))
(printf (+ 1 (+ 3 4)))
#+end_src

#+results: code:built-in-=
: 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}}}
#+name: code:built-in--
#+begin_src slime
(printf (-))
(printf (- 3))
(printf (- 5 3 1))
(printf (- 5 (+ 3 1)))
#+end_src

#+RESULTS: code:built-in--
: 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}}}
#+name: code:built-in-*
#+begin_src slime
(printf (*))
(printf (* 2))
(printf (* 5 3 2))
(printf (* 2 (+ 3 1)))
#+end_src

#+RESULTS: code:built-in-*
: 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}}}
#+name: code:built-in-/
#+begin_src slime
(printf (/))
(printf (/ 3))
(printf (/ 1 2))
(printf (/ 2 (+ 3 2 1)))
#+end_src

#+RESULTS: code:built-in-/
: 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}}}
#+name: code:built-in-**
#+begin_src slime
(printf (** 1 200))
(printf (** 2 6))
(printf (** 25 0.5))
(printf (** 27 (/ 1 3)))
#+end_src

#+RESULTS: code:built-in-**
: 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}}}
#+name: code:built-in-mod
#+begin_src slime
(printf (% 10 3))
(printf (% (+ 3 (* 12 15)) 15))
#+end_src

#+RESULTS: code:built-in-%
: evaluates to =>
: 1
: 3

 - =not= :: (=regular function [C++]=)

{{{slime_header}}}
#+name: code:built-in-not
#+begin_src slime
(printf (not 10))
(printf (not ()))
(printf (not (> 10 1)))
(printf (not (< 10 1)))
#+end_src

#+RESULTS: code:built-in-not
: evaluates to =>
: ()
: t
: ()
: t

 - =and= :: (=regular function [C++]=)

{{{slime_header}}}
#+name: code:built-in-and
#+begin_src slime
(printf (and))
(printf (and 1 2  3 4))
(printf (and 1 2 () 4))
(printf (and (> 3 1) (< 3 10)))
#+end_src

#+RESULTS: code:built-in-and
: evaluates to =>
: t
: t
: ()
: t

 - =or= :: (=regular function [C++]=)

{{{slime_header}}}
#+name: code:built-in-org
#+begin_src slime
(printf (or))
(printf (or 1 2  3 4))
(printf (or 1 2 () 4))
(printf (or (> 1 3) (< 3 10)))
#+end_src

#+RESULTS: code:built-in-org
: evaluates to =>
: ()
: t
: t
: t

 - =increment= :: (=regular function [Slime]=)
{{{slime_header}}}
#+name: code:built-in-increment
#+begin_src slime
  (printf (increment 11))
#+end_src

#+RESULTS: code:built-in-increment
: evaluates to =>
: 12


 - =decrement= :: (=regular function [Slime]=)
{{{slime_header}}}
#+name: code:built-in-decrement
#+begin_src slime
  (printf (decrement 12))
#+end_src

#+RESULTS: code:built-in-decrement
: 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}\]
          \indent and =()= otherwise.

{{{slime_header}}}
#+begin_src slime
;; numbers
(pe (= 1 (+ -1 2)))
(pe (= 0  (** 3 0)))
;; strings
(pe (= "abc" "abc"))
(pe (= "abc" "abs"))
;; symbols & keywords
(pe (= 'sym1 'sym2))
(pe (= :key1 :key1))
#+end_src

#+RESULTS:
: 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}\]
          \indent 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}\]
           \indent 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}\]
          \indent 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}\]
           \indent 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}}}
#+name: built-in-if
#+begin_src slime
(printf (if 1 1 2))
(printf (if () 1 2))
(printf (if () 1 ))
#+end_src

#+RESULTS: built-in-if
: evaluates to =>
: 1
: 2
: ()

 - =cond=  :: (=special form [Slime]=)

{{{slime_header}}}
#+name: built-in-cond
#+begin_src slime
  (define (fib n)
    (cond ((<= n 0) 0)
          ((=  n 1) 1)
          (else (+ (fib (- n 1))
                   (fib (- n 2))))))

  (printf (fib 6))
#+end_src

#+RESULTS: built-in-cond
: evaluates to =>
: 8

 - =while= :: (=special form [C++]=)

{{{slime_header}}}
#+name: built-in-while
#+begin_src slime
  (define animals '("Bird" "Dolphin" "Giraffe"))

  (while animals
    (printf (first animals) "is an animal")
    (define animals (rest animals))
    )
#+end_src

#+RESULTS: built-in-while
: evaluates to =>
: Bird is an animal
: Dolphin is an animal
: Giraffe is an animal


 - =n-times= :: (=special form [Slime]=)

{{{slime_header}}}
#+name: built-in-n-times
#+begin_src slime
(n-times 3 (printf "Three time's a charm"))
#+end_src

#+RESULTS: built-in-n-times
: evaluates to =>
: Three time's a charm
: Three time's a charm
: Three time's a charm


 - =when=   :: (=special form [Slime]=)

{{{slime_header}}}
#+name: built-in-when
#+begin_src slime
(printf (when 1 2 3))
(printf (when () 2 3))
#+end_src

#+RESULTS: built-in-when
: evaluates to =>
: 3
: ()

 - =unless= :: (=special form [Slime]=)

{{{slime_header}}}
#+name: built-in-unless
#+begin_src slime
(printf (unless 1 2 3))
(printf (unless () 2 3))
#+end_src

#+RESULTS: built-in-unless
: 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}}}
#+name: built-in-pair
#+begin_src slime
(printf (pair 1 "yes"))
(printf (pair '+ ()))
(printf (pair '+ (pair 1 (pair 3 ()))))
(printf (eval (pair '+ '(1  3))))
#+end_src

#+RESULTS: built-in-pair
: 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}}}
#+name: built-in-first
#+begin_src slime
(printf (first (pair 1 3)))
(printf (first (list 2 3)))
(printf (first '("hello" "world")))
#+end_src

#+RESULTS: built-in-first
: evaluates to =>
: 1
: 2
: hello


 - =rest= :: (=regular function [C++]=) Takes a list as argument and returns the contents of its
              =rest= field.
{{{slime_header}}}
#+name: built-in-rest
#+begin_src slime
(printf (rest (pair 1 3)))
(printf (rest (list 2 3)))
(printf (rest '("hello" "world")))
#+end_src


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

{{{slime_header}}}
#+name: built-in-list
#+begin_src slime
  (printf (list))
  (printf (list 1 2 3))
  (printf (list (pair 1 2)
                '(3 4)
                (list 5 6)))
#+end_src

#+RESULTS: built-in-list
: 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}}}
#+name: built-in-length
#+begin_src slime
  (printf (length ()))
  (printf (length '(1 2 3)))
  (printf (length '(+ 1 4 (+ 2 3))))
#+end_src

#+RESULTS: built-in-length
: evaluates to =>
: 0
: 3
: 4

 - =end= ::  (=regular function [Slime]=) Takes a list as argument. Returns the last pair in the
            list.
{{{slime_header}}}
#+name: built-in-end
#+begin_src slime
  (printf (end ()))
  (printf (end '(1 2 3)))
  (printf (end '(+ 1 4 (+ 2 3))))
#+end_src

#+RESULTS: built-in-end
: evaluates to =>
: ()
: (3)
: ((+ 2 3))

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

{{{slime_header}}}
#+name: built-in-last
#+begin_src slime
  (printf (last ()))
  (printf (last '(1 2 3)))
  (printf (last '(+ 1 4 (+ 2 3))))
#+end_src

#+RESULTS: built-in-last
: 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 [[Lambdas]].
 - =special-lambda= :: (=special form [C++]=) See the section about =Lambdas= in [[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 [[Define]].
 - =assert= :: (=regular function [C++]=)
* testbox                                                          :noexport:
#+BEGIN_SRC ditaa :file diagrams/test.eps :cmdline --no-separation --no-shadows
+-----+-----+    +-----+-----+    +-----+-----+    +-----+-----+
|     |     |    |     |     |    |     |     |    |     |     |
|     |     |--->|     |     |--->|     |     |--->|     |  /  |
|     |     |    |     |     |    |     |     |    |     |     |
+-----+-----+    +-----+-----+    +-----+-----+    +-----+-----+
   |
   |
   V
+-----+-----+
|     |     |
|     |  /  |
|     |     |
+-----+-----+
#+END_SRC

#+RESULTS:
[[file:diagrams/test.eps]]

{{{slime_header}}}
#+caption: Some text to illustrate
#+begin_src slime
  (define (fib x)
    (cond ((< x 1) 0)
          ((= x 1) 1)
          (else (+ (fib (- x 1))
                   (fib (- x 2))))))

  (print (if (> (fib 3) 1)
      "Hello World\n"
    "Goodbye World\n"))

  (fib 12)
#+end_src

#+RESULTS:
: => Hello Felixses
: 144.000000

{{{slime_header}}}
#+caption: Some text to illustrate
#+begin_src slime
  ;; Comment here
  (print "String here")
  (+ 1 2 3)
#+end_src

#+RESULTS:
: => String here6.000000

* meta                                                             :noexport:
# local variables:
# org-confirm-babel-evaluate: nil
# end:

#+author: Felix Brendel
#+mail: felix.brendel@airmail.cc
#+options: H:2 toc:nil

#+macro: slime_header (eval (concat "#+header: :exports both" "\n" "#+attr_latex: :options keywordstyle=\\color{slimeKeyword}, commentstyle=\\color{slimeComment}, stringstyle=\\color{slimeString}"))
#+macro: ditaa_header (eval (concat "#+header: :exports results :cmdline --no-separation --no-shadows"))

#+latex_class:article

#+latex_header: \usepackage[german]{babel}
#+latex_header: \usepackage{xcolor}
#+latex_header: \usepackage{listings}
#+latex_header: \usepackage[pageanchor=false]{hyperref}

#+latex_header: \definecolor{slimeKeyword}{HTML}{B58900}
#+latex_header: \definecolor{slimeString}{HTML}{2AA198}
#+latex_header: \definecolor{slimeComment}{HTML}{839496}


#+latex_header: \lstdefinelanguage{slime}
#+latex_header: {
#+latex_header:   % list of keywords
#+latex_header:   otherkeywords = {+,=,>,>=,<,<=,-,*,/,**},
#+latex_header:   morekeywords={+,=,>,>=,<,<=,-,*,/,**,assert,define,define-syntax,mutate,if,quote,quasiquote,and,or,not,while,let,lambda,special,eval,begin,list,pair,first,rest,set-type,delete-type,type,info,show,print,read,exit,break,memstat,try,load,copy,error,symbol->keyword,string->symbol,symbol->string,concat-strings},
#+latex_header:   basicstyle=\ttfamily\small,
#+latex_header:   showstringspaces=false,
#+latex_header:   sensitive=true, % keywords are not case-sensitive
#+latex_header:   morecomment=[l]{;}, % l is for line comment
#+latex_header:   morestring=[b]" % defines that strings are enclosed in double quotes
#+latex_header: }

#+latex_header:\AtBeginDocument{\renewcommand{\lstlistingname}{Code}}
#+latex_header:\AtBeginDocument{\renewcommand{\ref}[1]{\autoref{#1}}}
