One of the great resources we can have as developers is snippets and example code to understand how the idiom of a language is spoken and written.
Defining a function:
(defun function-name (param1 param2 &key (keyword1 default-value)) ;; keywords are optional; optional positional parameters are also available. ;; implicit progn )
Defining a method on a type:
(defmethod method-name ((param1 class-name)) ;; implicit progn )
Defining a class
DEFCLASS accessor functions for slots can be
SETF’d and serve as both getters and setters for the slot.
:INITARG is the keyword used in
MAKE-INSTANCE to denote the value of the initial argument (see below).
:INITFORM is the form used to initialize the slot. Without this, it defaults to
nil. I favor using
(error "You must set slot <slotname> to a value") as the usual initform set.
(:documentation ...) is the standard documentation mechanism, which can be viewed in the running image with
DESCRIBE (at least in SBCL).
;; no superclass, no slots. (defclass superclass-1 nil nil) (defclass my-class (superclass-1) ((variable :accessor accessor-function :initarg :variable :initform form-for-initializition.) another-variable) (:documentation "a class snippet!"))
Creating an instance
(make-instance 'my-class :variable value)
Adding a constructor
This function runs after the instance is initialized.
(defmethod initialize-instance :after ((obj my-class) &key) (setf (accessor-function obj) 10))
Defining a constant:
Note that the convention is that constants are surrounded with +
(defconstant +name+ value "docstring")
Defining a global variable:
Note that the convention is that globals are surrounded with *
(defparameter *name* value "docstring")
Creating local variables.
(let ((variable1 value-form) (variable2 value-again)) ;; implicit progn where variable are valid )
LOOP is a contentious form in Common Lisp: some people love its imperative style, others hate it. Regardless, its really handy! Here are my favorite LOOPs
(loop for i from 0 upto 10 collect i) (loop for i from 0 below 10 collect i) (loop for i from 0 upto 10 do (side-effect i)) (loop for ele in list collect (operate-on ele)) (loop for ele across array collect (operate-on ele))
The lambda functions is an anonymous function, i.e., unnamed.
Here we map over
numeric-list and increment each element in it by 1 with
1+, returning the incremented list.
(mapcar #'(lambda (x) (1+ x)) numeric-list)
Note that Lisp macros should be used with care: they read source code and emit source code.
(defmacro with-resource ((resource) &body body) (allocate-resource ,resource) (unwind-protect (progn ,@body) (deallocate-resource ,resource)))
See UNWIND-PROTECT for details on this very useful form.
Writing a text file
More complete reading and writing of text files can be done by using the ALEXANDRIA library; these routines are great for starting to customize your own routine.
(defun write-file (filename data) (with-open-file (stream filename :direction :output :if-exists :supersede :if-does-not-exist :create) (write-sequence data stream)))
Reading a text file
(defun read-file (filename) "Reads `filename` as a sequence of unsigned 8-bit bytes, no encoding" (with-open-file (fin filename :direction :input :if-does-not-exist :error) (let ((seq (make-array (file-length fin) :fill-pointer t))) (setf (fill-pointer seq) (read-sequence seq fin)) seq)))
Please feel free to contribute your examples or library information to this page! Send in those pull requests and file those bugs!