PRACTICAL COMMON LISP Peter Seibel 1.

Slides:



Advertisements
Similar presentations
Objects and Classes Part II
Advertisements

CPSC 388 – Compiler Design and Construction
Some non-recursive tricks. The Lambda expression. More on Let, Let*, apply and funcall.
Chapter 10- Instruction set architectures
Variables, Environments and Closures. Overview We will Touch on the notions of variable extent and scope Introduce the notions of lexical scope and.
Functional Programming COMP2003 A course on functional programming using Common Lisp Dr Eleni Mangina
Principles of programming languages 4: Parameter passing, Scope rules Department of Information Science and Engineering Isao Sasano.
A problem with functions: arguments must always have values that can be worked out Whenever we call a function we give it arguments. Lisp then works out.
Lisp Recitation (cse471/598 Fall 2007 ) Aravind Kalavagattu.
VBA Modules, Functions, Variables, and Constants
Tutorial 6 & 7 Symbol Table
1 Arrays  Arrays are objects that help us organize large amounts of information  Chapter 8 focuses on: array declaration and use passing arrays and array.
PRACTICAL COMMON LISP Peter Seibel 1.
Cs164 Prof. Bodik, Fall Symbol Tables and Static Checks Lecture 14.
Functional Programming COMP2003 A course on functional programming using Common Lisp Dr Eleni Mangina
FunctionsFunctions Systems Programming Concepts. Functions   Simple Function Example   Function Prototype and Declaration   Math Library Functions.
COMP 205 – Week 11 Dr. Chunbo Chu. Intro Lisp stands for “LISt Process” Invented by John McCarthy (1958) Simple data structure (atoms and lists) Heavy.
Chapter TwelveModern Programming Languages1 Memory Locations For Variables.
PRACTICAL COMMON LISP Peter Seibel 1.
Functional Programming Universitatea Politehnica Bucuresti Adina Magda Florea
COMPILERS Semantic Analysis hussein suleman uct csc3005h 2006.
PRACTICAL COMMON LISP Peter Seibel 1.
Functional Programming Here we briefly look at what functional programming is and why we want to study it –a function, in the mathematical sense, is a.
Functional Programming in Scheme and Lisp. Overview In a functional programming language, functions are first class objects. You can create them, put.
ASP.NET Programming with C# and SQL Server First Edition Chapter 3 Using Functions, Methods, and Control Structures.
Iteration Chapters 6 & 7. Iteration in LISP n LISP (unlike Prolog) allows iteration –mapcar, remove-if(-not), count-if, find-if for special purpose iteration.
Control Structures. Important Semantic Difference In all of these loops we are going to discuss, the braces are ALWAYS REQUIRED. Even if your loop/block.
Functional Programming and Lisp. Overview In a functional programming language, functions are first class objects. In a functional programming language,
04 Control. Control-Blocks Common Lisp has 3 basic operators for creating blocks of code progn block tagbody If ordinary function calls are the leaves.
COMPILERS Symbol Tables hussein suleman uct csc3003s 2007.
Interpretation Environments and Evaluation. CS 354 Spring Translation Stages Lexical analysis (scanning) Parsing –Recognizing –Building parse tree.
1 Type Checking Type checking ensures that the operands and the operator are of compatible types Generalized to include subprograms and assignments Compatible.
Constructors CMSC 202. Object Creation Objects are created by using the operator new in statements such as… The following expression invokes a special.
6 Chapter 61 Looping Programming Logic and Design, Second Edition, Comprehensive 6.
COMPUTER PROGRAMMING. Iteration structures (loops) There may be a situation when you need to execute a block of code several number of times. In general,
The Loop Macro Many of the CL “functions” are actually macros (let, progn, if, etc) The most complicated macro in CL is probably the Loop macro –The Loop.
Linked List. Iterators Operation to find a link, deleting, and inserting before or after a specified link, also involve searching through the list to.
11 Speed & Debug.  Lisp is really two languages:  A language for writing fast programs  A language for writing programs fast  In the early stage,
JavaScript, Fourth Edition
UMBC CMSC Common Lisp II. UMBC CMSC Input and Output Print is the most primitive output function > (print (list 'foo 'bar)) (FOO BAR) The.
PRACTICAL COMMON LISP Peter Seibel 1.
Variables, Environments and Closures. Overview Touch on the notions of variable extent and scope Introduce the notions of lexical scope and dynamic.
CSE (c) S. Tanimoto, 2002 AI Techniques 1 Where and When Do Symbols Refer to Values and Functions? Scope and Extent of Bindings Bindings Scope Extent.
Designing Classes CS239 – Jan 26, Key points from yesterday’s lab  Enumerated types are abstract data types that define a set of values.  They.
PRACTICAL COMMON LISP Peter Seibel 1.
Milos Hauskrecht (PDF) Hieu D. Vu (PPT) LISP PROGARMMING LANGUAGE.
1 Variable Declarations Global and special variables – (defvar …) – (defparameter …) – (defconstant …) – (setq var2 (list 4 5)) – (setf …) Local variables.
CMSC 202 Advanced Section Classes and Objects: Object Creation and Constructors.
Programming Fundamentals. Topics to be covered Today Recursion Inline Functions Scope and Storage Class A simple class Constructor Destructor.
Basic Introduction to Lisp
Functional Programming “When I code in C, I feel I'm on a knife-edge of ‘state’ — I focus on statements and what they do. I'm worried about the behaviour.
JavaScript for C# developers Dhananjay Microsoft MVP
PRACTICAL COMMON LISP Peter Seibel 1.
PRACTICAL COMMON LISP Peter Seibel 1.
Macros CSC 358/ Outline  Homework #6  Macro Intro  Backquote  Macros  Modify macros  Read Macros.
CS 326 Programming Languages, Concepts and Implementation
Variables, Environments and Closures
Variables, Environments and Closures
Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)
Bindings, Scope, and Extent
CSE S. Tanimoto Explicit Function Application
CISC101 Reminders All assignments are now posted.
Peter Seibel Practical Common Lisp Peter Seibel
Abstraction and Repetition
Lisp: Using Functions as Data
Bindings, Scope, and Extent
Bindings, Scope, and Extent
Common Lisp II.
Arrays.
Procedures with optional parameters which do not require matching arguments Example: consider the exponent function which may take one argument, m, in.
Presentation transcript:

