Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Common Lisp
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Data types== Common Lisp has many [[data type]]s. ===Scalar types=== ''Number'' types include [[integer]]s, [[ratio]]s, [[floating-point arithmetic|floating-point number]]s, and [[complex number]]s.<ref name="reddy">{{cite web |url=http://random-state.net/features-of-common-lisp.html |title=Features of Common Lisp |first=Abhishek |last=Reddy |date=August 22, 2008 }}</ref> Common Lisp uses [[Arbitrary-precision arithmetic|bignum]]s to represent numerical values of arbitrary size and precision. The ratio type represents fractions exactly, a facility not available in many languages. Common Lisp automatically coerces numeric values among these types as appropriate. The Common Lisp ''[[character (computing)|character]]'' type is not limited to [[ASCII]] characters. Most modern implementations allow [[Unicode]] characters.<ref>{{cite web |url=http://www.cliki.net/Unicode%20Support |title=Unicode support |work=The Common Lisp Wiki |access-date=August 21, 2008 }}</ref> The ''[[Symbol (programming)|symbol]]'' type is common to Lisp languages, but largely unknown outside them. A symbol is a unique, named data object with several parts: name, value, function, property list, and package. Of these, ''value cell'' and ''function cell'' are the most important. Symbols in Lisp are often used similarly to identifiers in other languages: to hold the value of a variable; however there are many other uses. Normally, when a symbol is evaluated, its value is returned. Some symbols evaluate to themselves, for example, all symbols in the keyword package are self-evaluating. Boolean values in Common Lisp are represented by the self-evaluating symbols T and NIL. Common Lisp has namespaces for symbols, called 'packages'. A number of functions are available for [[rounding]] scalar numeric values in various ways. The function <code>round</code> rounds the argument to the nearest integer, with halfway cases rounded to the even integer. The functions <code>truncate</code>, <code>floor</code>, and <code>ceiling</code> round towards zero, down, or up respectively. All these functions return the discarded fractional part as a secondary value. For example, <code>(floor -2.5)</code> yields β3, 0.5; <code>(ceiling -2.5)</code> yields β2, β0.5; <code>(round 2.5)</code> yields 2, 0.5; and <code>(round 3.5)</code> yields 4, β0.5. ===Data structures=== ''Sequence'' types in Common Lisp include lists, vectors, bit-vectors, and strings. There are many operations that can work on any sequence type. As in almost all other Lisp dialects, ''lists'' in Common Lisp are composed of ''conses'', sometimes called ''cons cells'' or ''pairs''. A cons is a data structure with two slots, called its ''car'' and ''cdr''. A list is a linked chain of conses or the empty list. Each cons's car refers to a member of the list (possibly another list). Each cons's cdr refers to the next consβexcept for the last cons in a list, whose cdr refers to the <code>nil</code> value. Conses can also easily be used to implement trees and other complex data structures; though it is usually advised to use structure or class instances instead. It is also possible to create circular data structures with conses. Common Lisp supports multidimensional ''arrays'', and can dynamically resize ''adjustable'' arrays if required. Multidimensional arrays can be used for matrix mathematics. A ''vector'' is a one-dimensional array. Arrays can carry any type as members (even mixed types in the same array) or can be specialized to contain a specific type of members, as in a vector of bits. Usually, only a few types are supported. Many implementations can optimize array functions when the array used is type-specialized. Two type-specialized array types are standard: a ''string'' is a vector of characters, while a ''bit-vector'' is a vector of [[bit]]s. ''[[Hash table]]s'' store associations between data objects. Any object may be used as key or value. Hash tables are automatically resized as needed. ''Packages'' are collections of symbols, used chiefly to separate the parts of a program into [[namespaces]]. A package may ''export'' some symbols, marking them as part of a public interface. Packages can use other packages. ''Structures'', similar in use to [[C (programming language)|C]] structs and [[Pascal (programming language)|Pascal]] records, represent arbitrary complex data structures with any number and type of fields (called ''slots''). Structures allow single-inheritance. ''Classes'' are similar to structures, but offer more dynamic features and multiple-inheritance. (See [[Common Lisp Object System|CLOS]]). Classes have been added late to Common Lisp and there is some conceptual overlap with structures. Objects created of classes are called ''Instances''. A special case is Generic Functions. Generic Functions are both functions and instances. ===Functions=== Common Lisp supports [[first-class function]]s. For instance, it is possible to write functions that take other functions as arguments or return functions as well. This makes it possible to describe very general operations. The Common Lisp library relies heavily on such higher-order functions. For example, the <code>sort</code> function takes a [[relational operator]] as an argument and key function as an optional keyword argument. This can be used not only to sort any type of data, but also to sort data structures according to a key. <syntaxhighlight lang="lisp"> ;; Sorts the list using the > and < function as the relational operator. (sort (list 5 2 6 3 1 4) #'>) ; Returns (6 5 4 3 2 1) (sort (list 5 2 6 3 1 4) #'<) ; Returns (1 2 3 4 5 6) </syntaxhighlight> <syntaxhighlight lang="lisp"> ;; Sorts the list according to the first element of each sub-list. (sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first) ; Returns ((3 B) (4 C) (9 A)) </syntaxhighlight> The evaluation model for functions is very simple. When the evaluator encounters a form <code>(f a1 a2...)</code> then it presumes that the symbol named f is one of the following: # A special operator (easily checked against a fixed list) # A macro operator (must have been defined previously) # The name of a function (default), which may either be a symbol, or a sub-form beginning with the symbol <code>lambda</code>. If f is the name of a function, then the arguments a1, a2, ..., an are evaluated in left-to-right order, and the function is found and invoked with those values supplied as parameters. ====Defining functions==== The [[Defun|macro <code>defun</code>]] defines functions where a function definition gives the name of the function, the names of any arguments, and a function body: <syntaxhighlight lang="lisp"> (defun square (x) (* x x)) </syntaxhighlight> Function definitions may include compiler [[Directive (programming)|directives]], known as ''declarations'', which provide hints to the compiler about optimization settings or the data types of arguments. They may also include ''documentation strings'' (docstrings), which the Lisp system may use to provide interactive documentation: <syntaxhighlight lang="lisp"> (defun square (x) "Calculates the square of the single-float x." (declare (single-float x) (optimize (speed 3) (debug 0) (safety 1))) (the single-float (* x x))) </syntaxhighlight> Anonymous functions ([[function literal]]s) are defined using <code>lambda</code> expressions, e.g. <code>(lambda (x) (* x x))</code> for a function that squares its argument. Lisp programming style frequently uses higher-order functions for which it is useful to provide anonymous functions as arguments. Local functions can be defined with <code>flet</code> and <code>labels</code>. <syntaxhighlight lang="lisp"> (flet ((square (x) (* x x))) (square 3)) </syntaxhighlight> There are several other operators related to the definition and manipulation of functions. For instance, a function may be compiled with the <code>compile</code> operator. (Some Lisp systems run functions using an interpreter by default unless instructed to compile; others compile every function). ====Defining generic functions and methods==== The macro <code>defgeneric</code> defines [[generic function]]s. Generic functions are a collection of [[Method (computer programming)|methods]]. The macro <code>defmethod</code> defines methods. Methods can specialize their parameters over CLOS ''standard classes'', ''system classes'', ''structure classes'' or individual objects. For many types, there are corresponding ''system classes''. When a generic function is called, [[multiple dispatch|multiple-dispatch]] will determine the effective method to use. <syntaxhighlight lang="lisp"> (defgeneric add (a b)) </syntaxhighlight> <syntaxhighlight lang="lisp"> (defmethod add ((a number) (b number)) (+ a b)) </syntaxhighlight> <syntaxhighlight lang="lisp"> (defmethod add ((a vector) (b number)) (map 'vector (lambda (n) (+ n b)) a)) </syntaxhighlight> <syntaxhighlight lang="lisp"> (defmethod add ((a vector) (b vector)) (map 'vector #'+ a b)) </syntaxhighlight> <syntaxhighlight lang="lisp"> (defmethod add ((a string) (b string)) (concatenate 'string a b)) </syntaxhighlight> <syntaxhighlight lang="lisp"> (add 2 3) ; returns 5 (add #(1 2 3 4) 7) ; returns #(8 9 10 11) (add #(1 2 3 4) #(4 3 2 1)) ; returns #(5 5 5 5) (add "COMMON " "LISP") ; returns "COMMON LISP" </syntaxhighlight> Generic Functions are also a [[First-class citizen|first class data type]]. There are many more features to Generic Functions and Methods than described above. ====The function namespace==== <!-- This section name is linked from several places; if you change it, update the links. --> The namespace for function names is separate from the namespace for data variables. This is a key difference between Common Lisp and [[Scheme (programming language)|Scheme]]. For Common Lisp, operators that define names in the function namespace include <code>defun</code>, <code>flet</code>, <code>labels</code>, <code>defmethod</code> and <code>defgeneric</code>. To pass a function by name as an argument to another function, one must use the <code>function</code> special operator, commonly abbreviated as <code>#'</code>. The first <code>sort</code> example above refers to the function named by the symbol <code>></code> in the function namespace, with the code <code>#'></code>. Conversely, to call a function passed in such a way, one would use the <code>funcall</code> operator on the argument. [[Scheme (programming language)|Scheme's]] evaluation model is simpler: there is only one namespace, and all positions in the form are evaluated (in any order) β not just the arguments. Code written in one dialect is therefore sometimes confusing to programmers more experienced in the other. For instance, many Common Lisp programmers like to use descriptive variable names such as ''list'' or ''string'' which could cause problems in Scheme, as they would locally shadow function names. Whether a separate namespace for functions is an advantage is a source of contention in the Lisp community. It is usually referred to as the ''Lisp-1 vs. Lisp-2 debate''. Lisp-1 refers to Scheme's model and Lisp-2 refers to Common Lisp's model. These names were coined in a 1988 paper by [[Richard P. Gabriel]] and [[Kent Pitman]], which extensively compares the two approaches.<ref>{{cite journal |title=Technical Issues of Separation in Function Cells and Value Cells |url=http://www.nhplace.com/kent/Papers/Technical-Issues.html |author=Richard P. Gabriel |author2=Kent M. Pitman |journal=LISP and Symbolic Computation |date=June 1988|volume=1 |issue=1 |pages=81β101 |doi=10.1007/bf01806178|s2cid=26716515}}</ref> ====Multiple return values==== Common Lisp supports the concept of ''multiple values'',<ref>{{cite web|title=Common Lisp Hyperspec: Section 3.1.7|url=http://www.lispworks.com/documentation/HyperSpec/Body/03_ag.htm}}</ref> where any expression always has a single ''primary value'', but it might also have any number of ''secondary values'', which might be received and inspected by interested callers. This concept is distinct from returning a list value, as the secondary values are fully optional, and passed via a dedicated side channel. This means that callers may remain entirely unaware of the secondary values being there if they have no need for them, and it makes it convenient to use the mechanism for communicating information that is sometimes useful, but not always necessary. For example, * The <code>TRUNCATE</code> function<ref>{{cite web|title=Common Lisp Hyperspec: Function FLOOR|url=http://www.lispworks.com/documentation/HyperSpec/Body/f_floorc.htm}}</ref> rounds the given number to an [[integer]] towards zero. However, it also returns a remainder as a secondary value, making it very easy to determine what value was truncated. It also supports an optional divisor parameter, which can be used to perform [[Euclidean division]] trivially: <syntaxhighlight lang="cl"> (let ((x 1266778) (y 458)) (multiple-value-bind (quotient remainder) (truncate x y) (format nil "~A divided by ~A is ~A remainder ~A" x y quotient remainder))) ;;;; => "1266778 divided by 458 is 2765 remainder 408" </syntaxhighlight> * <code>GETHASH</code><ref>{{cite web|title=Common Lisp Hyperspec: Accessor GETHASH|url=http://www.lispworks.com/documentation/HyperSpec/Body/f_gethas.htm}}</ref> returns the value of a key in an [[associative map]], or the default value otherwise, and a secondary Boolean indicating whether the value was found. Thus code that does not care about whether the value was found or provided as the default can simply use it as-is, but when such distinction is important, it might inspect the secondary Boolean and react appropriately. Both use cases are supported by the same call and neither is unnecessarily burdened or constrained by the other. Having this feature at the language level removes the need to check for the existence of the key or compare it to [[Null morpheme|null]] as would be done in other languages. <syntaxhighlight lang="cl"> (defun get-answer (library) (gethash 'answer library 42)) (defun the-answer-1 (library) (format nil "The answer is ~A" (get-answer library))) ;;;; Returns "The answer is 42" if ANSWER not present in LIBRARY (defun the-answer-2 (library) (multiple-value-bind (answer sure-p) (get-answer library) (if (not sure-p) "I don't know" (format nil "The answer is ~A" answer)))) ;;;; Returns "I don't know" if ANSWER not present in LIBRARY </syntaxhighlight> Multiple values are supported by a handful of standard forms, most common of which are the <code>MULTIPLE-VALUE-BIND</code> special form for accessing secondary values and <code>VALUES</code> for returning multiple values: <syntaxhighlight lang="cl"> (defun magic-eight-ball () "Return an outlook prediction, with the probability as a secondary value" (values "Outlook good" (random 1.0))) ;;;; => "Outlook good" ;;;; => 0.3187 </syntaxhighlight> ===Other types=== Other data types in Common Lisp include: *''Pathnames'' represent files and directories in the [[filesystem]]. The Common Lisp pathname facility is more general than most operating systems' file naming conventions, making Lisp programs' access to files broadly portable across diverse systems. *Input and output ''streams'' represent sources and sinks of binary or textual data, such as the terminal or open files. *Common Lisp has a built-in [[pseudo-random number generator]] (PRNG). ''Random state'' objects represent reusable sources of pseudo-random numbers, allowing the user to seed the PRNG or cause it to replay a sequence. *''Conditions'' are a type used to represent errors, exceptions, and other "interesting" events to which a program may respond. *''Classes'' are [[first-class object]]s, and are themselves instances of classes called [[metaclasses|metaobject classes]] ([[metaclasses]] for short). *''Readtables'' are a type of object which control how Common Lisp's reader parses the text of source code. By controlling which readtable is in use when code is read in, the programmer can change or extend the language's syntax.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)