608
1 CS 538 Spring 2008 © CS 538 Introduction to the Theory and Design of Programming Languages Charles N. Fischer Spring 2008 http://www.cs.wisc.edu/~fischer/cs538.html

UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

1CS 538 Spring 2008©

CS 538

Introduction to the Theory andDesign of Programming

Languages

Charles N. Fischer

Spring 2008

http://www.cs.wisc.edu/~fischer/cs538.html

Page 2: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

2CS 538 Spring 2008©

Class MeetsMondays, Wednesdays &Fridays,9:55 — 10:451325 Computer Sciences

InstructorCharles N. Fischer6367 Computer SciencesTelephone: 608.262.6635E-mail: [email protected] Hours:

10:30 - Noon, Tuesdays &Thursdays, or byappointment

Page 3: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

3CS 538 Spring 2008©

Teaching AssistantJongwon Yoon3361 Computer SciencesTelephone: 608.354.3613E-mail: [email protected] Hours:

2:00 - 3:00, Mondays,Wednesdays and Fridays,or by appointment

Page 4: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

4CS 538 Spring 2008©

Key Dates• Feb 25: Homework #1 (tentative)• March 24: Programming Assignment #1 -

Scheme (tentative)• April 2: Midterm Exam (tentative)• April 16: Programming Assignment #2 -

Standard ML (tentative)• May 2: Programming Assignment #3 -

Prolog (tentative)• May 9: Programming Assignment #4 -

Java, C#, Pizza and Python• May 15: Final Exam 2:45pm-4:45pm

Page 5: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

5CS 538 Spring 2008©

Class Text• Required text:

“Modern ProgrammingLanguages,” Adam Webber,Franklin, Beedle & Associates,2003.

• Handouts and Web-based reading willalso be used.

Reading Assignment• Webber: Chapters 1, 10, 18

(as background)

Page 6: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

6CS 538 Spring 2008©

Class Notes• Each lecture will be made available

prior to that lecture on the class Webpage (under the “Lecture Nodes” link).

Instructional ComputersDepartmental Linux Machines(king01- king12, emperor01-emperor40) have beenassigned to CS 538. Allnecessary compiler,interpreters and tools will beloaded onto these machines.

Page 7: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

7CS 538 Spring 2008©

You may also use your own PCor laptop. It will be yourresponsibility to load neededsoftware (instructions on whereto find needed software areincluded on the class webpage).

The Systems Lab teaches brieftutorials on Linux if you areunfamiliar with that OS.

Page 8: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

8CS 538 Spring 2008©

Academic Misconduct Policy• You must do your own assignments —

no copying or sharing of solutions.

• You may discuss general concepts andIdeas.

• All cases of misconduct must bereported to the Dean’s office.

• Penalties may be severe.

Page 9: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

9CS 538 Spring 2008©

Program & Homework LatePolicy• An assignment may be handed in up

to 7 days late, but no later.

• Each day late will be debited 4%, up toa maximum of 28%.

• All students are given 10 “free” latedays. That is, the first 40% in latedebits will be automatically forgiven.

• Your 10 free late days my be used atany time, and in any combination.

Page 10: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

10CS 538 Spring 2008©

Approximate Grade WeightsHomework 1 10%Program 1 - Scheme 16%Program 2 - ML 16%Program 3 - Prolog 12%Program 4 - Java, C#, Pizza and Python (optional extra credit) 10%Midterm Exam 23%Final Exam (non-cumulative) 23%

Page 11: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

11CS 538 Spring 2008©

Programming Languages to beConsidered in Detail1. Scheme

A modern variant of Lisp.A Functional Language:Functions are “first class” datavalues.Dynamically Typed:A variable’s type may changeduring execution; no typedeclarations are needed.All memory allocation anddeallocation is automatic.Primary data structures, listsand numbers, are unlimited insize and may grow withoutbound.

Page 12: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

12CS 538 Spring 2008©

Continuations provide a novelway to suspend and “re-execute” computations.

2. ML (“Meta Language”)Strong, compile-time typechecking.Types are determined byinference rather thandeclaration.Naturally polymorphic (onefunction declaration can beused with many differenttypes).Pattern-directed programming(you define patterns that areautomatically matched during acall).

Page 13: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

13CS 538 Spring 2008©

Typed exceptions are provided.Abstract data types, withconstructors, are included.

3. Prolog (Programming in Logic)Programs are Facts and Rules.Programmers are concernedwith definition, not execution.Execution order isautomatically determined.

Page 14: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

14CS 538 Spring 2008©

4. PizzaExtends a popular Object-oriented language, Java, toinclude• Parametric polymorphism (similar

to C++’s templates).

• First-class functional objects.

• Algebraic data types, includingpatterns.

5. C#Microsoft’s answer to Java. Inmost ways it is very similar toJava, with some C++ conceptsreintroduced and some usefuladditions.

Page 15: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

15CS 538 Spring 2008©

• Events and delegates are includedto handle asynchronous actions(like keyboard or mouse actions).

• Properties allow user-defined readand write actions for fields.

• Indexers allow objects other thanarrays to be indexed.

• Collection classes may be directlyenumerated:foreach (int i in array) ...

• Structs and classes co-exist andmay be inter-converted (boxed andunboxed).

• Enumerations, operatoroverloading and rectangular arraysare provided.

• Reference, out and variable-lengthparameter lists are allowed.

Page 16: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

16CS 538 Spring 2008©

6. Java 1.5 (Tiger Java, Java 5.0)Extends current definition ofJava to include:• Parametric polymorphism

(collection types may beparameterized).

• Enhanced loop iterators.

• Automatic boxing and unboxing ofwrapper classes.

• Typesafe enumerations.

• Static imports (out.println ratherthan System.out.println).

• Variable argument methods.

• Formatted output using printf:out.printf("Ans = %3d",a+b);

Page 17: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

17CS 538 Spring 2008©

7. PythonA simple, efficient scriptinglanguage that quickly buildsnew programs out of existingapplications and libraries.It cleanly includes objects.It scales nicely into largerapplications.

Page 18: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

18CS 538 Spring 2008©

Evolution of ProgrammingLanguages

In the beginning, ...programs were written inabsolute machine code—asequence of bits that encodemachine instructions.Example:

340200050000000c3c011001ac220000

This form of programming is• Very detailed

• Very tedious

• Very error-prone

• Very machine specific

Page 19: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

19CS 538 Spring 2008©

Symbolic AssemblersAllow use of symbols foroperation codes and labels.Example:

li $v0,5syscallsw $v0,a

Far more readable, but still verydetailed, tedious and machine-specific.Types are machine types.Control structures areconditional branches.Subprograms are blocks ofcode called via a “subroutinebranch” instruction.All labels are global.

Page 20: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

20CS 538 Spring 2008©

Fortran (Formula Translator)Example:

do 10 i=1,100

10 a(i)=0

Developed in the mid-50s.A major step forward:• Programming became more

“problem oriented” and less“machine oriented.”

• Notions of control structures (ifsand do loops) were introduced.

• Subprograms, calls, andparameters were made available.

• Notions of machine independencewere introduced.

• Has evolved into many newvariants, including Fortran 77,Fortran 90 and HPF (HighPerformance Fortran).

Page 21: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

21CS 538 Spring 2008©

Cobol (Common BusinessOriented Language)

Example:multiply i by 3 giving j.move j to k.write line1 after advancing1 lines.

Developed in the early 60s.The first widely-standardizedprogramming language.Once dominant in the businessworld; still important.Wordy in structure; designedfor non-scientific users.Raised the issue of who shouldprogram and how importantreadability and maintainabilityare.

Page 22: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

22CS 538 Spring 2008©

Algol 60 (Algorithmic Language)Example:

real procedure cheb(x,n);value x,n;real x; integer n;cheb :=

if n = 0 then 1 else if n = 1 then x else 2 × x × cheb(x,n-1)-cheb(x,n-2);

Developed about 1960.A direct precursor of Pascal, C,C++ and Java.Introduced many ideas now inwide use:• Blocks with local declarations and

scopes.

• Nested declarations and controlstructures.

Page 23: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

23CS 538 Spring 2008©

• Parameter passing

• Automatic recursion.

But,• I/O wasn’t standardized.

• IBM promoted Fortran and PL/I.

Page 24: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

24CS 538 Spring 2008©

Lisp (List Processing Language)Example:

((lambda (x) (* x x)) 10)

Developed in the early 60s.A radical departure from earlierprogramming languages.Programs and data arerepresented in a uniform listformat.Types are a property of datavalues, not variables orparameters.A program can build and runnew functions as it executes.Data values were not fixed insize.

Page 25: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

25CS 538 Spring 2008©

Memory management wasautomatic.A formal semantics wasdeveloped to define preciselywhat a program means.

Page 26: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

26CS 538 Spring 2008©

Simula 67 (Simulation Algol)Example:

Class Rectangle (Width, Height);Real Width, Height;Boolean Procedure IsSquare; IsSquare := Width=Height;End of Rectangle;

Developed about 1967.Introduced the notion of a class(for simulation purposes).Included objects, a garbagecollector, and notions ofextending a class.C++ was originally C withclasses (as Simula was Algolwith classes).

Page 27: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

27CS 538 Spring 2008©

C and C++C was developed in the early70’s; C++ in the mid-80s.These languages have aconcise, expressive syntax;they generate high quality codesufficient for performance-critical applications.C, along with Unix, proved theviability of platform-independent languages andapplications.C and C++ allow programmersa great deal of freedom inbending and breaking rules.Raises the issue of whether onelanguage can span both noviceand expert programmers.

Page 28: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

28CS 538 Spring 2008©

Interesting issue—if moststatements and expressions aremeaningful, can errors bereadily detected?

if (a=b)

a=0;

else a = 1;

Page 29: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

29CS 538 Spring 2008©

JavaDeveloped in the late 90s.Cleaner object-orientedlanguage than C++.Introduced notions of dynamicloading of class definitionsacross the Web.Much stronger emphasis onsecure execution and detectionof run-time errors.Extended notions of platformindependence to systemindependence.

Page 30: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

30CS 538 Spring 2008©

What Drives Research intoNew Programming Languages?Why isn’t C or C++ or C+++enough?1. Curiosity

What other forms can aprogramming language take?What other notions ofprogramming are possible?

2. ProductivityProcedural languages,including C, C++ and Java, arevery detailed.Many source lines implysignificant development andmaintenance expenses.

Page 31: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

31CS 538 Spring 2008©

3. ReliabilityToo much low-level detail inprograms greatly enhances thechance of minor errors. Minorerrors can raise significantproblems in applications.

4. SecurityComputers are entrusted withgreat responsibilities. How canwe know that a program is safeand reliable enough to trust?

5. Execution speedProcedural languages areclosely tied to the standardsequential model of instructionexecution. We may needradically different programmingmodels to fully exploit paralleland distributed computers.

Page 32: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

32CS 538 Spring 2008©

Desirable Qualities in aProgramming Language

Theoretically, all programminglanguages are equivalent (Why?)If that is so, what properties aredesirable in a programminglanguage?

• It should be easy to use.Programs should be easy to read andunderstand.Programs should be simple to write,without subtle pitfalls.It should be orthogonal, providingonly one way to do each step orcomputation.Its notation should be natural for theapplication being programed.

Page 33: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

33CS 538 Spring 2008©

• The language should supportabstraction.

You can’t anticipate all needed datastructures and operations, so addingnew definitions easily and efficientlyshould be allowed.

• The language should supporttesting, debugging andverification.

• The language should have a gooddevelopment environment.

Integrated editors, compilers,debuggers, and version control are abig plus.

• The language should be portable,spanning many platforms andoperating systems.

Page 34: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

34CS 538 Spring 2008©

• The language should beinexpensive to use:

Execution should be fast.Memory needs should be modest.Translation should be fast andmodular.Program creation and testing shouldbe easy and cheap.Maintenance should not be undulycumbersome.Components should be reusable.

Page 35: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

35CS 538 Spring 2008©

Programming ParadigmsProgramming languagesnaturally fall into a number offundamental styles orparadigms.

Procedural LanguagesMost of the widely-known andwidely-used programminglanguages (C, Fortran, Pascal,Ada, etc.) are procedural.Programs execute statement bystatement, reading andmodifying a shared memory.This programming style closelymodels conventional sequentialprocessors linked to a randomaccess memory (RAM).

Page 36: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

36CS 538 Spring 2008©

Question:Givena = a + 1;

if (a > 10) b = 10; else b = 15; a = a * b;

Why can’t 5 processors eachexecute one line to make theprogram run 5 times faster?

Page 37: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

37CS 538 Spring 2008©

Functional LanguagesLisp, Scheme and ML arefunctional in nature.Programs are expressions to beevaluated.Language design aims tominimize side-effects, includingassignment.Alternative evaluationmechanisms are possible,includingLazy (Demand Driven)

Eager (Data Driven orSpeculative)

Page 38: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

38CS 538 Spring 2008©

Object-Oriented LanguagesC++, Java, Smalltalk, Pizza andPython are object-oriented.Data and functions areencapsulated into Objects.Objects are active, havepersistent state, and uniforminterfaces (messages ormethods).Notions of inheritance andcommon interfaces are central.All objects that provide thesame interface are treateduniformly. In Java you can printany object that provides thetoString method. Iterationthrough the elements of anyobject that implements theEnumeration interface is possible.

Page 39: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

39CS 538 Spring 2008©

Subclassing allows to youextend or redefine part of anobject’s behavior withoutreprogramming all of theobject’s definition. Thus in Java,you can take a Hashtable class(which is fairly elaborate) andcreate a subclass in which anexisting method (like toString)is redefined, or new operationsare added.

Page 40: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

40CS 538 Spring 2008©

Logic ProgrammingLanguages

Prolog notes that mostprogramming languagesaddress both the logic of aprogram (what is to be done)and its control flow (how youdo what you want).A logic programming language,like Prolog, lets programmersfocus on a program’s logicwithout concern for controlissue.These languages have no realcontrol structures, and littlenotion of “flow of control.”What results are programs thatare unusually succinct andfocused.

Page 41: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

41CS 538 Spring 2008©

Example:inOrder( [] ).inOrder( [ _ ] ).inOrder([a,b|c]) :- (a<b),

inOrder([b|c]).

This is a complete, executablefunction that determines if alist is in order. It is naturallypolymorphic, and is notcluttered with declarations,variables or explicit loops.

Page 42: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

42CS 538 Spring 2008©

Review of Concepts fromProcedural ProgrammingLanguages

Declarations/Scope/Lifetime/BindingStatic/Dynamic

• Identifiers are declared, eitherexplicitly or implicitly (from context offirst use).

• Declarations bind type and kindinformation to an identifier. Kindspecifies the grouping of an identifier(variable, label, function, type name,etc.)

• Each identifier has a scope (or range)in a program—that part of theprogram in which the identifier isvisible (i.e., may be used).

Page 43: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

43CS 538 Spring 2008©

• Data objects have a lifetime—the spanof time, during program execution,during which the object exists andmay be used.

• Lifetimes of data objects are often tiedto the scope of the identifier thatdenotes them. The objects are createdwhen its identifier’s scope is entered,and they may be deleted when theidentifier’s scope is exited. Forexample, memory for local variableswithin a function is usually allocatedwhen the function is called (activated)and released when the call terminates.In Java, a method may be loaded intomemory when the object it is amember of is first accessed.

Page 44: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

44CS 538 Spring 2008©

Properties of an identifier (and theobject it represents) may be set at• Compile-time

These are static properties asthey do not change duringexecution. Examples includethe type of a variable, the valueof a constant, the initial valueof a variable, or the body of afunction.

• Run-time

These are dynamic properties.Examples include the value of avariable, the lifetime of a heapobject, the value of a function’sparameter, the number of timesa while loop iterates, etc.

Page 45: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

45CS 538 Spring 2008©

Example:In Fortran• The scope of an identifier is the whole

program or subprogram.

• Each identifier may be declared onlyonce.

• Variable declarations may be implicit.(Using an identifier implicitly declaresit as a variable.)

• The lifetime of data objects is thewhole program.

Page 46: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

46CS 538 Spring 2008©

Block Structured Languages• Include Algol 60, Pascal, C and Java.

• Identifiers may have a non-globalscope. Declarations may be local to aclass, subprogram or block.

• Scopes may nest, with declarationspropagating to inner (contained)scopes.

• The lexically nearest declaration of anidentifier is bound to uses of thatidentifier.

Page 47: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

47CS 538 Spring 2008©

Binding of an identifier to itscorresponding declaration isusually static (also calledlexical), though dynamicbinding is also possible.Static binding is done prior toexecution—at compile-time.Example (drawn from C):

int x,z;void A() {float x,y;

print(x,y,z);

}void B() { print (x,y,z)

}

floatfloat

int

int

intundeclared

Page 48: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

48CS 538 Spring 2008©

Block Structure Concepts• Nested Visibility

No access to identifiers outsidetheir scope.

• Nearest Declaration Applies

Static name scoping.• Automatic Allocation and Deallocation

of Locals

Lifetime of data objects isbound to the scope of theIdentifiers that denote them.

Page 49: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

49CS 538 Spring 2008©

Variations in these rules ofname scoping are possible.For example, in Java, thelifetime of all class objects isfrom the time of their creation(via new) to the last visiblereference to them.Thus ... Object O;...creates an object reference butdoes not allocate any memoryspace for O.You need ... Object O = new Object(); ...to actually create memoryspace for O.

Page 50: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

50CS 538 Spring 2008©

Dynamic ScopingAn alternative to static scopingis dynamic scoping, which wasused in early Lisp dialects (butnot in Scheme, which isstatically scoped).Under dynamic scoping,identifiers are bound to thedynamically closest declarationof the identifier. Thus if anidentifier is not locallydeclared, the call chain(sequence of callers) isexamined to find a matchingdeclaration.

Page 51: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

51CS 538 Spring 2008©

Example: int x;

void print() {

write(x); }

main () {

bool x;

print();

}

Under static scoping the xwritten in print is the lexicallyclosest declaration of x, whichis as an int.Under dynamic scoping, sinceprint has no local declarationof x, print’s caller is examined.Since main calls print, and ithas a declaration of x as a bool,that declaration is used.

Page 52: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

52CS 538 Spring 2008©

Dynamic scoping makes typechecking and variable accessharder and more costly thanstatic scoping. (Why?)However, dynamic scopingdoes allow a notion of an“extended scope” in whichdeclarations extend tosubprograms called within thatscope.Though dynamic scoping mayseen a bit bizarre, it is closelyrelated to virtual functionsused in C++ and Java.

Page 53: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

53CS 538 Spring 2008©

Virtual FunctionsA function declared in a class,C, may be redeclared in a classderived from C. Moreover, foruniformity of redeclaration, it isimportant that all calls,including those in methodswithin C, use the newdeclaration.Example:

class C {

void DoIt()(PrintIt();} void PrintIt() {println(“C rules!”);} } class D extends C { void PrintIt() {println(“D rules!”);} void TestIt() {DoIt();} } D dvar = new D(); dvar.TestIt();

D rules! is printed.

Page 54: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

54CS 538 Spring 2008©

Scope vs. LifetimeIt is usually required that thelifetime of a run-time object atleast cover the scope of theidentifier. That is, wheneveryou can access an identifier, therun-time object it denotesbetter exist.But,it is possible to have a run-timeobject’s lifetime exceed thescope of its identifier. Anexample of this is static or ownvariables.

Page 55: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

55CS 538 Spring 2008©

In C:void p() {

static int i = 0; print(i++); }

Each call to p prints a differentvalue of i (0, 1, ...) Variable iretains its value across calls.Some languages allow anexplicit binding of an identifierfor a fixed scope:

A declaration may appearwherever a statement orexpression is allowed. Limitedscopes enhance readability.

Letid = val

in statementsend;

{ type id = val; statements}

Page 56: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

56CS 538 Spring 2008©

Structs vs. BlocksMany programming languages,including C, C++, C#, Pascaland Ada, have a notion ofgrouping data together intostructs or records.For example:struct complex { float re, im; }

There is also the notion ofgrouping statements anddeclarations into blocks:{ float re, im;

re = 0.0; im = 1.0;

}

Page 57: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

57CS 538 Spring 2008©

Blocks and structs look similar,but there are significantdifferences:Structs are data,• As originally designed, structs

contain only data (no functions ormethods).

• Structs can be dynamically created,in any number, and included inother data structures (e.g., in anarray of structs).

• All fields in a struct are visibleoutside the struct.

Page 58: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

58CS 538 Spring 2008©

Blocks are code,• They can contain both code and

data.

• Blocks can’t be dynamically createdduring execution; they are “builtinto” a program.

• Locals in a block aren’t visibleoutside the block.

By adding functions andinitialization code to structs,we get classes—a nice blend ofstructs and blocks.For example:class complex{

float re, im;

complex (float v1, float v2){

re = v1; im = v2; }

}

Page 59: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

59CS 538 Spring 2008©

Classes• Class objects can be created as

needed, in any number, and includedin other data structure.

• They include both data (fields) andfunctions (methods).

• They include mechanisms to initializethemselves (constructors) and tofinalize themselves (destructors).

• They allow controlled access tomembers (private and publicdeclarations).

Page 60: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

60CS 538 Spring 2008©

Type Equivalence in ClassesIn C, C++ and Java, instances ofthe same struct or class aretype-equivalent, and mutuallyassignable.For example:class MyClass { ... }MyClass v1, v2;v1 = v2; // Assignment is OK

We expect to be able to assignvalues of the same type,including class objects.However, sometimes a classmodels a data object whosesize or shape is set uponcreation (in a constructor).

Page 61: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

61CS 538 Spring 2008©

Then we may not wantassignment to be allowed.

class Point { int dimensions; float coordinates[]; Point () { dimensions = 2; coordinates = new float[2]; } Point (int d) { dimensions = d; coordinates = new float[d]; } } Point plane = new Point(); Point solid = new Point(3); plane = solid; //OK in Java

This assignment is allowed,even though the two objectsrepresent points in differentdimensions.

Page 62: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

62CS 538 Spring 2008©

SubtypesIn C++, C# and Java we cancreate subclasses—new classesderived from an existing class.We can use subclasses to createnew data objects that aresimilar (since they are based ona common parent), but stilltype-inequivalent.Example:class Point2 extends Point {

Point2() {super(2); } } class Point3 extends Point { Point3() {super(3); } } Point2 plane = new Point2(); Point3 solid = new Point3();

plane = solid; //Illegal in Java

Page 63: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

63CS 538 Spring 2008©

Parametric PolymorphismWe can create distinctsubclasses based on the valuespassed to constructors. Butsometimes we want to createsubclasses based on distincttypes, and types can’t bepassed as parameters. (Typesare not values, but rather aproperty of values.)We see this problem in Java,which tries to create generalpurpose data structures bybasing them on the classObject. Since any object can beassigned to Object (all classesmust be a subclass of Object),this works—at least partially.

Page 64: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

64CS 538 Spring 2008©

class LinkedList { Object value; LinkedList next; Object head() {return value;}LinkedList tail(){return next;}

LinkedList(Object O) { value = O; next = null;} LinkedList(Object O, LinkedList L){ value = O; next = L;}}

Using this class, we can createa linked list of any subtype ofObject.But,• We can’t guarantee that linked lists

are type homogeneous (containonly a single type).

• We must cast Object types backinto their “real” types when weextract list values.

Page 65: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

65CS 538 Spring 2008©

• We must use wrapper classes likeInteger rather than int (becauseprimitive types like int aren’tobjects, and aren’t subclass ofObject).

For example, to use LinkedListto build a linked list of ints wedo the following:LinkedList l =

new LinkedList(new Integer(123));

int i = ((Integer) l.head()).intValue();

This is pretty clumsy code.We’d prefer a mechanism thatallows us to create a “customversion” of LinkedList, basedon the type we want the list tocontain.

Page 66: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

66CS 538 Spring 2008©

We can’t just call something likeLinkedList(int) orLinkedList(Integer) because

types can’t be passed asparameters.Parametric polymorphism isthe solution. Using thismechanism, we can use typeparameters to build a “customversion” of a class from ageneral purpose class.C++ allows this using itstemplate mechanism. Tiger Javaalso allows type parameters.In both languages, typeparameters are enclosed in“angle brackets” (e.g.,LinkedList<T> passes T, a type,to the LinkedList class).

Page 67: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

67CS 538 Spring 2008©

Thus we haveclass LinkedList<T> { T value; LinkedList<T> next; T head() {return value;} LinkedList<T> tail() { return next;} LinkedList(T O) { value = O; next = null;} LinkedList(T O,LinkedList<T> L) {value = O; next = L;}}LinkedList<int> l = new LinkedList(123);

int i = l.head();

Page 68: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

68CS 538 Spring 2008©

Overloading and Ad-hocPolymorphism

Classes usually allowoverloading of method names,if only to support multipleconstructors.That is, more than one methoddefinition with the same nameis allowed within a class, aslong as the method definitionsdiffer in the number and/ortypes of the parameters theytake.For example,class MyClass { int f(int i) { ... } int f(float g) { ... } int f(int i, int j) { ... }}

Page 69: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

69CS 538 Spring 2008©

Overloading is sometimescalled “ad hoc” polymorphism,because, to the programmer, itappears that one method cantake a variety of differentparameter types. This isn’t truepolymorphism because themethods have different bodies;there is no sharing of onedefinition among differentparameter types. There is noguarantee that the differentdefinitions do the same thing,even though they share acommon name.

Page 70: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

70CS 538 Spring 2008©

Issues in OverloadingThough many languages allowoverloading, few allowoverloaded methods to differonly on their result types.(Neither C++ nor Java allow thiskind of overloading, thoughAda does). For example,class MyClass { int f() { ... } float f() { ... }}

is illegal. This is unfortunate;methods with the same nameand parameters, but differentresult types, could be used toautomatically convert resultvalues to the type demandedby the context of call.

Page 71: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

71CS 538 Spring 2008©

Why is this form of overloadingusually disallowed?It’s because overload resolution(deciding which definition touse) becomes much harder.Considerclass MyClass { int f(int i, int j) { ... } float f(float i, float j) { ... } float f(int i, int j) { ... }}

inint a = f( f(1,2), f(3,4) );

which definitions of f do weuse in each of the three calls?Getting the correctly answercan be tricky, though solutionalgorithms do exist.

Page 72: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

72CS 538 Spring 2008©

Operator OverloadingSome languages, like C++ andC#, allow operators to beoverloaded. You may add newdefinitions to existingoperators, and use them onyour own types. For example, class MyClass {

int i; public: int operator+(int j) { return i+j; } } MyClass c; int i = c+10; int j = c.operator+(10); int k = 10+c; // Illegal!

Page 73: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

73CS 538 Spring 2008©

The expression 10+c is illegalbecause there is no definitionof + for the types int andMyClass&. We can create one byusing C++’s friend mechanismto insert a definition intoMyClass that will have access toMyClass’s private data:

class MyClass {

int i; public: int operator+(int j) { return i+j; } friend int operator+ (int j, MyClass& v){

return j+v.i; } } MyClass c; int k = 10+c; // Now OK!

Page 74: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

74CS 538 Spring 2008©

C++ limits operator overloadingto existing predefined operators.A few languages, like Algol 68 (asuccessor to Algol 60, developedin 1968), allow programmers todefine brand new operators.In addition to defining theoperator itself, it is also necessaryto specify the operator’sprecedence (which operator is tobe applied first) and itsassociativity (does the operatorassociate from left to right, orright to left, or not at all). Giventhis extra detail, it is possible tospecify something likeop +++ prec = 8;

int op +++(int& i, int& j) { return (i++)+(j++); }

(Why is int& used as theparameter type rather than int?)

Page 75: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

75CS 538 Spring 2008©

Parameter BindingAlmost all programminglanguages have some notion ofbinding an actual parameter(provided at the point of call) to aformal parameter (used in thebody of a subprogram).There are many different, andinequivalent, methods ofparameter binding. Exactly whichis used depends upon theprogramming language inquestion.Parameter Binding Modes include:• Value: The formal parameter

represents a local variableinitialized to the value of thecorresponding actual parameter.

Page 76: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

76CS 538 Spring 2008©

• Result: The formal parameterrepresents a local variable. Its finalvalue, at the point of return, iscopied into the correspondingactual parameter.

• Value/Result: A combination of thevalue and results modes. Theformal parameter is a local variableinitialized to the value of thecorresponding actual parameter.The formal’s final value, at thepoint of return, is copied into thecorresponding actual parameter.

• Reference: The formal parameter isa pointer to the correspondingactual parameter. All references tothe formal parameter indirectlyaccess the corresponding actualparameter through the pointer.

Page 77: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

77CS 538 Spring 2008©

• Name: The formal parameterrepresents a block of code(sometimes called a thunk) that isevaluated to obtain the value oraddress of the correspondingactual parameter. Each reference tothe formal parameter causes thethunk to be reevaluated.

• Readonly (sometimes called Const):Only reads of the formal parameterare allowed. Either a copy of theactual parameter’s value, or itsaddress, may be used.

Page 78: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

78CS 538 Spring 2008©

What Parameter Modes doProgramming Languages Use?• C: Value mode except for arrays which

pass a pointer to the start of the array.

• C++: Allows reference as well as valuemodes. E.g.,

int f(int a, int& b)

• C#: Allows result (out) as well asreference and value modes. E.g.,

int g(int a, out int b)

• Java: Scalar types (int, float, char,etc.) are passed by value; objects arepassed by reference (references toobjects are passed by value).

• Fortran: Reference (even forconstants!)

• Ada: Value/result, reference, andreadonly are used.

Page 79: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

79CS 538 Spring 2008©

Examplevoid p(value int a, reference int b, name int c) { a=1; b=2; print(c)}int i=3, j=3, k[10][10];p(i,j,k[i][j]);

What element of k is printed?• The assignment to a does not

affect i, since a is a valueparameter.

• The assignment to b does affect j,since b is a reference parameter.

• c is a name parameter, so it isevaluated whenever it is used. Inthe print statement k[i][j] isprinted. At that point i=3 and j=2,so k[3][2] is printed.

Page 80: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

80CS 538 Spring 2008©

Why are there so ManyDifferent Parameter Modes?

Parameter modes reflectdifferent views on howparameters are to be accessed,as well as different degrees ofefficiency in accessing andusing parameters.• Call by value protects the actual

parameter value. No matter whatthe subprogram does, theparameter can’t be changed.

• Call by reference allows immediateupdates to the actual parameter.

• Call by readonly protects the actualparameter and emphasizes the“constant” nature of the formalparameter.

Page 81: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

81CS 538 Spring 2008©

• Call by value/result allows actualparameters to change, but treats acall as a single step (assignparameter values, execute thesubprogram’s body, updateparameter values).

• Call by name delays evaluation ofan actual parameter until it isactually needed (which may benever).

Page 82: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

82CS 538 Spring 2008©

Call by NameCall by name is a special kindof parameter passing mode. Itallows some calls to completethat otherwise would fail.Considerf(i,j/0)

Normally, when j/0 isevaluated, a divide faultterminates execution. If j/0 ispassed by name, the division isdelayed until the parameter isneeded, which may be never.Call by name also allowsprogrammers to create someinteresting solutions to hardprogramming problems.

Page 83: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

83CS 538 Spring 2008©

Consider the conditionalexpression found in C, C++,and Java:(cond ? value1 : value2)

What if we want to implementthis as a function call:condExpr(cond,value1,value2) {

if (cond) return value1; else return value2; }

