diff options
Diffstat (limited to 'common-lisp.html.markdown')
| -rw-r--r-- | common-lisp.html.markdown | 251 | 
1 files changed, 162 insertions, 89 deletions
| diff --git a/common-lisp.html.markdown b/common-lisp.html.markdown index 757b6a14..9f2c9957 100644 --- a/common-lisp.html.markdown +++ b/common-lisp.html.markdown @@ -71,16 +71,21 @@ t  ; another atom, denoting true.  ;;; Symbols -'foo ; => FOO +'foo ; => FOO  Notice that the symbol is upper-cased automatically. + +;; Intern manually creates a symbol from a string.  (intern "AAAA") ; => AAAA +(intern "aaa") ; => |aaa| +  ;;; Numbers  9999999999999999999999 ; integers  #b111                  ; binary => 7  #o111                  ; octal => 73  #x111                  ; hexadecimal => 273 -3.14159                ; floating point +3.14159s0              ; single +3.14159d0              ; double  1/2                    ; ratios  #C(1 2)                ; complex numbers @@ -93,42 +98,42 @@ t  ; another atom, denoting true.  ;; You can also call a function manually:  (funcall #'+ 1 2 3) ; => 6  ;; Some arithmetic operations -(+ 1 1)  ; => 2 -(- 8 1)  ; => 7 -(* 10 2) ; => 20 -(expt 2 3) ; => 8 -(mod 5 2) ; => 1 -(/ 35 5) ; => 7 -(/ 1 3) ; => 1/3 +(+ 1 1)              ; => 2 +(- 8 1)              ; => 7 +(* 10 2)             ; => 20 +(expt 2 3)           ; => 8 +(mod 5 2)            ; => 1 +(/ 35 5)             ; => 7 +(/ 1 3)              ; => 1/3  (+ #C(1 2) #C(6 -4)) ; => #C(7 -2) -;;; Booleans -t ; for true (any not-nil value is true) -nil ; for false -(not nil) ; => t -(and 0 t) ; => t -(or 0 nil) ; => 0 +                     ;;; Booleans +t                    ; for true (any not-nil value is true) +nil                  ; for false - and the empty list +(not nil)            ; => t +(and 0 t)            ; => t +(or 0 nil)           ; => 0 -;;; Characters -#\A ; => #\A -#\λ ; => #\GREEK_SMALL_LETTER_LAMDA -#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA +                     ;;; Characters +#\A                  ; => #\A +#\λ                  ; => #\GREEK_SMALL_LETTER_LAMDA +#\u03BB              ; => #\GREEK_SMALL_LETTER_LAMDA -;;; Strings are fixed-length simple-arrays of characters. +;;; Strings are fixed-length arrays of characters.  "Hello, world!"  "Benjamin \"Bugsy\" Siegel"   ; backslash is an escaping character  ;; Strings can be concatenated too!  (concatenate 'string "Hello " "world!") ; => "Hello world!" -;; A string can be treated like a list of characters +;; A string can be treated like a sequence of characters  (elt "Apple" 0) ; => #\A  ;; format can be used to format strings:  (format nil "~a can be ~a" "strings" "formatted") -;; Printing is pretty easy -(format t "Common Lisp is groovy. Dude.\n") +;; Printing is pretty easy; ~% is the format specifier for newline. +(format t "Common Lisp is groovy. Dude.~%")  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -136,22 +141,26 @@ nil ; for false  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  ;; You can create a global (dynamically scoped) using defparameter  ;; a variable name can use any character except: ()[]{}",'`;#|\ + +;; Dynamically scoped variables should have earmuffs in their name! +  (defparameter *some-var* 5)  *some-var* ; => 5 -;; You can also use unicode characters. Not very easy to use though... -(defparameter *foo#\u03BBooo* nil) +;; You can also use unicode characters. +(defparameter *AΛB* nil) -;; Accessing a previously unassigned variable is an undefined -;; behavior (but possible). Don't do it. +;; Accessing a previously unbound variable is an +;; undefined behavior (but possible). Don't do it. +  ;; Local binding: `me` is bound to "dance with you" only within the  ;; (let ...). Let always returns the value of the last `form` in the  ;; let form.  (let ((me "dance with you")) -    me) +  me)  ;; => "dance with you"  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -165,9 +174,12 @@ nil ; for false                :breed "collie"                :age 5))  *rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5) +  (dog-p *rover*) ; => t  ;; ewww)  (dog-name *rover*) ; => "rover" +;; Dog-p, make-dog, and dog-name are all created by defstruct! +  ;;; Pairs  ;; `cons' constructs pairs, `car' and `cdr' extract the first  ;; and second elements @@ -188,17 +200,21 @@ nil ; for false  ;; Can still use `cons' to add an item to the beginning of a list  (cons 4 '(1 2 3)) ; => '(4 1 2 3) -;; Use `append' to add lists together +;; Use `append' to - surprisingly - append lists together  (append '(1 2) '(3 4)) ; => '(1 2 3 4) -;; Lists are a very basic type, so there is a wide variety of functionality for +;; Or use concatenate - + +(concatenate + +;; Lists are a very central type, so there is a wide variety of functionality for  ;; them, a few examples: -(mapcar #1+ '(1 2 3))          ; => '(2 3 4) -(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33) -(remove-if-not #'evenp '(1 2 3 4))    ; => '(2 4) -(every #'evenp '(1 2 3 4)) ; => nil -(some #'oddp '(1 2 3 4)) ; => T -(butlast '(subject verb object))  ; => (SUBJECT VERB) +(mapcar #'1+ '(1 2 3))             ; => '(2 3 4) +(mapcar #'+ '(1 2 3) '(10 20 30))  ; => '(11 22 33) +(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4) +(every #'evenp '(1 2 3 4))         ; => nil +(some #'oddp '(1 2 3 4))           ; => T +(butlast '(subject verb object))   ; => (SUBJECT VERB)  ;;; Vectors @@ -217,60 +233,96 @@ nil ; for false  (make-array (list 2 2)) +;; (make-array '(2 2)) works as well. +  ; => #2A((0 0) (0 0))  (make-array (list 2 2 2))  ; => #3A(((0 0) (0 0)) ((0 0) (0 0))) +;; Caution- the default initial values are +;; implementation-defined. Here's how to define them: -; access the element at 1,1,1, +(make-array '(2) :initial-element 'unset) + +; => #(UNSET UNSET) + +;; And, to access the element at 1,1,1 -  (aref (make-array (list 2 2 2)) 1 1 1)  ; => 0 -;;; Sets are just lists: +;;; Naively, sets are just lists:  (set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)  (intersection '(1 2 3 4) '(4 5 6 7)) ; => 4  (union '(1 2 3 4) '(4 5 6 7))        ; => (3 2 1 4 5 6 7)  (adjoin 4 '(1 2 3 4))     ; => (1 2 3 4) +;; But you'll want to use a better data structure than a linked list +;; for performant work! +  ;;; Dictionaries are implemented as hash tables.  ;; Create a hash table -(defparameter m (hash-table)) +(defparameter *m* (make-hash-table))  ;; set a value -(setf (gethash 'a hash-table 1)) +(setf (gethash 'a *m*) 1)  ;; Retrieve a value -(gethash 'a m) ; => 1 +(gethash 'a *m*) ; => 1, t -;; Retrieving a non-present value returns a nil - (gethash m 'd) ;=> nil +;; Detail - Common Lisp has multiple return values possible. gethash +;; returns t in the second value if anything was found, and nil if +;; not. + +;; Retrieving a non-present value returns nil + (gethash *m* 'd) ;=> nil, nil  ;; You can provide a default value for missing keys -(gethash m 'd :not-found) ; => :NOT-FOUND +(gethash *m* 'd :not-found) ; => :NOT-FOUND + +;; Let's handle the multiple return values here in code. + +(multiple-value-bind +      (a b) +    (gethash 'd *m*) +  (list a b)) +; => (NIL NIL) + +(multiple-value-bind +      (a b) +    (gethash 'a *m*) +  (list a b)) +; => (1 T)  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  ;; 3. Functions  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  ;; Use `lambda' to create anonymous functions. -;; A function always returns the value of its last expression -(lambda () "Hello World") ; => #<function> +;; A function always returns the value of its last expression. +;; The exact printable representation of a function will vary... + +(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>  ;; Use funcall to call lambda functions  (funcall (lambda () "Hello World")) ; => "Hello World" +;; Or Apply +(apply (lambda () "Hello World") nil) ; => "Hello World" +  ;; De-anonymize the function -(defun hello-world () "Hello World") +(defun hello-world () +   "Hello World")  (hello-world) ; => "Hello World"  ;; The () in the above is the list of arguments for the function  (defun hello (name) -    (format nil "Hello, ~a " name)) +   (format nil "Hello, ~a " name)) +  (hello "Steve") ; => "Hello, Steve"  ;; Functions can have optional arguments; they default to nil @@ -286,6 +338,12 @@ nil ; for false  (defun hello (name &optional (from "The world"))     (format t "Hello, ~a, from ~a" name from)) +(hello "Steve") +; => Hello, Steve, from The world + +(hello "Steve" "the alpacas") +; => Hello, Steve, from the alpacas +  ;; And of course, keywords are allowed as well... usually more  ;;   flexible than &optional. @@ -302,18 +360,18 @@ nil ; for false  ;; 4. Equality  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Common Lisp has a sophisticated equality system. +;; Common Lisp has a sophisticated equality system. A couple are covered yere.  ;; for numbers use `='  (= 3 3.0) ; => t  (= 2 1) ; => nil -;; for object identity (approximately) use `eq?' +;; for object identity (approximately) use `eql`  (eql 3 3) ; => t  (eql 3 3.0) ; => nil  (eql (list 3) (list 3)) ; => nil -;; for collections use `equal' +;; for lists, strings, and bit-vectors use `equal'  (equal (list 'a 'b) (list 'a 'b)) ; => t  (equal (list 'a 'b) (list 'b 'a)) ; => nil @@ -342,8 +400,8 @@ nil ; for false  ;; Typecase switches on the type of the value  (typecase 1 -           (string :string) -           (integer :int)) +  (string :string) +  (integer :int))  ; => :int @@ -352,9 +410,9 @@ nil ; for false  ;; Of course recursion is supported:  (defun walker (n) -    (if (= n 0) -        :walked -        (walker (1- n)))) +  (if (zerop 0) +      :walked +      (walker (1- n))))  (walker) ; => :walked @@ -362,12 +420,12 @@ nil ; for false  (dolist (i '(1 2 3 4)) -    (format t "~a" i)) +  (format t "~a" i))  ; => 1234  (loop for i from 0 below 10 -    collect i) +      collect i)  ; => (0 1 2 3 4 5 6 7 8 9) @@ -380,8 +438,8 @@ nil ; for false  ;; demonstrated earlier in the hash table example.  (let ((variable 10)) -    (setf variable 10)) - ; => 10 +    (setf variable 2)) + ; => 2  ;; Good Lisp style is to minimize destructive functions and to avoid @@ -395,34 +453,44 @@ nil ; for false  ;; Conveyances.  (defclass human-powered-conveyance () -    ((velocity -         :accessor velocity -         :initarg :velocity) -     (average-efficiency -         :accessor average-efficiency) -         :initarg :average-efficiency) -    (:documentation "A human powered conveyance")) +  ((velocity +    :accessor velocity +    :initarg :velocity) +   (average-efficiency +    :accessor average-efficiency) +   :initarg :average-efficiency) +  (:documentation "A human powered conveyance")) + +;; defclass, followed by name, followed by the superclass list, +;; followed by slot list, followed by optional qualities such as +;; :documentation. + +;; When no superclass list is set, the empty list defaults to the +;; standard-object class. This *can* be changed, but not until you +;; know what you're doing. Look up the Art of the Metaobject Protocol +;; for more information.  (defclass bicycle (human-powered-conveyance) -    ((wheel-size -        :accessor wheel-size -        :initarg :wheel-size -        :documentation "Diameter of the wheel.") -     (height -         :accessor height -         :initarg :height))) +  ((wheel-size +    :accessor wheel-size +    :initarg :wheel-size +    :documentation "Diameter of the wheel.") +   (height +    :accessor height +    :initarg :height)))  (defclass recumbent (bicycle) -    ((chain-type -        :accessor chain-type -        :initarg  :chain-type))) +  ((chain-type +    :accessor chain-type +    :initarg  :chain-type)))  (defclass unicycle (human-powered-conveyance) nil)  (defclass canoe (human-powered-conveyance) -    ((number-of-rowers -        :accessor number-of-rowers -        :initarg :number-of-rowers))) +  ((number-of-rowers +    :accessor number-of-rowers +    :initarg :number-of-rowers))) +  ;; Calling DESCRIBE on the human-powered-conveyance class in the REPL gives: @@ -438,7 +506,7 @@ nil ; for false  ;  Direct superclasses: STANDARD-OBJECT  ;  Direct subclasses: UNICYCLE, BICYCLE, CANOE  ;  Not yet finalized. -;  Direct slots: +(defparameter *foo#\u03BBooo* nil) ;  Direct slots:  ;    VELOCITY  ;      Readers: VELOCITY  ;      Writers: (SETF VELOCITY) @@ -450,14 +518,16 @@ nil ; for false  ;; designed to be an interactive system  ;; To define a method, let's find out what our circumference of the -;; bike turns out to be using the equation: C = d * pi +;; bike wheel turns out to be using the equation: C = d * pi  (defmethod circumference ((object bicycle)) -  (* 3.14159 (wheel-size object))) +  (* pi (wheel-size object))) + +;; pi is defined in Lisp already for us!  ;; Let's suppose we find out that the efficiency value of the number -;;  of rowers in a canoe is roughly logarithmic. This should probably be set -;;  in the constructor/initializer. +;; of rowers in a canoe is roughly logarithmic. This should probably be set +;; in the constructor/initializer.  ;; Here's how to initialize your instance after Common Lisp gets done  ;; constructing it: @@ -488,7 +558,7 @@ nil ; for false  `condition` is tested prior to each execution of `body`"      (let ((block-name (gensym)))          `(tagbody -           (when (not ,condition) +           (unless ,condition                 (go ,block-name))             (progn             ,@body) @@ -503,13 +573,14 @@ nil ; for false  `condition` is tested prior to each execution of `body`"    `(loop while ,condition           do -         ,@body)) +         (progn +            ,@body)))  ;; However, with a modern compiler, this is not required; the LOOP  ;; form compiles equally well and is easier to read. -;; Note that ` is used, as well as , and @. ` is a quote-type operator -;; known as quasiquote; it allows the use of ,. , allows "unquoting" +;; Note that ``` is used, as well as `,` and `@`. ``` is a quote-type operator +;; known as quasiquote; it allows the use of `,` . `,` allows "unquoting"  ;; variables. @ interpolates lists.  ;; Gensym creates a unique symbol guaranteed to not exist elsewhere in @@ -529,3 +600,5 @@ nil ; for false  Lots of thanks to the Scheme people for rolling up a great starting  point which could be easily moved to Common Lisp. + +- [Paul Khoung](https://github.com/pkhuong) for some great reviewing. | 
