Lisp/Variables

From Jonathan Gardner's Tech Wiki

Jump to: navigation, search

Contents

[edit] Variables

[edit] Lexical Variables

Two ways to bind variables: Function parameter definitions or LET.

(let ((x 1) (y 2))
  body)

(LET is almost equivalent to a function declaration.)

LET* behaves like a nested let, one for each variable. This allows later variables to reference earlier variables.

(let* ((x 1) (y (*x 2)))
  body)

The equivalent code is:

(let ((x 1))
  (let ((y (*x 2)))
    body)

These are lexically scoped. That is, x is different inside of the LET than it is outside.

[edit] Closures

Variables referenced by functions created within a LET (or DEFUN) will, if returned, still have access to those variables even though the scope has been left.

[edit] Dynamic (aka Special, aka Global) Variables

Two ways: DEFVAR or DEFPARAMETER.

Convention dictates that globals should start and end with *, eg *global-variable*

[edit] DEFVAR

(defvar *var* value
  "documentation")

If the variable is already declared, does nothing. Otherwise, creates and initializes it. If you rebuild the code but want to keep the state, use a DEFVAR.

[edit] DEFPARAMETER

(defparameter *var* value
  "documentation")

Always overrides whatever is there, unlike DEFVAR. These are parameters that should be reset when the code is recompiled.

[edit] DEFCONSTANT

You can define constants with DEFCONSTANT. Convention dictates that you surround the name with '+', eg, "+constant-variable+".

Constants can, and will, be overridden. Use them only for things that are really constant like π.

[edit] Using Lexical to Override Global Temporarily

(let ((*standard-output* *some-other-stream*))
  body)

Within body, *standard-output* is *some-other-stream*. Outside, it is what it would be otherwise.

[edit] Changing the Value

Use SETF to change the value.

(setf x 10)                   ; x = 10
(setf (aref a 0) 10)          ; a[0] = 10
(setf (gethash 'key hash) 10) ; hash[key] = 10
(setf (field o) 10)           ; o.field = 10

INCF and DECF are macros to make incrementing easier.

(incf x 10) ; x += 10
(decf x)    ; x -= 1

ROTATEF swaps two values, and returns NIL.

(rotatef a b)   ; a, b = b, a

SHIFTF slides the values to the left, and returns the left-most value.

(shiftf a b c 10)   ; a, b, c = b, c, 10
Personal tools