PRACTICAL COMMON LISP Peter Seibel 1

CHAPTER 6 VARIABLES 2

VARIABLE BASICS Common Lisp supports two kinds of variables: lexical ( 語彙的 ) and dynamic ( 動態的 ). These two types correspond roughly to “local” and “global” variables in other languages. In Common Lisp variables are named places that can hold a value. A variable can hold values of any type and the values carry type information that can be used to check types at runtime. Thus, Common Lisp is dynamically typed—type errors are detected dynamically. For instance, if we pass something other than a number to the + function, Common Lisp will signal a type error. Common Lisp is a strongly typed language in the sense that all type errors will be detected. 3

VARIABLE BASICS One way to introduce new variables is to define function parameters. When we define a function with DEFUN, the parameter list defines the variables that will hold the function's arguments when it's called. For example, this function defines three variables—x, y, and z—to hold its arguments. (defun foo (x y z) (+ x y z)) Another form that introduces new variables is the LET special operator. The skeleton of a LET form: (let (variable*) body-form*) where each variable is a variable initialization form. For example: (let ((x 10) (y 20) z)...) The LET form binds the three variables x, y, and z with initial values 10, 20, and NIL. 4

VARIABLE BASICS The scope of function parameters and LET is delimited ( 限定 ) by the binding form that introduces the variable. > (foo 1) Parameter: 1 Outer LET: 2 Inner LET: 3 Outer LET: 2 Parameter: 1 NIL 5

VARIABLE BASICS Another binding forms DOTIMES loop is a basic counting loop. It introduces a variable that holds the value of a counter that's incremented each time through the loop. The following loop prints the numbers from 0 to 9 and binds the variable x: (dotimes (x 10) (format t "~d " x)) NIL LET* In a LET, the variable names can be used only in the body of the LET. In a LET*, the initial value forms for each variable can refer to variables introduced earlier in the variables list. 6

VARIABLE BASICS LET and LET* > (let* ((x 10) (y (+ x 10))) (list x y)) (10 20) > (let ((x 10)) (let ((y (+ x 10))) (list x y))) (10 20) > (let* ((x 10) (y x)) (list x y)) (10 10) > (let ((x 10) (y x)) (list x y)) …ERROR 7

DYNAMIC VARIABLES Lexically scoped bindings help keep code understandable by limiting the scope in which a given name has meaning. This is why most modern languages use lexical scoping for local variables. Sometimes, however, we really want a global variable—a variable that you can refer to from anywhere in your program. Lisp's version of global variables, dynamic variables, are both more useful and more manageable. Common Lisp provides two ways to create global variables: DEFVAR and DEFPARAMETER. Global variables are conventionally named with names that start and end with *. 8

