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
Lisp (programming language)
(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!
===Control structures=== Lisp originally had very few control structures, but many more were added during the language's evolution. (Lisp's original conditional operator, {{Lisp2|cond}}, is the precursor to later {{Lisp2|if-then-else}} structures.) Programmers in the Scheme dialect often express loops using [[tail recursion]]. Scheme's commonality in academic computer science has led some students to believe that tail recursion is the only, or the most common, way to write iterations in Lisp, but this is incorrect. All oft-seen Lisp dialects have imperative-style iteration constructs, from Scheme's {{Lisp2|do}} loop to [[Common Lisp]]'s complex {{Lisp2|loop}} expressions. Moreover, the key issue that makes this an objective rather than subjective matter is that Scheme makes specific requirements for the handling of [[tail call]]s, and thus the reason that the use of tail recursion is generally encouraged for Scheme is that the practice is expressly supported by the language definition. By contrast, ANSI Common Lisp does not require<ref name="lGnFp">[http://www.lispworks.com/documentation/HyperSpec/Body/03_bbc.htm 3.2.2.3 Semantic Constraints] in [http://www.lispworks.com/documentation/HyperSpec/Front/index.htm ''Common Lisp HyperSpec'']</ref> the optimization commonly termed a tail call elimination. Thus, the fact that tail recursive style as a casual replacement for the use of more traditional [[iteration]] constructs (such as {{Lisp2|do}}, {{Lisp2|dolist}} or {{Lisp2|loop}}) is discouraged<ref name="VY38C">4.3. Control Abstraction (Recursion vs. Iteration) in [http://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf Tutorial on Good Lisp Programming Style] by [[Kent Pitman]] and [[Peter Norvig]], August, 1993.</ref> in Common Lisp is not just a matter of stylistic preference, but potentially one of efficiency (since an apparent tail call in Common Lisp may not compile as a simple [[Branch (computer science)|jump]]) and program correctness (since tail recursion may increase stack use in Common Lisp, risking [[stack overflow]]). Some Lisp control structures are ''special operators'', equivalent to other languages' syntactic keywords. Expressions using these operators have the same surface appearance as function calls, but differ in that the arguments are not necessarily evaluated—or, in the case of an iteration expression, may be evaluated more than once. In contrast to most other major programming languages, Lisp allows implementing control structures using the language. Several control structures are implemented as Lisp macros, and can even be macro-expanded by the programmer who wants to know how they work. Both Common Lisp and Scheme have operators for non-local control flow. The differences in these operators are some of the deepest differences between the two dialects. Scheme supports ''re-entrant [[continuation]]s'' using the {{Lisp2|call/cc}} procedure, which allows a program to save (and later restore) a particular place in execution. Common Lisp does not support re-entrant continuations, but does support several ways of handling escape continuations. Often, the same algorithm can be expressed in Lisp in either an imperative or a functional style. As noted above, Scheme tends to favor the functional style, using tail recursion and continuations to express control flow. However, imperative style is still quite possible. The style preferred by many Common Lisp programmers may seem more familiar to programmers used to structured languages such as C, while that preferred by Schemers more closely resembles pure-functional languages such as [[Haskell]]. Because of Lisp's early heritage in list processing, it has a wide array of higher-order functions relating to iteration over sequences. In many cases where an explicit loop would be needed in other languages (like a {{Lisp2|for}} loop in C) in Lisp the same task can be accomplished with a higher-order function. (The same is true of many functional programming languages.) A good example is a function which in Scheme is called {{Lisp2|map}} and in Common Lisp is called {{Lisp2|mapcar}}. Given a function and one or more lists, {{Lisp2|mapcar}} applies the function successively to the lists' elements in order, collecting the results in a new list: <syntaxhighlight lang="Lisp"> (mapcar #'+ '(1 2 3 4 5) '(10 20 30 40 50)) </syntaxhighlight> This applies the {{Lisp2|+}} function to each corresponding pair of list elements, yielding the result {{Lisp2|(11 22 33 44 55)}}.
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)