With most parameter passingmodes this implementationwon’t work! (Why?)But if value1 and value2 arepassed by name, theimplementation is correct.

Page 84: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

84CS 538 Spring 2008©

Call by Name and LazyEvaluation

Call by name has much of theflavor of lazy evaluation. Withlazy evaluation, you don’tcompute a value but rather asuspension—a function that willprovide a value when called.This can be useful when we needto control how much of acomputation is actuallyperformed.Consider an infinite list ofintegers. Mathematically it isrepresented as 1, 2, 3, ...How do we compute a datastructure that represents aninfinite list?

Page 85: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

85CS 538 Spring 2008©

The obvious computationinfList(int start) {

return list(start, infList(start+1)); }

doesn’t work. (Why?)A less obvious implementation,using suspensions, does work:infList(int start) {

return list(start, function() { return infList(start+1); });}

Now, whenever we are given aninfinite list, we get two things: thefirst integer in the list and asuspension function. When called,this function will give you the restof the infinite list (again, onemore value and anothersuspension function).

Page 86: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

86CS 538 Spring 2008©

The whole list is there, but only asmuch as you care to access isactually computed.

Page 87: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

87CS 538 Spring 2008©

Eager Parameter EvaluationSometimes we want parametersevaluated eagerly—as soon asthey are known.Consider a sorting routine thatbreaks an array in half, sortseach half, and then mergestogether the two sorted halves(this is a merge sort).In outline form it is:sort(inputArray) { ...merge(sort(leftHalf(inputArray)), sort(rightHalf(inputArray)));}

This definition lends itselfnicely to parallel evaluation:The two halves of an inputarray can be sorted in parallel.Each of these two halves can

Page 88: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

88CS 538 Spring 2008©

again be split in two, allowingparallel sorting of four quarter-sized arrays, then leading to 8sorts of 1/8 sized arrays, etc.But,to make this all work, the twoparameters to merge must beevaluated eagerly, rather thanin sequence.

Page 89: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

89CS 538 Spring 2008©

Type EquivalenceProgramming languages usetypes to describe the values adata object may hold and theoperations that may beperformed.By checking the types of values,potential errors in expressions,assignments and calls may beautomatically detected. Forexample, type checking tells usthat123 + "123"

is illegal because addition is notdefined for an integer, stringcombination.Type checking is usually done atcompile-time; this is static typing.

Page 90: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

90CS 538 Spring 2008©

Type-checking may also be doneat run-time; this is dynamictyping.A program is type-safe if it isimpossible to apply an operationto a value of the wrong type. In atype-safe language, plus is nevertold to add an integer to a string,because its definition does notallow that combination ofoperands. In type-safe programsan operator can still see an illegalvalue (e.g., a division by zero),but it can’t see operands of thewrong type.A strongly-typed programminglanguage forbids the execution oftype-unsafe programs.Weakly-typed programminglanguages allow the execution ofpotentially type-unsafe programs.

Page 91: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

91CS 538 Spring 2008©

The question reduces to whetherthe programming language allowsprogrammers to “break” the typerules, either knowingly orunknowingly.Java is strongly typed; type errorspreclude execution. C and C++are weakly typed; you can breakthe rules if you wish. Forexample: int i; int* p;

p = (int *) i * i;

Now p may be used as an integerpointer though multiplicationneed not produce valid integerpointers.If we are going to do typechecking in a program, we mustdecide whether two types, T1 andT2 are equivalent; that is, whetherthey be used interchangeably.

Page 92: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

92CS 538 Spring 2008©

There are two major approachesto type equivalence:Name Equivalence:Two types are equivalent if andonly if they refer to exactly thesame type declaration.For example,type PackerSalaries = int[100];

type AssemblySizes = int[100]; PackerSalaries salary; AssemblySizes size;

Issal = size;

allowed?Using name equivalence, no. Thatis, salary /≡N size since thesetwo variables have different typedeclarations (that happen to beidentical in structure).

Page 93: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

93CS 538 Spring 2008©

Formally, we define ≡N (name typeequivalence) as:(a) T ≡N T

(b) Given the declarationType T1 = T2;

T1 ≡N T2

We treat anonymous types (typesnot given a name) as anabbreviation for an implicitdeclaration of a new and uniquetype name.Thus int A[10];

is an abbreviation for Type Tnew = int[10];

Tnew A;

Page 94: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

94CS 538 Spring 2008©

Structural EquivalenceAn alternative notion of typeequivalence is structuralequivalence (denoted ≡S).Roughly, two types arestructurally equivalent if the twotypes have the same definition,independent of where thedefinitions are located. That is,the two types have the samedefinitional structure.Formally, (a) T ≡S T

(b) Given the declaration Type T = Q;

T ≡S Q

(c) If T and Q are defined usingthe same type constructor andcorresponding parameters in the

Page 95: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

95CS 538 Spring 2008©

two definitions are equal orstructurally equivalentthen T ≡S Q

Returning to our previousexample, type PackerSalaries = int[100];

type AssemblySizes = int[100]; PackerSalaries salary; AssemblySizes size;

salary ≡S size since both arearrays and 100=100 and int ≡Sint.

Page 96: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

96CS 538 Spring 2008©

Which notion of Equivalence doProgramming Languages Use?

C and C++ use structuralequivalence except for structsand classes (where nameequivalence is used). For arrays,size is ignored.Java uses structural equivalencefor scalars. For arrays, it requiresname equivalence for thecomponent type, ignoring size.For classes it uses nameequivalence except that a subtypemay be used where a parent typeis expected. Thus given void subr(Object O) { ... };

the callsubr(new Integer(100));

is OK since Integer is a subclass ofObject.

Page 97: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

97CS 538 Spring 2008©

Automatic Type ConversionsC, C++ and Java also allow variouskinds of automatic typeconversions.In C, C++ and Java, a float willbe automatically created from anint: float f = 10; // No type error

Also, an integer type (char,short, int, long) will bewidened: int i = 'x';

In C and C++ (but not Java), aninteger value can also benarrowed, possibly with the lossof significant bits: char c = 1000000;

Page 98: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

98CS 538 Spring 2008©

Reading Assignment• An Introduction to Scheme for C

Programmers (linked from class web page)

• The Scheme Language Definition (linked from class web page)

Page 99: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

99CS 538 Spring 2008©

Lisp & SchemeLisp (List Processing Language)is one of the oldestprogramming languages still inwide use.It was developed in the late 50sand early 60s by JohnMcCarthy.Its innovations include:• Support of symbolic computations.

• A functional programming stylewithout emphasis on assignmentsand side-effects.

• A naturally recursive programmingstyle.

• Dynamic (run-time) type checking.

Page 100: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

100CS 538 Spring 2008©

• Dynamic data structures (lists,binary trees) that grow withoutlimit.

• Automatic garbage collection tomanage memory.

• Functions are treated as “first class”values; they may be passed asarguments, returned as resultvalues, stored in data structures,and created during execution.

• A formal semantics (written in Lisp)that defines the meaning of allvalid programs.

• An Integrated ProgrammingEnvironment to create, edit andtest Lisp programs.

Page 101: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

101CS 538 Spring 2008©

SchemeScheme is a recent dialect ofLisp.It uses lexical (static) scoping.It supports true first-classfunctions.It provides program-levelaccess to control flow viacontinuation functions.

Page 102: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

102CS 538 Spring 2008©

Atomic (Primitive) Data TypesSymbols:Essentially the same form asidentifiers. Similar to enumerationvalues in C and C++.Very flexible in structure;essentially any sequence ofprintable characters is allowed;anything that starts a validnumber (except + or -) may notstart a symbol.Valid symbols include:

abc hello-world + <=!

Integers:Any sequence of digits, optionallyprefixed with a + or -. Usuallyunlimited in length.

Page 103: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

103CS 538 Spring 2008©

Reals:A floating point number in adecimal format (123.456) or inexponential format (1.23e45). Aleading sign and a signedexponent are allowed(-12.3, 10.0e-20).Rationals:Rational numbers of the forminteger/integer (e.g., 1/3 or 9/7)with an optional leading sign (-1/2, +7/8).Complex:Complex numbers of the formnum+num i or num-num i, wherenum is an integer or real number.Example include 1+3i, -1.5-2.5i, 0+1i).

Page 104: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

104CS 538 Spring 2008©

String:A sequence of charactersdelimited by double quotes.Double quotes and backslashesmust be escaped using abackslash. For example"Hello World" "\"Wow!\""

Character:A single character prefixed by #\.For example, #\a, #\0, #\\, #\#.Two special characters are#\space and #\newline.

Boolean:True is represented as #t andfalse is represented as #f.

Page 105: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

105CS 538 Spring 2008©

Binary TreesBinary trees are also calledS-Expressions in Lisp and Scheme.They are of the form ( item . item )where item is any atomic value orany S-Expression. For example:

( A . B ) (1.2 . "xyz" ) ( (A . B ) . C ) ( A . (B . C ) )

S-Expressions are linearizations ofbinary trees:

A B 1.2 "xyz"

Page 106: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

106CS 538 Spring 2008©

S-Expressions are built andaccessed using the predefinedfunctions cons, car and cdr.cons builds a new S-Expressionfrom two S-Expressions thatrepresent the left and rightchildren.cons(E1,E2) = (E1 . E2)car returns are left subtree of anS-Expression.car (E1 . E2) = E1cdr returns are right subtree of anS-Expression.cdr (E1 . E2) = E2

C A

A B B C

Page 107: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

107CS 538 Spring 2008©

ListsIn Lisp and Scheme lists are aspecial, widely-used form of S-Expressions.() represents the empty or null list(A) is the list containing A.By definition, (A) ≡ (A . () )

(A B) represents the listcontaining A and B. By definition,(A B) ≡ (A . (B . () ) )

In general, (A B C ... Z) ≡(A . (B . (C . ... (Z . () ) ... )))

(A B C )≡

A

B

C ()

Page 108: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

108CS 538 Spring 2008©

Function CallsIn List and Scheme, function callsare represented as lists.(A B C) means:Evaluate A (to a function)Evaluate B and C (as parameters)Call A with B and C as itsparametersUse the value returned by the callas the “meaning” of (A B C).cons, car and cdr are predefinedsymbols bound to built-infunctions that build and accesslists and S-Expressions.Literals (of type integer, real,rational, complex, string,character and boolean) evaluateto themselves.

Page 109: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

109CS 538 Spring 2008©

For example (⇒ means “evaluatesto”)(cons 1 2) ⇒ (1 . 2)

(cons 1 () ) ⇒ (1)

(car (cons 1 2)) ⇒ 1

(cdr (cons 1 ())) ⇒ ()

But,(car (1 2)) fails during

execution!Why?The expression (1 2) looks like acall, but 1 isn’t a function! Weneed some way to “quote”symbols and lists we don’t wantevaluated.(quote arg)

is a special function that returnsits argument unevaluated.

Page 110: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

110CS 538 Spring 2008©

Thus (quote (1 2)) doesn’t tryto evaluate the list (1 2); it justreturns it.Since quotation is so often used,it may be abbreviated using asingle quote. That is(quote arg) ≡ 'arg