DYNAMIC VARIABLES For examples: (defvar *count* 0 "Count of widgets made so far.") (defparameter *gap-tolerance* "Tolerance to be allowed in widget gaps.") The difference between the two forms is that DEFPARAMETER always assigns the initial value to the named variable while DEFVAR does so only if the variable is undefined. A DEFVAR form can also be used with no initial value to define a global variable without giving it a value. Such a variable is said to be unbound. Practically speaking, you should use DEFVAR to define variables that will contain data you'd want to keep even if you made a change to the source code that uses the variable. 9

DYNAMIC VARIABLES > (defvar *c* 0) > *c* 0 > (defvar *c* 12) > *c* 0 > (defparameter *a* 0) > *a* 0 > (defparameter *a* 12) > *a* 12 10

DYNAMIC VARIABLES For instance, suppose the two variables defined previously are part of an application for controlling a widget ( 小零件 ) factory. It's appropriate to define the *count* variable with DEFVAR because the number of widgets made so far isn't invalidated just because we make some changes to the widget-making code. On the other hand, the variable *gap-tolerance* presumably ( 可能 ) has some effect on the behavior of the widget-making code itself. If we decide we need a tighter or looser tolerance and change the value in the DEFPARAMETER form, we'd like the change to take effect when you recompile and reload the file. After defining a variable with DEFVAR or DEFPARAMETER, we can refer to it from anywhere. For instance, we might define this function to increment the count of widgets made: (defun increment-widget-count () (incf *count*)) 11

DYNAMIC VARIABLES Unlike a lexical binding, a dynamic binding can be referenced by any code that's invoked during the execution of the binding form. A dynamic binding turns out that all global variables are dynamic variables. Thus, if we want to temporarily redefine *standard-output*, the way to do it is simply to rebind it with a LET. (let ((*standard-output* *some-other-stream*)) (stuff)) In any code that runs as a result of the call to stuff, references to *standard-output* will use the binding established by the LET. And when stuff returns and control leaves the LET, the new binding of *standard-output* will go away and subsequent references to *standard-output* will see the binding that was current before the LET. 12

DYNAMIC VARIABLES A simple example shows how this works. (defvar *x* 10) (defun foo () (format t "X: ~d~%" *x*)) The DEFVAR creates a global binding for the variable *x* with the value 10. The reference to *x* in foo will look up the current binding dynamically. CL-USER> (foo) X: 10 NIL CL-USER> (let ((*x* 20)) (foo)) X: 20 NIL Now call foo again, with no LET, and it again sees the global binding. CL-USER> (foo) X: 10 NIL 13

DYNAMIC VARIABLES Now define another function. (defun bar () (foo) (let ((*x* 20)) (foo)) ; dynamic binding (foo)) Note that the middle call to foo is wrapped in a LET that binds *x* to the new value 20. CL-USER> (bar) X: 10 X: 20 X: 10 NIL The first call to foo sees the global binding, with its value of 10. The middle call sees the new binding with the value 20. But after the LET, foo once again sees the global binding. 14

DYNAMIC VARIABLES As with lexical bindings, assigning a new value affects only the current binding. For example: (defun foo () (format t "Before assignment~18tX: ~d~%" *x*) (setf *x* (+ 1 *x*)) (format t "After assignment~18tX: ~d~%" *x*)) Now foo prints the value of *x*, increments it, and prints it again. CL-USER> (foo) Before assignment X: 10 After assignment X: 11 NIL 15

DYNAMIC VARIABLES Not too surprising. Now run bar. CL-USER> (bar) Before assignment X: 11 After assignment X: 12 Before assignment X: 20 After assignment X: 21 Before assignment X: 12 After assignment X: 13 NIL The name of every variable defined with DEFVAR and DEFPARAMETER is automatically declared globally special. This means whenever you use such a name in a binding form—in a LET or as a function parameter or any other construct that creates a new variable binding—the binding that's created will be a dynamic binding. Dynamic bindings make global variables much more manageable. 16

SUMMARY Common Lisp supports two kinds of variables: lexical ( 語彙的 ) and dynamic ( 動態的 ). When a variable is lexically scoped, the system looks to where the function is defined to find the value for a free variable. When a variable is dynamically scoped, the system looks to where the function is called to find the value for the free variable. Variables in Common Lisp are all lexical by default; however, dynamically scoped variables can be defined at the top level using defvar or defparameter. An example: lexical scoping (with setf): (setf x 3) (defun foo () x) > (let ((x 4)) (foo)) ; returns 3 dynamic scoping (with defvar): (defvar x 3) (defun foo () x) > (let ((x 4)) (foo)) ; returns 4 17

