Skip to content
b-studios edited this page Aug 12, 2011 · 7 revisions

assert CONDITION MSG

Throws an exception containing MSG if CONDITION evaluates to false.

(assert false "My Exception")
; ERROR: My Exception

List Manipulation

cons FIRST REST

Creates a new Lisp-Pair with the two elements FIRST and REST

(cons 123 456) 
;-> (123 . 456)

car PAIR

Retreives first element of Pair

(car (1 . 2)) 
;-> 1

cdr PAIR

Retreives last element of Pair

(cdr (1 . 2)) 
;-> 2

Quote and Eval

quote SOMETHING

Just returns the first argument, without evaluating it.

(quote Foo)
;-> Foo

get-bindings

Returns the current binding (= LISP.Environment)

(get-bindings)
;-> <Environment>

(eval 'n ((lambda (n) (get-bindings)) 2))
;-> 2

eval LIST ENV?

Evals the given LIST. If the optional parameter ENV is given, this environment is used to eval LIST.

(define my_env ((lambda (foo) (get-bindings)) 4))
(eval '(+ foo 1) my_env)
;-> 5

Mathematical Operators

There are a bunch of mathematical operators. All of them can be used with a variable number of arguments (i.e. (+ 1 2 3 4 5 6) is supported).

+ ARG1 ARGS*

- ARG1 ARGS*

* ARG1 ARGS*

/ ARG1 ARGS*

% ARG1 ARGS*

Logical Operators

Again there are a few logical operators, which can be used to work on logical expressions like (not (and true false)) One may note, that the current implementation evaluates both arguments all the time. When using (and (expr1) (expr2)) both expressions are evaluated before comparison.

and ARG1 ARG2

or ARG1 ARG2

xor ARG1 ARG2

not ARG1 ARG2

Comparators

All Comparators, except eq? are built to work with Numbers.

eq? ARG1 ARG2

Evaluates both arguments and compares them afterwards. At first the types are checked for equality. Then the values of both arguments are compared. Lists are compared recursive.

(eq? 4 4)
;-> true

(eq? "Foo" "Foo")
;-> true

(eq? '(1 2 3) '(1 2 3))
;-> true

(eq? '(1 2) '(1 2 3))
;-> false

gt? ARG1 ARG2

Greater than. (>)

(gt? 5 4)
;-> true

(gt? 5 5)
;-> false

ge? ARG1 ARG2

Greater than, or equal. (>=)

(ge? 5 4)
;-> true

(ge? 5 5)
;-> true

lt? ARG1 ARG2

Less than. (<)

le? ARG1 ARG2

Less than, or equal. (<=)

Environment Manipulation

define KEY VALUE

Defines KEY (which has to be a symbol) as VALUE in the current environment.

(define foo 1)
foo
;-> 1

define (KEY ARGS* . VARARGS?) BODY+

Shorthand for (define SYMBOL (lambda (args) body)). As with lambda, let and begin define can take multiple bodies, which are evaluated one after another on execution.

(define (say_hello name)
   (print "Hello!")
   (print name))
   
(say_hello "Mister")
; "Hello"
; "Mister"
;-> nil

defined? KEY

Returns true if KEY is defined in the current environment - otherwise false is returned.

(define foo 4)
(defined? foo)
;-> true

(defined? bar)
;-> false

set! KEY VALUE

Changes the defined value of KEY to VALUE. (KEY has to be already defined somewhere in the environment chain!!)

(define foo 4)
(set! foo 7)
foo
;-> 7

(set! bar 8)
; ERROR: bar is not defined, and cannot be set to 8

let ( (KEY VALUE)* ) BODY+

A new temporary environment is created and for each key-value pair VALUE is bound to the KEY. Afterwards all bodies are evaluated in this environment and the last return-value is returned.

(let ( (Foo 3)
       (Bar 2) )
  (+ Foo Bar))
;-> 5

reset

Clears the global environment and resets it. Afterwards only the builtins are defined.

(define Foo 5)
(reset)

(defined? Foo)
;-> false

(defined? +)
;-> true

Strings and Symbols

To make it possible to work with string and convert them from / to symbols the following methods are available

to_s SYMBOL

Converts a symbol (or anything, that's got a value) to a string

to_sym STRING

Converts a string (or anything, that's got a value) to a symbol.

split STRING

Splits a string into a list of characters:

(split "Hello World")
;-> '("H" "e" "l" "l" "o" " " "W" "o" "r" "l" "d")

join LIST

Joins a list back to a string

(join '("H" "e" "l" "l" "o" " " "W" "o" "r" "l" "d"))
;-> "Hello World"

Introspection

typeof ELEMENT

Returns a symbol, which describes the type of the ELEMENT.

(typeof 123)
;-> 'Number

(typeof 'Foo)
;-> 'Symbol

Program Flow

if COND TRUE-EXP FALSE-EXP

Evals TRUE-EXP if COND evaled to true. Otherwise evals FALSE-EXP

lambda (ARGS* . VARARGS?) BODY+

Lambdas can contain multiple bodies.

((lambda (a b)
  (+ a b)) 2 3)
;-> 5

Using varargs can look like

(lambda (first_arg . all_other_args)
   (... body ...))

all_other_args is a list, containing all other applied arguments. If only varargs are wished one can write:

(lambda varargs
   (... body ...))

begin EXPR+

begin evals all given expressions one after another and returns the return-value of the last one.

(begin
  (print "Hello")
  (print "World")
  (+ 4 3)
)
; "Hello"
; "World"
;-> 7

Macros

defmacro NAME (ARGS* . VARARGS) BODY

Defines a macro and stores it in the current environment

(defmacro defun (name args body) '(define ,(cons name args) ,body))

When the macro is being called, the macro is evaluated the first time, then expanded (all backquotes are resolved) and afterwards evaluated a second time. So in this example calling the macro like:

(defun Foo (n) (+ n 1))

is fully equivalent to

(define (Foo n) (+ n 1))

macroexpand NAME CALLARGS*#

When building macros, sometimes unforeseen problems can occur. To get a better understanding of what your macro is doing you can expand it using macroexpand. In this case the macro is only evaluated the first time and afterwards expanded, without evaluating it a second time. This enables you to see the expanded version of the macro.

Using the example above the macro expands to:

(macroexpand defun Foo (n) (+ n 1))
;-> (define (Foo n) (+ n 1))

Continuations

call/cc LAMBDA(ARG1)

call/cc expects a lambda with one argument. This lambda will be called with the current continuation. This continuation can be stored somewhere else and called later on (even multiple times) to gain another way of program flow control.

This little exception-handling sample, shows the use of call/cc:

(define try-catch (lambda (try-block catch-block)
  (let ( (exception nil) )
    (set! exception (call/cc try-block))
    (if (eq? exception  nil)
      (print "Nothing") ; do nothing
    ; else
      (catch-block exception)
    )
  )
))

(try-catch
  (lambda (throw)
    (print "inside lambda")
    (throw "My Exception")
    (print "after exception"))
    
  (lambda (e)
    (print (+ "caught exception: " e))))

; "inside lambda"
; "caught exception: My Exception"

A more advanced example for exception-handling can be found here

Printing and System Configuration

Because lisp.js is built to be run in a browser, there are some debugging and configuration functions, that made developing more easy. All output methods are in this section, too.

print MSG

Prints MSG to the std-out (your browser console, or jsconsole)

error MSG

Throws an error, containing MSG as message

inspect ELEMENT

Evals ELEMENT and outputs the result to your browser console (i.e. console.log())

system

Prints some System information about the use of Webworkers and the builtin cooperative multitasking.

(system)
; Using browser's webworkers: true
; Using continuations for cooperative multitasking: false

set-coop TRUE_FALSE

Turns on the continuation-based cooperative multitasking. This feature can be used, if your browser does not support web workers and you want your GUI to be more responsive. But be careful, this option slows down the interpreter!

(set-coop true)
; Using browser's webworkers: false
; Using continuations for cooperative multitasking: true