Thus(car '(a b c)) ⇒ a

(cdr '( (A) (B) (C))) ⇒( (B) (C) )

(cons 'a '1) ⇒ (a . 1)

But,('cdr '(A B)) fails!

Why?

Page 111: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

111CS 538 Spring 2008©

User-defined FunctionsThe list(lambda (args) (body))

evaluates to a function with(args) as its argument list and(body) as the function body.No quotes are needed for(args) or (body).Thus(lambda (x) (+ x 1)) evaluatesto the increment function.Similarly,((lambda (x) (+ x 1)) 10) ⇒11

Page 112: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

112CS 538 Spring 2008©

We can bind values andfunctions to global symbolsusing the define function.The general form is(define id object)

id is not evaluated but objectis. id is bound to the valueobject evaluates to.For example,(define pi 3.1415926535)

(define plus1 (lambda (x) (+ x 1)) )

(define pi*2 (* pi 2))

Once a symbol is defined, itevaluates to the value it isbound to:(plus1 12) ⇒ 13

Page 113: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

113CS 538 Spring 2008©

Since functions are frequentlydefined, we may abbreviate(define id (lambda (args) (body)) )

as(define (id args) (body) )

Thus(define (plus1 x) (+ x 1))

Page 114: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

114CS 538 Spring 2008©

Conditional Expressions inScheme

A predicate is a function thatreturns a boolean value. Byconvention, in Scheme, predicatenames end with “?”For example, number? symbol? equal? null? list?

In conditionals, #f is false, andeverything else, including #t, istrue.The if expression is(if pred E1 E2)

First pred is evaluated.Depending on its value (#f ornot), either E1 or E2 is evaluated(but not both) and returned as thevalue of the if expression.

Page 115: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

115CS 538 Spring 2008©

For example,(if (= 1 (+ 0 1))

'Yes 'No )

(define (fact n) (if (= n 0) 1 (* n (fact (- n 1))) ))

Page 116: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

116CS 538 Spring 2008©

Generalized ConditionalThis is similar to a switch or case:(cond (p1 e1) (p2 e2) ... (else en))

Each of the predicates (p1, p2, ...)is evaluated until one is true (≠#f). Then the correspondingexpression (e1, e2, ...) isevaluated and returned as thevalue of the cond. else acts like apredicate that is always true.Example:

(cond

((= a 1) 2) ((= a 2) 3) (else 4) )

Page 117: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

117CS 538 Spring 2008©

Recursion in SchemeRecursion is widely used inScheme and most other functionalprogramming languages.Rather than using a loop to stepthrough the elements of a list orarray, recursion breaks a problemon a large data structure into asimpler problem on a smaller datastructure.A good example of this approachis the append function, whichjoins (or appends) two lists intoone larger list containing all theelements of the two input lists (inthe correct order).Note that cons is not append.cons adds one element to thehead of an existing list.

Page 118: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

118CS 538 Spring 2008©

Thus(cons '(a b) '(c d)) ⇒ ((a b) c d)(append '(a b) '(c d)) ⇒ (a b c d)

The append function is predefinedin Scheme, as are many otheruseful list-manipulating functions(consult the Scheme definition forwhat’s available).It is instructive to define appenddirectly to see its recursiveapproach:(define (append L1 L2) (if (null? L1) L2 (cons (car L1) (append (cdr L1) L2)) ))

Page 119: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

119CS 538 Spring 2008©

Let’s trace (append '(a b) '(c d))

Our definition is(define (append L1 L2) (if (null? L1) L2 (cons (car L1) (append (cdr L1) L2)) ))

Now L1 = (a b) and L2 = (c d).(null? L1) is false, so weevaluate(cons (car L1) (append (cdr L1) L2))= (cons (car '(a b))

(append (cdr '(a b)) '(c d)))= (cons 'a (append '(b) '(c d))

We need to evaluate (append '(b) '(c d))

In this call, L1 = (b) and L2 = (c d).L1 is not null, so we evaluate

Page 120: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

120CS 538 Spring 2008©

(cons (car L1) (append (cdr L1) L2))= (cons (car '(b)) (append (cdr '(b)) '(c d)))

= (cons 'b (append '() '(c d))

We need to evaluate (append '() '(c d))

In this call, L1 = () and L2 = (c d).L1 is null, so we return (c d).Therefore(cons 'b (append '() '(c d)) =(cons 'b '(c d)) = (b c d) =(append '(b) '(c d))

Finally,(append '(a b) '(c d)) =(cons 'a (append '(b) '(c d)) =

(cons 'a '(b c d)) = (a b c d)

Note:Source files for append, and otherScheme examples, are in~cs538-1/public/scheme/example1.scm,~cs538-1/public/scheme/example2.scm,etc.

Page 121: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

121CS 538 Spring 2008©

Reversing a ListAnother useful list-manipulationfunction is rev, which reversesthe members of a list. That is, thelast element becomes the firstelement, the next-to-last elementbecomes the second element, etc.For example,(rev '(1 2 3)) ⇒ (3 2 1)

The definition of rev isstraightforward:(define (rev L) (if (null? L) L (append (rev (cdr L))

(list (car L)) ) ))

Page 122: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

122CS 538 Spring 2008©

As an example, consider(rev '(1 2))

Here L = (1 2). L is not null so weevaluate(append (rev (cdr L)) (list (car L))) =(append (rev (cdr '(1 2))) (list (car '(1 2)))) =

(append (rev '(2)) (list 1)) =(append (rev '(2)) '(1))

We must evaluate (rev '(2))

Here L = (2). L is not null so weevaluate(append (rev (cdr L)) (list (car L))) =

(append (rev (cdr '(2))) (list (car '(2)))) =(append (rev ())(list 2)) =(append (rev ())'(2))

We must evaluate (rev '())

Here L = (). L is null so (rev '())= ()

Page 123: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

123CS 538 Spring 2008©

Thus (append (rev ())'(2)) =(append () '(2)) = (2) = (rev '(2))

Finally, recall (rev '(1 2)) =(append (rev '(2)) '(1)) =(append '(2) '(1)) = (2 1)

As constructed, rev only reversesthe “top level” elements of a list.That is, members of a list thatthemselves are lists aren’treversed.For example, (rev '( (1 2) (3 4))) = ((3 4) (1 2))

We can generalize rev to alsoreverse list members that happento be lists.To do this, it will be convenient touse Scheme’s let construct.

Page 124: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

124CS 538 Spring 2008©

The Let ConstructScheme allows us to create localnames, bound to values, for usein an expression.The structure is(let ( (id1 val1) (id2 val2) ... ) expr )

In this construct, val1 isevaluated and bound to id1,which will exist only within thislet expression. If id1 is alreadydefined (as a global or parametername) the existing definition ishidden and the local definition,bound to val1, is used. Thenval2 is evaluated and bound toid2, .... Finally, expr is evaluatedin a scope that includes id1, id2,...

Page 125: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

125CS 538 Spring 2008©

For example,(let ( (a 10) (b 20) )

(+ a b)) ⇒ 30

Using a let, the definition ofrevall, a version of rev thatreverses all levels of a list, is easy:

(define (revall L)

(if (null? L) L (let ((E (if (list? (car L)) (revall (car L)) (car L) ))) (append (revall (cdr L))

(list E)) ) ))

(revall '( (1 2) (3 4))) ⇒ ((4 3) (2 1))

Page 126: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

126CS 538 Spring 2008©

SubsetsAnother good example ofScheme’s recursive style ofprogramming is subsetcomputation.Given a list of distinct atoms, wewant to compute a list of allsubsets of the list values.For example,(subsets '(1 2 3)) ⇒ ( () (1) (2) (3) (1 2) (1 3) (2 3) (1 2 3))

The order of atoms and sublists isunimportant, but all possiblesubsets of the list values must beincluded.Given Scheme’s recursive style ofprogramming, we need arecursive definition of subsets.

Page 127: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

127CS 538 Spring 2008©

That is, if we have a list of allsubsets of n atoms, how do weextend this list to one containingall subsets of n+1 values?First, we note that the number ofsubsets of n+1 values is exactlytwice the number of subsets of nvalues.For example,(subsets '(1 2) ) ⇒( () (1) (2) (1 2)), which

contains 4 subsets.(subsets '(1 2 3)) contains 8subsets (as we saw earlier).Moreover, the extended list (ofsubsets for n+1 values) is simplythe list of subsets for n valuesplus the result of “distributing”the new value into each of theoriginal subsets.

Page 128: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

128CS 538 Spring 2008©

Thus (subsets '(1 2 3)) ⇒( () (1) (2) (3) (1 2) (1 3) (2 3) (1 2 3)) =( () (1) (2) (1 2) ) plus

( (3) (1 3) (2 3) (1 2 3) )

This insight leads to a conciseprogram for subsets.We will let (distrib L E) be afunction that “distributes” E intoeach list in L.For example,(distrib '(() (1) (2) (1 2)) 3) =

( (3) (3 1) (3 2) (3 1 2) )

(define (distrib L E) (if (null? L) () (cons (cons E (car L)) (distrib (cdr L) E)) ))

Page 129: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

129CS 538 Spring 2008©

We will let (extend L E) extend alist L by distributing element Ethrough L and then appendingthis result to L.For example,(extend '( () (a) ) 'b) ⇒ ( () (a) (b) (b a))

(define (extend L E) (append L (distrib L E)))

Now subsets is easy:

(define (subsets L)

(if (null? L) (list ()) (extend (subsets (cdr L))

(car L)) ))

Page 130: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

130CS 538 Spring 2008©

Data Structures in SchemeIn Scheme, lists and S-expressionsare basic. Arrays can be simulatedusing lists, but access to elements“deep” in the list can be slow(since a list is a linked structure).To access an element deep withina list we can use:• (list-tail L k)

This returns list L after removingthe first k elements. For example,(list-tail '(1 2 3 4 5) 2) ⇒(3 4 5)

• (list-ref L k)This returns the k-th element in L(counting from 0). For example,(list-ref '(1 2 3 4 5) 2) ⇒ 3

Page 131: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

131CS 538 Spring 2008©

Vectors in SchemeScheme provides a vector typethat directly implements onedimensional arrays.Literals are of the form #( ... )For example, #(1 2 3) or#(1 2.0 "three")

The function (vector? val)tests whether val is a vector ornot.(vector? 'abc) ⇒ #f

(vector? '(a b c)) ⇒ #f

(vector? #(a b c)) ⇒ #t

The function (vector v1 v2...) evaluates v1, v2, ... and putsthem into a vector.(vector 1 2 3) ⇒ #(1 2 3)

Page 132: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

132CS 538 Spring 2008©

The function (make-vector k val)

creates a vector composed of kcopies of val. Thus(make-vector 4 (/ 1 2)) ⇒ #(1/2 1/2 1/2 1/2)

The function (vector-ref vect k)returns the k-th element of vect,starting at position 0. It isessentially the same as vect[k]in C or Java. For example,(vector-ref #(2 4 6 8 10) 3) ⇒ 8

The function(vector-set! vect k val) setsthe k-th element of vect, startingat position 0, to be val. It isessentially the same asvect[k]=val in C or Java. Thevalue returned by the function isunspecified. The suffix “!” in set!indicates that the function has aside-effect.

Page 133: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

133CS 538 Spring 2008©

For example,(define v #(1 2 3 4 5))(vector-set! v 2 0)v ⇒ #(1 2 0 4 5)

Vectors aren’t lists (and listsaren’t vectors).Thus (car #(1 2 3)) doesn’twork.There are conversion routines:• (vector->list V) converts

vector V to a list containing thesame values as V. For example,(vector->list #(1 2 3)) ⇒ (1 2 3)

• (list->vector L) converts list Lto a vector containing the samevalues as L. For example,(list->vector '(1 2 3)) ⇒#(1 2 3)

Page 134: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

134CS 538 Spring 2008©

• In general Scheme names aconversion function from type T totype Q as T->Q. For example,string->list converts a stringinto a list containing thecharacters in the string.

Page 135: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

135CS 538 Spring 2008©

Records and StructsIn Scheme we can represent arecord, struct, or class object asan association list of the form((obj1 val1) (obj2 val2) ...)

In the association list, which is alist of (object value) sublists,object serves as a “key” to locatethe desired sublist.For example, the association list( (A 10) (B 20) (C 30) )

serves the same role asstruct

{ int a = 10; int b = 20; int c = 30;}

Page 136: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

136CS 538 Spring 2008©

The predefined Scheme function(assoc obj alist)

checks alist (an association list)to see if it contains a sublist withobj as its head. If it does, the liststarting with obj is returned;otherwise #f (indicating failure) isreturned.For example,(define L '( (a 10) (b 20) (c 30) ) )

(assoc 'a L) ⇒ (a 10)

(assoc 'b L) ⇒ (b 20)

(assoc 'x L) ⇒ #f

Page 137: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

137CS 538 Spring 2008©

We can use non-atomic objects askeys too!(define price-list

'( ((bmw m5) 71095)

((bmw z4) 40495)

((jag xj8) 56975)

((mb sl500) 86655)

)

)

(assoc '(bmw z4) price-list)⇒ ((bmw z4) 40495)

Page 138: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

138CS 538 Spring 2008©

Using assoc, we can easily definea structure function:(structure key alist) willreturn the value associated withkey in alist; in C or Javanotation, it returns alist.key.(define (structure key alist) (if (assoc key alist)

(car (cdr (assoc key alist))) #f ))

We can improve this function intwo ways:• The same call to assoc is made

twice; we can save the valuecomputed by using a letexpression.

• Often combinations of car and cdrare needed to extract a value.

Page 139: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

139CS 538 Spring 2008©

Scheme has a number ofpredefined functions that combineseveral calls to car and cdr intoone function. For example,(caar x) ≡ (car (car x))(cadr x) ≡ (car (cdr x))(cdar x) ≡ (cdr (car x))(cddr x) ≡ (cdr (cdr x))

Using these two insights we cannow define a better version ofstructure

(define (structure key alist) (let ((p (assoc key alist))) (if p (cadr p) #f ) ) )

Page 140: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

140CS 538 Spring 2008©

What does assoc do if more thanone sublist with the same keyexists?It returns the first sublist with amatching key. In fact, thisproperty can be used to make asimple and fast function thatupdates association lists:(define (set-structure key alist val) (cons (list key val) alist))

Page 141: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

141CS 538 Spring 2008©

If we want to be more space-efficient, we can create a versionthat updates the internal structureof an association list, usingset-cdr! which changes the cdrvalue of a list:(define (set-structure! key alist val) (let ( (p (assoc key alist))) (if p (begin (set-cdr! p (list val)) alist ) (cons (list key val) alist) ) ))

Page 142: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

142CS 538 Spring 2008©

Functions are First-classObjects

Functions may be passed asparameters, returned as the valueof a function call, stored in dataobjects, etc.This is a consequence of the factthat(lambda (args) (body))

evaluates to a function just as(+ 1 1)

evaluates to an integer.

Page 143: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

143CS 538 Spring 2008©

ScopingIn Scheme scoping is static(lexical). This means that non-local identifiers are bound tocontaining lambda parameters, orlet values, or globally definedvalues. For example,(define (f x) (lambda (y) (+ x y)))

Function f takes one parameter,x. It returns a function (of y), withx in the returned function boundto the value of x used when f wascalled.Thus(f 10) ≡ (lambda (y) (+ 10 y))

((f 10) 12) ⇒ 22

Page 144: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

144CS 538 Spring 2008©

Unbound symbols are assumed tobe globals; there is a run-timeerror if an unbound global isreferenced. For example,(define (p y) (+ x y))

(p 20) ; error -- x is unbound

(define x 10)

(p 20) ⇒ 30

We can use let bindings to createprivate local variables forfunctions:(define F (let ( (X 1) ) (lambda () X) ))

F is a function (of no arguments).(F) calls F.(define X 22)

(F) ⇒ 1;X used in F is private

Page 145: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

145CS 538 Spring 2008©

We can encapsulate internal statewith a function by using private,let-bound variables:(define cnt (let ( (I 0) ) (lambda ()

(set! I (+ I 1)) I) ))

Now, (cnt) ⇒ 1

(cnt) ⇒ 2

(cnt) ⇒ 3

etc.

Page 146: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

146CS 538 Spring 2008©

Let Bindings can be SubtleYou must check to see if the let-bound value is created when thefunction is created or when it iscalled.Compare(define cnt

(let ( (I 0) ) (lambda ()

(set! I (+ I 1)) I) ) )vs. (define reset (lambda () (let ( (I 0) )

(set! I (+ I 1)) I) ) )(reset) ⇒ 1, (reset) ⇒ 1, etc.

Page 147: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

147CS 538 Spring 2008©

Simulating Class ObjectsUsing association lists and privatebound values, we can encapsulatedata and functions. This gives usthe effect of class objects.(define (point x y) (list (list 'rect (lambda () (list x y))) (list 'polar (lambda () (list (sqrt (+ (* x x) (* y y))) (atan (/ x y)) ) ) ) ))

A call (point 1 1) creates anassociation list of the form( (rect funct) (polar funct) )

Page 148: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

148CS 538 Spring 2008©

We can use structure to accesscomponents:(define p (point 1 1) )

( (structure 'rect p) ) ⇒ (1 1)

( (structure 'polar p) ) ⇒

( )2 π4---

Page 149: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

149CS 538 Spring 2008©

We can add new functionality byjust adding new (id function)pairs to the association list.(define (point x y) (list (list 'rect (lambda () (list x y))) (list 'polar (lambda () (list (sqrt (+ (* x x) (* y y))) (atan (/ x y)) ))) (list 'set-rect! (lambda (newx newy) (set! x newx) (set! y newy) (list x y) )) (list 'set-polar! (lambda (r theta) (set! x (* r (sin theta))) (set! y (* r (cos theta))) (list r theta) ))))

Page 150: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

150CS 538 Spring 2008©

Now we have(define p (point 1 1) )

( (structure 'rect p) ) ⇒ (1 1)

( (structure 'polar p) ) ⇒

( )

((structure 'set-polar! p) 1 π/4)⇒ (1 π/4)

( (structure 'rect p) ) ⇒

( )

2 π4---

12

------- 12

-------

Page 151: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

151CS 538 Spring 2008©

Limiting Access to InternalStructure

We can improve upon ourassociation list approach byreturning a single function(similar to a C++ or Java object)rather than an explicit list of (idfunction) pairs.The function will take the name ofthe desired operation as one of itsarguments.

Page 152: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

152CS 538 Spring 2008©

First, let’s differentiate between(define def1 (let ( (I 0) ) (lambda () (set! I (+ I 1)) I) ))

and(define (def2) (let ( (I 0) ) (lambda () (set! I (+ I 1)) I) ))

def1 is a zero argument functionthat increments a local variableand returns its updated value.def2 is a a zero argumentfunction that generates a functionof zero arguments (thatincrements a local variable andreturns its updated value). Eachcall to def2 creates a differentfunction.

Page 153: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

153CS 538 Spring 2008©

Stack Implemented as aFunction

(define ( stack ) (let ( (s () ) ) (lambda (op . args) ; var # args (cond ((equal? op 'push!)

(set! s (cons (car args) s)) (car s)) ((equal? op 'pop!) (if (null? s) #f (let ( (top (car s)) ) (set! s (cdr s)) top ))) ((equal? op 'empty?) (null? s)) (else #f) ) ) ))

Page 154: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

154CS 538 Spring 2008©

(define stk (stack));new empty stack

(stk 'push! 1) ⇒ 1 ;s = (1)

(stk 'push! 3) ⇒ 3 ;s = (3 1)

(stk 'push! 'x) ⇒ x ;s = (x 3 1)

(stk 'pop!) ⇒ x ;s = (3 1)

(stk 'empty?) ⇒ #f ;s = (3 1)

(stk 'dump) ⇒ #f ;s = (3 1)

Page 155: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

155CS 538 Spring 2008©

Higher-Order FunctionsA higher-order function is afunction that takes a function as aparameter or one that returns afunction as its result.A very important (and useful)higher-order function is map,which applies a function to a listof values and produces a list orresults:(define (map f L) (if (null? L) () (cons (f (car L)) (map f (cdr L))) ))

Note: In Scheme’s built-inimplementation of map, the orderof function application isunspecified.

Page 156: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

156CS 538 Spring 2008©

(map sqrt '(1 2 3 4 5)) ⇒ (1 1.414 1.732 2 2.236)

(map (lambda(x) (* x x)) '(1 2 3 4 5)) ⇒ (1 4 9 16 25)

Map may also be used withmultiple argument functions bysupplying more than one list ofarguments:(map + '(1 2 3) '(4 5 6)) ⇒ (5 7 9)

Page 157: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

157CS 538 Spring 2008©

The Reduce FunctionAnother useful higher-orderfunction is reduce, which reducesa list of values to a single value byrepeatedly applying a binaryfunction to the list values.This function takes a binaryfunction, a list of data values, andan identity value for the binaryfunction:(define (reduce f L id) (if (null? L) id (f (car L) (reduce f (cdr L) id)) ))

(reduce + '(1 2 3 4 5) 0) ⇒ 15(reduce * '(1 2 4 6 8 10) 1) ⇒3840

Page 158: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

158CS 538 Spring 2008©

(reduce append '((1 2 3) (4 5 6) (7 8)) ())⇒ (1 2 3 4 5 6 7 8)

(reduce expt '(2 2 2 2) 1) ⇒

= 65536

(reduce expt '(2 2 2 2 2) 1)⇒ 265536

(string-length (number->string(reduce expt '(2 2 2 2 2) 1)))

⇒ 19729 ; digits in 265536

2222

Page 159: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

159CS 538 Spring 2008©

Sharing vs. CopyingIn languages without side-effectsan object can be copied bycopying a pointer (reference) tothe object; a complete new copyof the object isn’t needed.Hence in Scheme (define A B)normally means

A B

Page 160: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

160CS 538 Spring 2008©

But, if side-effects are possible wemay need to force a physical copyof an object or structure:(define (copy obj)

(if (pair? obj)

(cons (copy (car obj))(copy (cdr obj)))

obj

))

Page 161: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

161CS 538 Spring 2008©

For example,(define A '(1 2))

(define B (cons A A))

B = ( (1 2) 1 2)

A B

1

2 ()

Page 162: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

162CS 538 Spring 2008©

(set-car! (car B) 10)

B = ( (10 2) 10 2)

(define C (cons (copy A) (copy A)))

A B

10

2 ()

C

10

2 ()

10

2 ()

Page 163: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

163CS 538 Spring 2008©

(set-car! (car C) 20)

C = ((20 2) 10 2)

Similar concerns apply tostrings and vectors, becausetheir internal structure can bechanged.

C

20

2 ()

10

2 ()

Page 164: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

164CS 538 Spring 2008©

Shallow & Deep CopyingA copy operation that copies apointer (or reference) rather thanthe object itself is a shallow copy.For example, In Java,Object O1 = new Object();

Object O2 = new Object();

O1 = O2; // shallow copy

If the structure within an object isphysically copied, the operation isa deep copy.In Java, for objects that supportthe clone operation,O1 = O2.clone(); // deep copy

Even in Java’s deep copy (via theclone() operation), objectsreferenced from within an objectare shallow copied. Thus given

Page 165: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

165CS 538 Spring 2008©

class List {

int value;

List next;

}

List L,M;

M = L.clone();

L.value and M.value areindependent, but L.next andM.next refer to the same Listobject.A complete deep copy, that copiesall objects linked directly orindirectly, is expensive and trickyto implement.(Consider a complete copy of acircular linked list).

Page 166: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

166CS 538 Spring 2008©

Equality Checking in SchemeIn Scheme = is used to test fornumeric equality (includingcomparison of different numerictypes). Non-numeric argumentscause a run-time error. Thus(= 1 1) ⇒ #t

(= 1 1.0) ⇒ #t

(= 1 2/2) ⇒ #t

(= 1 1+0.0i) ⇒ #t

Page 167: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

167CS 538 Spring 2008©

To compare non-numeric values,we can use either:pointer equivalence (do the twooperands point to the sameaddress in memory)structural equivalence (do the twooperands point to structures withthe same size, shape andcomponents, even if they are indifferent memory locations)In general pointer equivalence isfaster but less accurate.

Scheme implements both kinds ofequivalence tests.(eqv? obj1 obj2)

This tests if obj1 and obj2 arethe exact same object. This worksfor atoms and pointers to thesame structure.

Page 168: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

168CS 538 Spring 2008©

(equal? obj1 obj2)

This tests if obj1 and obj2 arethe same, component bycomponent. This works foratoms, lists, vectors and strings.(eqv? 1 1) ⇒ #t

(eqv? 1 (+ 0 1)) ⇒ #t

(eqv? 1/2 (- 1 1/2)) ⇒ #t

(eqv? (cons 1 2) (cons 1 2)) ⇒#f

(eqv? "abc" "abc") ⇒ #f

(equal? 1 1) ⇒ #t

(equal? 1 (+ 0 1)) ⇒ #t

(equal? 1/2 (- 1 1/2)) ⇒ #t

(equal? (cons 1 2) (cons 1 2)) ⇒#t

(equal? "abc" "abc") ⇒ #t

In general it is wise to use equal?unless speed is a critical factor.

Page 169: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

169CS 538 Spring 2008©

I/O in SchemeScheme has simple read and writefunctions, directed to the“standardin” and “standard out” files.(read)

Reads a single Scheme object (anatom, string, vector or list) fromthe standard in file. No quoting isneeded.(write obj)

Writes a single object, obj, to thestandard out file.(display obj)

Writes obj to the standard out filein a more readable format.(Strings aren’t quoted, andcharacters aren’t escaped.)(newline)

Forces a new line on standard outfile.

Page 170: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

170CS 538 Spring 2008©

PortsPorts are Scheme objects thatinterface with systems files. I/O tofiles is normally done through aport object bound to a systemfile.(open-input-file "path to file")

This returns an input portassociated with the "path tofile" string (which is systemdependent). A run-time error issignalled if "path to file"specifies an illegal or inaccessiblefile.(read port)

Reads a single Scheme object (anatom, string, vector or list) fromport, which must be an inputport object.

Page 171: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

171CS 538 Spring 2008©

(eof-object? obj)

When the end of an input file isreached, a special eof-object isreturned. eof-object? testswhether an object is this specialend-of-file marker.(open-output-file "path to file")

This returns an output portassociated with the "path tofile" string (which is systemdependent). A run-time error issignalled if "path to file"specifies an illegal or inaccessiblefile.(write obj port)

Writes a single object, obj, to theoutput port specified by port.

Page 172: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

172CS 538 Spring 2008©

(display obj port)

Writes obj to the output portspecified by port. display uses amore readable format than writedoes. (Strings aren’t quoted, andcharacters aren’t escaped.)(close-input-port port)

This closes the input portspecified by port.(close-output-port port)

This closes the output portspecified by port.

Page 173: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

173CS 538 Spring 2008©

Example—Reading & Echoing aFile

We will iterate through a file,reading and echoing its contents.We need a good way to doiteration; recursion is neithernatural nor efficient here.Scheme provides a nicegeneralization of the letexpression that is similar to C’sfor loop.(let X ( (id1 val1) (id2 val2) ... ) ... (X v1 v2 ...))

A name for the let (X in theexample) is provided. As usual,val1 is evaluated and bound toid1, val2 is evaluated and boundto id2, etc. In the body of the let,the let may be “called” (using its

Page 174: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

174CS 538 Spring 2008©

name) with a fresh set of valuesfor the let variables. Thus (X v1v2 ...) starts the next iterationof the let with id1 bound to v1,id2, bound to v2, etc.The calls look like recursion, butthey are implemented as loopiterations.For example, in(let loop ( (x 1) (sum 0) ) (if (<= x 10) (loop (+ x 1) (+ sum x))

sum ))

we sum the values of x from 1 to10.Compare it tofor (x=1,sum=0; x <= 10; sum+=x,x+=1)

{}

Page 175: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

175CS 538 Spring 2008©

Now a function to read and echo afile is straightforward:(define (echo filename) (let (

(p (open-input-file filename))) (let loop ( (obj (read p))) (if (eof-object? obj) #t ;normal termination (begin (write obj) (newline) (loop (read p)) ) ) ) ))

Page 176: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

176CS 538 Spring 2008©

We can create an alternative toecho that uses(call-with-input-file filename function)

This function opens filename,creates an input port from it, andthen calls function with thatport as an argument:(define (echo2 filename) (call-with-input-file filename (lambda(port)

(let loop ( (obj (read port))) (if (eof-object? obj) #t (begin (write obj) (newline) (loop (read port)) ) ) ) )) )

Page 177: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

177CS 538 Spring 2008©

Control Flow in SchemeNormally, Scheme’s control flow issimple and recursive:• The first argument is evaluated to

get a function.

• Remaining arguments areevaluated to get actual parameters.

• Actual parameters are bound to thefunction’s formal parameters.

• The functions’ body is evaluated toobtain the value of the functioncall.

This approach routinely leads todeeply nested expressionevaluation.

Page 178: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

178CS 538 Spring 2008©

As an example, consider a simplefunction that multiplies a list ofintegers:(define (*list L) (if (null? L) 1 (* (car L)(*list (cdr L))) ))

The call (*list '(1 2 3 4 5))expands to(* 1 (* 2 (* 3 (* 4 (* 5 1)))))

But,what if we get clever and decideto improve this function by notingthat if 0 appears anywhere in listL, the product must be 0?

Page 179: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

179CS 538 Spring 2008©

Let’s try(define (*list0 L) (cond ((null? L) 1) ((= 0 (car L)) 0) (else (* (car L) (*list0 (cdr L)))) ))

This helps a bit—we never gopast a zero in L, but we stillunnecessarily do a sequence ofpending multiplies, all of whichmust yield zero!Can we escape from a sequenceof nested calls once we knowthey’re unnecessary?

Page 180: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

180CS 538 Spring 2008©

ExceptionsIn languages like Java, astatement may throw anexception that’s caught by anenclosing exception handler.Code between the statement thatthrows the exception and thehandler that catches it isabandoned.Let’s solve the problem ofavoiding multiplication of zero inJava, using its exceptionmechanism:class Node {

int val;

Node next;

}

class Zero extends Throwable{};

Page 181: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

181CS 538 Spring 2008©

int mult (Node L) {

try {

return multNode(L);

} catch (Zero z) {

return 0;

}

}

int multNode(Node L)

throws Zero {

if (L == null)

return 1;

else if (L.val == 0)

throw new Zero();

else return L.val * multNode(L.next);

}

In this implementation, nomultiplies by zero are ever done.

Page 182: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

182CS 538 Spring 2008©

ContinuationsIn our Scheme implementation of*list, we’d like a way to delaydoing any multiplies until weknow no zeros appear in the list.One approach is to build acontinuation—a function thatrepresents the context in which afunction’s return value will beused:(define (*listC L con)

(cond ((null? L) (con 1)) ((= 0 (car L)) 0) (else (*listC (cdr L) (lambda (n) (* n (con (car L))))) ) ))

Page 183: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

183CS 538 Spring 2008©

The top-level call is(*listC L (lambda (x) x))

For ordinary lists *listC expandsto a series of multiplies, just like*list did.(define (id x) x)

(*listC '(1 2 3) id) ⇒(*listC '(2 3) (lambda (n) (* n (id 1)))) ≡(*listC '(2 3) (lambda (n) (* n 1))) ⇒(*listC '(3) (lambda (n) (* n (* 2 1)))) ≡(*listC '(3) (lambda (n) (* n 2))) ⇒(*listC () (lambda (n) (* n (* 3 2)))) ≡(*listC () (lambda (n) (* n 6)))

⇒ (* 1 6) ⇒ 6

Page 184: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

184CS 538 Spring 2008©

But for a list with a zero in it, weget a different execution path:(*listC '(1 0 3) id) ⇒(*listC '(0 3)(lambda (n) (* n (id 1)))) ⇒ 0

No multiplies are done!

Page 185: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

185CS 538 Spring 2008©

Another Example ofContinuations

Let’s redo our list multiplyexample so that if a zero is seenin the list we return a functionthat computes the product of allthe non-zero values and aparameter that is the“replacement value” for theunwanted zero value. Thefunction gives the caller a chanceto correct a probable error in theinput data.We create(*list2 L) ≡Product of all integers in L ifno zero appears

else(lambda (n) (* n product-of-all-nonzeros-in-L)

Page 186: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

186CS 538 Spring 2008©

(define (*list2 L) (*listE L id))

(define (*listE L con) (cond ((null? L) (con 1)) ((= 0 (car L)) (lambda(n) (* (con n) (*listE (cdr L) id)))) (else (*listE (cdr L) (lambda(m) (* m (con (car L)))))) ))

Page 187: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

187CS 538 Spring 2008©

In the following, we check to seeif *list2 returns a number or afunction. If a function is returned,we call it with 1, effectivelyremoving 0 from the list(let ( (V (*list2 L)) )

(if (number? V)

V

(V 1)

)

)

Page 188: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

188CS 538 Spring 2008©

For ordinary lists *list2 expandsto a series of multiplies, just like*list did.(*listE '(1 2 3) id) ⇒(*listE '(2 3) (lambda (m) (* m (id 1)))) ≡(*listE '(2 3) (lambda (m) (* m 1))) ⇒(*listE '(3) (lambda (m) (* m (* 2 1)))) ≡(*listE '(3) (lambda (m) (* m 2))) ⇒(*listE () (lambda (m) (* m (* 3 2)))) ≡(*listE () (lambda (n) (* n 6)))

⇒ (* 1 6) ⇒ 6

Page 189: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

189CS 538 Spring 2008©

But for a list with a zero in it, weget a different execution path:(*listE '(1 0 3) id) ⇒(*listE '(0 3) (lambda (m) (* m (id 1)))) ⇒(lambda (n) (* (con n) (* listE '(3) id))) ≡(lambda (n) (* (* n 1)

(* listE '(3) id))) ≡(lambda (n) (* (* n 1) 3))

This function multiplies n, thereplacement value for 0, by 1 and3, the non-zero values in the inputlist.

Page 190: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

190CS 538 Spring 2008©

But note that only one zero valuein the list is handled correctly!Why?(define (*listE L con) (cond ((null? L) (con 1)) ((= 0 (car L)) (lambda(n) (* (con n)

(*listE (cdr L) id)))) (else (*listE (cdr L) (lambda(m) (* m (con (car L)))))) ))

Page 191: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

191CS 538 Spring 2008©

Continuations in SchemeScheme provides a built-inmechanism for creatingcontinuations. It has a long name:call-with-current-continuation

This name is often abbreviated ascall/cc

(perhaps using define).call/cc takes a single function asits argument. That function alsotakes a single argument. That is,we use call/cc as

(call/cc funct) wherefunct ≡ (lambda (con) (body))call/cc calls the function that itis given with the “currentcontinuation” as the function’sargument.

Page 192: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

192CS 538 Spring 2008©

Current ContinuationsWhat is the current continuation?It is itself a function of oneargument. The currentcontinuation function representsthe execution context withinwhich the call/cc appears. Theargument to the continuation is avalue to be substituted as thereturn value of call/cc in thatexecution context.For example, given(+ (fct n) 3)

the current continuation for(fct n) is (lambda (x) (+ x 3)

Given (* 2 (+ (fct z) 10))

the current continuation for (fct z) is(lambda (m) (* 2 (+ m 10))

Page 193: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

193CS 538 Spring 2008©

To use call/cc to grab acontinuation in (say) (+ (fct n) 3)we make (fct n) the body of afunction of one argument. Call thatargument return. We therefore build(lambda (return) (fct n))

Then(call/cc (lambda (return) (fct n)))

binds the current continuation toreturn and executes (fct n).We can ignore the currentcontinuation bound to returnand do a normal returnorwe can use return to force areturn to the calling context of thecall/cc.The call (return value) forcesvalue to be returned as the valueof call/cc in its context of call.

Page 194: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

194CS 538 Spring 2008©

Example:

(define (g con) (con 5))

Now during evaluation no divideby zero error occurs. Rather, when(g return) is called, 5 is passedto con, which is bound to return.Therefore 5 is used as the value ofthe call to call/cc, and 50 iscomputed.

(* (call/cc (lambda(return) (/ (g return) 0))) 10)

return

Page 195: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

195CS 538 Spring 2008©

Continuations are JustFunctions

Continuations may be saved invariables or data structures andcalled in the future to “reactive” acompleted or suspendedcomputation.(define CC ())(define (F) (let ( (v (call/cc (lambda(here) (set! CC here) 1))))

(display "The ans is: ") (display v)(newline)

) )

This displays The ans is: 1

At any time in the future, (CC 10)will display The ans is: 10

Page 196: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

196CS 538 Spring 2008©

List Multiplication RevisitedWe can use call/cc toreimplement the original *list toforce an immediate return of 0(much like a throw in Java):(define (*listc L return) (cond ((null? L) 1) ((= 0 (car L)) (return 0)) (else (* (car L)

(*listc (cdr L) return)))) )

(define (*list L) (call/cc (lambda (return) (*listc L return)) ))

A 0 in L forces a call of (return0) which makes 0 the value ofcall/cc.

Page 197: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

197CS 538 Spring 2008©

Interactive Replacement ofError Values

Using continuations, we can alsoredo *listE so that zeroes canbe replaced interactively! Multiplezeroes (in both original andreplacement values) are correctlyhandled.(define (*list L) (let ( (V (call/cc (lambda (here) (*liste L here)))) ) (if (number? V) V (begin (display "Enter new value for 0") (newline) (newline) (V (read)) ) ) ))

Page 198: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

198CS 538 Spring 2008©

(define (*liste L return) (if (null? L) 1 (let loop ((value (car L))) (if (= 0 value) (loop (call/cc (lambda (x) (return x)))) (* value (*liste (cdr L) return)) ) ) ))

If a zero is seen, *liste passesback to the caller (via return) acontinuation that will set the nextvalue of value. This value ischecked, so if it is itself zero, asubstitute is requested. Eachoccurrence of zero forces a returnto the caller for a substitute value.

Page 199: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

199CS 538 Spring 2008©

Implementing Coroutines withcall/cc

Coroutines are a very handygeneralization of subroutines. Acoroutine may suspend itsexecution and later resume fromthe point of suspension. Unlikesubroutines, coroutines do nohave to complete their executionbefore they return.Coroutines are useful forcomputation of long or infinitestreams of data, where we wish tocompute some data, use it,compute additional data, use it,etc.Subroutines aren’t always able tohandle this, as we may need tosave a lot of internal state toresume with the correct nextvalue.

Page 200: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

200CS 538 Spring 2008©

Producer/Consumer usingCoroutines

The example we will use is one ofa consumer of a potentiallyinfinite stream of data. The nextinteger in the stream (representedas an unbounded list) is read. Callthis value n. Then the next nintegers are read and summedtogether. The answer is printed,and the user is asked whetheranother sum is required. Since wedon’t know in advance how manyintegers will be needed, we’ll usea coroutine to produce the datalist in segments, requestinganother segment as necessary.

Page 201: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

201CS 538 Spring 2008©

(define (consumer)

(next 0); reset next function (let loop ((data (moredata))) (let ( (sum+restoflist (sum-n-elems (car data) (cons 0 (cdr data))))) (display (car sum+restoflist)) (newline) (display "more? ") (if (equal? (read) ’y) (if (= 1

(length sum+restoflist)) (loop (moredata))

(loop (cdr sum+restoflist)) )

#t ; Normal completion ) ) ))

Page 202: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

202CS 538 Spring 2008©

Next, we’ll consider sum-n-elems, which adds the firstelement of list (a running sum) tothe next n elements on the list.We’ll use moredata to extend thedata list as needed.(define (sum-n-elems n list) (cond ((= 0 n) list) ((null? (cdr list)) (sum-n-elems n

(cons (car list)(moredata)))) (else (sum-n-elems (- n 1) (cons (+ (car list) (cadr list)) (cddr list))))

))

Page 203: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

203CS 538 Spring 2008©

The function moredata is calledwhenever we need more data.Initially a producer function iscalled to get the initial segment ofdata. producer actually returnsthe next data segment plus acontinuation (stored inproducer-cc) used to resumeexecution of producer when thenext data segment is required.

Page 204: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

204CS 538 Spring 2008©

(define moredata (let ( (producer-cc () ) ) (lambda () (let ( (data+cont (if (null? producer-cc) (call/cc (lambda (here)

(producer here))) (call/cc (lambda (here) (producer-cc here))) ) )) (set! producer-cc (cdr data+cont)) (car data+cont) ) ) ))

Page 205: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

205CS 538 Spring 2008©

Function (next z) returns thenext z integers in an infinitesequence that starts at 1. A valuez=0 is a special flag indicatingthat the sequence should be resetto start at 1.(define next (let ( (i 1)) (lambda (z) (if (= 0 z) (set! i 1) (let loop

((cnt z) (val i) (ints () )) (if (> cnt 0) (loop (- cnt 1) (+ val 1) (append ints (list val))) (begin (set! i val) ints ) ) )) ) ) )

Page 206: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

206CS 538 Spring 2008©

The function producer generatesan infinite sequence of integers(1,2,3,...). It suspends every 5/10/15/25 elements and returnscontrol to moredata.(define (producer initial-return) (let loop ( (return initial-return) ) (set! return (call/cc (lambda (here)

(return (cons (next 5) here))))) (set! return (call/cc (lambda (here)

(return (cons (next 10) here))))) (set! return (call/cc (lambda (here) (return (cons (next 15) here))))) (loop (call/cc (lambda (here)

(return (cons (next 25) here)))))) )

Page 207: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

207CS 538 Spring 2008©

Reading Assignment• MULTILISP: a language for concurrent

symbolic computation,by Robert H. Halstead(linked from class web page)

Page 208: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

208CS 538 Spring 2008©

Lazy EvaluationLazy evaluation is sometimescalled “call by need.” We do anevaluation when a value is used;not when it is defined.Scheme provides for lazyevaluation:(delay expression)

Evaluation of expression isdelayed. The call returns a“promise” that is essentially alambda expression.(force promise)

A promise, created by a call todelay, is evaluated. If the promisehas already been evaluated, thevalue computed by the first call toforce is reused.

Page 209: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

209CS 538 Spring 2008©

Example:Though and is predefined, writinga correct implementation for it isa bit tricky.The obvious program(define (and A B)

(if A

B

#f

)

)

is incorrect since B is alwaysevaluated whether it is needed ornot. In a call like(and (not (= i 0)) (> (/ j i) 10))

unnecessary evaluation might befatal.

Page 210: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

210CS 538 Spring 2008©

An argument to a function is strictif it is always used. Non-strictarguments may cause failure ifevaluated unnecessarily.With lazy evaluation, we candefine a more robust andfunction:(define (and A B)

(if A

(force B)

#f

)

)

This is called as:(and (not (= i 0)) (delay (> (/ j i) 10)))

Note that making the programmerremember to add a call to delayis unappealing.

Page 211: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

211CS 538 Spring 2008©

Delayed evaluation also allows usa neat implementation ofsuspensions.The following definition of aninfinite list of integers clearlyfails:(define (inflist i)

(cons i (inflist (+ i 1))))

But with use of delays we get thedesired effect in finite time:(define (inflist i) (cons i (delay (inflist (+ i 1)))))

Now a call like (inflist 1)creates

1 promise for(inflist 2)

Page 212: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

212CS 538 Spring 2008©

We need to slightly modify howwe explore suspended infinitelists. We can’t redefine car andcdr as these are far toofundamental to tamper with.Instead we’ll define head andtail to do much the same job:(define head car)

(define (tail L)

(force (cdr L)))

head looks at car values whichare fully evaluated.tail forces one level ofevaluation of a delayed cdr andsaves the evaluated value in placeof the suspension (promise).

Page 213: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

213CS 538 Spring 2008©

Given(define IL (inflist 1))

(head (tail IL)) returns 2 andexpands IL into

2 promise for(inflist 3)

1

Page 214: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

214CS 538 Spring 2008©

Exploiting ParallelismConventional proceduralprogramming languages aredifficult to compile formultiprocessors.Frequent assignments make itdifficult to find independentcomputations.Consider (in Fortran):

do 10 I = 1,1000 X(I) = 0 A(I) = A(I+1)+1 B(I) = B(I-1)-1 C(I) = (C(I-2) + C(I+2))/210 continue

This loop defines 1000 values forarrays X, A, B and C.

Page 215: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

215CS 538 Spring 2008©

Which computations can be donein parallel, partitioning parts of anarray to several processors, eachoperating independently?• X(I) = 0

Assignments to X can be readilyparallelized.

• A(I) = A(I+1)+1Each update of A(I) uses an A(I+1)value that is not yet changed. Thusa whole array of new A values canbe computed from an array of “old”A values in parallel.

• B(I) = B(I-1)-1This is less obvious. Each B(I)uses B(I-1) which is defined interms of B(I-2), etc. Ultimately allnew B values depend only on B(0)and I. That is, B(I) = B(0) - I. Sothis computation can beparallelized, but it takes a fairamount of insight to realize it.

Page 216: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

216CS 538 Spring 2008©

• C(I) = (C(I-2) + C(I+2))/2It is clear that even and oddelements of C don’t interact. Hencetwo processors could computeeven and odd elements of C inparallel. Beyond this, since bothearlier and later C values are usedin each computation of an element,no further means of parallelevaluation is evident. Serialevaluation will probably be neededfor even or odd values.

Page 217: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

217CS 538 Spring 2008©

Exploiting Parallelism inScheme

Assume we have a shared-memory multiprocessor. We mightbe able to assign differentprocessors to evaluate variousindependent subexpressions.For example, consider(map (lambda(x) (* 2 x)) '(1 2 3 4 5))We might assign a processor toeach list element and computethe lambda function on eachconcurrently:

1 2 3 4 5

2 4 6 8 10

Processor 1 Processor 5...

Page 218: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

218CS 538 Spring 2008©

How is Parallelism Found?There are two approaches:• We can use a “smart” compiler that is

able to find parallelism in existingprograms written in standard serialprogramming languages.

• We can add features to an existingprogramming language that allows aprogrammer to show where parallelevaluation is desired.

Page 219: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

219CS 538 Spring 2008©

ConcurrentizationConcurrentization (often calledparallelization) is process ofautomatically finding potentialconcurrent execution in a serialprogram.Automatically finding currentexecution is complicated by anumber of factors:• Data Dependence

Not all expressions areindependent. We may need todelay evaluation of an operator orsubprogram until its operands areavailable.Thus in(+ (* x y) (* y z))

we can’t start the addition untilboth multiplications are done.

Page 220: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

220CS 538 Spring 2008©

• Control DependenceNot all expressions need be (orshould be) evaluated.In(if (= a 0)

0

(/ b a))

we don’t want to do the divisionuntil we know a ≠ 0.

• Side EffectsIf one expression can write avalue that another expressionmight read, we probably will needto serialize their execution.Consider(define rand! (let ((seed 99))

(lambda () (set! seed (mod (* seed 1001) 101101)) seed)) )

Page 221: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

221CS 538 Spring 2008©

Now in(+ (f (rand!)) (g (rand!)))

we can’t evaluate (f (rand!))and (g (rand!)) in parallel,because of the side effect of set!in rand!. In fact if we did, f and gmight see exactly the same“random” number! (Why?)

• GranularityEvaluating an expressionconcurrently has an overhead (tosetup a concurrent computation).Evaluating very simpleexpressions (like (car x) or(+ x 1)) in parallel isn’t worththe overhead cost.Estimating where the “breakeven” threshold is may be tricky.

Page 222: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

222CS 538 Spring 2008©

Utility of ConcurrentizationConcurrentization has been mostsuccessful in engineering andscientific programs that are veryregular in structure, evaluatinglarge multidimensional arrays insimple nested loops. Many verycomplex simulations (weather,fluid dynamics, astrophysics) arerun on multiprocessors afterextensive concurrentization.Concurrentization has been farless successful on non-scientificprograms that don’t use largearrays manipulated in nested forloops. A compiler, for example, isdifficult to run (in parallel) on amultiprocessor.

Page 223: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

223CS 538 Spring 2008©

Concurrentization withinProcessors

Concurrentization is usedextensively within many modernuniprocessors. Pentium andPowerPC processors routinelyexecute several instructions inparallel if they are independent(e.g., read and write distinctregisters). This are superscalarprocessors.These processors also routinelyspeculate on execution paths,“guessing” that a branch will (orwon’t) be taken even before thebranch is executed! This allowsfor more concurrent executionthan if strictly “in order” executionis done. These processors arecalled “out of order” processors.

Page 224: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

224CS 538 Spring 2008©

Adding Parallel Features toProgramming Languages.

It is common to take an existingserial programming language andadd features that supportconcurrent or parallel execution.For example versions for Fortran(like HPF—High PerformanceFortran) add a parallel do loopthat executes individual iterationsin parallel.Java supports threads, which maybe executed in parallel.Synchronization and mutualexclusion are provided to avoidunintended interactions.

Page 225: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

225CS 538 Spring 2008©

MultilispMultilisp is a version of Schemeaugmented with three parallelevaluation mechanisms:• Pcall

Arguments to a call are evaluatedin parallel.

• FutureEvaluation of an expression startsimmediately. Rather than waitingfor completion of the computation,a “future” is returned. This futurewill eventually transform itself intothe result value (when thecomputation completes)

• DelayEvaluation is delayed until theresult value is really needed.

Page 226: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

226CS 538 Spring 2008©

The Pcall MechanismPcall is an extension to Scheme’sfunction call mechanism thatcauses the function and itsarguments to be all computed inparallel.Thus(pcall F X Y Z)

causes F, X, Y and Z to all beevaluated in parallel. When allevaluations are done, F is calledwith X, Y and Z as its parameters(just as in ordinary Scheme).Compare(+ (* X Y) (* Y Z))

with(pcall + (* X Y) (* Y Z))

Page 227: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

227CS 538 Spring 2008©

It may not look like pcall cangive you that much parallelexecution, but in the context ofrecursive definitions, the effectcan be dramatic.Consider treemap, a version ofmap that operates on binary trees(S-expressions).

(define (treemap fct tree)

(if (pair? tree)

(pcall cons

(treemap fct (car tree))

(treemap fct (cdr tree))

)

(fct tree)

))

Page 228: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

228CS 538 Spring 2008©

Look at the execution of treemapon the tree (((1 . 2) . (3 . 4)) .

((5 . 6) . (7 . 8)))

We start with one call that usesthe whole tree. This splits intotwo parallel calls, one operatingon((1 . 2) . (3 . 4))

and the other operating on((5 . 6) . (7 . 8))

Each of these calls splits into 2calls, and finally we have 8independent calls, each operatingon the values 1 to 8.

Page 229: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

229CS 538 Spring 2008©

FuturesEvaluation of an expression as afuture is the most interestingfeature of Multilisp.The call(future expr)

begins the evaluation of expr.But rather than waiting for expr’sevaluation to complete, the call tofuture returns immediately witha new kind of data object—afuture. This future is actually an“IOU.” When you try to use thevalue of the future, thecomputation of expr may or maynot be completed. If it is, you seethe value computed instead of thefuture—it automaticallytransforms itself. Thus evaluationof expr appears instantaneous.

Page 230: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

230CS 538 Spring 2008©

If the computation of expr is notyet completed, you are forced towait until computation iscompleted. Then you may use thevalue and resume execution.But this is exactly what ordinaryevaluation does anyway—youbegin evaluation of expr and waituntil evaluation completes andreturns a value to you!

To see the usefulness of futures,consider the usual definition ofScheme’s map function:

(define (map f L) (if (null? L) () (cons (f (car L)) (map f (cdr L))) ))

Page 231: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

231CS 538 Spring 2008©

If we have a call(map slow-function long-list)

where slow-function executesslowly and long-list is a largedata structure, we can expect towait quite a while forcomputation of the result list tocomplete.

Now consider fastmap, a versionof map that uses futures:(define (fastmap f L) (if (null? L) () (cons (future (f (car L))) (fastmap f (cdr L)) ) ))

Now look at the call(fastmap slow-function long-list)

Page 232: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

232CS 538 Spring 2008©

We will exploit a useful aspect offutures—they can be cons’edtogether without delay, even if thecomputation isn’t completed yet.Why? Well a cons just stores a pairof pointers, and it really doesn’tmatter what the pointersreference (a future or an actualresult value).The call to fastmap can actuallyreturn before any of the call toslow-function have completed:

future1

future2

future3 ...

Page 233: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

233CS 538 Spring 2008©

Eventually all the futuresautomatically transformthemselves into data values:

Note that pcall can beimplemented using futures.

answer1

answer2

answer3 ...

Page 234: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

234CS 538 Spring 2008©

That is, instead of(pcall F X Y Z)

we can use((future F)

(future X) (future Y) (future Z))

In fact the latter version isactually more parallel—executionof F can begin even if all theparameters aren’t completelyevaluated.

Page 235: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

235CS 538 Spring 2008©

Another Example of FuturesThe following function,partition, will take a list and adata value (called pivot).partition will partition the listinto two sublists:(a) Those elements ≤ pivot

(b) Those elements > pivot(define (partition pivot L) (if (null? L) (cons () () ) (let ((tail-part

(partition pivot (cdr L)))) (if (<= (car L) pivot) (cons

(cons (car L) (car tail-part))(cdr tail-part))

(cons(car tail-part))(cons (car L) (cdr tail-part))

)) ) )

Page 236: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

236CS 538 Spring 2008©

We want to add futures topartition, but where?It makes sense to use a futurewhen a computation may belengthy and we may not need touse the value computedimmediately.What computation fits thatpattern?The computation of tail-part.We’ll mark it in a blue box to showwe plan to evaluate it using afuture:

Page 237: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

237CS 538 Spring 2008©

(define (partition pivot L) (if (null? L) (cons () () ) (let ((tail-part

(partition pivot (cdr L)))) (if (<= (car L) pivot) (cons

(cons (car L) (car tail-part))(cdr tail-part))

(cons(car tail-part))(cons (car L) (cdr tail-part))

)) ) )

But this one change isn’t enough!We soon access the car and cdrof tail-part, which forces us towait for its computation tocomplete. To avoid this delay, wecan place the four references tocar or cdr of tail-part intofutures too:

Page 238: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

238CS 538 Spring 2008©

(define (partition pivot L) (if (null? L) (cons () () ) (let ((tail-part

(partition pivot (cdr L)))) (if (<= (car L) pivot) (cons

(cons (car L) (car tail-part))(cdr tail-part))

(cons(car tail-part))(cons (car L) (cdr tail-part))

)) ) )

Page 239: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

239CS 538 Spring 2008©

Now we can build the initial partof the partitioned list (thatinvolving pivot and (car L)independently of the recursive callof partition, which completesthe rest of the list.For example,(partition 17 '(5 3 8 ...))

creates a future (call it future1)to compute(partition 17 '(3 8 ...))

It also creates future2 tocompute (car tail-part) andfuture3 to compute (cdr tail-part). The call builds

5 future2

future3

Page 240: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

240CS 538 Spring 2008©

Reading Assignment• Introduction to Standard ML

(linked from class web page)

• Webber: Chapters 5, 7, 9, 11

Page 241: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

241CS 538 Spring 2008©

ML—Meta LanguageSML is Standard ML, a popular MLvariant.ML is a functional language that isdesigned to be efficient and type-safe. It demonstrates that afunctional language need not useScheme’s odd syntax and neednot bear the overhead of dynamictyping.SML’s features and innovationsinclude:1. Strong, compile-time typing.2. Automatic type inferencerather than user-supplied typedeclarations.3. Polymorphism, including “typevariables.”

Page 242: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

242CS 538 Spring 2008©

4. Pattern-directed Programmingfun len([]) = 0 | len(a::b) = 1+len(b);

5. Exceptions6. First-class functions7. Abstract Data Types

coin of int |bill of int |check of string*real;val dime = coin(10);

A good ML reference is“Elements of ML Programming,”by Jeffrey Ullman(Prentice Hall, 1998)

Page 243: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

243CS 538 Spring 2008©

SML is InteractiveYou enter a definition orexpression, and SML returns aresult with an inferred type.The command use "file name";

loads a set of ML definitions froma file.For example (SML responses arein blue):21;val it = 21 : int

(2 div 3);val it = 0 : int

true;val it = true : bool

"xyz";val it = "xyz" : string

Page 244: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

244CS 538 Spring 2008©

Basic SML Predefined Types• Unit

Its only value is (). Type unit issimilar to void in C; it is usedwhere a type is needed, but no“real” type is appropriate. Forexample, a call to a write functionmay return unit as its result.

• IntegerConstants are sequences of digits.Negative values are prefixed witha ~ rather than a - (- is a binarysubtraction operator). Forexample, ~123 is negative 123.Standard operators include+ - * div mod< > <= >= = <>

Page 245: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

245CS 538 Spring 2008©

• RealBoth fractional (123.456) andexponent forms (10e7) areallowed. Negative signs andexponents use ~ rather than -(~10.0e~12).Standard operators include+ - * /< > <= >=

Note that = and <> aren’t allowed!(Why?)Conversion routines includereal(int) to convert an int to areal,floor(real) to take the floor ofa real,ceil(real) to take the ceiling ofa real.round(real) to round a real,trunc(real) to truncate a real.

Page 246: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

246CS 538 Spring 2008©

For example, real(3) returns3.0, floor(3.1) returns 3,ceiling(3.3) returns 4,round(~3.6) returns ~4,trunc(3.9) returns 3.Mixed mode expressions, like1 + 2.5 aren’t allowed; you mustdo explicit conversion, likereal(1) + 2.5

• StringsStrings are delimited by doublequotes. Newlines are \n, tabs are\t, and \" and \\ escape doublequotes and backslashes. E.g. "Byenow\n" The ^ operator isconcatenation."abc" ^ "def" = "abcdef"

The usual relational operators areprovided: < > <= >= = <>

Page 247: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

247CS 538 Spring 2008©

• CharactersSingle characters are delimited bydouble quotes and prefixed by a#. For example, #"a" or #"\t". Acharacter is not a string of lengthone. The str function may beused to convert a character into astring. Thus str(#"a") = "a"

• BooleanConstants are true and false.Operators include andalso (short-circuit and), orelse (short-circuitor), not, = and <>.A conditional expression,(if boolval v1 else v2) isavailable.

Page 248: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

248CS 538 Spring 2008©

TuplesA tuple type, composed of two ormore values of any type isavailable.Tuples are delimited byparentheses, and values areseparated by commas.Examples include:(1,2);val it = (1,2) : int * int

("xyz",1=2);val it = ("xyz",false) : string * bool

(1,3.0,false);val it = (1,3.0,false) : int * real * bool

(1,2,(3,4));val it = (1,2,(3,4)) :int * int * (int * int)

Page 249: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

249CS 538 Spring 2008©

Equality is checkedcomponentwise:(1,2) = (0+1,1+1);val it = true : bool

(1,2,3) = (1,2) causes acompile-time type error (tuplesmust be of the same length andhave corresponding types to becompared).#i selects the i-th component ofa tuple (counting from 1). Hence#2(1,2,3);val it = 2 : int

Page 250: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

250CS 538 Spring 2008©

ListsLists are required to have a singleelement type for all theirelements; their length isunbounded.Lists are delimited by [ and ] andelements are separated bycommas.Thus [1,2,3] is an integer list.The empty (or null) list is [] ornil.The cons operator is ::Hence [1,2,3] ≡ 1::2::3::[]

Lists are automatically typed byML:[1,2];val it = [1,2] : int list

Page 251: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

251CS 538 Spring 2008©

ConsCons is an infix operatorrepresented as ::The left operand of :: is anyvalue of type T.The right operand of :: is any listof type T list.The result of :: is a list of typeT list.

Hence :: is polymorphic.[] is the empty list. It has a type'a list. The symbol 'a, read as“alpha” or “tic a” is a type variable.Thus [] is a polymorphicconstant.

Page 252: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

252CS 538 Spring 2008©

List EqualityTwo lists may be compared forequality if they are of the sametype. Lists L1 and L2 areconsidered equal if:(1) They have the same number of elements(2) Corresponding members of

the two lists are equal.

List Operatorshd ≡ head of list operator ≈ car

tl ≡ tail of list operator ≈ cdr

null ≡ null list predicate ≈ null?

@ ≡ infix list append operator ≈append

Page 253: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

253CS 538 Spring 2008©

RecordsTheir general form is{name1=val1, name2=val2, ... }

Field selector names are local to arecord.For example:{a=1,b=2};

val it = {a=1,b=2} : {a:int, b:int}

{a=1,b="xyz"};val it = {a=1,b="xyz"} : {a:int, b:string}

{a=1.0,b={c=[1,2]}};val it = {a=1.0,b={c=[1,2]}} :{a:real, b:{c:int list}}

Page 254: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

254CS 538 Spring 2008©

The order of fields is irrelevant;equality is tested using fieldnames.{a=1,b=2}={b=2,a=2-1};val it = true : bool

#id extracts the field named idfrom a record.#b {a=1,b=2} ;

val it = 2 : int

Page 255: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

255CS 538 Spring 2008©

IdentifiersThere are two forms:• Alphanumeric (excluding reserved

words)

Any sequence of letters, digits,single quotes and underscores;must begin with a letter or singlequote.Case is significant. Identifiers thatbegin with a single quote are typevariables.Examples include:abc a10 'polar sum_of_20

• Symbolic

Any sequence (except predefinedoperators) of! % & + - / : < = > ? @ \ ~ ^ | #Usually used for user-definedoperators.Examples include: ++ <=> !=

Page 256: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

256CS 538 Spring 2008©

CommentsOf form(* text *)

May cross line boundaries.

Declaration of ValuesThe basic form isval id = expression;

This defines id to be bound toexpression; ML answers with thename and value defined and theinferred type.For exampleval x = 10*10;val x = 100 : int

Page 257: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

257CS 538 Spring 2008©

Redefinition of an identifier is OK,but this is redefinition notassignment;Thusval x = 100;

val x = (x=100);

is fine; there is no type error eventhough the first x is an integerand then it is a boolean.val x = 100 : int

val x = true : bool

Page 258: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

258CS 538 Spring 2008©

Examplesval x = 1;val x = 1 : int

val z = (x,x,x);val z = (1,1,1) : int * int * int

val L = [z,z];val L = [(1,1,1),(1,1,1)] : (int * int * int) list

val r = {a=L};val r = {a=[(1,1,1),(1,1,1)]} :{a:(int * int * int) list}

After rebinding, the “nearest”(most recent) binding is used.The and symbol (not boolean and)is used for simultaneous binding:val x = 10;val x = 10 : int

val x = true and y = x;val x = true : bool

val y = 10 : int

Page 259: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

259CS 538 Spring 2008©

Local definitions are temporaryvalue definitions:local

val x = 10

in

val u = x*x;

end;val u = 100 : int

Let bindings are used inexpressions:let

val x = 10

in 5*x

end;val it = 50 : int

Page 260: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

260CS 538 Spring 2008©

Patterns Scheme (and most otherlanguages) use access ordecomposition functions to accessthe components of a structuredobject.Thus we might write(let ( (h (car L) (t (cdr L)) )

body )

Here car and cdr are used asaccess functions to locate theparts of L we want to access.In ML we can access componentsof lists (or tuples, or records)directly by using patterns. Thecontext in which the identifierappears tells us the part of thestructure it references.

Page 261: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

261CS 538 Spring 2008©

val x = (1,2);val x = (1,2) : int * int

val (h,t) = x;val h = 1 : int

val t = 2 : int

val L = [1,2,3];val L = [1,2,3] : int list

val [v1,v2,v3] = L;val v1 = 1 : int

val v2 = 2 : int

val v3 = 3 : int

val [1,x,3] = L;val x = 2 : int

val [1,rest] = L;(* This is illegal. Why? *)

val yy::rest = L;val yy = 1 : int

val rest = [2,3] : int list

Page 262: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

262CS 538 Spring 2008©

WildcardsAn underscore (_) may be used asa “wildcard” or “don’t care”symbol. It matches part of astructure without defining an newbinding.val zz::_ = L;val zz = 1 : int

Pattern matching works in recordstoo.val r = {a=1,b=2};val r = {a=1,b=2} : {a:int, b:int}

val {a=va,b=vb} = r;val va = 1 : int

val vb = 2 : int

val {a=wa,b=_}=r;val wa = 1 : int

val {a=za, ...}=r;val za = 1 : int

Page 263: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

263CS 538 Spring 2008©

Patterns can be nested too.val x = ((1,3.0),5);val x = ((1,3.0),5) : (int * real) * int

val ((1,y),_)=x;val y = 3.0 : real

Page 264: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

264CS 538 Spring 2008©

FunctionsFunctions take a single argument(which can be a tuple).Function calls are of the formfunction_name argument;

For examplesize "xyz";

cos 3.14159;

The more conventional formsize("xyz"); or cos(3.14159);

is OK (the parentheses around theargument are allowed, butunnecessary).The form (size "xyz") or(cos 3.14159)

is OK too.

Page 265: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

265CS 538 Spring 2008©

Note that the callplus(1,2);

passes one argument, the tuple(1,2)

to plus.The call dummy();passes one argument, the unitvalue, to dummy.All parameters are passed byvalue.

Page 266: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

266CS 538 Spring 2008©

Function TypesThe type of a function in ML isdenoted as T1->T2. This says thata parameter of type T1 is mappedto a result of type T2.The symbol fn denotes a valuethat is a function.Thussize;val it = fn : string -> int

not;val it = fn : bool -> bool

Math.cos;val it = fn : real -> real

(Math is an ML structure—anexternal library member thatcontains separately compileddefinitions).

Page 267: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

267CS 538 Spring 2008©

User-Defined FunctionsThe general form isfun name arg = expression;

ML answers back with the namedefined, the fact that it is afunction (the fn symbol) and itsinferred type.For example,fun twice x = 2*x;val twice = fn : int -> int

fun twotimes(x) = 2*x;val twotimes = fn : int -> int

fun fact n =

if n=0

then 1

else n*fact(n-1);val fact = fn : int -> int

Page 268: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

268CS 538 Spring 2008©

fun plus(x,y):int = x+y;val plus = fn : int * int -> int

The :int suffix is a typeconstraint.It is needed to help ML decide that+ is integer plus rather than realplus.

Page 269: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

269CS 538 Spring 2008©

Patterns In FunctionDefinitions

The following defines a predicatethat tests whether a list, L is null(the predefined null functionalready does this).fun isNull L = if L=[] then true elsefalse;val isNull = fn : 'a list -> bool

However, we can decompose thedefinition using patterns to get asimpler and more elegantdefinition: fun isNull [] = true

| isNull(_::_) = false;val isNull = fn : 'a list -> bool

Page 270: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

270CS 538 Spring 2008©

The “|” divides the functiondefinition into different argumentpatterns; no explicit conditionallogic is needed. The definitionthat matches a particular actualparameter is automaticallyselected.fun fact(1) = 1

| fact(n) = n*fact(n-1);val fact = fn : int -> int

If patterns that cover all possiblearguments aren’t specified, youmay get a run-time Matchexception.If patterns overlap you may get awarning from the compiler.

Page 271: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

271CS 538 Spring 2008©

fun append([],L) = L

| append(hd::tl,L) =hd::append(tl,L);

val append = fn : 'a list * 'a list -> 'a list

If we add the patternappend(L,[]) = L

we get a redundant patternwarning (Why?)fun append ([],L) = L

| append(hd::tl,L) =hd::append(tl,L)

| append(L,[]) = L;stdIn:151.1-153.20 Error: matchredundant

(nil,L) => ...

(hd :: tl,L) => ...

--> (L,nil) => ...

Page 272: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

272CS 538 Spring 2008©

But a more precise decompositionis fine:fun append ([],L) = L

| append(hd::tl,hd2::tl2) = hd::append(tl,hd2::tl2)

| append(hd::tl,[]) = hd::tl;val append = fn : 'a list * 'a list -> 'a list

Page 273: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

273CS 538 Spring 2008©

Function Types Can bePolytypes

Recall that 'a, 'b, ... representtype variables. That is, any validtype may be substituted for themwhen checking type correctness.ML said the type of append isval append = fn : 'a list * 'a list -> 'a list

Why does 'a appear three times?We can define eitherNull, apredicate that determineswhether either of two lists is nullasfun eitherNull(L1,L2) = null(L1) orelse null(L2);val eitherNull = fn : ’a list * ’b list -> bool

Why are both 'a and 'b used ineitherNull’s type?

Page 274: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

274CS 538 Spring 2008©

CurryingML chooses the most general(least-restrictive) type possible foruser-defined functions.Functions are first-class objects,as in Scheme.The function definitionfun f x y = expression;

defines a function f (of x) thatreturns a function (of y).Reducing multiple argumentfunctions to a sequence of oneargument functions is calledcurrying (after Haskell Curry, amathematician who popularizedthe approach).

Page 275: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

275CS 538 Spring 2008©

Thusfun f x y = x :: [y];val f = fn : 'a -> 'a -> 'a list

says that f takes a parameter x,of type 'a, and returns a function(of y, whose type is 'a) thatreturns a list of 'a.Contrast this with the moreconventionalfun g(x,y) = x :: [y];val g = fn : 'a * 'a -> 'a list

Here g takes a pair of arguments(each of type 'a) and returns avalue of type 'a list.The advantage of currying is thatwe can bind one argument andleave the remaining argument(s)free.

Page 276: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

276CS 538 Spring 2008©

For examplef(1);

is a legal call. It returns a functionof typefn : int -> int list

The function returned isequivalent tofun h b = 1 :: [b];val h = fn : int -> int list

Page 277: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

277CS 538 Spring 2008©

Map RevisitedML supports the map function,which can be defined asfun map(f,[]) = [] | map(f,x::y) = (f x) :: map(f,y);val map =fn : ('a -> 'b) * 'a list -> 'b list

This type says that map takes apair of arguments. One is afunction from type 'a to type 'b.The second argument is a list oftype 'a. The result is a list of type'b.In curried form map is defined asfun map f [] = [] | map f (x::y) = (f x) :: map f y;val map = fn : ('a -> 'b) -> 'a list -> 'b list

Page 278: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

278CS 538 Spring 2008©

This type says that map takes oneargument that is a function fromtype 'a to type 'b. It returns afunction that takes an argumentthat is a list of type 'a and returnsa list of type 'b.The advantage of the curried formof map is that we can now use mapto create “specialized” functionsin which the function that ismapped is fixed.For example,val neg = map not;val neg = fn : bool list -> bool list

neg [true,false,true];val it = [false,true,false] : bool list

Page 279: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

279CS 538 Spring 2008©

Power Sets RevisitedLet’s compute power sets in ML.We want a function pow that takesa list of values, viewed as a set,and which returns a list of lists.Each sublist will be one of thepossible subsets of the originalargument.For example,pow [1,2] = [[1,2],[1],[2],[]]

We first define a version of consin curried form:fun cons h t = h::t;val cons = fn : 'a -> 'a list -> 'a list

Page 280: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

280CS 538 Spring 2008©

Now we define pow. We define thepowerset of the empty list, [], tobe [[]]. That is, the power set ofthe empty set is set that containsonly the empty set.For a non-empty list, consisting ofh::t, we compute the power setof t, which we call pset. Then thepower set for h::t is just hdistributed through psetappended to pset.We distribute h through pset veryelegantly: we just map thefunction (cons h) to pset. (consh) adds h to the head of any list itis given. Thus mapping (cons h)to pset adds h to all lists in pset.

Page 281: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

281CS 538 Spring 2008©

The complete definition is simplyfun pow [] = [[]] | pow (h::t) =

let

val pset = pow t

in

(map (cons h) pset) @ pset

end;val pow = fn : 'a list -> 'a list list

Let’s trace the computation ofpow [1,2].Here h = 1 and t = [2]. We needto compute pow [2].Now h = 2 and t = [].We know pow [] = [[]],so pow [2] =(map (cons 2) [[]])@[[]] =([[2]])@[[]] = [[2],[]]

Page 282: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

282CS 538 Spring 2008©

Therefore pow [1,2] =

(map (cons 1) [[2],[]])@[[2],[]] =[[1,2],[1]]@[[2],[]] =[[1,2],[1],[2],[]]

Page 283: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

283CS 538 Spring 2008©

Composing FunctionsWe can define a compositionfunction that composes twofunctions into one:fun comp (f,g)(x) = f(g(x));val comp = fn :('a -> 'b) * ('c -> 'a) -> 'c -> 'b

In curried form we havefun comp f g x = f(g(x));

val comp = fn :('a -> 'b) ->('c -> 'a) -> 'c -> 'b

For example,fun sqr x:int = x*x;

val sqr = fn : int -> int

comp sqr sqr;

val it = fn : int -> int

comp sqr sqr 3;

val it = 81 : int

Page 284: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

284CS 538 Spring 2008©

In SML o (lower-case O) is the infixcomposition operator.Hencesqr o sqr ≡ comp sqr sqr

Page 285: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

285CS 538 Spring 2008©

Lambda TermsML needs a notation to writedown unnamed (anonymous)functions, similar to the lambdaexpressions Scheme uses.That notation isfn arg => body;

For example,val sqr = fn x:int => x*x;val sqr = fn : int -> int

In fact the notation used to definefunctions,fun name arg = body;

is actually just an abbreviation forthe more verboseval name = fn arg => body;

Page 286: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

286CS 538 Spring 2008©

An anonymous function can beused wherever a function value isneeded.For example,map (fn x => [x]) [1,2,3];val it =[[1],[2],[3]] : int list list

We can use patterns too:(fn [] => [] |(h::t) => h::h::t);val it = fn : 'a list -> 'a list

(What does this function do?)

Page 287: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

287CS 538 Spring 2008©

Polymorphism vs. OverloadingML supports polymorphism.A function may accept a polytype(a set of types) rather than asingle fixed type.In all cases, the same functiondefinition is used. Details of thesupplied type are irrelevant andmay be ignored.For example,fun id x = x;val id = fn : 'a -> 'a

fun toList x = [x];val toList = fn : 'a -> 'a list

Page 288: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

288CS 538 Spring 2008©

Overloading, as in C++ and Java,allows alternative definitions ofthe same method or operator,with selection based on type.Thus in Java + may representinteger addition, floating pointaddition or string concatenation,even though these are reallyrather different operations.In ML +, -, * and = areoverloaded.When = is used (to test equality),ML deduces that an equality typeis required. (Most,but not all, typescan be compared for equality).When ML decides an equality typeis needed, it uses a type variablethat begins with two tics ratherthan one.fun eq(x,y) = (x=y);val eq = fn : ''a * ''a -> bool

Page 289: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

289CS 538 Spring 2008©

Defining New Types in MLWe can create new names forexisting types (typeabbreviations) usingtype id = def;

For example,type triple = int*real*string;type triple = int * real * string

type rec1= {a:int,b:real,c:string};type rec1 = {a:int, b:real, c:string}

type 'a triple3 = 'a*'a*'a;type 'a triple3 = 'a * 'a * 'a

type intTriple = int triple3;type intTriple = int triple3

These type definitions areessentiality macro-like namesubstitutions.

Page 290: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

290CS 538 Spring 2008©

The Datatype MechanismThe datatype mechanismspecifies new data types usingvalue constructors.For example,datatype color = red|blue|green;

datatype color = blue | green |red

Pattern matching works too usingthe type’s constructors:fun translate red = "rot" | translate blue = "blau" | translate green = "gruen";val translate = fn : color -> stringfun jumble red = blue | jumble blue = green | jumble green = red;

val jumble = fn : color -> color

translate (jumble green);

val it = "rot" : string

Page 291: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

291CS 538 Spring 2008©

SML ExamplesSource code for most of the SMLexamples presented here may befound in~cs538-1/public/sml/class.sml

Page 292: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

292CS 538 Spring 2008©

Parameterized ConstructorsThe constructors used to definedata types may be parameterized:datatype money = none | coin of int

| bill of int

| iou of real * string;datatype money = bill of int | coin of int | iou of real * string | none

Now expressions like coin(25)or bill(5) oriou(10.25,"Lisa") representvalid values of type money.

Page 293: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

293CS 538 Spring 2008©

We can also define values andfunctions of type money:val dime = coin(10);val dime = coin 10 : money

val deadbeat =iou(25.00,"Homer Simpson");val deadbeat = iou (25.0,"Homer Simpson") : money

fun amount(none) = 0.0

| amount(coin(cents)) = real(cents)/100.0

| amount(bill(dollars)) = real(dollars)

| amount(iou(amt,_)) = 0.5*amt; val amount = fn : money -> real

Page 294: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

294CS 538 Spring 2008©

Polymorphic DatatypesA user-defined data type may bepolymorphic. An excellentexample isdatatype 'a option = none | some of 'a;datatype 'a option = none | some of 'a

val zilch = none;val zilch = none : 'a option

val mucho =some(10e10);val mucho =some 100000000000.0 : real option

type studentInfo = {name:string, ssNumber:int option};type studentInfo = {name:string,ssNumber:int option}

Page 295: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

295CS 538 Spring 2008©

val newStudent ={name="Mystery Man", ssNumber=none}:studentInfo;val newStudent ={name="Mystery Man", ssNumber=none} : studentInfo

Page 296: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

296CS 538 Spring 2008©

Datatypes may be RecursiveRecursive datatypes allow linkedstructures without explicitpointers.datatype binTree = null| leaf

| node of binTree * binTree;datatype binTree =leaf | node of binTree * binTree | null

fun size(null) = 0

| size(leaf) = 1

| size(node(t1,t2)) = size(t1)+size(t2) + 1val size = fn : binTree -> int

Page 297: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

297CS 538 Spring 2008©

Recursive Datatypes may bePolymorphic

datatype 'a binTree = null| leaf of 'a| node of 'a binTree * 'a binTree

datatype 'a binTree = leaf of 'a | node of 'a binTree * 'a binTree | null

fun frontier(null) = [] | frontier(leaf(v)) = [v] | frontier(node(t1,t2)) = frontier(t1) @ frontier(t2)

val frontier = fn : 'a binTree -> 'a list

Page 298: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

298CS 538 Spring 2008©

We can model n-ary trees by usinglists of subtrees:datatype 'a Tree = null| leaf of 'a| node of 'a Tree list;datatype 'a Tree = leaf of 'a |node of 'a Tree list | null

fun frontier(null) = []

| frontier(leaf(v)) = [v]

| frontier(node(h::t)) = frontier(h) @frontier(node(t))

| frontier(node([])) = []val frontier = fn : 'a Tree -> 'a list

Page 299: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

299CS 538 Spring 2008©

Abstract Data TypesML also provides abstract datatypes in which theimplementation of the type ishidden from users.The general form isabstype name = implementation

with

val and fun definitions

end;

Users may access the name of theabstract type and the val and fundefinitions that follow the with,but the implementation may beused only with the body of theabstype definition.

Page 300: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

300CS 538 Spring 2008©

Exampleabstype 'a stack = stk of 'a list

with

val Null = stk([])

fun empty(stk([])) = true

| empty(stk(_::_)) = false

fun top(stk(h::_)) = h fun pop(stk(_::t)) = stk(t) fun push(v,stk(L)) = stk(v::L)

endtype 'a stack

val Null = - : 'a stack

val empty = fn : 'a stack -> bool

val top = fn : 'a stack -> 'a

val pop = fn : 'a stack -> 'a stack

val push = fn : 'a * 'a stack -> 'a stack

Page 301: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

301CS 538 Spring 2008©

Local value and functiondefinitions, not to be exported tousers of the type can be createdusing the local definitionmechanism described earlier:local

val and fun definitions

in

exported definitions

end;

Page 302: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

302CS 538 Spring 2008©

abstype 'a stack = stk of 'a listwithlocal fun size(stk(L))=length(L); in val Null = stk([]) fun empty(s) = (size(s) = 0)fun top(stk(h::_)) = h

fun pop(stk(_::t)) = stk(t) fun push(v,stk(L)) = stk(v::L) endendtype 'a stackval Null = - : 'a stackval empty = fn : 'a stack -> boolval top = fn : 'a stack -> 'aval pop = fn : 'a stack -> 'a stackval push = fn : 'a * 'a stack -> 'a stack

Page 303: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

303CS 538 Spring 2008©

Why are abstract data typesuseful?Because they hide animplementation of a type from auser, allowing implementationchanges without any impact onuser programs.Consider a simple implementationof queues:abstype 'a queue = q of 'a list

with

val Null = q([])

fun front(q(h::_)) = h fun rm(q(_::t)) = q(t) fun enter(v,q(L)) = q(rev(v::rev(L)))

endtype 'a queue

val Null = - : 'a queue

val front = fn : 'a queue -> 'a

Page 304: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

304CS 538 Spring 2008©

val rm = fn : 'a queue -> 'a queue

val enter = fn : 'a * 'a queue -> 'a queue

This implementation of queues isvalid, but somewhat inefficient. Inparticular to enter a new valueonto the rear end of a queue, wedo the following:fun enter(v,q(L)) = q(rev(v::rev(L)))

We reverse the list thatimplements the queue, add thenew value to the head of thereversed queue then reverse thelist a second time.

Page 305: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

305CS 538 Spring 2008©

A more efficient (but less obvious)implementation of a queue is tostore it as two lists. One listrepresents the “front” of thequeue. It is from this list that weextract the front value, and fromwhich we remove elements.The other list represents the“back” of the queue (in reversedorder). We add elements to therear of the queue by addingelements to the front of the list.From time to time, when the frontlist becomes null, we “promote”the rear list into the front list (byreversing it). Now access to boththe front and the back of thequeue is fast and direct. The newimplementation is:

Page 306: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

306CS 538 Spring 2008©

abstype 'a queue = q of 'a list * 'a list

with

val Null = q([],[])

fun front(q(h::_,_)) = h | front(q([],L)) = front(q(rev(L),[])) fun rm(q(_::t,L)) = q(t,L) | rm(q([],L)) = rm(q(rev(L),[])) fun enter(v,q(L1,L2)) = q(L1,v::L2)

end

type 'a queue

val Null = - : 'a queueval front = fn :'a queue -> 'a

val rm = fn :'a queue -> 'a queue

val enter = fn :'a * 'a queue -> 'a queue

Page 307: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

307CS 538 Spring 2008©

From the user’s point of view, thetwo implementations are identical(they export exactly the same setof values and functions). Hencethe new implementation canreplace the old implementationwithout any impact at all to theuser (except, of course,performance!).

Page 308: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

308CS 538 Spring 2008©

Exception HandlingOur definitions of stacks andqueues are incomplete.Reconsider our definition ofstack:abstype 'a stack = stk of 'a list

with

val Null = stk([])

fun empty(stk([])) = true

| empty(stk(_::_)) = false

fun top(stk(h::_)) = h fun pop(stk(_::t)) = stk(t) fun push(v,stk(L)) = stk(v::L)

end

What happens if we evaluatetop(Null);

Page 309: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

309CS 538 Spring 2008©

We see “match failure” since ourdefinition of top is incomplete!In ML we can raise anexception if an illegal orunexpected operation occurs.Asking for the top of an emptystack ought to raise anexception since the requestedvalue does not exist.ML contains a number ofpredefined exceptions,includingMatch Empty Div Overflow

(exception names usuallybegin with a capital letter).Predefined exception are raisedby illegal values or operations.If they are not caught, the run-time prints an error message.

Page 310: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

310CS 538 Spring 2008©

fun f(1) = 2;val f = fn : int -> int

f(2);uncaught exception nonexhaustivematch failure

hd [];uncaught exception Empty

1000000*1000000;uncaught exception overflow

(1 div 0);uncaught exception divide by zero

1.0/0.0;

val it = inf : real

(inf is the IEEE floating-pointstandard “infinity” value)

Page 311: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

311CS 538 Spring 2008©

User Defined ExceptionsNew exceptions may bedefined asexception name;

orexception name of type;

For exampleexception IsZero;exception IsZero

exception NegValue of real;exception NegValue of real

Page 312: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

312CS 538 Spring 2008©

Exceptions May be RaisedThe raise statement raises(throws) an exception:raise exceptionName;

orraise exceptionName(expr);

For examplefun divide(a,0) = raise IsZero | divide(a,b) = a div b;val divide = fn : int * int -> int

divide(10,3);val it = 3 : int

divide(10,0);uncaught exception IsZero

Page 313: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

313CS 538 Spring 2008©

val sqrt = Real.Math.sqrt;val sqrt = fn : real -> real

fun sqroot(x) = if x < 0.0 then raise NegValue(x) else sqrt(x);val sqroot = fn : real -> real

sqroot(2.0);val it = 1.41421356237 : real

sqroot(~2.0);uncaught exception NegValue

Page 314: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

314CS 538 Spring 2008©

Exception HandlersYou may catch an exception bydefining a handler for it:(expr) handle exception1 => val1 || exception2 => val2 || ... ;

For example,(sqroot ~100.0) handle NegValue(v) => (sqrt (~v));val it = 10.0 : real

Page 315: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

315CS 538 Spring 2008©

Stacks RevisitedWe can add an exception,EmptyStk, to our earlier stacktype to handle top or popoperations on an empty stack:abstype 'a stack = stk of 'a listwith val Null = stk([]) exception EmptyStk fun empty(stk([])) = true | empty(stk(_::_)) = false fun top(stk(h::_)) = h | top(stk([])) = raise EmptyStk fun pop(stk(_::t)) = stk(t) | pop(stk([])) = raise EmptyStk fun push(v,stk(L)) = stk(v::L)end

Page 316: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

316CS 538 Spring 2008©

type 'a stackval Null = - : 'a stackexception EmptyStkval empty = fn : 'a stack -> boolval top = fn : 'a stack -> 'aval pop = fn : 'a stack -> 'a stackval push = fn : 'a * 'a stack ->'a stack

pop(Null);uncaught exception EmptyStktop(Null) handle EmptyStk => 0;val it = 0 : int

Page 317: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

317CS 538 Spring 2008©

User-Defined OperatorsSML allows users to definesymbolic operators composedof non-alphanumericcharacters. This meansoperator-like symbols can becreated and used. Care must betaken to avoid predefinedoperators (like +, -, ^, @, etc.).If we wish, we can redo ourstack definition using symbolsrather than identifiers. Wemight use the followingsymbols:top |=

pop <==

push ==>

null <@>

empty <?>

Page 318: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

318CS 538 Spring 2008©

We can have expressions like<?> <@>;val it = true : bool

|= (==> (1,<@>));val it = 1 : int

Binary functions, like ==> (push)are much more readable if theyare infix. That is, we’d like to beable to write1 ==> 2+3 ==> <@>

which pushes 2+3, then 1 ontoan empty stack.To make a function (eitheridentifier or symbolic) infixrather than prefix we use thedefinitioninfix level name

orinfixr level name

Page 319: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

319CS 538 Spring 2008©

level is an integer representingthe “precedence” level of theinfix operator. 0 is the lowestprecedence level; higherprecedence operators areapplied before lowerprecedence operators (in theabsence of explicitparentheses).infix defines a left-associativeoperator (groups from left toright). infixr defines a right-associative operator (groupsfrom right to left).Thusfun cat(L1,L2) = L1 @ L2;

infix 5 cat

makes cat a left associativeinfix operator at the same

Page 320: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

320CS 538 Spring 2008©

precedence level as @. We cannow write[1,2] cat [3,4,5] cat [6,7];val it = [1,2,3,4,5,6,7] : int list

The standard predefinedoperators have the followingprecedence levels:Level Operator3 o

4 = <> < > <= >=

5 :: @

6 + - ^

7 * / div mod

Page 321: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

321CS 538 Spring 2008©

If we define ==> (push) asinfixr 2 ==>

then1 ==> 2+3 ==> <@>

will work as expected,evaluating expressions like 2+3before doing any pushes, withpushes done right to left.

Page 322: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

322CS 538 Spring 2008©

abstype 'a stack = stk of 'a list

with

val <@> = stk([])

exception emptyStk

fun <?>(stk([])) = true

| <?>(stk(_::_)) = false

fun |=(stk(h::_)) = h

| |=(stk([])) = raise emptyStk

fun <==(stk(_::t)) = stk(t)

| <==(stk([])) = raise emptyStk

fun ==>(v,stk(L)) = stk(v::L)

infixr 2 ==>

end

Page 323: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

323CS 538 Spring 2008©

type 'a stack

val <@> = - : 'a stack

exception emptyStk

val <?> = fn : 'a stack -> bool

val |= = fn : 'a stack -> 'a

val <== = fn : 'a stack -> 'a stack

val ==> = fn : 'a * 'a stack ->'a stack

infixr 2 ==>

Now we can writeval myStack = 1 ==> 2+3 ==> <@>;val myStack = - : int stack

|= myStack;val it = 1 : int

|= (<== myStack);val it = 5 : int

Page 324: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

324CS 538 Spring 2008©

Using Infix Operators asValues

Sometimes we simply want touse an infix operator as asymbol whose value is afunction.For example, givenfun dupl f v = f(v,v);val dupl =fn : ('a * 'a -> 'b) -> 'a -> 'b

we might try the calldupl ^ "abc";

This fails because SML tries toparse dupl and "abc" as theoperands of ^.To pass an operator as anordinary function value, weprefix it with op which tells the

Page 325: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

325CS 538 Spring 2008©

SML compiler that the followingsymbol is an infix operator.

Thusdupl op ^ "abc";val it = "abcabc" : string

works fine.

Page 326: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

326CS 538 Spring 2008©

The Case ExpressionML contains a case expressionpatterned on switch and casestatements found in otherlanguages.As in function definitions,patterns are used to chooseamong a variety of values.The general form of the case iscase expr of

pattern1 => expr1|

patternn => expr2|

...

patternn => exprn;

If no pattern matches, a Matchexception is thrown.

Page 327: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

327CS 538 Spring 2008©

It is common to use _ (thewildcard) as the last pattern ina case.Examples includecase c of

red => "rot" |

blue => "blau" |

green => "gruen";

case pair of

(1,_) => "win" |

(2,_) => "place" |

(3,_) => "show" |

(_,_) => "loser";

case intOption of

none => 0 |

some(v) => v;

Page 328: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

328CS 538 Spring 2008©

Imperative Features of MLML provides references to heaplocations that may be updated.This is essentially the same asaccess to heap objects viareferences (Java) or pointers (Cand C++).The expressionref val

creates a reference to a heaplocation initialized to val. Forexample, ref 0; val it = ref 0 : int ref

The prefix operator ! fetchesthe value contained in a heaplocation (just as * dereferencesa pointer in C or C++).

Page 329: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

329CS 538 Spring 2008©

Thus ! (ref 0); val it = 0 : int

The expressionref := val

updates the heap locationreferenced by ref to containval. The unit value, (), isreturned.Henceval x = ref 0;val x = ref 0 : int ref

!x;val it = 0 : int

x:=1;val it = () : unit

!x;val it = 1 : int

Page 330: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

330CS 538 Spring 2008©

Sequential CompositionExpressions or statements aresequenced using “;”. Henceval a = (1+2;3+4);val a = 7 : int

(x:=1;!x);val it = 1 : int

Iterationwhile expr1 do expr2

implements iteration (andreturns unit); Thus(while false do 10);val it = () : unit

while !x > 0 do x:= !x-1;val it = () : unit

!x;val it = 0 : int

Page 331: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

331CS 538 Spring 2008©

Simple I/OThe function print;

val it = fn : string -> unit

prints a string onto standardoutput.For example,print("Hello World\n");

Hello World

The conversion routines Real.toString; val it = fn : real -> string

Int.toString; val it = fn : int -> string

Bool.toString; val it = fn : bool -> string

Page 332: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

332CS 538 Spring 2008©

convert a value (real, int orbool) into a string. Unlike Java,the call must be explicit.For example,print(Int.toString(123));123

Also available areReal.fromString;val it = fn : string -> realoption

Int.fromString;val it = fn : string -> intoption

Bool.fromString;val it = fn : string -> booloption

which convert from a string toa real or int or bool if possible.(That’s why the option type isused).

Page 333: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

333CS 538 Spring 2008©

For example,case (Int.fromString("123")) of

SOME(i) => i | NONE => 0;val it = 123 : int

case (Int.fromString( "One two three")) of

SOME(i) => i | NONE => 0;val it = 0 : int

Page 334: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

334CS 538 Spring 2008©

Text I/OThe structure TextIO contains awide variety of I/O types,values and functions. You loadthese by entering:open TextIO;

Among the values loaded are• type instream

This is the type that representsinput text files.

• type outstreamThis is the type that representsoutput text files.

• type vector = stringMakes vector a synonym forstring.

• type elem = charMakes elem a synonym for char.

Page 335: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

335CS 538 Spring 2008©

• val stdIn : instreamval stdOut : outstreamval stdErr : outstreamPredefined input & output streams.

• val openIn : string -> instreamval openOut : string -> outstreamOpen an input or output stream.For example,val out = openOut("/tmp/test1");val out = - : outstream

• val input : instream -> vectorRead a line of input into a string(vector is defined as equivalent tostring). For example (user input isin red):val s = input(stdIn);Hello! val s = "Hello!\n" : vector

Page 336: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

336CS 538 Spring 2008©

• val inputN : instream * int -> vectorRead the next N input charactersinto a string. For example,val t = inputN(stdIn,3);abcdeval t = "abc" : vector

• val inputAll : instream -> vectorRead the rest of the input file into astring (with newlines separatinglines). For example,val u = inputAll(stdIn); Four score and seven years ago ... val u = "Four score and\nseven years ago ...\n" : vector

• val endOfStream : instream -> boolAre we at the end of this inputstream?

Page 337: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

337CS 538 Spring 2008©

• val output : outstream * vector -> unitOutput a string on the specifiedoutput stream. For example,output(stdOut, "That’s all folks!\n");That’s all folks!

Page 338: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

338CS 538 Spring 2008©

String OperationsML provides a wide variety ofstring manipulation routines.Included are:• The string concatenation operator,

^ "abc" ^ "def" = "abcdef"

• The standard 6 relationaloperators: < > <= >= = <>

• The string size operator:val size : string -> intsize ("abcd");val it = 4 : int

• The string subscripting operator(indexing from 0):val sub = fn : string * int -> charsub("abcde",2);val it = #"c" : char

Page 339: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

339CS 538 Spring 2008©

• The substring functionval substring :string * int * int -> stringThis function is called assubstring(string,start,len)start is the starting position,counting from 0.len is the length of the desiredsubstring. For example,substring("abcdefghij",3,4)val it = "defg" : string

• Concatenation of a list of stringsinto a single string:concat : string list -> stringFor example,concat ["What’s"," up","?"];val it = "What’s up?" : string

Page 340: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

340CS 538 Spring 2008©

• Convert a character into a string:str : char -> stringFor example, str(#"x");val it = "x" : string

• “Explode” a string into a list ofcharacters:explode : string -> char listFor example,explode("abcde");val it =[#"a",#"b",#"c",#"d",#"e"] :char list

• “Implode” a list of characters into astring.implode : char list -> stringFor example,implode[#"a",#"b",#"c",#"d",#"e"];val it = "abcde" : string

Page 341: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

341CS 538 Spring 2008©

Structures and SignaturesIn C++ and Java you can groupvariable and functiondefinitions into classes. In Javayou can also group classes intopackages.In ML you can group value,exception and functiondefinitions into structures.You can then import selecteddefinitions from the structure(using the notationstructure.name) or you can openthe structure, therebyimporting all the definitionswithin the structure.(Examples used in this sectionmay be found at~cs538-1/public/sml/struct.sml)

Page 342: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

342CS 538 Spring 2008©

The general form of a structuredefinition isstructure name =struct

val, exception and fun definitions

end

For example,structure Mapping =struct exception NotFound; val create = []; fun lookup(key,[]) = raise NotFound | lookup(key, (key1,value1)::rest) = if key = key1 then value1 else lookup(key,rest);

Page 343: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

343CS 538 Spring 2008©

fun insert(key,value,[]) = [(key,value)] | insert(key,value, (key1,value1)::rest) = if key = key1 then (key,value)::rest else (key1,value1):: insert(key,value,rest);end;

We can access members of thisstructure as Mapping.name. ThusMapping.insert(538,"languages",[]);

val it = [(538,"languages")] :(int * string) list

open Mapping;exception NotFound

val create : 'a list

val insert : ''a * 'b * (''a * 'b) list -> (''a * 'b) list

val lookup : ''a * (''a * 'b)list -> 'b

Page 344: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

344CS 538 Spring 2008©

SignaturesEach structure has a signature,which is it type.For example, Mapping’ssignature isstructure Mapping :

sig

exception NotFound

val create : 'a list

val insert : ''a * 'b * (''a * 'b) list -> (''a * 'b) list

val lookup : ''a * (''a * 'b) list -> 'b

end

Page 345: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

345CS 538 Spring 2008©

You can define a signature assignature name = sig

type definitions for values, functions and exceptions

end

For example,signature Str2IntMapping =sig exception NotFound; val lookup:

string * (string*int) list -> int;

end;

Page 346: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

346CS 538 Spring 2008©

Signatures can be used to• Restrict the type of a value or

function in a structure.

• Hide selected definitions thatappear in a structure

For examplestructure Str2IntMap :

Str2IntMapping = Mapping;

defines a new structure,Str2IntMap, created byrestricting Mapping to theStr2IntMapping signature. Whenwe do this we get

Page 347: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

347CS 538 Spring 2008©

open Str2IntMap; exception NotFound

val lookup : string * (string * int) list -> int

Only lookup and NotFound arecreated, and lookup is limited tokeys that are strings.

Page 348: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

348CS 538 Spring 2008©

Extending ML’s PolymorphismIn languages like C++ and Javawe must use types like void* orObject to simulate thepolymorphism that MLprovides. In ML wheneverpossible a general type (apolytype) is used rather than afixed type. Thus infun len([]) = 0 | len(a::b) = 1 + len(b);

we get a type of 'a list -> int

because this is the mostgeneral type possible that isconsistent with len’s definition.Is this form of polymorphismgeneral enough to capture the

Page 349: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

349CS 538 Spring 2008©

general idea of makingprogram definitions as type-independent as possible?It isn’t, and to see why considerthe following ML definition of amerge sort. A merge sortoperates by first splitting a listinto two equal length sublists.The following function doesthis:fun split [] = ([],[]) | split [a] = ([a],[]) | split (a::b::rest) = let val (left,right) = split(rest) in (a::left, b::right) end;

Page 350: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

350CS 538 Spring 2008©

After the input list is split intotwo halves, each half isrecursively sorted, then thesorted halves are mergedtogether into a single list.The following ML functionmerges two sorted lists intoone:

fun merge([],[]) = [] | merge([],hd::tl) = hd::tl | merge(hd::tl,[]) = hd::tl | merge(hd::tl,h::t) = if hd <= h then hd::merge(tl,h::t) else h::merge(hd::tl,t)

Page 351: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

351CS 538 Spring 2008©

With these two subroutines, adefinition of a sort is easy:fun sort [] = [] | sort([a]) = [a] | sort(a::b::rest) = let val (left,right) = split(a::b::rest) in merge(sort(left),

sort(right)) end;

Page 352: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

352CS 538 Spring 2008©

This definition looks verygeneral—it should work for alist of any type.Unfortunately, when ML typesthe functions we get a surprise:val split = fn : 'a list -> 'a list * 'a listval merge = fn : int list * int list -> int listval sort = fn : int list -> int list

split is polymorphic, but mergeand sort are limited to integerlists!Where did this restriction comefrom?

Page 353: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

353CS 538 Spring 2008©

The problem is that we did acomparison in merge using the<= operator, and ML typed thisas an integer comparison.We can make our definition ofsort more general by adding acomparison function, le(a,b)as a parameter to merge andsort. If we curry this parameterwe may be able to hide it fromend users. Our updateddefinitions are:fun merge(le,[],[]) = [] | merge(le,[],hd::tl) = hd::tl | merge(le,hd::tl,[]) = hd::tl | merge(le,hd::tl,h::t) = if le(hd,h) then hd::merge(le,tl,h::t) else h::merge(le,hd::tl,t)

Page 354: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

354CS 538 Spring 2008©

fun sort le [] = [] | sort le [a] = [a] | sort le (a::b::rest) = let val (left,right) = split(a::b::rest) in merge(le, sort le left,

sort le right) end;

Now the types of merge andsort are:val merge = fn : ('a * 'a -> bool) * 'a list * 'a list -> 'a listval sort = fn : ('a * 'a -> bool) -> 'a list -> 'a list

We can now “customize” sortby choosing a particulardefinition for the le parameter:fun le(a,b) = a <= b;val le = fn : int * int -> bool

Page 355: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

355CS 538 Spring 2008©

fun intsort L = sort le L;val intsort = fn : int list -> int listintsort( [4,9,0,2,111,~22,8,~123]);val it = [~123,~22,0,2,4,8,9,111]: int list

fun strle(a:string,b) = a <= b;val strle = fn : string * string -> bool

fun strsort L = sort strle L;val strsort =fn : string list -> string liststrsort( ["aac","aaa","ABC","123"]);val it =["123","ABC","aaa","aac"] :string list

Page 356: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

356CS 538 Spring 2008©

Making the comparison relationan explicit parameter works,but it is a bit ugly andinefficient. Moreover, if we haveseveral functions that dependon the comparison relation, weneed to ensure that they all usethe same relation. Thus if wewish to define a predicateinOrder that tests if a list isalready sorted, we can use:fun inOrder le [] = true | inOrder le [a] = true | inOrder le (a::b::rest) = le(a,b) andalso inOrder le (b::rest);val inOrder = fn : ('a * 'a -> bool) -> 'a list -> bool

Now sort and inOrder need touse the same definition of le.But how can we enforce this?

Page 357: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

357CS 538 Spring 2008©

The structure mechanism westudied earlier can help. We canput a single definition of le inthe structure, and share it:structure Sorting =struct fun le(a,b) = a <= b;

fun split [] = ([],[]) | split [a] = ([a],[]) | split (a::b::rest) = let val (left,right) = split rest in

(a::left,b::right) end; fun merge([],[]) = [] | merge([],hd::tl) = hd::tl | merge(hd::tl,[]) = hd::tl | merge(hd::tl,h::t) = if le(hd,h) then hd::merge(tl,h::t) else h::merge(hd::tl,t)

Page 358: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

358CS 538 Spring 2008©

fun sort [] = [] | sort([a]) = [a] | sort(a::b::rest) = let val (left,right) = split(a::b::rest) in merge(sort(left), sort(right)) end; fun inOrder [] = true | inOrder [a] = true | inOrder (a::b::rest) = le(a,b) andalso inOrder (b::rest);end;structure Sorting : sig val inOrder : int list -> bool val le : int * int -> bool val merge : int list * int list -> int list val sort : int list -> int list val split : 'a list -> 'a list * 'a list end

Page 359: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

359CS 538 Spring 2008©

To sort a type other thanintegers, we replace thedefinition of le in the structure.But rather than actually editthat definition, ML gives us apowerful mechanism toparameterize a structure. Thisis the functor, which allows usto use one or more structuresas parameters in the definitionof a structure.

Page 360: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

360CS 538 Spring 2008©

FunctorsThe general form of a functor isfunctor name (structName:signature) = structure definition;

This functor will create aspecific version of the structuredefinition using the structureparameter passed to it.For our purposes this is ideal—we pass in a structure definingan ordering relation (the lefunction). This then creates acustom version of all thefunctions defined in thestructure body, using thespecific le definition provided.

Page 361: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

361CS 538 Spring 2008©

We first definesignature Order =

sig

type elem

val le : elem*elem -> bool

end;

This defines the type of astructure that defines a lepredicate defined on a pair oftypes called elem.An example of such a structureisstructure IntOrder:Order =

struct

type elem = int;

fun le(a,b) = a <= b;

end;

Page 362: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

362CS 538 Spring 2008©

Now we just define a functorthat creates a Sorting structurebased on an Order structure:functor MakeSorting(O:Order) =structopen O; (* makes le available*)

fun split [] = ([],[]) | split [a] = ([a],[]) | split (a::b::rest) = let val (left,right) = split rest in (a::left,b::right) end;

fun merge([],[]) = [] | merge([],hd::tl) = hd::tl | merge(hd::tl,[]) = hd::tl | merge(hd::tl,h::t) = if le(hd,h) then hd::merge(tl,h::t) else h::merge(hd::tl,t)

Page 363: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

363CS 538 Spring 2008©

fun sort [] = [] | sort([a]) = [a] | sort(a::b::rest) = let val (left,right) = split(a::b::rest) in merge(sort(left),

sort(right)) end;

fun inOrder [] = true | inOrder [a] = true | inOrder (a::b::rest) = le(a,b) andalso inOrder (b::rest);end;

Page 364: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

364CS 538 Spring 2008©

Nowstructure IntSorting = MakeSorting(IntOrder);

creates a custom structure forsorting integers: IntSorting.sort [3,0,~22,8];val it = [~22,0,3,8] : elem list

To sort strings, we just define astructure containing an ledefined for strings with Orderas its signature (i.e., type) andpass it to MakeSorting:structure StrOrder:Order =

struct

type elem = string

fun le(a:string,b) = a <= b;

end;

Page 365: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

365CS 538 Spring 2008©

structure StrSorting = MakeSorting(StrOrder);

StrSorting.sort( ["cc","abc","xyz"]);val it = ["abc","cc","xyz"] : StrOrder.elem list

StrSorting.inOrder( ["cc","abc","xyz"]);val it = false : bool

StrSorting.inOrder( [3,0,~22,8]);stdIn:593.1-593.32 Error:operator and operand don’t agree[literal]operator domain: strOrder.elem

list operand: int list in expression:

StrSorting.inOrder (3 :: 0 ::~22 :: <exp> :: <exp>)

Page 366: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

366CS 538 Spring 2008©

The SML Basis LibrarySML provides a wide variety ofuseful types and functions,grouped into structures, thatare included in the BasisLibrary.A web page fully documentingthe Basis Library is linked fromthe ML page that is part of theProgramming Languages Linkspage on the CS 538 home page.Many useful types, operatorsand functions are “preloaded”when you start the SMLcompiler. These are listed in the“Top-level Environment” sectionof the Basis Librarydocumentation.

Page 367: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

367CS 538 Spring 2008©

Many other useful definitionsmust be explicitly fetched fromthe structures they are definedin.For example, the Math structurecontains a number of usefulmathematical values andoperations.You may simply enteropen Math;

while will load all thedefinitions in Math. Doing thismay load more definitions thanyou want. What’s worse, adefinition loaded may redefinea definition you currently wantto stay active. (Recall that MLhas virtually no overloading, sofunctions with the same name

Page 368: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

368CS 538 Spring 2008©

in different structures arecommon.)A more selective way to accessa definition is to qualify it withthe structure’s name. HenceMath.pi;val it = 3.14159265359 : real

gets the value of pi defined inMath.Should you tire of repeatedlyqualifying a name, you can (ofcourse) define a local value tohold its value. Thusval pi = Math.pi;val pi = 3.14159265359 : real

works fine.

Page 369: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

369CS 538 Spring 2008©

An Overview of Structures inthe Basis Library

The Basis Library contains awide variety of usefulstructures. Here is an overviewof some of the most importantones.• Option

Operations for the option type.• Bool

Operations for the bool type.• Char

Operations for the char type.• String

Operations for the string type.• Byte

Operations for the byte type.

Page 370: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

370CS 538 Spring 2008©

• Int

Operations for the int type.• IntInf

Operations for an unboundedprecision integer type.

• Real

Operations for the real type.• Math

Various mathematical values andoperations.

• List

Operations for the list type.• ListPair

Operations on pairs of lists.• Vector

A polymorphic type forimmutable (unchangeable)sequences.

Page 371: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

371CS 538 Spring 2008©

• IntVector, RealVector,BoolVector, CharVector

Monomorphic types forimmutable sequences.

• Array

A polymorphic type for mutable(changeable) sequences.

• IntArray, RealArray,BoolArray, CharArray

Monomorphic types for mutablesequences.

• Array2

A polymorphic 2 dimensionalmutable type.

• IntArray2, RealArray2,BoolArray2, CharArray2

Monomorphic 2 dimensionalmutable types.

• TextIO

Character-oriented text IO.

Page 372: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

372CS 538 Spring 2008©

• BinIO

Binary IO operations.• OS, Unix, Date, Time, Timer

Operating systems types andoperations.

Page 373: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

373CS 538 Spring 2008©

ML Type InferenceOne of the most novel aspects ofML is the fact that it infers typesfor all user declarations.How does this type inferencemechanism work?Essentially, the ML compilercreates an unknown type for eachdeclaration the user makes. Itthen solves for these unknownsusing known types and a set oftype inference rules. That is, for auser-defined identifier i, ML wantsto determine T(i), the type of i.

Page 374: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

374CS 538 Spring 2008©

The type inference rules are:1. The types of all predefinedliterals, constants and functionsare known in advance. They maybe looked-up and used. Forexample,2 : int

true : bool

[] : 'a list

:: : 'a * 'a list -> 'a list

2. All occurrences of the samesymbol (using scoping rules) havethe same type.

3. In the expressionI = J

we know T(I) = T(J).

Page 375: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

375CS 538 Spring 2008©

4. In a conditional(if E1 then E2 else E3)

we know thatT(E1) = bool,T(E2) = T(E3) = T(conditional)

5. In a function call(f x)

we know that if T(f) = 'a -> 'b then T(x) = 'a and T(f x) = 'b

6. In a function definitionfun f x = expr;

if t(x) = 'a and T(expr) = 'b then T(f) = 'a -> 'b

7. In a tuple (e1,e2, ..., en)

if we know that T(ei) = 'ai 1 ≤ i ≤ n

then T(e1,e2, ..., en) = 'a1*'a2*...*'an

Page 376: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

376CS 538 Spring 2008©

8. In a record { a=e1,b=e2, ... }

if T(ei) = 'ai 1 ≤ i ≤ n then the type of the record =

{a:'a1, b:'a2, ...}

9. In a list [v1,v2, ... vn]

if we know that T(vi) = 'ai 1 ≤ i ≤ n

then we know that'a1='a2=...='an andT([v1,v2, ... vn]) = 'a1 list

Page 377: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

377CS 538 Spring 2008©

To Solve for Types:1. Assign each untyped symbol its

own distinct type variable.2.Use rules (1) to (9) to solve for and

simplify unknown types.3. Verify that each solution “works”

(causes no type errors)throughout the program.

ExamplesConsiderfun fact(n)=if n=1 then 1 else n*fact(n-1);

To begin, we’ll assign typevariables:T(fact) = 'a -> 'b(fact is a function)T(n) = 'c

Page 378: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

378CS 538 Spring 2008©

Now we begin to solve for thetypes 'a, 'b and 'c mustrepresent.We know (rule 5) that 'c = 'asince n is the argument of fact.We know (rule 3) that 'c = T(1)= int since n=1 is part of thedefinition.We know (rule 4) that T(1) =T(if expression)='b since the ifexpression is the body of fact.Thus, we have‘a = 'b ='c = int, soT(fact) = int -> int

T(n) = int

These types are correct for alloccurrences of fact and n in thedefinition.

Page 379: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

379CS 538 Spring 2008©

A Polymorphic Function:fun leng(L) =

if L = []

then 0

else 1+len(tl L);

To begin, we know thatT([]) = 'a list andT(tl) = 'b list -> 'b list

We assign types to leng and L:T(leng) = 'c -> 'd

T(L) = 'e

Since L is the argument of leng,'e = 'c

From the expression L=[] weknow'e = 'a list

Page 380: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

380CS 538 Spring 2008©

From the fact that 0 is the resultof the then, we know the ifreturns an int, so 'd = int.Thus T(leng) = 'a list -> intandT(L) = 'a list

These solutions are typecorrect throughout thedefinition.

Page 381: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

381CS 538 Spring 2008©

Type Inference for PatternsType inference works forpatterns too.Considerfun leng [] = 0

| leng (a::b) = 1 + leng b;

We first create type variables:T(leng) = 'a -> 'b

T(a) = 'c

T(b) = 'd

From leng [] we conclude that'a = 'e list

From leng [] = 0 we concludethat'b = int

From leng (a::b) we concludethat

Page 382: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

382CS 538 Spring 2008©

'c ='e and 'd = 'e list

Thus we haveT(leng) = 'e list -> int

T(a) = 'e

T(b) = 'e list

This solution is type correctthroughout the definition.

Page 383: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

383CS 538 Spring 2008©

Not Everything can beAutomatically Typed in ML

Let’s try to typefun f x = (x x);

We assumeT(f) = 'a -> 'b

t(x) = 'c

Now (as usual) 'a = 'c since x isthe argument of f.From the call (x x) we concludethat 'c must be of the form 'd ->'e (since x is being used as afunction).Moreover, 'c = 'd since x is anargument in (x x).Thus 'c = 'd ->'e = 'c ->'e.But 'c = 'c->'e has no solution,so in ML this definition is invalid.We can’t pass a function to itself

Page 384: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

384CS 538 Spring 2008©

as an argument—the type systemdoesn’t allow it.In Scheme this is allowed:(define (f x) (x x))

but a call like(f f)

certainly doesn’t do anythinggood!

Page 385: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

385CS 538 Spring 2008©

Type UnionsLet’s try to typefun f g = ((g 3), (g true));

Now the type of g is 'a -> 'bsince g is used as a function.The call (g 3) says 'a = int andthe call (g true) says 'a =boolean.Does this mean g is polymorphic?That is, is the type of ff : ('a->'b)->'b*'b?NO!All functions have the type 'a ->'b but not all functions can bepassed to f.Consider not: bool->bool.The call (not 3) is certainlyillegal.

Page 386: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

386CS 538 Spring 2008©

What we’d like in this case is aunion type. That is, we’d like to beable to type g as(int|bool)->'b which MLdoesn’t allow.Fortunately, ML does allow typeconstructors, which are just whatwe need.Givendatatype T = I of int|B of bool;

we can redefine f asfun f g = (g (I(3)), g (B(true)));val f = fn : (T -> 'a) -> 'a * 'a

Page 387: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

387CS 538 Spring 2008©

Finally, note that in a definitionlikelet val f =

fn x => x (* id function*)in (f 3,f true)end;

type inference works fine:val it = (3,true) : int * bool

Here we define f in advance, soits type is known when calls toit are seen.

Page 388: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

388CS 538 Spring 2008©

Reading Assignment• Webber: Chapters 19, 20 and 22

Page 389: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

389CS 538 Spring 2008©

PrologProlog presents a view ofprogramming that is verydifferent from most otherprogramming languages.A famous text book is entitled“Algorithms + Data Structures =Programs”This formula represents well theconventional approach toprogramming that mostprogramming languages support.In Prolog there is an alternativerule of programming:“Algorithms = Logic + Control”This rule encompasses a non-procedural view of programming.Logic (what the program is tocompute) comes first.

Page 390: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

390CS 538 Spring 2008©

Then control (how to implementthe logic) is considered.In Prolog we program the logic ofa program, but the Prolog systemautomatically implements thecontrol.Logic is essential—control is justefficiency.

Page 391: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

391CS 538 Spring 2008©

Logic ProgrammingProlog implements logicprogramming.In fact Prolog meansProgramming in Logic.

In Prolog programs arestatements of rules and facts.Program execution isdeduction—can an answer beinferred from known rules andfacts.Prolog was developed in 1972by Kowalski and Colmerauer atthe University of Marseilles.

Page 392: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

392CS 538 Spring 2008©

Elementary Data Objects• In Prolog integers and atoms are the

elementary data objects.

• Integers are ordinary integer literalsand values.

• Atoms are identifiers that begin with alower-case letter (much like symbolicvalues in Scheme).

• In Prolog data objects are calledterms.

• In Prolog we define relations amongterms (integers, atoms or otherterms).

• A predicate names a relation.Predicates begin with lower-caseletters.

• To define a predicate, we write clausesthat define the relation.

Page 393: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

393CS 538 Spring 2008©

• There are two kinds of programclauses, facts and rules.

• A fact is a predicate that prefixes asequence of terms, and which endswith a period (“.”).

As an example, consider thefollowing facts which define“fatherOf” and “motherOf”relations.

fatherOf(tom,dick).

fatherOf(dick,harry).

fatherOf(jane,harry).

motherOf(tom,judy).

motherOf(dick,mary).

motherOf(jane,mary).

The symbols fatherOf and motherOfare predicates. The symbols tom,dick, harry, judy, mary and jane areatoms.

Page 394: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

394CS 538 Spring 2008©

Once we have entered rules andfacts that define relations, we canmake queries (ask the Prologsystem questions).Prolog has two interactive modesthat you can switch between.To enter definition mode (to definerules and facts) you enter[user].

You then enter facts and rules,terminating this phase with ^D(end of file).Alternatively, you can enter['filename'].

to read in rules and facts stored inthe file named filename.

Page 395: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

395CS 538 Spring 2008©

When you start Prolog, or afteryou leave definitions mode, youare in query mode.In query mode you see a promptof the form| ?- or ?- (depending on thesystem you are running).In query mode, Prolog allows youto ask whether a relation amongterms is true or false.Thus given our definition ofmotherOf and fatherOfrelations, we can ask:| ?- fatherOf(tom,dick).yes

A “yes” response means thatProlog is able to conclude fromthe facts and rules it has beengiven that the relation querieddoes hold.

Page 396: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

396CS 538 Spring 2008©

| ?- fatherOf(georgeW,george).no

A “no” response to a query meansthat Prolog is unable to concludethat the relation holds from whatit has been told. The relation mayactually be true, but Prolog maylack necessary facts or rules todeduce this.

Page 397: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

397CS 538 Spring 2008©

Variables in QueriesOne of the attractive features ofProlog is the fact that variablesmay be included in queries. Avariable always begins with acapital letter.When a variable is seen, Prologtries to find a value (binding) forthe variable that will make thequeried relation true.For example,fatherOf(X,harry).

asks Prolog to find an value for Xsuch that X’s father is harry.When we enter the query, Prologgives us a solution (if one can befound): ?- fatherOf(X,harry).

X = dick

Page 398: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

398CS 538 Spring 2008©

If no solution can be found, it tellsus so:| ?- fatherOf(Y,jane).no

Since solutions to queries neednot be unique, Prolog will give usalternate solutions if we ask forthem. We do so by entering a “;”after a solution is printed. We geta “no” when no more solutionscan be found:| ?- fatherOf(X,harry).

X = dick ;X = jane ;no

Page 399: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

399CS 538 Spring 2008©

Variables may be placedanywhere in a query. Thus wemay ask| ?- fatherOf(jane,X).

X = harry ;no

We may use more than onevariable if we wish:| ?- fatherOf(X,Y).X = tom,

Y = dick ;X = dick,

Y = harry ;X = jane,

Y = harry ;

no(This query displays all thefatherOf relations).

Page 400: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

400CS 538 Spring 2008©

Conjunction of GoalsMore than one relation can beincluded as the “goal” of a query.A comma (“,”) is used as an ANDoperator to indicate a conjunctionof goals—all must be satisfied bya solution to the query.| ?-fatherOf(jane,X),motherOf(jane,Y).

X = harry,

Y = mary ;no

A given variable may appear morethan once in a query. The samevalue of the variable must beused in all places in which thevariable appears (this is calledunification).

Page 401: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

401CS 538 Spring 2008©

For example,| ?-fatherOf(tom,X),fatherOf(X,harry).

X = dick ;no

Page 402: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

402CS 538 Spring 2008©

Rules in PrologRules allow us to state that arelation will hold depending onthe truth (correctness) of otherrelations.In effect a rules says,“If I know that certain relationshold, then I also know that thisrelation holds.”A rule in Prolog is of the formrel1 :- rel2, rel3, ... reln.

This says rel1 can be assumedtrue if we can establish that rel2and rel3 and all relations to relnare true.rel1 is called the head of the rule.

rel2 to reln form the body of therule.

Page 403: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

403CS 538 Spring 2008©

ExampleThe following two rules define agrandMotherOf relation using themotherOf and fatherOfrelations:grandMotherOf(X,GM) :-

motherOf(X,M), motherOf(M,GM).

grandMotherOf(X,GM) :-

fatherOf(X,F), motherOf(F,GM).

| ?- grandMotherOf(tom,GM).

GM = mary ;no

| ?- grandMotherOf(dick,GM).no

| ?- grandMotherOf(X,mary).

X = tom ;no

Page 404: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

404CS 538 Spring 2008©

As is the case for allprogramming, in all languages,you must be careful when youdefine a rule that it correctlycaptures the idea you have inmind.Consider the following rule thatdefines a sibling relationbetween two people:sibling(X,Y) :-motherOf(X,M), motherOf(Y,M),fatherOf(X,F), fatherOf(Y,F).

This rule says that X and Y aresiblings if each has the samemother and the same father.But the rule is wrong!Why?

Page 405: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

405CS 538 Spring 2008©

Let’s give it a try:| ?- sibling(X,Y).

X = Y = tom

Darn! That’s right, you can’t beyour own sibling. So we refine therule to force X and Y to bedistinct:sibling(X,Y) :- motherOf(X,M), motherOf(Y,M), fatherOf(X,F), fatherOf(Y,F), not(X=Y).

(A few Prolog systems use “\+” fornot; but most include a notrelation.)| ?- sibling(X,Y).X = dick,

Y = jane ;X = jane,

Y = dick ;no

Page 406: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

406CS 538 Spring 2008©

Note that distinct but equivalentsolutions (like X = dick,Y = jane vs.X = jane,Y = dick) often appear

in Prolog solutions. You maysometimes need to “filter out”solutions that are effectivelyredundant (perhaps byformulating stricter or moreprecise rules).

Page 407: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

407CS 538 Spring 2008©

How Prolog Solves QueriesThe unique feature of Prolog isthat it automatically chooses thefacts and rules needed to solve aquery.But how does it make its choice?It starts by trying to solve eachgoal in a query, left to right (recallgoals are connected using “,”which is the and operator).For each goal it tries to match acorresponding fact or the head ofa corresponding rule.

A fact or head of rule matches agoal if:• Both use the same predicate.

• Both have the same number ofterms following the predicate.

Page 408: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

408CS 538 Spring 2008©

• Each term in the goal and fact orrule head match (are equal),possibly binding a free variable toforce a match.

For example, assume we wish tomatch the following goal:x(a,B)

This can match the factx(a,b).

or the head of the rulex(Y,Z) :- Y = Z.

But x(a,B) can’t matchy(a,b) (wrong predicate name)orx(b,d) (first terms don’t match)orx(a,b,c) (wrong number ofterms).

Page 409: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

409CS 538 Spring 2008©

If we succeed in matching a rule,we have solved the goal inquestion; we can go on to matchany remaining goals.If we match the head of a rule, wearen’t done—we add the body ofthe rule to the list of goals thatmust be solved.Thus if we match the goal x(a,B)with the rulex(Y,Z) :- Y = Z.

then we must solve a=B which isdone by making B equal to a.

Page 410: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

410CS 538 Spring 2008©

BacktrackingIf we reach a point where a goalcan’t be matched, or the body of arule can’t be matched, webacktrack to the last (mostrecent) spot where a choice ofmatching a particular fact or rulewas made. We then try to match adifferent fact or rule. If this failswe go back to the next previousplace where a choice was madeand try a different match there.We try alternatives until we areable to solve all the goals in ourquery or until all possible choiceshave been tried and found to fail.If this happens, we answer “no”the query can’t be solved.As we try to match facts and ruleswe try them in their order ofdefinition.

Page 411: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

411CS 538 Spring 2008©

ExampleLet’s trace how| ?- grandMotherOf(tom,GM).

is solved.Recall thatgrandMotherOf(X,GM) :- motherOf(X,M), motherOf(M,GM).

grandMotherOf(X,GM) :- fatherOf(X,F), motherOf(F,GM).fatherOf(tom,dick).fatherOf(dick,harry).fatherOf(jane,harry).motherOf(tom,judy).motherOf(dick,mary).motherOf(jane,mary).

Page 412: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

412CS 538 Spring 2008©

We try the first grandMotherOfrule first.This forces X = tom. We have tosolve motherOf(tom,M), motherOf(M,GM).

We now try to solvemotherOf(tom,M)

This forces M = judy.We then try to solvemotherOf(judy,GM)

None of the motherOf rulesmatch this goal, so we backtrack.No other motherOf rule can solvemotherOf(tom,M)

so we backtrack again and try thesecond grandMotherOf rule:

Page 413: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

413CS 538 Spring 2008©

grandMotherOf(X,GM) :- fatherOf(X,F), motherOf(F,GM).

This matches, forcing X = tom.We have to solvefatherOf(tom,F),motherOf(F,GM).We can match the first goal withfatherOf(tom,dick).

This forces F = dick.We then must solvemotherOf(dick,GM)

which can be matched bymotherOf(dick,mary).

We have matched all our goals, sowe know the query is true, withGM = mary.

Page 414: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

414CS 538 Spring 2008©

List Processing in PrologProlog has a notation similar to“cons cells” of Lisp and Scheme.The “.” functor (predicate name)acts like cons.Hence .(a,b) in Prolog isessentially the same as (a . b)in Scheme.Lists in Prolog are formed muchthe same way as in Scheme andML:[] is the empty list[1,2,3] is an abbreviation for.(1, .(2, .(3,[])))

just as(1,2,3) in Scheme is anabbreviation for(cons 1 (cons 2 (cons 3 () )))

Page 415: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

415CS 538 Spring 2008©

The notation [H|T] represents alist with H matching the head ofthe list and T matching the rest ofthe list.Thus [1,2,3] ≡ [1| [2,3]] ≡[1,2| [3]] ≡ [1,2,3| [] ]

As in ML, “_” (underscore) can beused as a wildcard or “don’t care”symbol in matches.Given the fact p([1,2,3,4]).

The query | ?- p([X|Y]).

answersX = 1,

Y = [2,3,4]

Page 416: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

416CS 538 Spring 2008©

The queryp([_,_,X|Y]).

answersX = 3,

Y = [4]

Page 417: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

417CS 538 Spring 2008©

List Operations in PrologList operations are defined usingrules and facts. The definitionsare similar to those used inScheme or ML, but they are non-procedural.That is, you don’t given anexecution order. Instead, you giverecursive rules and non-recursive“base cases” that characterize theoperation you are defining.Consider append: append([],L,L).

append([H|T1],L2,[H|T3]) :- append(T1,L2,T3).

The first fact says that an emptylist (argument 1) appended to anylist L (argument 2) gives L(argument 3) as its answer.

Page 418: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

418CS 538 Spring 2008©

The rule in line 2 says that if youtake a list that begins with H andhas T1 as the rest of the list andappend it to a list L then theresulting appended list will beginwith H.Moreover, the rest of the resultinglist, T3, is the result of appendingT1 (the rest of the first list) withL2 (the second input list).The query | ?- append([1],[2,3],[1,2,3]).

answersYes

because with H=1, T1=[], L2=[2,3] and T3=[2,3] it must bethe case thatappend([],[2,3],[2,3]) is trueand fact (1) says that this is so.

Page 419: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

419CS 538 Spring 2008©

Inverting Inputs and OutputsIn Prolog the division between“inputs” and “outputs” isintentionally vague. We canexploit this. It is often possible to“invert” a query and ask whatinputs would compute a givenoutput. Few other languagesallow this level of flexibility. Consider the queryappend([1],X,[1,2,3]).

This asks Prolog to find a list Xsuch that if we append [1] to Xwe will get [1,2,3]. Prolog answersX = [2,3]

How does it choose this answer?

Page 420: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

420CS 538 Spring 2008©

First Prolog tries to match thequery against fact (1) or rule (2).Fact (1) doesn’t match (the firstarguments differ) so we matchrule (2).This gives us H=1, T1=[], L2=Xand T3 = [2,3].We next have to solve the body ofrule (2) which isappend([],L2,[2,3]).

Fact (1) matches this, and tells usthat L2=[2,3]=X, and that’s ouranswer!

Page 421: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

421CS 538 Spring 2008©

The Member RelationA common predicate whenmanipulating lists is amembership test—is a givenvalue a member of a list?An “obvious” definition is arecursive one similar to what wemight program in Scheme or ML:member(X,[X|_]).member(X,[_|Y]):- member(X,Y).

This definition states that the firstargument, X, is a member of thesecond argument (a list) if Xmatches the head of the list or if Xis (recursively) a member of therest of the list.

Note that we don’t have to “tell”Prolog that X can’t be a memberof an empty list—if we don’t tell

Page 422: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

422CS 538 Spring 2008©

Prolog that something is true, itautomatically assumes that itmust be false.Thus saying nothing aboutmembership in an empty list isthe same as saying thatmembership in an empty list isimpossible.Since inputs and outputs in arelation are blurred, we can usemember in an unexpected way—toiterate through a list of values.

If we want to know if any memberof a list L satisfies a predicate p,we cansimply write:member(X,L),p(X).

Page 423: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

423CS 538 Spring 2008©

There is no explicit iteration orsearching. We simply ask Prologto find an X such thatmember(X,L) is true (X is in L)and p(X) is true. Backtrackingwill find the “right” value for X (ifany such X exists).This is sometimes called the“guess and verify” technique.Thus we can querymember(X,[3,-3,0,10,-10]), (X > 0).

This asks for an X in the list[3,-3,0,10,-10] which isgreater than 0.

Prolog answersX = 3 ;X = 10 ;

Page 424: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

424CS 538 Spring 2008©

Note too that our “obvious”definition of member is not theonly one possible.An alternative definition (which isfar less obvious) ismember(X,L) :- append(_,[X|_],L).

This definition says X is a memberof L if I can take some list (whosevalue I don’t care about) andappend it to a list that begins withX (and which ends with values Idon’t care about) and get a listequal to L.Said more clearly, X is a memberof L if X is anywhere in the“middle” of L.Prolog solves a query involvingmember by partitioning the list Lin all possible ways, and checkingto see if X ever is the head of the

Page 425: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

425CS 538 Spring 2008©

second list. Thus formember(X,[1,2,3]), it tries thepartition [] and [1,2,3](exposing 1 as a possible X), then[1] and [2,3] (exposing 2) andfinally [1,2] and [3] (exposing3).

Page 426: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

426CS 538 Spring 2008©

Sorting AlgorithmsSorting algorithms are goodexamples of Prolog’s definitionalcapabilities. In a Prolog definitionthe “logic” of a sorting algorithmis apparent, stripped of thecumbersome details of datastructures and control structuresthat dominate algorithms in otherprogramming languages.Consider the simplest possiblesort imaginable, which we’ll callthe “naive sort.”At the simplest level a sorting of alist L requires just two things:• The sorting is a permutation (a

reordering) of the values in L.

• The values are “in order”(ascending or descending).

Page 427: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

427CS 538 Spring 2008©

We can implement this concept ofa sort directly in Prolog. We(a) permute an input list(b) check if it is in sorted order(c) repeat (a) & (b) until a sorting

is found.

Page 428: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

428CS 538 Spring 2008©

PermutationsLet’s first look at howpermutations are defined inProlog. In most languagesgenerating permutations is non-trivial—you need data structuresto store the permutations you aregenerating and control structuresto visit all permutations in someorder.In Prolog, permutations aredefined quite concisely, thoughwith a bit of subtlety:perm(X,Y) will be true if list Y is apermutation of list X.Only two definitions are needed:perm([],[]).

perm(L,[H|T]) :- append(V,[H|U],L), append(V,U,W), perm(W,T).

Page 429: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

429CS 538 Spring 2008©

The first definition,perm([],[]).

is trivial. An empty list may onlybe permuted into another emptylist.The second definition is rathermore complex:perm(L,[H|T]) :-append(V,[H|U],L), append(V,U,W), perm(W,T).

This rule says a list L may bepermuted in to a list that beginswith H and ends with list T if:(1) L may be partitioned into two

lists, V and [H|U]. (That is, H is somewhere in the

“middle” of L).(2) Lists V and U (all of L except H) may be appended into list W.(3) List W may be permuted into T.

Page 430: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

430CS 538 Spring 2008©

Let’s see perm in action:| ?- perm([1,2,3],X).

X = [1,2,3] ;

X = [1,3,2] ;

X = [2,1,3] ;

X = [2,3,1] ;

X = [3,1,2] ;

X = [3,2,1] ;no

We’ll trace how the first fewanswers are computed. Notethough that all permutations aregenerated, and with no apparentdata structures or controlstructures.We start with L=[1,2,3] andX=[H|T].We first solveappend(V,[H|U],L), which

Page 431: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

431CS 538 Spring 2008©

simplifies toappend(V,[H|U],[1,2,3]).One solution to this goal isV = [], H = 1, U = [2,3]

We next solve append(V,U,W)which simplifies toappend([],[2,3],W).The only solution for this isW=[2,3].Finally, we solve perm(W,T),which simplifies toperm([2,3],T).One solution to this is T=[2,3].This gives us our first solution:[H|T]=[1,2,3].To get our next solution webacktrack. Where is the mostrecent place we made a choice ofhow to solve a goal?

Page 432: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

432CS 538 Spring 2008©

It was at perm([2,3],T). Wechose T=[2,3], but T=[3,2] isanother solution. Using thissolution, we get out next answer[H|T]=[1,3,2].Let’s try one more. We backtrackagain. No more solutions arepossible for perm([2,3],T), sowe backtrack to an earlier choicepoint.At append(V,[H|U],[1,2,3])another solution isV=[1], H = 2, U = [3]

Using this binding, we solveappend(V,U,W) which simplifiesto append([1],[3],W). Thesolution to this must be W=[1,3].We then solve perm(W,T) whichsimplifies to perm([1,3],T). Onesolution to this is T=[1,3]. This

Page 433: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

433CS 538 Spring 2008©

makes our third solution for[H|T] = [2,1,3].You can check out the otherbindings that lead to the lastthree solutions.

Page 434: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

434CS 538 Spring 2008©

A Permutation SortNow that we know how togenerate permutations, thedefinition of a permutation sort isalmost trivial.We define an inOrder relationthat characterizes our notion ofwhen a list is properly sorted:inOrder([]).

inOrder([_]).

inOrder([A,B|T]) :- A =< B, inOrder([B|T]).

These definitions state that a nulllist, and a list with only oneelement are always in sortedorder. Longer lists are in order ifthe first two elements are inproper order. (A=<B) checks thisand then the rest of the list,

Page 435: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

435CS 538 Spring 2008©

excluding the first element, ischecked.Now our naive permutation sort isonly one line long:naiveSort(L1,L2) :- perm(L1,L2), inOrder(L2).

And the definition works too!| ?-naiveSort([1,2,3],[3,2,1]).no

?- naiveSort([3,2,1],L).

L = [1,2,3] ;no

| ?-naiveSort([7,3,88,2,1,6,77, -23,5],L).L = [-23,1,2,3,5,6,7,77,88]

Page 436: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

436CS 538 Spring 2008©

Though this sort works, it ishopelessly inefficient—itrepeatedly “shuffles” the inputuntil it happens to find anordering that is sorted. Theprocess is largely undirected. Wedon’t “aim” toward a correctordering, but just search until weget lucky.

Page 437: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

437CS 538 Spring 2008©

A Bubble SortPerhaps the best known sortingtechnique is the interchange or“bubble” sort. The idea is simple.We examine a list of values,looking for a pair of adjacentvalues that are “out of order.” Ifwe find such a pair, we swap thetwo values (placing them incorrect order). Otherwise, thewhole list must be in sorted orderand we are done.In conventional languages weneed a lot of code to search forout-of-order pairs, and tosystematically reorder them. InProlog, the whole sort may bedefined in a few lines:

Page 438: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

438CS 538 Spring 2008©

bubbleSort(L,L) :- inOrder(L).

bubbleSort(L1,L2) :- append(X,[A,B|Y],L1), A > B, append(X,[B,A|Y],T), bubbleSort(T,L2).

The first line says that if L isalready in sorted order, we aredone.The second line is a bit morecomplex. It defines what it meansfor a list L2 to be a sorting for listL1, using our insight that weshould swap out-of-orderneighbors. We first partition listL1 into two lists, X and [A,B|Y].This “exposes” two adjacentvalues in L, A and B. Next weverify that A and B are out-of-order (A>B). Next, inappend(X,[B,A|Y],T), wedetermine that list T is just our

Page 439: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

439CS 538 Spring 2008©

input L, with A and B swappedinto B followed by A.Finally, we verify thatbubbleSort(T,L2) holds. Thatis, T may be bubble-sorted intoL2.This approach is rather moredirected than our permutationsort—we look for an out-of-orderpair of values, swap them, andthen sort the “improved” list.Eventually there will be no moreout-of-order pairs, the list will bein sorted order, and we will bedone.

Page 440: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

440CS 538 Spring 2008©

Merge SortAnother popular sort in the“merge sort” that we have alreadyseen in Scheme and ML. The ideahere is to first split a list of lengthL into two sublists of length L/2.Each of these two lists isrecursively sorted. Finally, the twosorted sublists are mergedtogether to form a completesorted list.The bubble sort can take timeproportional to n2 to sort nelements (as many as n2/2 swapsmay be needed). The merge sortdoes better—it takes timeproportional to n log2 n to sort nelements (a list of size n can onlybe split in half log2 n times).

Page 441: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

441CS 538 Spring 2008©

We first need Prolog rules on howto split a list into two equalhalves:split([],[],[]).split([A],[A],[]).split([A,B|T],[A|P1],[B|P2]) :- split(T,P1,P2).

The first two lines characterizetrivial splits. The third ruledistributes one of the first twoelements to each of the twosublists, and then recursivelysplits the rest of the list.

Page 442: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

442CS 538 Spring 2008©

We also need rules thatcharacterize how to merge twosorted sublists into a completesorted list:

merge([],L,L).merge(L,[],L).merge([A|T1],[B|T2],[A|L2]) :- A =< B, merge(T1,[B|T2],L2).merge([A|T1],[B|T2],[B|L2]) :- A > B, merge([A|T1],T2,L2).

The first 2 lines handle mergingnull lists. The third line handlesthe case where the head of thefirst sublist is ≤ the head of thesecond sublist; the final rulehandles the case where the headof the second sublist is smaller.

Page 443: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

443CS 538 Spring 2008©

With the above definitions, amerge sort requires only threelines:mergeSort([],[]).

mergeSort([A],[A]).mergeSort(L1,L2) :- split(L1,P1,P2), mergeSort(P1,S1),mergeSort(P2,S2),merge(S1,S2,L2).

The first two lines handle thetrivial cases of lists of length 0 or1. The last line contains the full“logic” of a merge sort: split theinput list, L into two half-sizedlists P1 and P2. Then merge sortP1 into S1 and P2 into S2. Finally,merge S1 and S2 into a sorted listL2. That’s it!

Page 444: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

444CS 538 Spring 2008©

Quick SortThe merge sort partitions its inputlist rather blindly, alternatingvalues between the two lists.What if we partitioned the inputlist based on values rather thanpositions?The quick sort does this. It selectsa “pivot” value (the head of theinput list) and divides the inputinto two sublists based onwhether the values in the list areless than the pivot or greater thanor equal to the pivot. Next thetwo sublists are recursivelysorted. But now, after sorting, nomerge phase is needed. Rather,the two sorted sublists can simplybe appended, since we know allvalues in the first list are less thanall values in the second list.

Page 445: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

445CS 538 Spring 2008©

We need a Prolog relation thatcharacterizes how we will do ourpartitioning. We we definepartition(E,L1,L2,L3) to betrue if L1 can be partitioned intoL2 and L3 using E as the pivotelement. The necessary rules are:

partition(E,[],[],[]).partition(E,[A|T1],[A|T2],L3) :- A<E, partition(E,T1,T2,L3).partition(E,[A|T1],L2,[A|T3]) :- A>=E, partition(E,T1,L2,T3)

The first line defines a trivialpartition of a null list. The secondline handles the case in which thefirst element of the list to bepartitioned is less than the pivot,while the final line handles thecase in which the list head isgreater than or equal to the pivot.

Page 446: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

446CS 538 Spring 2008©

With our notion of partitioningdefined, the quicksort itselfrequires only 2 lines:

qsort([],[]).qsort([A|T],L) :-partition(A,T,L1,L2),qsort(L1,S1),qsort(L2,S2),append(S1,[A|S2],L).

The first line defines a trivial sortof an empty list.The second line says to sort a listthat begins with A and ends withlist T, we partition T into sublistsL1 and L2, based on A. Then werecursively quick sort L1 into S1and L2 into S2. Finally we appendS1 to [A|S2](A must be > all values in S1 and Amust be ≤ all values in S2). Theresult is L, a sorting of [A|T].

Page 447: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

447CS 538 Spring 2008©

Arithmetic in PrologThe = predicate can be used totest bound variables for equality(actually, identity).If one or both of =’s arguments arefree variables, = forces a bindingor an equality constraint.Thus| ?- 1=2.no

| ?- X=2.

X = 2

| ?- Y=X.

Y = X = _10751

| ?- X=Y, X=joe.

X = Y = joe

Page 448: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

448CS 538 Spring 2008©

Arithmetic Terms are SymbolicEvaluation of an arithmetic terminto a numeric value must beforced.That is, 1+2 is an infixrepresentation of the relation+(1,2). This term is not aninteger!Therefore| ?- 1+2=3.no

To force arithmetic evaluation, weuse the infix predicate is.The right-hand side of is must beall ground terms (literals orvariables that are already bound).No free (unbound) variables areallowed.

Page 449: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

449CS 538 Spring 2008©

Hence|?- 2 is 1+1.yes

| ?- X is 3*4.X = 12

| ?- Y is Z+1.! Instantiation error in argument2 of is/2! goal: _10712 is _10715+1

The requirement that the right-hand side of an is relation beground is essentially procedural.It exists to avoid having to invertcomplex equations. Consider,

(0 is (I**N)+(J**N)-K**N)), N>2.

Page 450: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

450CS 538 Spring 2008©

Counting in PrologRules that involve counting oftenuse the is predicate to evaluate anumeric value.Consider the relation len(L,N)that is true if the length of list L isN.len([],0).

len([_|T],N) :- len(T,M), N is M+1.

| ?- len([1,2,3],X).

X = 3

| ?- len(Y,2).

Y = [_10903,_10905]

The symbols _10903 and _10905are “internal variables” created asneeded when a particular value isnot forced in a solution.

Page 451: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

451CS 538 Spring 2008©

Debugging PrologCare is required in developing andtesting Prolog programs becausethe language is untyped;undeclared predicates or relationsare simply treated as false.Thus in a definition like adj([A,B|_]) :- A=B.

adj([_,B|T]) :- adk([B|T]).

| ?- adj([1,2,2]).no

(Some Prolog systems warn whenan undefined relation isreferenced, but many othersdon’t).

Page 452: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

452CS 538 Spring 2008©

Similarly, givenmember(A,[A|_]).

member(A,[_|T]) :- member(A,[T]).

| ?- member(2,[1,2]).

Infinite recursion! (Why?)

If you’re not sure what is goingon, Prolog’s trace feature is veryhandy.The commandtrace.

turns on tracing. (notrace turnstracing off).Hence| ?- trace.yes

[trace]

| ?- member(2,[1,2]).

Page 453: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

453CS 538 Spring 2008©

(1) 0 Call: member(2,[1,2]) ?

(1) 1 Head [1->2]:member(2,[1,2]) ?

(1) 1 Head [2]:member(2,[1,2]) ?

(2) 1 Call: member(2,[[2]]) ?

(2) 2 Head [1->2]:member(2,[[2]]) ?

(2) 2 Head [2]:member(2,[[2]]) ?

(3) 2 Call: member(2,[[]]) ?

(3) 3 Head [1->2]:member(2,[[]]) ?

(3) 3 Head [2]: member(2,[[]])?

(4) 3 Call: member(2,[[]]) ?

(4) 4 Head [1->2]:member(2,[[]]) ?

(4) 4 Head [2]: member(2,[[]])?

(5) 4 Call: member(2,[[]]) ?

Page 454: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

454CS 538 Spring 2008©

Termination Issues in PrologSearching infinite domains (likeintegers) can lead to non-termination, with Prolog tryingevery value.Considerodd(1).

odd(N) :- odd(M), N is M+2.

| ?- odd(X).

X = 1 ;

X = 3 ;

X = 5 ;X = 7

Page 455: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

455CS 538 Spring 2008©

A query | ?- odd(X), X=2.going into an infinite search,generating each and every oddinteger and finding none is equalto 2!The obvious alternative,odd(2) (which is equivalent toX=2, odd(X)) also does aninfinite, but fruitless search.We’ll soon learn that Prolog doeshave a mechanism to “cut off”fruitless searches.

Page 456: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

456CS 538 Spring 2008©

Definition Order can MatterIdeally, the order of definition offacts and rules should not matter.But,in practice definition order canmatter. A good general guidelineis to define facts before rules. Tosee why, consider a very completedatabase of motherOf relationsthat goes back as far asmotherOf(cain,eve).

Now we defineisMortal(X) :- isMortal(Y), motherOf(X,Y).

isMortal(eve).

Page 457: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

457CS 538 Spring 2008©

These definitions state that thefirst woman was mortal, and allindividuals descended from herare also mortal.But when we try as trivial a queryas| ?- isMortal(eve).

we go into an infinite search!Why?Let’s trace what Prolog does whenit sees| ?- isMortal(eve).It matches with the first definitioninvolving isMortal, which isisMortal(X) :- isMortal(Y), motherOf(X,Y).

It sets X=eve and tries to solveisMortal(Y), motherOf(eve,Y).

It will then expand isMortal(Y)into

Page 458: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

458CS 538 Spring 2008©

isMortal(Z), motherOf(Y,Z).

An infinite expansion ensues.The solution is simple—place the“base case” fact that terminatesrecursion first.If we useisMortal(eve).

isMortal(X) :- isMortal(Y), motherOf(X,Y).yes

| ?- isMortal(eve).

yes

But now another problem appears!If we ask| ?- isMortal(clarkKent).

we go into another infinite search!Why?The problem is that Clark Kent isfrom the planet Krypton, and

Page 459: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

459CS 538 Spring 2008©

hence won’t appear in ourmotherOf database.Let’s trace the query.It doesn’t matchisMortal(eve).We next tryisMortal(clarkKent) :- isMortal(Y), motherOf(clarkKent,Y).

We try Y=eve, but eve isn’t Clark’smother. So we recurse, getting:isMortal(Z), motherOf(Y,Z),motherOf(clarkKent,Y).

But eve isn’t Clark’s grandmothereither! So we keep going furtherback, trying to find a chain ofdescendents that leads from eveto clarkKent. No such chainexists, and there is no limit tohow long a chain Prolog will try.

Page 460: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

460CS 538 Spring 2008©

There is a solution though!We simply rewrite our recursivedefinition to be isMortal(X) :- motherOf(X,Y),isMortal(Y).

This is logically the same, butnow we work from the individualX back toward eve, rather thanfrom eve toward X. Since we haveno motherOf relation involvingclarkKent, we immediately stopour search and answer no!

Page 461: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

461CS 538 Spring 2008©

Extra-logical Aspects ofProlog

To make a Prolog program moreefficient, or to represent negativeinformation, Prolog needsfeatures that have a proceduralflavor. These constructs are called“extra-logical” because they gobeyond Prolog’s core of logic-based inference.

Page 462: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

462CS 538 Spring 2008©

The CutThe most commonly used extra-logical feature of Prolog is the “cutsymbol,” “!”A ! in a goal, fact or rule “cuts off”backtracking.In particular, once a ! is reached(and automatically matched), wemay not backtrack across it. Therule we’ve selected and thebindings we’ve already selectedare “locked in” or “frozen.”For example, givenx(A) :- y(A,B), z(B), ! , v(B,C).

once the ! is hit we can’tbacktrack to resatisfy y(A,B) orz(B) in some other way. We arelocked into this rule, with thebindings of A and B already inplace.

Page 463: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

463CS 538 Spring 2008©

We can backtrack to try varioussolutions to v(B,C).It is sometimes useful to haveseveral !’s in a rule. This allows usto find a partial solution, lock itin, find a further solution, thenlock it in, etc.For example, in a rulea(X) - b(X), !, c(X,Y), ! , d(Y).

we first try to satisfy b(X),perhaps trying several facts orrules that define the b relation.Once we have a solution to b(X),we lock it in, along with thebinding for X.Then we try to satisfy c(X,Y),using the fixed binding for X, butperhaps trying several bindingsfor Y until c(X,Y) is satisfied.We then lock in this match usinganother !.

Page 464: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

464CS 538 Spring 2008©

Finally we check if d(Y) can besatisfied with the binding of Yalready selected and locked in.

Page 465: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

465CS 538 Spring 2008©

When are Cuts Needed?A cut can be useful in improvingefficiency, by forcing Prolog toavoid useless or redundantsearches.Consider a query likemember(X,list1),member(X,list2), isPrime(X).

This asks Prolog to find an X thatis in list1 and also in list2 andalso is prime.X will be bound, in sequence, toeach value in list1. We thencheck if X is also in list2, andthen check if X is prime.Assume we find X=8 is in list1and list2. isPrime(8) fails (ofcourse). We backtrack tomember(X,list2) and resatisfy itwith the same value of X.

Page 466: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

466CS 538 Spring 2008©

But clearly there is never anypoint in trying to resatisfymember(X,list2). Once weknow a value of X is in list2, wetest it using isPrime(X). If itfails, we want to go right back tomember(X,list1) and get adifferent X.To create a version of memberthat never backtracks once it hasbeen satisfied we can use !.We definemember1(X,[X|_]) :- !.member1(X,[_|Y]) :- member1(X,Y).

Our query is nowmember(X,list1), member1(X,list2), isPrime(X).

(Why isn’t member1 used in bothterms?)

Page 467: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

467CS 538 Spring 2008©

Expressing NegativeInformation

Sometimes it is useful to staterules about what can’t be true.This allows us to avoid long andfruitless searches.fail is a goal that always fails. Itcan be used to represent goals orresults that can never be true.Assume we want to optimize ourgrandMotherOf rules by statingthat a male can never be anyone’sgrandmother (and hence acomplete search of all motherOfand fatherOf relations isuseless).A rule to do this isgrandMotherOf(X,GM) :- male(GM), fail.

Page 468: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

468CS 538 Spring 2008©

This rule doesn’t do quite whatwe hope it will!Why?The standard approach in Prologis to try other rules if the currentrule fails.Hence we need some way to “cutoff” any further backtracking oncethis negative rule is found to beapplicable.This can be done using grandMotherOf(X,GM) :- male(GM),!, fail.

Page 469: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

469CS 538 Spring 2008©

Other Extra-LogicalOperators

• assert and retract

These operators allow a Prologprogram to add new rules duringexecution and (perhaps) laterremove them. This allowsprograms to learn as theyexecute.•findall

Called as findall(X,goal,List)where X is a variable in goal. Allpossible solutions for X thatsatisfy goal are found and placedin List.For example,findall(X,(append(_,[X|_],[-1,2,-3,4]),(X<0)), L).

L = [-1,-3]

Page 470: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

470CS 538 Spring 2008©

• var and nonvar

var(X) tests whether X isunbound (free).nonvar(Y) tests whether Y is

bound (no longer free).These two operators are useful intailoring rules to particularcombinations of bound andunbound variables. For example,grandMotherOf(X,GM) :- male(GM),!, fail.

might backfire if GM is not yetbound. We could set GM to aperson for whom male(GM) istrue, then fail because we don’twant grandmothers who are male!To remedy this problem. we usethe rule only when GM is bound.Our rule becomesgrandMotherOf(X,GM) :- nonvar(GM), male(GM),!, fail.

Page 471: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

471CS 538 Spring 2008©

An Example of Extra-LogicalProgramming

Factorial is a very commonexample program. It’s well known,and easy to code in mostlanguages.In Prolog the “obvious” solution is:fact(N,1) :- N =< 1.

fact(N,F) :- N > 1, M is N-1, fact(M,G), F is N*G.

This definition is certainly correct.It mimics the usual recursivesolution.But,in Prolog “inputs” and “outputs”are less distinct than in mostlanguages.In fact, we can envision 4different combinations of inputs

Page 472: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

472CS 538 Spring 2008©

and outputs, based on what isfixed (and thus an input) andwhat is free (and hence is to becomputed):1. N and F are both ground (fixed).

We simply must decide if F=N!2. N is ground and F is free. Thisis how fact is usually used. Wemust compute an F such that F=N!3. F is fixed and N is free. This isan uncommon usage. We mustfind an N such that F=N!, ordetermine that no such N ispossible.4. Both N and F are free. Wegenerate, in sequence, pairs of Nand F values such that F=N!

Page 473: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

473CS 538 Spring 2008©

Our solution works forcombinations 1 and 2 (where N isfixed), but not combinations 3and 4. (The problem is that N =<1 and N > 1 can’t be satisfiedwhen N is free).We’ll need to use nonvar and ! toform a solution that works for all4 combinations of inputs.We first handle the case where Nis ground:fact(1,1).fact(N,1) :- nonvar(N), N =< 1, ! .fact(N,F) :- nonvar(N), N > 1, !,M is N-1, fact(M,G), F is N*G, ! .

The first rule handles the basecase of N=1.The second rule handles the caseof N<1.

Page 474: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

474CS 538 Spring 2008©

The third rule handles the case ofN >1. The value of F is computedrecursively. The first ! in each ofthese rules forces that rule to bethe only one used for the valuesof N that match. Moreover, thesecond ! in the third rule statesthat after F is computed, furtherbacktracking is useless; there isonly one F value for any given Nvalue.To handle the case where F isbound and N is free, we usefact(N,F) :- nonvar(F), !, fact(M,G), N is M+1, F2 is N*G, F =< F2, !, F=F2.

In this rule we generate N, F2pairs until F2 >= F. Then wecheck if F=F2. If this is so, wehave the N we want. Otherwise,no such N can exist and we fail(and answer no).

Page 475: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

475CS 538 Spring 2008©

For the case where both N and Fare free we use:fact(N,F) :- fact(M,G), N is M+1, F is N*G.

This systematically generates N, Fpairs, starting with N=2, F=2 andthen recursively buildingsuccessor values (N=3, F=6, thenN=4, F=24, etc.)

Page 476: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

476CS 538 Spring 2008©

Parallelism in PrologOne reason that Prolog is ofinterest to computer scientists isthat its search mechanism lendsitself to parallel evaluation.In fact, it supports two differentkinds of parallelism:• AND Parallelism

• OR Parallelism

Page 477: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

477CS 538 Spring 2008©

And ParallelismWhen we have a goal thatcontains subgoals connected bythe “,” (And) operator, we may beable to utilize “and parallelism.”Rather than solve subgoals insequence, we may be able tosolve them in parallel if bindingscan be properly propagated.Thus ina(X), b(X,Y), c(X,Z), d(Y,Z).

we may be able to first solvea(X), binding X, then solveb(X,Y) and c(X,Z) in parallel,binding Y and Z, then finally solved(Y,Z).

Page 478: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

478CS 538 Spring 2008©

An example of this sort of andparallelism ismember(X,list1), member1(X,list2), isPrime(X).

Here we can let member(X,list1)select an X value, then testmember1(X,list2) andisPrime(X) in parallel. If one orthe other fails, we just selectanother X from list1 and retestmember1(X,list2) andisPrime(X) in parallel.

Page 479: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

479CS 538 Spring 2008©

OR ParallelismWhen we match a goal we almostalways have a choice of severalrules or facts that may beapplicable. Rather than try themin sequence, we can try severalmatches of different facts or rulesin parallel. This is “or parallelism.”Thus given a(X) :- b(X).

a(Y) :- c(Y).

when we try to solvea(10).

we can simultaneously check bothb(10) and c(10).

Page 480: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

480CS 538 Spring 2008©

Recall our definition ofmember(X,L) :- append(P,[X|S],L).

where append is defined asappend([],L,L).

append([X|L1],L2,[X|L3]) :- append(L1,L2,L3).

Assume we have the query| ? member(2,[1,2,3]).

This immediately simplifies toappend(P,[2|S],[1,2,3]).

Now there are two appenddefinitions we can try in parallel:(1) match append(P,[2|S],[1,2,3])with append([],L,L). Thisrequires that [2|S] = [1,2,3],which must fail.(2) matchappend(P,[2|S],[1,2,3]) withappend([X|L1],L2,[X,L3]).

Page 481: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

481CS 538 Spring 2008©

This requires that P=[X|L1],[2|S]=L2, [1,2,3]=[X,L3].Simplifying, we require that X=1,P=[1|L1], L3=[2,3].Moreover we must solveappend(L1,L2,L3) whichsimplifies toappend(L1,[2|S],[2,3]).We can match this call to appendin two different ways, so orparallelism can be used again.When we try matchingappend(L1,[2|S],[2,3]) againstappend([],L,L) we get[2|S]=[2,3], which is satisfiableif S is bound to [3]. We thereforesignal back that the query is true.

Page 482: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

482CS 538 Spring 2008©

Speculative ParallelismProlog also lends itself nicely tospeculative parallelism. In thisform of parallelism, we “guess” orspeculate that some computationmay be needed in the future andstart it early. This speculativecomputation can often be done inparallel with the main (non-speculative) computation.Recall our example ofmember(X,list1), member1(X,list2), isPrime(X).

After member(X,list1) hasgenerated a preliminary solutionfor X, it is tested (perhaps inparallel) by member1(X,list2)and isPrime(X).But this value of X may berejected by one or both of these

Page 483: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

483CS 538 Spring 2008©

tests. If it is, we’ll askmember(X,list1) to find a newbinding for X. If we wish, this nextbinding can be generatedspeculatively, while the currentvalue of X is being tested. In thisway if the current value of X isrejected, we’ll have a new valueready to try (or know that noother binding of X is possible).If the current value of X isaccepted, the extra speculativework we did is ignored. It wasn’tneeded, but was useful insurancein case further X bindings wereneeded.

Page 484: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

484CS 538 Spring 2008©

Reading Assignment• Python Tutorial

(linked from class web page)

Page 485: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

485CS 538 Spring 2008©

PythonA modern and innovativescripting languages is Python,developed by Guido van Rossumin the mid-90s. Python is namedafter the BBC “Monty Python”television series.Python blends the expressivepower and flexibility of earlierscripting languages with thepower of object-orientedprogramming languages.It offers a lot to programmers:• An interactive development mode

as well as an executable “batch”mode for completed programs.

• Very reasonable execution speed.Like Java, Python programs arecompiled. Also like Java, thecompiled code is in an intermediate

Page 486: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

486CS 538 Spring 2008©

language for which an interpreteris written. Like Java this insulatesPython from many of the vagariesof the actual machines on which itruns, giving it portability of anequivalent level to that of Java.Unlike Java, Python retains theinteractivity for which interpretersare highly prized.

• Python programs require nocompilation or linking.Nevertheless, the semi-compiledPython program still runs muchfaster than its traditionallyinterpreted rivals such as theshells, awk and perl.

• Python is freely available on almostall platforms and operatingsystems (Unix, Linux, Windows,MacOs, etc.)

Page 487: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

487CS 538 Spring 2008©

• Python is completely objectoriented. It comes with a full set ofobjected oriented features.

• Python presents a first class objectmodel with first class functions andmultiple inheritance. Also includedare classes, modules, exceptionsand late (run-time) binding.

• Python allows a clean and openprogram layout. Python code is lesscluttered with the syntactic “noise”of declarations and scopedefinitions. Scope in a Pythonprogram is defined by theindentation of the code in question.Python thus breaks with currentlanguage designs in that whitespace has now once again acquiredsignificance.

Page 488: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

488CS 538 Spring 2008©

• Like Java, Python offers automatedmemory management through run-time reference counting andgarbage collection of unreferencedobjects.

• Python can be embedded in otherproducts and programs as a controllanguage.

• Python’s interface is well exposedand is reasonably small and simple.

• Python’s license is truly public.Python programs can be used orsold without copyright restrictions.

• Python is extendable. You candynamically load compiled Python,Python source, or even dynamicallyload new machine (object) code toprovide new features and newfacilities.

Page 489: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

489CS 538 Spring 2008©

• Python allows low-level access toits interpreter. It exposes itsinternal plumbing to a significantdegree to allow programs to makeuse of the way the plumbingworks.

• Python has a rich set of externallibrary services available. Thisincludes, network services, a GUIAPI (based on tcl/Tk), Web supportfor the generation of HTML and theCGI interfaces, direct access todatabases, etc.

Page 490: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

490CS 538 Spring 2008©

Using PythonPython may be used in eitherinteractive or batch mode.In interactive mode you start upthe Python interpreter and enterexecutable statements. Justnaming a variable (a trivialexpression) evaluates it andechoes its value.For example (>>> is the Pythoninteractive prompt):>>> 11

>>> a=1

>>> a1

>>> b=2.5

>>> b2.5

Page 491: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

491CS 538 Spring 2008©

>>> a+b3.5

>>> print a+b3.5

You can also incorporate Pythonstatements into a file and executethem in batch mode. One way todo this is to enter the commandpython file.py

where file.py contains thePython code you want executed.Be careful though; in batch modeyou must use a print (or someother output statement) to forceoutput to be printed. Thus1

a=1

a

b=2.5

Page 492: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

492CS 538 Spring 2008©

b

a+b

print a+b

when run in batch mode printsonly 3.5 (the output of the printstatement).You can also run Python programsas Unix shell scripts by adding theline#! /usr/bin/env pythonto the head of your Python file.(Since # begins Python comments,you can also feed the sameaugmented file directly to thePython interpreter)

Page 493: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

493CS 538 Spring 2008©

Python Command FormatIn Python, individual primitivecommands and expressions mustappear on a single line.This means that a = 1

+b

does not assign 1+b to a! Rather, itassigns 1 to a, then evaluates +b.If you wish to span more than oneline, you must use \ to escape theline:a = 1 \

+b

is equivalent toa = 1 +b

Page 494: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

494CS 538 Spring 2008©

Compound statements, like ifstatements and while loops, canspan multiple lines, but individualstatements within an if or while(if they are primitive) must appearone a single line.

Why this restriction?With it, ;’s are mostlyunnecessary!A ; at the end of a statement islegal but usually unnecessary, asthe end-of-line forces thestatement to end.You can use a ; to squeeze morethan one statement onto a line, ifyou wish:a=1; b=2 ; c=3

Page 495: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

495CS 538 Spring 2008©

Identifiers and Reserved WordsIdentifiers look much the same asin most programming languages.They are composed of letters,digits and underscores. Identifiersmust begin with a letter orunderscore. Case is significant. Asin C and C++, identifiers thatbegin with an underscore oftenhave special meaning.

Python contains a fairly typical setof reserved words:and del for is raiseassert elif from lambda returnbreak else global not tryclass except if or whilecontinue exec import passdef finally in print

Page 496: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

496CS 538 Spring 2008©

Numeric TypesThere are four numeric types:1. Integers, represented as a 32

bit (or longer) quantity. Digitssequences (possibly) signed areinteger literals:1 -123 +456

2. Long integers, of unlimitedprecision. An integer literalfollowed by an l or L is a longinteger literal:12345678900000000000000L

3. Floating point values, representedas a 64 bit floating point number.Literals are of fixed decimal orexponential form:123.456 1e10 6.0231023

Page 497: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

497CS 538 Spring 2008©

4. Complex numbers, represented asa pair of floating point numbers.In complex literals j or J is usedto denote the imaginary part ofthe complex value:1.0+2.0j -22.1j 10e10J+20.0

There is no character type. Aliteral like 'a' or "c" denotes astring of length one.

There is no boolean type. A zeronumeric value (any form), or None(the equivalent of void) or anempty string, list, tuple ordictionary is treated as false;other values are treated as true.Hence "abc" and "def"

is treated as true in an if, sinceboth strings are non-empty.

Page 498: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

498CS 538 Spring 2008©

Arithmetic OperatorsOp Description** Exponentiation+ Unary plus- Unary minus~ Bit-wise complement

(int or long only)* Multiplication/ Division% Remainder+ Binary plus- Binary minus<< Bit-wise left shift

(int or long only)>> Bit-wise right shift

(int or long only)& Bit-wise and (int or long only)| Bit-wise or (int or long only)^ Bit-wise Xor (int or long only)

Page 499: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

499CS 538 Spring 2008©

< Less than> Greater than>= Greater than or equal<= Less than or equal== Equal!= Not equaland Boolean andor Boolean ornot Boolean not

Page 500: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

500CS 538 Spring 2008©

Operator Precedence LevelsListed from lowest to highest:or Boolean ORand Boolean ANDnot Boolean NOT<, <=, >, >=, <>, !=, == Comparisons| Bitwise OR^ Bitwise XOR& Bitwise AND<<, >> Shifts+, - Addition and subtraction*, /, % Multiplication, division,

remainder** Exponentiation+, - Positive, negative (unary)~ Bitwise not

Page 501: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

501CS 538 Spring 2008©

Arithmetic Operator UseArithmetic operators may be usedwith any arithmetic type, withconversions automaticallyapplied. Bit-wise operations arerestricted to integers and longintegers. The result type isdetermined by the “generality” ofthe operands. (Long is moregeneral than int, float is moregeneral than both int and long,complex is the most generalnumeric type). Thus>>> 1+23

>>> 1+111L112L

>>> 1+1.12.1

>>> 1+2.0j

Page 502: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

502CS 538 Spring 2008©

(1+2j)

Unlike almost all otherprogramming languages,relational operators may be“chained” (as in standardmathematics).Therefore a > b > c

means (a > b) and (b > c)

Page 503: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

503CS 538 Spring 2008©

Assignment StatementsIn Python assignment is astatement not an expression.Thus a+(b=2)

is illegal.Chained assignments are allowed:a = b = 3

Since Python is dynamicallytyped, the type (and value)associated with an identifier canchange because of anassignment:>>> a = 0

>>> print a0

>>> a = a + 0L

>>> print a

Page 504: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

504CS 538 Spring 2008©

0L

>>> a = a + 0.0

>>> print a0.0

>>> a = a + 0.0J

>>> print a0j

Page 505: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

505CS 538 Spring 2008©

If and While StatementsPython contains if and whilestatements that are fairly similarto those found in C and Java.There are some significantdifferences though.A line that contains an if, else orwhile ends in a “:”. Thus wemight write: if a > 0:

b = 1

Moreover the indentation of thethen part is significant! You don’tneed { and } in Python becauseall statements indented at thesame level are assumed to be partof the same block.

Page 506: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

506CS 538 Spring 2008©

In the following Pythonstatementsif a>0:

b=1

c=2

d=3

the assignments to b and cconstitute then part; theassignment to d follows the ifstatement, and is independent ofit. In interactive mode a blank lineis needed to allow the interpreterto determine where the ifstatement ends; this blank line isnot needed in batch mode.

Page 507: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

507CS 538 Spring 2008©

The if StatementThe full form of the if statementisif expression:

statement(s)

elif expression:

statement(s)

...

else:

statement(s)

Note those pesky :’s at the end ofthe if, elif and else lines. Theexpressions following the if andoptional elif lines are evaluateduntil one evaluates to true. Thenthe following statement(s),delimited by indentation, areexecuted. If no expressionevaluates to true, the statementsfollowing the else are executed.

Page 508: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

508CS 538 Spring 2008©

Use of else and elif areoptional; a “bare” if may be used.If any of the lists of statements isto be null, use pass to indicatethat nothing is to be done.For exampleif a>0:

b=1

elif a < 0:

pass

else:

b=0

This if sets b to 1 if a is > 0; itsets b to 0 if a == 0, and doesnothing if a < 0.

Page 509: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

509CS 538 Spring 2008©

While LoopsPython contains a fairlyconventional while loop:while expression:

body

Note the “:” that ends the headerline. Also, indentation delimits thebody of the loop; no braces areneeded. For example,>>> a=0; b=0

>>> while a < 5:

... b = b+a**2

... a= a+1

...

>>> print a,b5 30

Page 510: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

510CS 538 Spring 2008©

Break, Continue and Else inLoops

Like C, C++ and Java, Pythonallows use of break within a loopto force loop termination. Forexample,>>> a=1

>>> while a < 10:

... if a+a == a**2:

... break

... else:

... a=a+1

...

>>> print a2

Page 511: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

511CS 538 Spring 2008©

A continue may be used to forcethe next loop iteration:>>> a=1

>>> while a < 100:

... a=a+1

... if a%2==0:

... continue

... a=3*a

...

>>> print a105

Page 512: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

512CS 538 Spring 2008©

Python also allows you to add anelse clause to a while (or for)loop.The syntax iswhile expression:

body

else:

statement(s)

The else statements areexecuted when the terminationcondition becomes false, but notwhen the loop is terminated witha break. As a result, you canreadily program “search loops”that need to handle the specialcase of search failure:

Page 513: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

513CS 538 Spring 2008©

>>> a=1

>>> while a < 1000:

... if a**2 == 3*a-1:

... print "winner: ",a

... break

... a=a+1

... else:

... print "No match"

...

No match

Page 514: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

514CS 538 Spring 2008©

Sequence TypesPython includes three sequencetypes: strings, tuples and lists. Allsequence types may be indexed,using a very general indexingsystem.Strings are sequences ofcharacters; tuples and lists maycontain any type or combinationof types (like Scheme lists).Strings and tuples are immutable(their components may not bechanged). Lists are mutable, andbe updated, much like arrays.Strings may be delimited by eithera single quote (') or a doublequote (") or even a triple quote(''' or """). A given string muststart and stop with the samedelimiter. Triply quoted stringsmay span multiple lines. There is

Page 515: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

515CS 538 Spring 2008©

no character type or value;characters are simply strings oflength 1. Legal strings include'abc' "xyz" '''It's OK!'''

Lists are delimited by “[“ and “]”.Empty (or null lists) are allowed.Valid list literals include [1,2,3] ["one",1] [['a'],['b'],['c']] []

Tuples are a sequence of valuesseparated by commas. A tuplemay be enclosed withinparentheses, but this isn’trequired. A empty tuple is (). Asingleton tuple ends with acomma (to distinguish it from asimple scalar value).Thus (1,) or just 1, is a validtuple of length one.

Page 516: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

516CS 538 Spring 2008©

Indexing Sequence TypesPython provides a very generaland powerful indexingmechanism. An index is enclosedin brackets, just like a subscript inC or Java. Indexing starts at 0.Thus we may have>>> 'abcde'[2]'c'

>>> [1,2,3,4,5][1]2

>>> (1.1,2.2,3.3)[0]1.1

Using an index that’s too bigraises an IndexError exception:>>> 'abc'[3]IndexError: string index out ofrange

Page 517: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

517CS 538 Spring 2008©

Unlike most languages, you canuse negative index values; thesesimply index from the right:>>> 'abc'[-1]'c'

>>> [5,4,3,2,1][-2]2

>>> (1,2,3,4)[-4]1

You may also access a slice of asequence value by supplying arange of index values. Thenotation isdata[i:j]

which selects the values in datathat are >=i and < j. Thus>>> 'abcde'[1:2]'b'

>>> 'abcde'[0:3]'abc'

Page 518: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

518CS 538 Spring 2008©

>>> 'abcde'[2:2]''

You may omit a lower or upperbound on a range. A missinglower bound defaults to 0 and amissing upper bound defaults tothe maximum legal index. Forexample,>>> [1,2,3,4,5][2:][3, 4, 5]

>>> [1,2,3,4,5][:3][1, 2, 3]

An upper bound that’s too large ina range is interpreted as themaximum legal index:>>> 'abcdef'[3:100]'def'

You may use negative values inranges too—they’re interpreted asbeing relative to the right end ofthe sequence:

Page 519: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

519CS 538 Spring 2008©

>>> 'abcde'[0:-2]'abc'

>>> 'abcdefg'[-5:-2]'cde'

>>> 'abcde'[-3:]'cde'

>>> 'abcde'[:-1]'abcd'

Since arrays may be assigned to,you may assign a slice to changeseveral values at once:>>> a=[1,2,3,4]

>>> a[0:2]=[-1,-2]

>>> a[-1, -2, 3, 4]

>>> a[2:]=[33,44]

>>> a[-1, -2, 33, 44]

Page 520: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

520CS 538 Spring 2008©

The length of the value assignedto a slice need not be the samesize as the slice itself, so you canshrink or expand a list byassigning slices:>>> a=[1,2,3,4,5]

>>> a[2:3]=[3.1,3.2]

>>> a[1, 2, 3.1, 3.2, 4, 5]

>>> a[4:]=[]

>>> a[1, 2, 3.1, 3.2]

>>> a[:0]=[-3,-2,-1]

>>> a[-3, -2, -1, 1, 2, 3.1, 3.2]

Page 521: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

521CS 538 Spring 2008©

Other Operations onSequences

Besides indexing and slicing, anumber of other useful operationsare provided for sequence types(strings, lists and tuples).These include:

+ (catenation):>>> [1,2,3]+[4,5,6][1, 2, 3, 4, 5, 6]

>>> (1,2,3)+(4,5)(1, 2, 3, 4, 5)

>>> (1,2,3)+[4,5]TypeError: illegal argumenttype for built-in operation

>>> "abc"+"def"'abcdef'

Page 522: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

522CS 538 Spring 2008©

• * (Repetition):>>> 'abc'*2'abcabc'

>>> [3,4,5]*3[3, 4, 5, 3, 4, 5, 3, 4, 5]

• Membership (in, not in)>>> 3 in [1,2,3,4]1

>>> 'c' in 'abcde'1

• max and min:>>> max([3,8,-9,22,4])22

>>> min('aa','bb','abc')'aa'

Page 523: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

523CS 538 Spring 2008©

Operations on ListsAs well as the operationsavailable for all sequence types(including lists), there are manyother useful operations availablefor lists. These include:• count (Count occurrences of an

item in a list):>>> [1,2,3,3,21].count(3)2

• index (Find first occurrence of anitem in a list):>>> [1,2,3,3,21].index(3)2

>>> [1,2,3,3,21].index(17)ValueError: list.index(x): xnot in list

Page 524: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

524CS 538 Spring 2008©

• remove (Find and remove an itemfrom a list):>>> a=[1,2,3,4,5]>>> a.remove(4)>>> a[1, 2, 3, 5]

>>> a.remove(17)ValueError: list.remove(x): xnot in list

• pop (Fetch and remove i-th elementof a list):>>> a=[1,2,3,4,5]>>> a.pop(3)4

>>> a[1, 2, 3, 5]

>>> a.pop()5

>>> a[1, 2, 3]

Page 525: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

525CS 538 Spring 2008©

• reverse a list:>>> a=[1,2,3,4,5]>>> a.reverse()>>> a[5, 4, 3, 2, 1]

• sort a list:>>> a=[5,1,4,2,3]>>> a.sort()>>> a[1, 2, 3, 4, 5]

• Create a range of values:>>> range(1,5)[1, 2, 3, 4]

>>> range(1,10,2)[1, 3, 5, 7, 9]

>>> range(10,1,-2)[10, 8, 6, 4, 2]

Page 526: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

526CS 538 Spring 2008©

DictionariesPython also provides a dictionarytype (sometimes called anassociative array). In a dictionaryyou can use a number (including afloat or complex), string or tupleas an index. In fact anyimmutable type can be an index(this excludes lists anddictionaries).An empty dictionary is denoted{ }.A non-empty dictionary may bewritten as{ key1:value1, key2:value2, ... }

For example,c={ 'bmw':650, 'lexus':'LS 460', 'mercedes':'S 550'}

Page 527: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

527CS 538 Spring 2008©

You can use a dictionary muchlike an array, indexing it usingkeys, and updating it byassigning a new value to a key:>>> c['bmw']650

>>> c['bmw']='M6'

>>> c['honda']='accord'

You can delete a value usingdel:>>> del c['honda']>>> c['honda']

KeyError: honda

Page 528: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

528CS 538 Spring 2008©

You can also check to see if agiven key is valid, and also listall keys, values, or key-valuepairs in use:>>> c.has_key('edsel')0

>>> c.keys()['bmw', 'mercedes', 'lexus']

>>> c.values()['M6', 'S 550', 'LS 460']

>>> c.items()[('bmw', 'M6'), ('mercedes', 'S 550'), ('lexus', 'LS 460')]

Page 529: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

529CS 538 Spring 2008©

For LoopsIn Python’s for loops, you don’texplicitly control the steps of aniteration. Instead, you provide asequence type (a string, list orsequence), and Pythonautomatically steps through thevalues.Like a while loop, you must endthe for loop header with a “:” andthe body is delimited usingindentation. For example,>>> for c in 'abc':

... print c

...

a

b

c

Page 530: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

530CS 538 Spring 2008©

The range function, whichcreates a list of values in a fixedrange is useful in for loops:>>> a=[5,2,1,4]

>>> for i in range(0,len(a)):

... a[i]=2*a[i]

...

>>> print a[10, 4, 2, 8]

Page 531: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

531CS 538 Spring 2008©

You can use an else with forloops too. Once the values in thespecified sequence are exhausted,the else is executed unless thefor is exited using a break. Forexample, for i in a:

if i < 0:

print 'Neg val:',i

break

else:

print 'No neg vals'

Page 532: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

532CS 538 Spring 2008©

SetsLists are often used to representsets, and Python allows a list (orstring or tuple) to be converted toa set using the set function:>>> set([1,2,3,1])set([1, 2, 3])

>>> set("abac")set([’a’, ’c’, ’b’])

>>> set((1,2,3,2,1))set([1, 2, 3])

Sets (of course) disallow duplicateelements. They are unordered(and thus can’t be indexed), butthey can be iterated throughusing a for:>>> for v in set([1,1,2,2,3,4,2,1]):

... print v,

1 2 3 4

Page 533: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

533CS 538 Spring 2008©

The usual set operators areprovided:

Union (|),Intersection (&),Difference (-)and Symmetric Difference (^, select members in either but

not both operands)>>> set([1,2,3]) | set([3,4,5])set([1, 2, 3, 4, 5])>>> set([1,2,3]) & set([3,4,5])set([3])>>> set([1,2,3]) - set([3,4,5])set([1, 2])>>> set([1,2,3]) ^ set([3,4,5])set([1, 2, 4, 5])

Page 534: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

534CS 538 Spring 2008©

List ComprehensionsPython provides an elegantmechanism for building a list byembedding a for within listbrackets. This a termed a ListComprehension.The general form is anexpression, followed by a for togenerate values, optionallyfollowed by ifs (to select or rejectvalues) of additional fors.In essence this is a proceduralversion of a map, without the needto actually provide a function tobe mapped.

To begin with a simple example,>>> [2*i for i in [1,2,3]][2, 4, 6]

Page 535: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

535CS 538 Spring 2008©

This is the same as mapping thedoubling function on the list[1,2,3], but without an explicitfunction.With an if to filter values, wemight have:>>> [2*i for i in [3,2,1,0,-1] if i != 0]

[6, 4, 2, -2]

We can also (in effect) nest for’s:[(x,y) for x in [1,2,3] for y in [-1,0] ]

[(1, -1), (1, 0), (2, -1), (2, 0), (3, -1), (3, 0)]

Page 536: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

536CS 538 Spring 2008©

Function DefinitionsFunction definitions are of theformdef name(args):

body

The symbol def tells Python thata function is to be defined. Thefunction is called name and argsis a tuple defining the names ofthe function’s arguments. Thebody of the function is delimitedusing indentation. For example,def fact(n):

if n<=1:

return 1

else:

return n*fact(n-1)

>>> fact(5)120

>>> fact(20L)

Page 537: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

537CS 538 Spring 2008©

2432902008176640000L

>>> fact(2.5)3.75

>>> fact(2+1J)(1+3j)

Scalar parameters are passed byvalue; mutable objects areallocated in the heap and henceare passed (in effect) by reference:>>> def asg(ar):

... a[1]=0

... print ar

...

>>> a=[1,2,3,4.5]

>>> asg(a)[1, 0, 3, 4.5]

Page 538: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

538CS 538 Spring 2008©

Arguments may be given a defaultvalue, making them optional in acall. Optional parameters mustfollow required parameters indefinitions. For example, >>> def expo(val,exp=2):

... return val**exp

...

>>> expo(3,3)27

>>> expo(3)9

>>> expo()TypeError: not enough arguments;expected 1, got 0

Page 539: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

539CS 538 Spring 2008©

A variable number of argumentsis allowed; you prefix the lastformal parameter with a *; thisparameter is bound to a tuplecontaining all the actualparameters provided by the caller:>>> def sum(*args):... sum=0... for i in args:... sum=sum+i... return sum...

>>> sum(1,2,3)6

>>> sum(2)2

>>> sum()0

Page 540: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

540CS 538 Spring 2008©

You may also use the name offormal parameters in a call,making the order of parametersless important:>>> def cat(left="[",body="",

right="]"):

... return left+body+right

...

>>> cat(body='xyz');'[xyz]'

>>> cat(body='hi there!' ,left='--[')'--[hi there!]'

Page 541: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

541CS 538 Spring 2008©

Scoping Rules in FunctionsEach function body has its ownlocal namespace duringexecution. An identifier isresolved (if possible) in the localnamespace, then (if necessary) inthe global namespace.Thus>>> def f():

... a=11

... return a+b

...

>>> b=2;f()13

>>> a=22;f()13

>>> b=33;f()44

Page 542: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

542CS 538 Spring 2008©

Assignments are to localvariables, even if a global exists.To force an assignment to refer toa global identifier, you use thedeclarationglobal id

which tells Python that in thisfunction id should be consideredglobal rather than local. Forexample,>>> a=1;b=2

>>> def f():

... global a

... a=111;b=222

...

>>> f();print a,b111 2

Page 543: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

543CS 538 Spring 2008©

Other Operations on FunctionsSince Python is interpreted, youcan dynamically create andexecute Python code.The function eval(string)interprets string as a Pythonexpression (in the currentexecution environment) andreturns what is computed. Forexample,>>> a=1;b=2

>>> eval('a+b')3

Page 544: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

544CS 538 Spring 2008©

exec(string) executes stringas arbitrary Python code (in thecurrent environment):>>> a=1;b=2

>>> exec('for op in "+-*/":print(eval("a"+op+"b"))')3

-1

2

0

execfile(string) executes thecontents of the file whosepathname is specified by string.This can be useful in loading anexisting set of Python definitions.

Page 545: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

545CS 538 Spring 2008©

The expressionlambda args: expression

creates an anonymous functionwith args as its argument list andexpression as it body. Forexample,>>> (lambda a:a+1)(2)3

And there are definitions of map,reduce and filter to map afunction to a list of values, toreduce a list (using a binaryfunction) and to select valuesfrom a list (using a predicate):>>> def double(a):

... return 2*a;

...

>>> map(double,[1,2,3,4])[2, 4, 6, 8]

Page 546: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

546CS 538 Spring 2008©

>>> def sum(a,b):

... return a+b

...

>>> reduce(sum,[1,2,3,4,5])15

>>> def even(a):

... return not(a%2)

...

>>> filter(even,[1,2,3,4,5])[2, 4]

Page 547: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

547CS 538 Spring 2008©

GeneratorsMany languages, including Java,C# and Python provide iteratorsto index through a collection ofvalues. Typically, a next functionis provided to generate the nextvalue and hasNext is used to testfor termination.Python provides generators, avariety of function (in effect a co-routine) to easily and cleanlygenerate the sequence of valuesrequired of an iterator.In any function a yield (ratherthan a return) can provide a valueand suspend execution. When thenext value is needed (by aninvisible call to next) the functionis resumed at the point of theyield. Further yields generatesuccessive values. Normal

Page 548: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

548CS 538 Spring 2008©

termination indicates thathasNext is no longer true.As a very simple example, thefollowing function generates allthe values in a list L except theinitial value:>>> def allButFirst(L):

... for i in L[1:]:

... yield i

>>> for j in allButFirst([1,2,3,4]):

... print j,

2 3 4

The power of generators is theirability to create non-standardtraversals of a data structure in aclean and compact manner.

Page 549: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

549CS 538 Spring 2008©

As an example, assume we wishto visit the elements of a list notin left-to-right or right-to-leftorder, but in an order that visitseven positions first, then oddpositions. That is we will first seeL[0], then L[2], then L[4], ...,then L[1], L[3], ...We just write a generator thattakes a list and produces thecorrect visit order:>>> def even_odd(L):... ind = range(0,len(L),2)

... ind = ind + range(1,len(L),2)

... for i in ind:

... yield L[i]

Then we can use this generatorwherever an iterator is needed:>>> for j in even_odd([10,11,12,13,14]):

... print j,

...10 12 14 11 13

Page 550: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

550CS 538 Spring 2008©

Generators work in listcomprehensions too:>>> [j for j in even_odd([11,12,13])]

[11, 13, 12]

Page 551: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

551CS 538 Spring 2008©

I/O in PythonThe easiest way to printinformation in Python is theprint statement. You supply alist of values separated bycommas. Values are converted tostrings (using the str() function)and printed to standard out, witha terminating new lineautomatically included. Forexample,>>> print "1+1=",1+11+1= 2

If you don’t want the automaticend of line, add a comma to theend of the print list:>>> for i in range(1,11):

... print i,

...

1 2 3 4 5 6 7 8 9 10

Page 552: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

552CS 538 Spring 2008©

For those who love C’s printf,Python provides a nice formattingcapability using a printf-likenotation. The expressionformat % tuple

formats a tuple of values using aformat string. The detailedformatting rules are those of C’sprintf. Thus>>> print "%d+%d=%d" % (10,20,10+20)

10+20=30

Page 553: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

553CS 538 Spring 2008©

File-oriented I/OYou open a file usingopen(name,mode)

which returns a “file object.”name is a string representing thefile’s path name; mode is a stringrepresenting the desired accessmode('r' for read, 'w' for write,etc.).Thus>>> f=open("/tmp/f1","w");>>> f<open file '/tmp/f1', mode 'w' atdecd8>

opens a temp file for writing.The command f.read(n)

reads n bytes (as a string).

Page 554: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

554CS 538 Spring 2008©

f.read() reads the whole file intoa string. At end-of-file, f.readreturns the null string:>>> f = open("/tmp/ttt","r")

>>> f.read(3)'aaa'

>>> f.read(5)' bbb '

>>> f.read()'ccc\012ddd eee fff\012g h i\012'

>>> f.read()''

f.readline() reads a whole lineof input, and f.readlines()reads the whole input file into alist of strings:>>> f = open("/tmp/ttt","r")

>>> f.readline()'aaa bbb ccc\012'

>>> f.readline()

Page 555: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

555CS 538 Spring 2008©

'ddd eee fff\012'

>>> f.readline()'g h i\012'

>>> f.readline()''

>>> f = open("/tmp/ttt","r")

>>> f.readlines()['aaa bbb ccc\012', 'ddd eeefff\012', 'g h i\012']

f.write(string) writes a stringto file object f; f.close() closesa file object:>>> f = open("/tmp/ttt","w")

>>> f.write("abcd")

>>> f.write("%d %d"%(1,-1))

>>> f.close()

>>> f = open("/tmp/ttt","r")

>>> f.readlines()['abcd1 -1']

Page 556: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

556CS 538 Spring 2008©

Classes in PythonPython contains a class creationmechanism that’s fairly similar towhat’s found in C++ or Java.There are significant differencesthough:• All class members are public.

• Instance fields aren’t declared.Rather, you just create fields asneeded by assignment (often inconstructors).

• There are class fields (shared by allclass instances), but there are noclass methods. That is, all methodsare instance methods.

Page 557: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

557CS 538 Spring 2008©

• All instance methods (includingconstructors) must explicitlyprovide an initial parameter thatrepresents the object instance. Thisparameter is typically called self.It’s roughly the equivalent of thisin C++ or Java.

Page 558: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

558CS 538 Spring 2008©

Defining ClassesYou define a class by executing aclass definition of the formclass name:

statement(s)

A class definition creates a classobject from which class instancesmay be created (just like in Java).The statements within a classdefinition may be data members(to be shared among all classinstances) as well as functiondefinitions (prefixed by a defcommand). Each function musttake (at least) an initial parameterthat represents the class instancewithin which the function(instance method) will operate.For example,

Page 559: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

559CS 538 Spring 2008©

class Example: cnt=1 def msg(self): print "Bo"+"o"*Example.cnt+

"!"*self.n

>>> Example.cnt1

>>> Example.msg<unbound method Example.msg>

Example.msg is unbound becausewe haven’t created any instancesof the Example class yet.We create class instances by usingthe class name as a function:>>> e=Example()

>>> e.msg()AttributeError: n

Page 560: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

560CS 538 Spring 2008©

We get the AttributeErrormessage regarding n because wehaven’t defined n yet! One way todo this is to just assign to it,using the usual field notation:>>> e.n=1

>>> e.msg()Boo!

>>> e.n=2;Example.cnt=2

>>> e.msg()Booo!!

We can also call an instancemethod by making the classobject an explicit parameter:>>> Example.msg(e)Booo!!

It’s nice to have data membersinitialized when an object iscreated. This is usually done witha constructor, and Python allowsthis too.

Page 561: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

561CS 538 Spring 2008©

A special method named__init__ is called whenever anobject is created. This methodtakes self as its first parameter;other parameters (possibly madeoptional) are allowed.We can therefore extend ourExample class with a constructor:class Example: cnt=1 def __init__(self,nval=1): self.n=nval def msg(self): print "Bo"+"o"*Example.cnt+ "!"*self.n

>>> e=Example()

>>> e.n1

>>> f=Example(2)

>>> f.n2

Page 562: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

562CS 538 Spring 2008©

You can also define the equivalentof Java’s toString method bydefining a member functionnamed __str__(self).For example, if we adddef __str__(self):

return "<%d>"%self.n

to Example,then we can include Exampleobjects in print statements:>>> e=Example(2)

>>> print e<2>

Page 563: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

563CS 538 Spring 2008©

InheritanceLike any language that supportsclasses, Python allows inheritancefrom a parent (or base) class. Infact, Python allows multipleinheritance in which a classinherits definitions from morethan one parent.When defining a class you specifyparents classes as follows:class name(parent classes):

statement(s)

The subclass has access to itsown definitions as well as thoseavailable to its parents. Allmethods are virtual, so the mostrecent definition of a method isalways used.

Page 564: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

564CS 538 Spring 2008©

class C: def DoIt(self): self.PrintIt() def PrintIt(self): print "C rules!"

class D(C): def PrintIt(self): print "D rules!" def TestIt(self): self.DoIt()

dvar = D() dvar.TestIt()

D rules!

Page 565: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

565CS 538 Spring 2008©

If you specify more than oneparent for a class, lookup isdepth-first, left to right, in the listof parents provided. For example,givenclass A(B,C): ...

we first look for a non-localdefinition in B (and its parents),then in C (and its parents).

Page 566: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

566CS 538 Spring 2008©

Operator OverloadingYou can overload definitions of allof Python’s operators to apply tonewly defined classes. Eachoperator has a correspondingmethod name assigned to it. Forexample, + uses __add__, - uses__sub__, etc.

Page 567: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

567CS 538 Spring 2008©

Givenclass Triple: def __init__(self,A=0,B=0,C=0): self.a=A self.b=B self.c=C def __str__(self): return "(%d,%d,%d)"% (self.a,self.b,self.c) def __add__(self,other):

return Triple(self.a+other.a,self.b+other.b,

self.c+other.c)

the following codet1=Triple(1,2,3)

t2=Triple(4,5,6)

print t1+t2

produces(5,7,9)

Page 568: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

568CS 538 Spring 2008©

ExceptionsPython provides an exceptionmechanism that’s quite similar tothe one used by Java.You “throw” an exception by usinga raise statement:raise exceptionValue

There are numerous predefinedexceptions, includingOverflowError (arithmeticoverflow), EOFError (when end-of-file is hit), NameError (when anundeclared identifier isreferenced), etc.

Page 569: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

569CS 538 Spring 2008©

You may define your ownexceptions as subclasses of thepredefined class Exception:class badValue(Exception):

def __init__(self,val):

self.value=val

You catch exceptions in Python’sversion of a try statement:try:

statement(s)

except exceptionName1, id1:

statement(s)

...

except exceptionNamen, idn:

statement(s)

As was the case in Java, anexception raised within the trybody is handled by an exceptclause if the raised exceptionmatches the class named in the

Page 570: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

570CS 538 Spring 2008©

except clause. If the raisedexception is not matched by anyexcept clause, the next enclosingtry is considered, or theexception is reraised at the pointof call.For example, using our badValueexception class, def sqrt(val): if val < 0.0: raise badValue(val) else: return cmath.sqrt(val)

try: print "Ans =",sqrt(-123.0)except badValue,b: print "Can’t take sqrt of",

b.value

When executed, we getAns = Can’t take sqrt of -123.0

Page 571: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

571CS 538 Spring 2008©

ModulesPython contains a module featurethat allows you to access Pythoncode stored in files or libraries. Ifyou have a source file mydefs.pythe command import mydefs

will read in all the definitionsstored in the file. What’s read incan be seen by executingdir(mydefs)

To access an imported definition,you qualify it with the name ofthe module. For example,mydefs.fct

accesses fct which is defined inmodule mydefs.

Page 572: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

572CS 538 Spring 2008©

To avoid explicit qualification youcan use the commandfrom modulename import id1, id2,...

This makes id1, id2, ... availablewithout qualification. Forexample,>>> from test import sqrt

>>> sqrt(123)(11.0905365064+0j)

You can use the commandfrom modulename import *

to import (without qualification)all the definitions in modulename.

Page 573: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

573CS 538 Spring 2008©

The Python LibraryOne of the great strengths ofPython is that it contains a vastnumber of modules (at leastseveral hundred) knowncollectively as the Python Library.What makes Python really usefulis the range of prewrittenmodules you can access. Includedare network access modules,multimedia utilities, data baseaccess, and much more.Seewww.python.org/doc/lib

for an up-to-date listing of what’savailable.

Page 574: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

574CS 538 Spring 2008©

Java 1.5/1.6 (Tiger Java)Java has been extended to includea variety of improvements, manydrawn from functional languages.Added features include:• Parametric polymorphism.

Classes and interfaces may beparameterized using a typeparameter.class List<T> {

T head;

List<T> tail;

}

Interfaces may also beparameterized.

• Enhanced loop iterators.for (v : myArray) {

// each element of myArray // appears as a value of v }

Page 575: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

575CS 538 Spring 2008©

• Automatic boxing and unboxing ofwrapper classes.

Conversion from int to Integeror Integer to int is nowautomatic.

• Typesafe enumerations.public enum Color {RED, BLUE, GREEN};

• Static imports. You may import all staticmembers of a class and use themwithout qualification. Thus youmay now write out.printlnrather thanSystem.out.println.

• Variable argument methods.

• Formatted output using printf:out.printf("Ans = %3d",a+b);

Page 576: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

576CS 538 Spring 2008©

Reading Assignment• Pizza Tutorial

(linked from class web page)

Page 577: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

577CS 538 Spring 2008©

C#C# is Microsoft’s answer to Java.In most ways it is very similar toJava, with some C++ conceptsreintroduced and some usefulnew features.Similarities to Java include:• C# is object-based, with all

objected descended from classObject.

• Objects are created from classesusing new. All objects are heap-allocated and garbage collection isprovided.

• All code is placed within methodswhich must be defined withinclasses.

• Almost all Java reserved wordshave C# equivalents (many areidentical).

Page 578: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

578CS 538 Spring 2008©

• Classes have single inheritance.

• C# generates code for a virtualmachine to support cross-platformexecution.

• Interfaces are provided to capturefunctionality common to manyclasses.

• Exceptions are very similar in formto Java’s.

• Instance and static data within anobject must be initialized at pointof creation.

Page 579: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

579CS 538 Spring 2008©

C# Improves Upon Some JavaFeatures

• Operators as well as methods canbe overloaded:class Point {

int x, y; static Point operator + ( Point p1, Point p2) { return new Point(p1.x+p2.x,

p1.y+p2.y); } }

• Switch statements may be indexedby string literals.

• In a switch, fall-throughs to thenext case are disallowed (if non-empty).

• Goto’s are allowed.

• Virtual methods must be marked.

Page 580: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

580CS 538 Spring 2008©

• Persistent objects (that may bestored across executions) areavailable.

Page 581: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

581CS 538 Spring 2008©

C# Adds Useful Features• Events and delegates are included

to handle asynchronous actions(like keyboard or mouse actions).

• Properties allow user-defined readand write actions for fields. You canadd get and set methods to thedefinition of a field. For example,class Customer {

private string name;

public string Name {

get { return name; }}

}

Customer c; ...

string s = c.Name;

Page 582: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

582CS 538 Spring 2008©

• Indexers allow objects other thanarrays to be indexed. The []operator is overloadable. Thisallows you to define the meaningofobj[123] or obj["abc"]within any class definition.

• Collection classes may be directlyenumerated:foreach (int i in array) ...

• Fields, methods and constructorsmay be defined within a struct aswell as a class. Structs are allocatedwithin the stack instead of theheap, and are passed by value. Forexample:

struct Point {

int x,y;

void reset () {

x=0; y=0; }

}

Page 583: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

583CS 538 Spring 2008©

• When an object is needed, aprimitive (int, char, etc.) or astruct will be automatically boxedor unboxed without explicit use ofa wrapper class (like Integer orCharacter). Thus if methodList.add expects an object, youmay writeList.add(123);

and 123 will be boxed into anInteger object automatically.

• Enumerations are provided:enum Color {Red, Blue, Green};

• Rectangular arrays are provided:int [,] multi = new int[5,5];

• Reference, out and variable-lengthparameter lists are allowed.

• Pointers may be used in methodsmarked unsafe.

Page 584: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

584CS 538 Spring 2008©

Version 3.0 of C# AddsAdditional Features

• Implicitly Typed Local Variables(Old form):int n = 5;

string s = "CS 538 rules!";

int[] nums =new int[] {1, 2, 3};

(New form):var n = 5;

var s = "CS 538 rules!";

var nums =new int[] {1, 2, 3};

Page 585: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

585CS 538 Spring 2008©

• Lambda Expressionsstring[] arr ={ "asdf", "pop", "crazy", "mine" };

var sorted =arr.OrderBy(e => e[e.Length-1]);

//sorted by last char in the string

• Object Initializers(Old form):Contact contact =new Contact();

contact.LastName = "Magennis";contact.DateOfBirth =new DateTime(1973,12,09);

(New form):Contact contact =new Contact { LastName = "Magennis", DateOfBirth =

new DateTime(1973,12,09)};;

Page 586: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

586CS 538 Spring 2008©

• Collection InitializersList<int> digits =new List<int> { 0, 1, 2,3, 4, 5, 6, 7, 8, 9 };

List<Contact> contacts = new List<Contact> { new Contact {

LastName = "Doherty",DOB = newDateTime(1989,1,1)},

new Contact {LastName = "Wilcox",DOB =new DateTime(1987,3,3)}

};

• Anonymous Typesvar anonType = new {X = 1, Y = 2};

Page 587: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

587CS 538 Spring 2008©

• Implicitly Typed ArraysOld:int[] a = new int[] { 1, 10, 100, 1000 };double[] b = new double[] { 1, 1.5, 2, 2.5 };string[] c = new string[] { "hello",null,"world"};

New:var a = new[] { 1, 10, 100, 1000 };var b = new[] { 1, 1.5, 2, 2.5 };var c = new[] {"hello", null,"world"};

• Automatic PropertiesOld:private string _name;public string Name{ get { return _name; } set { _name = value; }}

New:public string Name { get; set; }

Page 588: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

588CS 538 Spring 2008©

PizzaPizza is an extension to Javadeveloped in the late 90s byOdersky and Wadler.Pizza shows that many of the bestideas of functional languages canbe incorporated into a“mainstream” language, giving itadded power and expressability.Pizza adds to Java:

1. Parametric PolymorphismClasses can be parameterizedwith types, allowing thecreation of “custom” data typeswith full compile-time typechecking.

Page 589: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

589CS 538 Spring 2008©

2. First-class FunctionsFunctions can be passed,returned and stored just likeother types.

3. Patterns and Value ConstructorsClasses can be subdivided intoa number of valueconstructors, and patterns canbe used to structure thedefinition of methods.

Page 590: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

590CS 538 Spring 2008©

Parametric PolymorphismJava allows a form ofpolymorphism by definingcontainer classes (lists, stacks,queues, etc.) in terms of values oftype Object.For example, to implement alinked list we might use:

class LinkedList { Object value; LinkedList next; Object head() {return value;}LinkedList tail(){return next;}

LinkedList(Object O) { value = O; next = null;} LinkedList(Object O, LinkedList L){ value = O; next = L;}}

Page 591: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

591CS 538 Spring 2008©

We use class Object because anyobject can be assigned to Object(all classes must be a subclass ofObject).Using this class, we can create alinked list of any subtype ofObject.But,• We can’t guarantee that linked lists

are type homogeneous (containonly a single type).

• We must unbox Object types backinto their “real” types when weextract list values.

• We must use wrapper classes likeInteger rather than int (becauseprimitive types like int aren’tobjects, and aren’t subclass ofObject).

Page 592: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

592CS 538 Spring 2008©

For example, to use LinkedListto build a linked list of ints wedo the following:LinkedList L =

new LinkedList(new Integer(123));

int i = ((Integer) L.head()).intValue();

This is pretty clumsy code. We’dprefer a mechanism that allows usto create a “custom version” ofLinkedList, based on the typewe want the list to contain.We can’t just call something likeLinkedList(int) orLinkedList(Integer) because

types can’t be passed asparameters.Parametric polymorphism is thesolution. Using this mechanism,we can use type parameters to

Page 593: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

593CS 538 Spring 2008©

build a “custom version” of a classfrom a general purpose class.C++ allows this using its templatemechanism. Pizza also allowstype parameters.In both languages, typeparameters are enclosed in “anglebrackets” (e.g., LinkedList<T>passes T, a type, to theLinkedList class).In Pizza we haveclass LinkedList<T> { T value; LinkedList<T> next; T head() {return value;} LinkedList<T> tail() { return next;} LinkedList(T O) { value = O; next = null;} LinkedList(T O,LinkedList<T> L) {value = O; next = L;}}

Page 594: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

594CS 538 Spring 2008©

When linked list objects arecreated (using new) no typequalifiers are needed—the type ofthe constructor’s parameters areused. We can createLinkedList<int> L1 = new LinkedList(123);

int i = L1.head();

LinkedList<String> L2 = new LinkedList("abc");

String s = L2.head();

LinkedList<LinkedList<int> > L3 = new LinkedList(L1);

int j = L3.head().head();

Page 595: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

595CS 538 Spring 2008©

Bounded PolymorphismIn Pizza we can use interfaces tobound the type parameters aclass will accept.Recall our Compare interface:interface Compare {

boolean lessThan(Object o1, Object o2);

}

We can specify that aparameterized class will onlytakes types that implementCompare:class LinkedList<T implements

Compare> { ... }

Page 596: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

596CS 538 Spring 2008©

In fact, we can improve upon howinterfaces are defined and used.Recall that in method lessThanwe had to use parametersdeclared as type Object to begeneral enough to match (andaccept) any object type. Thisleads to clumsy casting (with run-time correctness checks) whenlessThan is implemented for aparticular type:class IntCompare implements Compare { public boolean lessThan(Object i1, Object i2){ return ((Integer)i1).intValue() < ((Integer)i2).intValue();}}

Page 597: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

597CS 538 Spring 2008©

Pizza allows us to parameterizeclass definitions with typeparameters, so why not do thesame for interfaces?In fact, this is just what Pizzadoes. We now define Compare asinterface Compare<T> { boolean lessThan(T o1, T o2);}

Now class LinkedList isclass LinkedList<T implements

Compare<T> > { ... }

Given this form of interfacedefinition, no casting (from typeObject) is needed in classes thatimplement Compare:class IntCompare implements

Compare<Integer> { public boolean lessThan(Integer i1,

Integer i2){ return i1.intValue() < i2.intValue();}}

Page 598: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

598CS 538 Spring 2008©

First-class Functions in PizzaIn Java, functions are treated asconstants that may appear only inclasses.To pass a function as a parameter,you must pass a class thatcontains that function as amember. For example,class Fct { int f(int i) { return i+1; }}class Test {static int call(Fct g, int arg)

{ return g.f(arg); }}

Page 599: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

599CS 538 Spring 2008©

Changing the value of a functionis even nastier. Since you can’tassign to a member function, youhave to use subclassing tooverride an existing definition:class Fct2 extends Fct { int f(int i) { return i+111; }}

Computing new functions duringexecutions is nastier still, as Javadoesn’t have any notion of alambda-term (that builds a newfunction).

Page 600: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

600CS 538 Spring 2008©

Pizza makes functions first-class,as in ML. You can have functionparameters, variables and returnvalues. You can also define newfunctions within a method.The notation used to define thetype of a function value is(T1,T2, ...)->T0

This says the function will takethe list (T1,T2, ...) as itarguments and will return T0 asits result.Thus(int)->int

represents the type of a methodlikeint plus1(int i) {return i+1;}

Page 601: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

601CS 538 Spring 2008©

The notation used by Java forfixed functions still works. Thusstatic int f(int i){return 2*i;};

denotes a function constant, f.The definition static (int)->int g = f;

defines a field of type (int)->intnamed g that is initialized to thevalue of f.The definitionstatic int call((int)->int f, int i) {return f(i);};

defines a constant function thattakes as parameters a functionvalue of type (int)->int and anint value. It calls the functionparameter with the int parameterand returns the value the functioncomputes.

Page 602: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

602CS 538 Spring 2008©

Pizza also has a notation foranonymous functions (functionliterals), similar to fn in ML andlambda in Scheme. The notationfun (T1 a1, T2 a2, ...) -> T0 {Body}

defines a nameless function witharguments declared as(T1 a1, T2 a2, ...) and a resulttype of T0. The function’s body iscomputed by executing the block{Body}.For example,static (int)->int compose( (int)->int f, (int)->int g){ return fun (int i) -> int {return f(g(i));};

}

Page 603: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

603CS 538 Spring 2008©

defines a method namedcompose. It takes as parameterstwo functions, f and g, each oftype (int)->int.The function returns a function asits result. The type of the result is(int)->int and its value is thecomposition of functions f and g: return f(g(i));

Thus we can now have a call likecompose(f1,f2)(100)

which computes f1(f2(100)).

Page 604: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

604CS 538 Spring 2008©

With function parameters, somefamiliar functions can be readilyprogrammed:class Map { static int[] map((int)->int f, int[] a){ int [] ans = new int[a.length]; for (int i=0;i<a.length;i++) ans[i]=f(a[i]); return ans; };}

Page 605: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

605CS 538 Spring 2008©

And we can make such operationspolymorphic by using parametricpolymorphism:class Map<T> { private static T dummy; Map(T val) {dummy=val;}; static T[] map((T)->T f,

T[] a){ T [] ans = (T[]) a.clone();

for (int i=0;i<a.length;i++) ans[i]=f(a[i]); return ans; };}

Page 606: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

606CS 538 Spring 2008©

Algebraic Data TypesPizza also provides “algebraicdata types” which allow a type tobe defined as a number of cases.This is essentially the pattern-oriented approach we saw in ML.A list is a good example of theutility of algebraic data types.Lists come in two forms, null andnon-null, and we must constantlyask which form of list wecurrently have. With patterns, theneed to consider both forms isenforced, leading to a morereliable programming style.In Pizza, patterns are modeled as“cases” and grafted onto theexisting switch statement (thisformulation is a bit clumsy):

Page 607: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

607CS 538 Spring 2008©

class List { case Nil; case Cons(char head, List tail); int length(){ switch(this){ case Nil: return 0; case Cons(char x, List t): return 1 + t.length(); } }}

Page 608: UW Computer Sciences User Pagespages.cs.wisc.edu/~fischer/cs538.s08/lectures/LectureAll.pdf · CS 538 Spring 2008 11 © Programming Languages to be Considered in Detail 1. Scheme

608CS 538 Spring 2008©

And guess what! We can useparametric polymorphism alongwith algebraic data types:class List<T> { case Nil; case Cons(T head, List<T> tail); int length(){ switch(this){ case Nil: return 0; case Cons(T x, List<T> t): return 1 + t.length(); } }}