EXAMPLES ;; the lexical version (setf x 10) (defun lex-foo () (format t "Before assignment~18tX: ~d~%" x) (setf x (+ 1 x)) (format t "After assignment~18tX: ~d~%" x)) (defun lex-bar () (lex-foo) (let ((x 20)) ;; does not do anything (lex-foo)) CL-USER> (lex-bar) Before assignment X: 10 After assignment X: 11 Before assignment X: 11 After assignment X: 12 Before assignment X: 12 After assignment X: 13 ;; the dynamic version (defvar *x* 10) (defun dyn-foo () (format t "Before assignment~18tX: ~d~%" *x*) (setf *x* (+ 1 *x*)) (format t "After assignment~18tX: ~d~%" *x*)) (defun dyn-bar() (dyn-foo) (let ((*x* 20)) (dyn-foo)) CL-USER> (dyn-bar) Before assignment X: 10 After assignment X: 11 Before assignment X: 20 After assignment X: 21 Before assignment X: 11 After assignment X: 12 18

CONSTANTS Constants are global and are defined with DEFCONSTANT. The basic form of DEFCONSTANT: (defconstant name initial-value-form [ documentation-string ]) > (defconstant speed-of-light "Speed of light in meters per second") SPEED-OF-LIGHT > (setf speed-of-light ) Error: can't assign to SPEED-OF-LIGHT. > (print speed-of-light) It's a good idea to use DEFCONSTANT only to define things that are really constant, such as the value of π. For things you might ever want to change, you should use DEFPARAMETER instead. 19

ASSIGNMENT The SETF macro can be used to assign a new value to a binding. It is a Common Lisp's general-purpose assignment operator. The basic form of SETF: (setf place value) For instance, to assign the value 10 to the variable x: (setf x 10) SETF assigns a new value to a binding has no effect on any other bindings of that variable. For example: (defun foo (x) (setf x 10)) > (let ((y 20)) (foo y) (print y)) will print 20, not 10, as it's the value of y that's passed to foo where it's briefly the value of the variable x before the SETF gives x a new value. 20

ASSIGNMENT SETF can also assign to multiple places in sequence. For instance, instead of the following: (setf x 1) (setf y 2) We can write this: (setf x 1 y 2) SETF returns the newly assigned value, so we can also nest calls to SETF as in the following expression, which assigns both x and y the same random value: (setf x (setf y (random 10))) 21

GENERALIZED ASSIGNMENT The various ways = (assignment) used in other languages The Lisp equivalents of the assignments in Table 6-1 AREF: the array access function GETHASH: a hash table lookup FIELD: a function that accesses a slot named field of a user-defined object Simple variable: (setf x 10) Array: (setf (aref a 0) 10) Hash table: (setf (gethash 'key hash) 10) Slot named 'field':(setf (field o) 10) 22

OTHER WAYS TO MODIFY PLACES While all assignments can be expressed with SETF, certain patterns involving assigning a new value based on the current value are sufficiently common to warrant( 授權 ) their own operators. For instance, increment or decrement a number with SETF: (setf x (+ x 1)) (setf x (- x 1)) Instead, the macros INCF and DECF can be also used to increase and decrease a number: (incf x) ≡ (setf x (+ x 1)) (decf x) ≡ (setf x (- x 1)) (incf x 10) ≡ (setf x (+ x 10)) INCF and DECF are examples of a kind of macro called modify macros. Modify macros are macros built on top of SETF that modify places by assigning a new value based on the current value of the place. 23

OTHER WAYS TO MODIFY PLACES The macros PUSH and POP are another modify macros. > (setf mystack nil) NIL > (push 'dish1 mystack) (DISH1) > (push 'dish2 mystack) (DISH2 DISH1) > (push 'dish3 mystack) (DISH3 DISH2 DISH1) > (pop mystack) DISH3 > (pop mystack) DISH2 > (pop mystack) DISH1 24

OTHER WAYS TO MODIFY PLACES The macros ROTATEF and SHIFTF are useful modify macros. ROTATEF rotates values between places. (rotatef a b) swaps the values of two variables a, b and returns NIL. (rotatef a b) ≡ (let ((tmp a)) (setf a b b tmp) nil) SHIFTF is similar except instead of rotating values it shifts them to the left. The original value of the first argument is simply returned. (shiftf a b 10) ≡ (let ((tmp a)) (setf a b b 10) tmp) Both ROTATEF and SHIFTF can be used with any number of arguments and are guaranteed to evaluate them exactly once, in left to right order. 25

EXAMPLES > (setf x 10) 10 > (setf y 20) 20 > (setf z 30) 30 > (list x y z) ( ) > (rotatef x y z) NIL > (list x y z) ( ) 26 > (setf x 10) 10 > (setf y 20) 20 > (setf z 30) 30 > (list x y z) ( ) > (shiftf x y z) 10 > (list x y z) ( )