Isaac Ibrahim Sadaqah -Notes
Principles of Programing Languages
Taught by- Daniel Scharstein
Grading
HW 60% 3 24 hours exceptions no questions asked
Quizzes 10% 1 every one or two weeks
Midterm 20% Wednesday 3/18 7:30pm
Final 30% Self-Scheduled
Principles of Programming Languages
Programming Languages Survey
Programming Languages Paradigms
- Procedural
- FORTRAN, ALGOL, BASIC, C, Pascal, Python
- OO
- Ada, C++, Java, C#, SmallTalk, Python
- Functional
- LISP {Common LISP, Dylan, Logo, Scheme }, Haskell, ML, Python
- Logic (declarative, based on mathematical logic)
- Scripting Languages (text processing, shells, HTML, CGI)
- awk (text processing, extracts patterns), Perl, Tcl/Tk, Python, PHP, Ruby
Monday Feb 9, 2009 Lecture #1- Why study programming languages
- As users
- know how to choose PL
- know useful programming constructs
- As designers
- understand the motivation; why a feature is present in one language and not the other.
- As implementers (compiler writer)
- All programming languages have universal computing power (equivalent to Turing machine)
- we are interested in practical power
- how easy to implement
- libraries
- how fast the language runs (trade off with the above 2)
- easy to compile
- platforms
- how easy to debug
Programming Language
| Pros
| Cons
|
Java
| platform independent garbage collector (frees memory)
| garbage collector (takes up time every time it runs)
|
C
|
| no objects not very safe
|
Ruby
| clean object oriented language interpreted/easy to use
| slow
|
Python
| everything is an object
| slow
|
BASIC
|
|
|
Scheme
|
| too many parenthesis
|
Tcl
|
|
|
PHP
|
|
|
Javascript
|
|
|
Matlab
|
|
|
Perl
|
|
|
SmallTalk
|
|
|
ML
|
|
| Prolog |
|
|
- Programming Linguistics
- Sapir-Wharf hypothesis
- Structure of languages define the boundaries of thought.
- applied to PL
- Language choice affects solutions you are likely to use.
- Trade offs we think about when choosing a language
- expressive power vs. safety
- pascal and Java are safe, everything is typed, you can not access things unsafely, but it is a pain to have to declare everything, or you may need to write a program that needs to change itself.
- implementation (building compiler) vs. usefulness
- what features to build into your language, LISP and Scheme look very similar, the language of scheme is the minimal subset of LISP, LISP has way too many features.
- Syntax: concise vs. clean syntax
- C vs. Java
- = assignment == equal/comparison
- PASCAL == assignment = equal
HW for Wed, Read Chapter 1
Wednesday Feb 11, 2009 Lecture #2
- Verbal Quiz on reading
- what is machine language?
- code, the language of 0s and 1s.
- what is assembly language?
- is English words that has one to one translation to machine code.
- what are the advantages of higher-level languages?
- portability/ machine independent
- readable
- concise
- how do you get back to machine code
- compiler
- read source code, compiles the whole thing.
- interpreter
- a program that keeps running, reads line by line and execute at the fly
- something like a CPU that understands JAVA,
- more flexible and interactive
- Syntax vs. Semantics
- Syntax: how it is written
- Semantics: what it means
- in Programming Languages
- different syntax
- true: Pascal, Java; 1: C; T: Lisp; .TRUE.: FORTRAN; #t: Scheme; True: Python;
= Pascal; ==: C, Java
a+b Java, Pascal, ...; (+ab) Lisp, Scheme; a b add: Postscript
- a = b+c;
a = b c + j syntax error
- different semantics
- Grammars
- context-free grammars CFGs
- set of Non-terminals N (Variables, args<program>)
- set of Terminals T (characters/symbols/keywords[if.. for])
- set of Productions (Rules e.g. NT::= [left-hand side: non-terminal, right-hand side: terminals/non-terminals])
- start symbol S belongs N (usually the left-hand side of the first rule)
- Example
- Grammar for Pascal
- <program>::= program <name>
<declarations> /<decls>
begin
<statements> / <stmts>
end. - <decls>::=<decl><decls> | <decls>
- Terminals: program, begin, end, .
- Final programs have no non-terminals
- <date>::=<month>/<day>/<year> | <day>" "<month>" "<year>
Terminals: / and " " (space)
<monthname>= Jan | Feb | ... | Dec
<year>=<d><d> | <d><d><d><d>
- Identifier
- a variable, method, ...etc name
- rules:
- letter, digits, underscore
- can not start with a digit
- <Ident>::= <letter>
::= <ident><char>
<char>::=<letter>|<digit>
<letter>::= _ | a | b | ..| z | A | ... | Z
<digit>::= 0 | 1 | ... | 9 - example: a3
<ident>--><ident><char>-->(from ident)<letter>--> a
-->(from char)<digit>-->3
- Abstract syntax tree
- 3-4+5
+ 5
- 4
3 - prefix: + - 3 4 5
- postfix: 3 4 - 5 +
- 3-4*5
- 3
* 5
4 - pre: - 3 * 4 5
- post: 3 4 5 * -
- E -> E + E | E- E | E * E | Num
HW#2: reading chapter 2 and hw on the web for next wednesdayhow is BNF more powerful than regular expressions?HW#1- Read Sethi Chapters 1 and 2. Sethi pp. 21-22, problems 1.1, 1.9
- Sethi pp. 49-52, problems 2.1, 2.2, 2.3, 2.4, 2.10, 2.11, 2.21
- Modify the context-free grammar for variables given in class to allow the following more general class of identifiers:
- Identifiers may contain uppercase letters, lowercase letters, digits, and the underscore symbol.
- Every identifier must contain at least one letter, either uppercase or lowercase.
- Every identifier must contain at least one uppercase letter or at least one digit.
- Neither the first nor the last character in an identifier may be an underscore, nor may there be two consecutive underscores.
Legal examples: Cost_1, cost_1, Cost, C_o_s_t, 1_c
Illegal examples:
cost (no uppercase letter or digit) _Cost (begins with an underscore) 1234 (no letters) 12__A (two consecutive underscores) - How much time did it take you to complete this assignment?
4. <ident>::= <letter> <lower_case> <ident><letter_><ident>::= (<upper_case> | <<char1>::= <upper_case> | <digit><char2>::= <lower_case><char_>::=<letter> | <digit> | <underscore><char>::= <letter> | <digit><letter>::= <upper_case> | <lower_case><letter_>::= <upper_case> | <lower_case> | <underscore> <upper_case>::= A | B | ... | Y | Z <lower_case>::= a | b | ... | y | z <underscore>::= _<digit>::= 0 | 1 | ... | 8 |9
Friday Feb 13, 2009 Lecture #3
- History of Programming Languages
- Punch Cards
- Jacquard looms
- cards with rows of holes that compose the design of the textile.
- Analytical engine (Charles Babbage and Ada Byron Lovelace) 1834
- Earliest known computer
- never fully built
- operations and variables on separate punch cards
- conditional jumps accomplished mechanically by physically jumping over a band of cards
- Collaborator Lady Ada Byron, Countess of Lovelace
- Babbage first computer scientist . Ada Byron first computer programmer
- US Census data (Herman Hallarith)
- Hand-coded machine language
- Assembly Language Programs
- Modern Language Programs.
- Von Neumann architecture 1945
- mathematician John von Neuman. Part of design og ENAC, one of the first electronic computers
- ..
- First Generation
- Second Generation (early 1950s)
- symbolic assemblers
- inter ...
- Third Generation (mid 1950s - present)
- High level, general-purpose
- Fortran, LISP, COBOL, ALGOL
- FORTRAN 1954
- designed at IBM to effeciently translate mathematical formulas into IBM 704 machine code. Wanted code at least as effecienct as hand coded.
- language based on variables.
- LISP 1958
- innovations on LISP
- the function as the basic program unit
- the list as the basic data structure
- dynamic data structures
- facilities for "garbage collection" of unused memory
- ....
- ALGOL
- designed by international team
- ALGOrithmatic Language
- Several Revisions
- ALGOL60 had profound influence on programming language design ...
- ....
- innovations on ALGOL60
- block structure and localized data environments
- nesting of program units
- free format program code
- explicit type declarations
- dynamic memory allocation
- paramater passing by value and by name
- COBOL
- US Dept of Defense wanted "common" PL for data processing
- CODASYL committee (Conference on Data Systems Languages)
- Result was COBOL in 1960 (COmmon Business-Oriented Language)
- Grace Hopper was involved in development and wrote 1st compiler ..
- ....
- innovations
- the record data structure
- file description and manipulation ..
- ...
- APL (early 1960s)
- A Programming Language
- Based on notation developed by Ken Iverson at Harvard 1957-1962
- Functional, interactive, science-oriented language that assumes the array as the default data structure
- ...
- BASIC
- Designed at Dartmouth in 1960s by Tom Kurtz, John Kemeny, and a successtion of undergraduates; first ran in 1964
- Beginner's All-purpose Symbolic Instructional Code
- intended to introduce students in non-scientific disciplines to computing
- influenced by FORTRAN AND ALGOL
- Major goal to simplify user interface
- Simplicity chosen over efficiency
- Time sharing over punching language
- PL/1 (1964)
- Planned and designed by IBM as an extesion to FORTRAN
- "Extension" departed from FORTRAN specs and was first released as NPL. Renamed PL/1 (Programming Language 1)
- ...
- innovations
- multitasking
- programmer ...
- ...
- ALGOL68
- ALGOL committee produced ...
- ...
- Pascal 1970
- Designed by Nikilaus Wirth
- member of ALGOL committee, he proposed a revision known as ALGOL-W in 1965)
- Pascal fir....
- C (1972)
- Designed by Kenneth Thmpson and Dennis Ritchie at Bell Labs in 1972
- Designed for coding the routines of the UNIX operating system.
- "High Level" systems programming language ...
- ....
- Ada
- Designed according to specifications developed by US Dept of Defense
- Requirements stressed structural programming methodology and readability over writibality
- Development period 1975-1985
- ...
- Ada, ....
- evolution
- begins with FORTRAN in 1954
- generation of high-level programming languages
- languages stress expressivity and machine independence
- Fourth Generation (1970-):
- specification languages, query languages, report generators, systems engineering
- Maple, Mathematica, Postscript, SPSS, SQL
- Fifth Generation (1980s - ):
- Solve problems using constraints rather than algorithms, used in artificial intelligence
- Konard Zuse's Plankalkul 1945
- Language for expressing computations
- not published until 1972
- anticipated many developments of programming languages
- arrays
- assertions
- algorithms for sorting, numerical computations, syntax analysis, and chess
- A family tree of languages
- 99 bottles of wine/ website
Monday Feb 16, 2009 Lecture #4
- Quiz 1
- Expression Grammars
- cont'd from Wednesday (Context-Free Grammars)
- E -> E + E | E * E | Id | Num
3+4*a
How?
E ==> E
OR
E
- Unambiguous expression grammar
- (expression) E -> E + T | E - T | T
(term) T -> T * F | T / F | F
(factor) F -> num | id | (E)
(precedence) from top to down - 3-4+5
E
E + T
E - T F
T F num
F num 5
num 4
3 - something like this:
+
- 5
3 4
- 3-(4*5)
E
E - T
E F
. ( E )
. T
. T * F
3 . .
4 5 - something like this
-
3 *
4 5
- Pascal
- starts with the word "program"
begin {main}
....
end {main}
- running ./name
- bottom-up declaration (order matters, any thing to be called in the begin end must be declared above.
- basics
- variable declaration:
var a: integer;
b,c: real;
- print on screen: writeln('...')
- division:
- / for float
- div for integers
- example
- program helllllo;
var a, i : integer;
b, c : real;
begin {main}
a := 3;
b := 5.5;
writeln('hello there!!!');
writeln('a = ', a, ' b = ', b);
for i := 3 to 10 do
begin
writeln('another line, i = ', i);
writeln('another line, i = ', i);
end;
end. {main}
- errors
- case insensitive (like html) - stay clean!
- semicolon is not required at the end
- QUESTIONS
Wednesday Feb 18, 2009 Lecture# 5
(* Type declarations *)
- basic types:
- integer
- real
- char
- boolean
- (String): was not in the original Pascal, but modern versions such as fpc (Free Pascal) has a string type and provides string methods
- declaring your own types
- Float = real
- enumerated types
- season = (Winter, Spring, Summer, Fall)
- they will be internally represented by integers (0,1,2,3)
- Subrange
- A subrange type is defined in terms of another ordinal data type. The type specification is:
- lowest_value .. highest_value
where lowest_value < highest_value and the two values are both in the range of another ordinal data type.
For example, you may want to declare the days of the week as well as the work week:
type
DaysOfWeek = (Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday);
DaysOfWorkWeek = Monday..Friday;
You can also use subranges for built-in ordinal types such as char and integer.
- Arrays:
- 1-D: http://www.taoyue.com/tutorials/pascal/pas5c.html
- examples
type
arraytype = array[1..50] of integer;
var
myarray : arraytype;
use:
for count := 1 to 50 do
read (myarray[count]);
Brackets [ ] enclose the subscript when referring to arrays
- myarray[5] := 6;
- multi-D
- you can define arrays of arrays instead of using multi-D arrays
- x.Name, x.Age .. gets the value
- OO grew from this ideas
- Defining a point type
- ipod=record;
x,y, real;
var p ipod;
px=25
VAR (* Variable declarations *)- something to do with change value of a global variable versus changing its value when it enters a function as a parameter.
(* Subprogram definitions *)BEGIN (* Executable statements *) - Functions and Procedures
- http://www.taoyue.com/tutorials/pascal/pas4c.html
END.
- maze prgram
- HW: game of life
Monday Feb 23, 2009 Lecture# 6
- grammar rules for pascal
- Figure 4.1 Types, using the syntax of Pascal p104
- Figure 3.3 BNF rules for statements using the syntax of Pascal p65
- Figure 5.9 Each procedure declaration is enclosed in a box, as is the whole program
- things are passed by value
- use var in front of the array in the parameters so it does not copy the whole thing and it just makes a reference.
- UNIX time command
- Pascal Pointers
- declaring a pointer
- var p,q: ^integer; --> mental image: a box that holds addresses of integer boxes
a: integer; --> allocates some space in the stack frame that is big enough to hold an integer. mental image [creates a box] - a:=5;
- new(p);
- p^:=7 ==> p has the address of a box that contains 7 in it.
- q:=p ==> copy what is in p into q, effect: q points to the same box that has 7 in it.
- new (p); ==> it will lose the current pointer and will have a new address of a new box that has an integer it. Effect: q's will also lose its point and will point to the new box, What happens to the box that is no longer pointed to by p and q? It will be collected by garbage collector
- dispose(p) Effect: q becomes a dangling pointer that points to something that has been de-allocated.
- Linked List
type
list = ^ elt
elt = record
val: integer
next:
end
- implement a stack using a linked list
- the whole idea. the last pointer will be nil
- CODE
var
stack: list;
procedure push (n integer);
var e.list
begin
new (e);
e^.val=n;
e^.next:=stack;
stack:=e;
end
function empty:boolean;
begin
empty:= (stack=nil);
end;
function pop:integer;
var e: list;
begin
pop:= stack^.val;
e:=stack; // [] is code for garbage disposal stack:=stack^.next;
dispose(e);
end
Wednesday Feb 25, 2009 Lecture #7
submit313, ~schar/bin/submit313
Friday Lunch: FYS algorithms- Parameter passing (5.2)
- call-by-reference
parameter is a pointer to actual parameter
procedure (var a: integer)
void p (int&a)
gives you more power, example: swap function directly
- call-by-value-result Ada
copy-in, copy-out
like call-by-reference, except ref is only modified at end
-> can produce different results
aliasing: multiple names for same location
example:
var i
proc p (x)
begin
i:=0
end
i:=2
p(i)
write(i)
- how this code is interpreted using different call methods?
- call-by-name Algol60
- textual substitution
proc swap (a, b)
var t
t:=a, a:=b, b:=t;
swap (x,y) will be translated as t:=x; x=y; y:=t
swap (i, A[i]) will be translated as t:=i; i:=A[i]; A[i]:=t (i has changed in the last A[i] so it will not give us the intended resluts)
C
#define SQR(x) (x*x)
a=SQR(b); will be translated as a=(b*b);
b=SQR(b+1); will be translated as a=(b+1*b+1)
how to avoid this? use parentheses ((x)*(x))
- Scopes (5.4)
- static/ lexical scope
- just by looking you can always know which declaration refer to which variable
- example:
var n
proc w
write(n)
proc D
var n
w
what happens if we change n to i in proc D? you will have a different effect.
conclusion: dynamic scopes that call by name like algol are not desirable, actually algol60 renames these names for you so to avoid this problem.
Friday Feb 27, 2009 Lecture #8
- Outline
- C (15.2, 4.8)
- Syntax, [types] like java
- no String type, instead an array of char (char[])
- not OO
- pure C, -ansi -pedantic
- old C, examples
- commenting '//' is not allowed
- mixed declaration of type
- declare stuff first, you can not have print'***' and then declare a new variable.
- you should get all the warnings
- pointers
- similar to Pascal, except that pointers in C can point to anything.
- int a; int *a;
p=&a; *p=5;
*p=5; p=5 - stimulating pass by reference in C [the trick is to pass the locations as values]
int a=1, b=2;
swap (&a, &b);
void swap( int *p, int *q)
{
int temp=*p;
*p= *q;
*q=temp;
}
- include <>, include ""
- advantage: splits code in different files
- the sub file, compile it using -c and it creates an object file that you can include somewhere else.
- ld -o *.o : link needed o files together
- if silly math was running slowly, turn -o -O optimization levels.
- debugging: -g
- gcc -o [output] -g [filename]
- useful for segmentation errors
- creates core file
- unlimit -c unlimited
- xemacs bash c
- gdb executable core
- use up/down
- ddb output core
- /* division.c
*
* Example for CS 313
*
* Daniel Scharstein
*
* to compile, use gcc -Wall -o division division.c
* to test for "pure" (ANSI) C, use -ansi - pedantic
*/
#include <stdio.h>
#include "sillymath.h"
int main ()
{
int a, b;
float c;
a = 5;
b = 3;
printf("Hi!\n");
c = quotient(a, b);
printf("FYI, %d/%d is %f\n", a, b, c);
return 0; /* success exit status */
}
isadaqah@wilson:/home/schar/cs313/C> more sillymath.c
float quotient(int a, int b) {
float c;
c = (float)a / (float)b;
return c;
}
- scanf is the opposite of printf
- scanf ("%d",&n)
- reads more than one token
- you have to have &, otherwise it will not read anything
- int[10]
- does 2 things at the same time
- in Java int a[] = int[10]
- an array and a pointer are the same
- int b[]; and int *c;
- neither has memory allocated
- graphically showed as two empty boxes
- a[5] is the same as *(a+5)
- 4 bits for each element of an array {side info}
- dispose = free
new = malloc
- header and body of a function
function p (n: ... ) <--- header
kjl
fdslfjs
^ body of function
Monday Mar 2, 2009 Lecture#9- struct fraction { int num; int dec }
- struct fraction r; <- declare
- struct elt { int val; struct elt* next; };
typedef struct elt * intlist; {means that intlist is a pointer to struct elt}
struct elt e;
intlist l;
e.val=3;
l=&e;
- intlist l;
l= (intlist)malloc(sizeof(struct elt)) {12 for bst}
l->val
l->next
- a string is an array of characters
- char *t; t[0]=h; t[1]='i'; t[2]='\0'
- segmentation error: because u have not allocated a space for t,
- it is like filling an array with values before initializing it.
- solution char t[10] or t=()malloc()
- strlen goes through the whole string whereas in java it's constant time operation, so calling strelen as a condition in a for loop is not effecient
- why is it dangerous?
the function has no way to know the length of s
if someone gives more than 1000 characters then it will over-write memory.
- Python
- dynamically typed interpreted
- everything is an object
- even integers carry a type around
- example:
a=3
print a
a="hi"
print a - no need to compile
- double quotes vs single quotes? why??
Wednesday Mar 4, 2009 Lecture# 10
- Python
- List
- you can assign something to a variable, say a={2,3,7}
- you can use ??length??
- you can access elements by a[i]
- once you have 2 lists, I can concatenate them using "con??"
- Python does not have a character type, it is actually a string of length 1
- implement game of life or connect 4:=> use list of lists.
- ??3x3 array, is an array of 3 references to the same link.??
- range : gives a list, and you can use it to iterate over a range of values in a for loop.
- ??for n=1 in range (1..10):???
- define a function: def
- how to iterate over rows and cols
- have one array and another and then add them to each other]
- Activation records Ch 5.5 5.6 5.2
- = storage for locals and params of procedures
- = stack frame for C, Pascal and other imperative languages
- stack frame:
params
|
locals
|
return address (location of a machine instruction)
|
registers
|
return value
|
frame pointer (location on stack) so to go back once done with the job.
|
- binding
- name -> declaration -> memory --------> value
printf(a) -> int -> if local: on stack }-> value
if global: somewhere else }
- python never have declaration!? False
- the first initialization of a variable is considered as declaration
- nested procedures in Pascal
- how does it look on the stack?
- see graph p 193, figure 5.25
- static declaration of a variable inside a function
- means that it will be used inside the function
- it will act as if it was global
Friday Mar 6, 2009 Lecture #11
- OO pardaigm (Ch 7)
- Principles
- modular decomposition
- data abstraction
- information hiding
- History:
- started when larger programs started to be written
- having all functions on the global level got messy
- functions were put around the data and called "methods"
- Elements:
- Class
- a blueprint that describes a set of object
- Object
- Instance Variable
- proprieties of an object that describes the object
- declared in the class
- Method
- functions of an object
- associated with the object
- types
- access-er methods: give information about the state of the object
- mutators: modifies the state of the object
- Message
- a method call: is a message
- calling a method === sending a message to the object
- Technical stuff
- most modern OO PLs have garbage collectors
- method constructors
- difference between java and c
- if you program in java and make everything static so u end up with something similar to java
- Inheritance:
- the superclass of everything is Object
- you make a class say Goo, Goo is a sub-class of Object
- if you create a new class SmartGoo that is a sub-class of Goo and Goo is a super-class of SuperGood
- this is done through "extends Goo"
- you can have access to tall methods
- Polymorphism
- same message can be sent to different objects.
- in a dynamically typed language like Python
- if I define the same method say "test()" in different classes, then if i have a variable x and then I say x.test()
- how to decide which test
- depending on the type of x
- how is a+b is polymorphic?
- it means:
- concatentation for strings
- operator overloading: the propriety that you can have different meanings to an operator depending on the type of objects
- Dynamic binding
- means that you dont know the type of an object until runtime
- OR: association of method object occurs at runtime
- Garbage Collection
- Java, Lisp, SmallTalk, Python, C#, ..
- NOT: C (free), Pascal(dispose), C++(delete)
- reaction inaccessible allocated storage
- eager approach
- uses reference counting
- each object keeps track of how many pointers are still pointed,
- when the last pointer disappears then you know that it no longer need to be accessed
- hence deallocate it
- send it to garbage when reference count reaches to 0
- examples: SmallTalk
- microsoft: image data type to keep track
- lazy approach
- let garbage accumulate
- and when there is a need it runs the garbage collector
- types
- mark and sweep
- goes through objects, mark them and then delete unmarked ones.
- takes time of the order of the size of the memory
- disadvantages
- puppy collector
- when memory runs out
- advantage
- order of allocated memory, but you have to copy it
- disadvantage
- if u do it only once memory runs out, it will take time to collect the garbage
- research static meanings?!?
- SmallTalk
- the first purely OO language
- Basics
- everything is an object
- even ints, booleans and classes
- very uniform
- in Java, for effeciency reasons, ints, booleans are not objects
- an Object's data (its instance variables)
- are always private
- in Java (public, private, ..) does not exist
- SmallTalk systems
- are interactive environments ??
- Object Hierarchy
- Object
- Magnitude: an value that has ordering on it
- Collection
- ...
- everything that starts with a capital letter is a Class
- Basic Types
- 3: Integer
- 41: Float
- $A: Characters
- 'Hello' String
- "Hello" Comment
- Other:
- #(3, 4.1, $X) array of 3 elements
- #apple: symbol
- Variables
- are not typed
- a:=3
- statement separators are periods (.)
- local variables (use | and |)
- | i |
i:=1
i<=10 while True: [
i print CR.
i := i+1.
] - optional
- methods
- 7 sign -> 1
- 4 sqrt -> 2
- 2 + 3 is read like this
- take 2 and send a message + 3 to it
- 2 + 10 * 3
- 2 send it the message +10 becomes 12
- 12 send it the message *3 and becomes 36
- #(3 4 5) at:1 -> 3
Monday Mar 9, 2009 Lecture #12
- Review
- 7+4*3-4//2
- because syntax is so uniform, they get rid of precedence rules.
- thus result would be14
- some operators
- 16 sqrt
- 3 max: 5 -> 5
- 3 max: 2 ->3
- 3 in Between: 2 and:5 -> true
- in Java: int x =3; return (x.inBetween (2,5));
- arrays
- a:= #(2,3,5,7,11)
- indexed starting at 1
- access: a at: 4 -> 7
- modify: a at 1 put: 10
- unary binds more strongly
- example: 3+4 sqrt is read 3 + (4 sqrt)
- so to express 7 sqrt in terms of 3 and 4 you must use paranthesis (3 + 4) sqrt
- capitalization
- set (class)
- set new -> new instance of a set???
- 3=4 (equal)
- 3==4 (identical) ---refers to the same reference
- difference between .equals and == in Java
- Blocks
- an if statement
- 3<4 if True:[ 10 ] if False:[ 3+5 ]
- [ ] more code could be put in the brackets
- i is optional
- if true it would return 10
- [ ... ] block (of code)
- example of a block
- for loop
- code:
(1 to: 10) do: [ :i | i printCR ]
b:=[:x :y | x+y]
b value:3 value:4 -> 7
#(10 11 12) A0: [:x | x printCR]
Wednesday Mar 11, 2009 Lecture#13 - smallTalk:
* sumUpTp
"return sum of num
* (1 to: 10) do: [ :x | x printCR ]
- output will show up in terminal
- Ctrl+P evaluates the value/ runs the script
* [ ] is a block
- a piece of code that is thrwon around like an object
- (1 to 10) do: [ :x | x printCR ]
* If statements
-(3 > 4) ifTrue: 'yes' ifFalse: #no
* Loops
- | i |
i := 0.
[i<=5] whileTrue: [ i printCR. i:=i+1]
* Loops vs. If statements
- the condition in if statemtement is ()
- the condition in loop is []
- blocks are not evaluated unless you add 'value' to them.
* ex. ([5>4] value)
- how [ i printCR. i:=i+1] and [ :x | x printCR ] differ?
* the first runs its on its own, does not need a parameter, all it needs is a local variable.
* the second needs a parameter.
* evaluation:
- for i:=0 ([ i printCR. i:=i+1] value ) will produce 1
- ([ :x | x printCR ] value:17) will print 17 (needs a parameter)
* classes
- let's write factorial
* new! gives a template
* 2 versions of factorial
- factIter
"returns the factorial of receiver (iterative version) "
| f |
f := 1.
(2 to: self) do: [:i | f := f * i].
^ f
- factRec
"returns the factorial of receiver (recursive version) "
factRec: i
self <= 1 ifTrue: [^ f]
ifFalse [^ self * ((self-1) factRec)] // can be written as self * (self-1) factRec
// why? because factRec is a unary operation
* what does (1 to: 10) mean?
evaluate: (1 to: 10) class
it gives: Interval
Interval: creates the loop when called, and this is maybe why it is more effecient to avoid it.
* Monday Homework
- Sieve
- primes upto: returns a primes
- use the class: ordered collections.
- create an array of 2 to upto
- do bunch of loops to implement it
- send the primes to an ordered collection
- Binary Search Tree
* Defining new classes
- myQueue
* Code
Object subclass MyQueue
>>" instance variables "
data " an ordered collection "
>>" class methods "
new
"returns new instance of class MyQueue"
| q |
q := super new.
q init
^ q
" shorter version "
^ super new init
>>" instance methods "
init
"initilizes the queue called by 'new'"
data = OrderedCollection new
|a i|
$A printCR.
a:=Array new: 4.
i:=1.
(1 to: a size-1) do: [:x| a at:x put:1.(a at:x)print].
(1 to: (a size)) do: [:x |
(x to: a size by:x+1) do: [
(x+1)print.
]
]
|a i|
a:=Array new: 13.
i:=1.
' ' printCR. ' ' printCR.
(1 to: a size) do: [:x| a at:x put:1].
(2 to: a size) do: [:y|(2*y to: a size by: y) do: [:x | a at: x put: 0].].
' ' printCR.
a select: [:y|y>0].
(x to: a size by:2) do: [
(x)print.
]
|a i|
a:=Array new: 12.
i:=1.
' ' printCR.
(1 to: a size-1) do: [:x| a at:x put:1.(a at:x)print].
(1 to: a size) do: [:y|(y+1 to: a size+1 by: y+1) do: [:x | a at: x put: 0].' ' printCR. (1 to: a size-1) do: [:z|(a at:z)print].].
*****
|a i r|
a:=Array new: 13.
i:=1.
' ' printCR. ' ' printCR.
(1 to: a size) do: [:x| a at:x put:1].
(2 to: a size) do: [:y|(2*y to: a size by: y) do: [:x | a at: x put: 0].].
' ' printCR.
"a select: [:y|y>0]."
"to be added"
r:= OrderedCollection new.
i:=0.
[ i<=a size do: [:z|
*****
|a i r|
a:=Array new: 14.
' ' printCR. ' ' printCR.
(1 to: a size) do: [:x| a at:x put:1].
(2 to: a size) do: [:y|(2*y to: a size by: y) do: [:x | a at: x put: 0].].
i:=1.
r:= OrderedCollection new.
[(a at: i)>0. i < a size] whileTrue: [r add:i. i := i+1.].
^r
/**** final ***/
|a i r|
a:=Array new: 10.
' ' printCR. ' ' printCR.
(1 to: a size) do: [:x| a at:x put:1].
(2 to: a size) do: [:y|(2*y to: a size by: y) do: [:x | a at: x put: 0].].
i:=1.
r:= OrderedCollection new.
(1 to: a size) do:[:c | ((a at: c)>0) ifTrue:[ r add:c.].].
^ r
OrderedCollection(1 2 3 5 7)
/***/
Friday Mar 13, 2009 Lecture#14
Object subclass:#MyQueue "want to specify a subclass from object"
instance VariableNames: 'data' "after telling object that such subclass exists, and will create MyQueue on the fly"
q->[data [nil]] "this big box is a graphical representation of MyQueue"
- implementing an intlist in smalltalk
ILE: IntList Element
[[-]-]-> [][-]->[][-]->[][/]
IntList ILE ILE ILE
head
is In-
side
intListElement (ILE)
val Integer
next ILE
// rest of code is on the website
- key differences, you can not call intList.next, like you can in Java and Python. this is because instance variables are private.
- way around this, is to create accessor methods.
/*******************************/
IntList / IntListElt
CS 313 Smalltalk linked list example
Also serves as an example for how you could organize your code for
the printed submission of homework 5 part 2.
Class IntListElt
================
Object subclass:#IntListElt
instanceVariableNames:'val next'
classVariableNames:''
poolDictionaries:''
category:'DanielsClasses'
Class methods
-------------
none (the accessor methods val: and next: will be used to initialize
the instance variables)
Instance methods
----------------
val: anInt
"set the value of the instance variable 'val'"
val := anInt.
val
"return the value of the instance variable 'val'"
^ val.
next: anIntListElt
"set the value of the instance variable 'next'"
next := anIntListElt.
next
"return the value of the instance variable 'next'"
^ next.
lengthR
"returns length of list (recursive version)"
"called by IntList's instance method lengthR"
(next == nil) ifTrue: [ ^ 1 ].
^ 1 + (next lengthR).
maxR
"returns maximum value in list (recursive version)"
"called by IntList's instance method maxR"
(next == nil) ifTrue: [ ^ val ].
^ val max: (next maxR).
Class IntList
=============
Object subclass:#IntList
instanceVariableNames:'head'
classVariableNames:''
poolDictionaries:''
category:'DanielsClasses'
Class methods
-------------
none ("new" will initialize "head" to nil, which is just what we want)
Instance methods
----------------
isEmpty
"returns whether list is empty"
^ (head == nil).
add: anInt
"inserts anInt at the head of the list"
| e |
e := IntListElt new.
e val: anInt.
e next: head.
head := e.
remove
"removes first element in the list and returns its value"
"assert: list not empty"
| v |
self isEmpty ifTrue: [self error: 'cannot remove from empty list'].
v := head val.
head := head next.
^ v.
length
"returns length of list"
| n e |
n := 0.
e := head.
[ e ~~ nil ] whileTrue: [
n := n + 1.
e := e next
].
^n.
lengthR
"returns length of list (recursive version)"
"most of the work is done by IntListElt's instance method lengthR"
self isEmpty ifTrue: [ ^ 0 ].
^ head lengthR.
max
"returns maximum value in list"
"assert: list not empty"
| m e |
self isEmpty ifTrue: [self error: 'cannot compute max of empty list'].
m := head val.
e := head next.
[ e ~~ nil ] whileTrue: [
(e val > m) ifTrue: [
m := e val
].
e := e next
].
^m.
maxR
"returns maximum value in list (recursive version)"
"all of the work is done by IntListElt's instance method maxR"
"assert: list not empty"
self isEmpty ifTrue: [self error: 'cannot compute max of empty list'].
^ head maxR.
Testing and sample output
=========================
|t| t:= IntList new.
'Testing IntList methods on list (0, 4, 2, 3)' printCR.
t add: 3. t add: 2. t add: 4. t add: 0.
'max: ' print. t max printCR.
'isEmpty: ' print. t isEmpty printCR.
'length: ' print. t length printCR.
'remove: ' print. t remove printCR.
'lengthR: ' print. t lengthR printCR.
'remove: ' print. t remove printCR.
'max: ' print. t max printCR.
'maxR: ' print. t maxR printCR.
'remove: ' print. t remove printCR.
'isEmpty: ' print. t isEmpty printCR.
'remove: ' print. t remove printCR.
'isEmpty: ' print. t isEmpty printCR.
output (produced using "doIt" on the code above):
-------------------------------------------------
Testing IntList methods on list (0, 4, 2, 3)
max: 4
isEmpty: false
length: 4
remove: 0
lengthR: 3
remove: 4
max: 3
maxR: 3
remove: 2
isEmpty: false
remove: 3
/*******************************************/
isEmpty: true
Monday March 16, 2009 Lecture#15
- SmallTalk Wrap-up
- check code on the web, for implementing a list.
- how to evaluate a block
- if it has an argument
- [:n | n printCR] value: 7 output: 7
- if it has more than one argument
- [:n :m | n printCR m printCR] value: 7 value:8
- if it does not have an argument
- OO programming in Python
- how to define classes in Python.
class Point:
pass # empty block to avoid error
p= Point ()
p.x = 7
p.y = 5
print p.x, p.y
q= Point ()
q.x = 3
q.y = 3
print q.x, q.y
but also:
q= Point ()
q.s = 3
q.t = 3
print p.s, p.t
would give the same output, it is only because you do not have to declare variables in Python, it is like saying
x =3
print x
and then saying
y =3
print y
- Methods (important to understand the mechanism, of passing self)
def myadd (x, y):
return x+y
class Point:
def setxy (self, myx, myy) :
self.x = myx
self.y = myy
p = Point()
p.setxy(3, 4) # what happens: setxy (p, 3, 4) -> gives error [provided 4 args instead of 3] self is a mandotary argument taken from before the period
self is not necassary, u can subtitute with any name in the class function
p.print p.x, p.y, myadd(p.x, p.y)
Output:
3 4 7
- Constructor methods
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p = Point (6, 7)
print p.x, p.y, myadd(p.x, p.y)
Output:
6 7 13
- get methods
def getx (self):
return self.x
Wednesday March 18, 2009 Lecture#16- look at some code and tell me what it outputs/ prints/ computes
- corresponding readings and compare them to notes
- More Python
- default values for initialization
class Point3(Point2)
def __init__ (self, x=0, y=0):
self.x = x
self.y = y
q = Point3 ( 12, 10 ) x= 12, y= 10
q = Point3 ( 10 ) x= 10, y=0
q = Point3 ( ) x=0, y=0
what if you want to leave x to default and y to something
q = Point3 ( y= 10)
- rectangle class
class rect:
def __init__ (self, x=0, y=0, w=0, h=0):
self.x = x
self.y = y
self.w = w
self.h = h
def __str__(self):
return "rect "%3d x %3d at %3d, %3d" % (self.w, self.h, self.x, self.y)
# if you run out of space and you have to use multiple lines then use paranthese to the whole expression or use \ at the end of the first line to let the complier know that the next line is part of this line.
return ("rect "%3d x %3d at %3d, %3d" % (self.w, self.h, self.x, self.y))
# sube class of rectangle
class Square (Rect{,DrawableObject}): #you can multiple inherent,but it's tricky
def __init__(self, x=0, y=0, size=0):
self.x = x
self.y = y
self.w = size
self.h = size
# testing code for Rect
a = Rect ()
b = Rect (20, 30)
c = Rect (100, 100, 30, 10)
# testing code for Square
d = Square(30, 40, 100)
print "d = %s, area
#print "a = %s\nb = %s\nc = %s" % ("hi", 34, 3.4)
print "a = %s\nb = %s\nc = %s" % (a, b, c)
# if str is not defined it will print the address of the rect in memory
# you can reserve space, just like in C %3s or %2d
- Tupals
>>(x, y) =(3, 4)
>>a =(x, y)
>>print a
(3, 4)
- importing
import rect # filename w/o .py
Class Square (rect.Rect):
print __name__
in rect: it will print __main__
if in the subclass (square) it will print: rect
you can exploit this to run code only if you are in the main class or only if you are in the subclass
if __name__ ="__main__":
- print
Wednesday March 18, 2009 Midterm
Friday March 20, 2009 Lecture#17- C not in pascal
- arbitrary memory access
- macro processors
- smalltalk not in Java
- dynamically typed
- everything is an object
- variables are private
- blocks
- in python not in c, pascal or java
- Functional Programming CH 8-11 {I slept in class, read from the book}
Spring Break
Monday March 30 Lecture#18HWs and midterm back, feedback.
- Scheme CH 10.1-3 15.6
- ( > 3 2)
- write in prefix
- #t : true
- #f: false
- define a max function
(define (max a b)
- more code
(define x 3)
x -> 3
(define f +)
(f 2 3) -> 5
((if #f + *) 3 4)
->12
- is not case sensitive
- it needs spaces between the arguments
- comparisons
=, >, <, >=, <=, not, and, or - not equal (!= or <>) is not an a operator
(define (ne a b)
(not (< a b))
(define (sign a)
(if (> a 0)
1
(if (< a 0)
-1
0)))
- cond, a generalized version of if
(define (sign a)
(cond (( > a 0) 1)
((< a 0) -1)
(else 0))
- Lists: basic data structure in scheme
- things are either lists or atoms
- atom
- booleans #t #F
- numbers 3 2.5
- symbols a b c
- how is list represented in memory
like a linked list
( a b c)
[a | -]--> [b | -]--> [c | / ]
*
/ \
a *
/ \
b *
/ \
c () <=== nil/empty list
- ( _ . _)
(a . (b . ( c . ())) === (a b c) - ( ( a b ) ( c ) d )
*
/ \
* *
/ \ / \
a * * *
/ \ / \ / \
b ( ) c () d () - car -> first element of par (head)
- cdr -> second element (tail, rest)
example: L = ( a b )
Tree representation
*
/ \
a *
/ \
b ()
( car L ) -> a
( cdr L) -> (b)
( cdr (cdr L)) -> ()
( car (cdr L)) -> b
Wednesday April 1, 2009 Lecture#19on my notebook
Friday April 3, 2009 Lecture#20
on my notebook
- rev. reverse
( define ( reverse x )
( if (null? x)
()
(append ( reverse (cdr x)
( list ( car x )))))
- rev. factorial
(define (fact n)
(if (= n 0)
1
(* n (fact ( - n 1))))) ;; * is a pending operation
- factorial using tail recursion
idea:
prod:=1 ;;product
cnt:=1 ;;count
while cnt<=n
cnt, prod:=cnt+1, cnt*prod
(define (fact2 n)
(define (iter prod cnt)
(if (> cnt n)
prod
(iter (* cnt prod)
(+ cnt 1))))
(iter 1 1))
- why this is more efficient? no pending operations (nothing is done after the recursion is done)
- scheme detects tail recursion and does not create a new stack frame, and basically pretends that there is a stack frame and just reuses the same stack frame.
- Fibonnaci numbers
- regular version
( define ( fib n )
( cond ( ( = n 0 ) 0 )
( ( = n 1 ) 1 )
( else ( + ( fib ( - n 1 ) )
( fib ( - n 2 ) ) ) ) ) ) )
- optimized version
idea:
n, b = 1, 0
repeat n times
a, b = a+b, a
^a
( define ( fib2 n )
( define ( iter a b cnt )
( if ( = cnt 0 )
a
( iter ( + a b )
a
( - cnt 1 ))))
(iter 1 0 n))
- Lists
3 -> 4 -> 2 -> 1 -> 7
how to reverse: cons the car into an empty list
( define ( rev2 x )
( define ( rev-iter a b )
( if ( null? a )
b
( rev-iter ( cdr a )
( cons ( car a ) b) ) ) )
( rev-iter x () ) )
- Higher-order functions
b
(sum sign) = i
i = a
( define ( sum-nums a b )
( if (> a b)
0
( + a (sum-nums (+ a 1) b ))) <-- this is not tail recursion
HW: make it tail recursive
- sum cubes
b
(sum sign) = i^3
i = a
( define ( sum-cubes a b )
( if ( > a b )
0
( + ( cube a ) ( sum-cubes ( + a 1) b))))
define ( cube x )
( * x x x ))
- more general
b
(sum sign) = f (i)
i = a
( define ( sum f next a b ) ;; f and next are functions ;; next gives the next arg
( if ( > a b)
0
( + ( f a)
(sum f next ( next a) b) )))
- more
( define ( add1 x )
( + x 1))
( sum cube add1 1 10)
( define ( sum-cubes a b)
( sum cube add1 a b ))
- anonymous functions (lambde)
like blocks in smalltalk
(lambda (x) (+ x 1))
( define (sum-cubes a b)
(sum ( lambda (x) (* x x x) ) ;; similar to a block
( lambda (x) ( + x 1) )
a
b ))
- function returns a new function
( define ( add-n-fn n )
( lambda (x) ( + x n ) )))
( define add7 ( add-n-fn 7 ))
__________________ testing ______________________
(add7 3 ) -> 10 === (( add-n-fn 3 ) 7 ) -> 10
- passing functions around can be handy:
( map f l )
;;applies f to each elt of l
( map add1 ( 2 3 7 9))
-> ( 3 4 8 10)
--- define map ----
( define ( map f l )
( if (null? l )
()
(cons ( f ( car l))
(map f (cdr l))))
Monday April 6, 2009 Lecture#21
missed class
Wednesday April 8, 2009 Lecture#22
Symbolic differentiation
given f(x), compute f'(x)
c' = 0
x' = 1
y ' = 0
1 - (f(x)+g(x))' = f'(x) + g'(x)
2 - (f(x)*g(x))' = f'(x)*g(x) + g(x)'*f(x)
3 - (x^n)' = n*x^(n-1) < on hw
implementation of 1
deriv1.scm
fancier version: deriv.scm
all methods
evaluation...
implementation of 2
implementation of 3
procedure application/evaluation order ch 8.4
( define (test a b)
(if (= a 0) 0 b)))
( test (+ 1 2 ) ( + 3 4))
question: param passing mechanism.
call-by-value & call-by-reference & call-by-value result are equav. in pure functional languages
and the reason is that there is no assignment. (define x 3) will make x=3 all the time. hence there is no changes on the data structures?
call-by-name?
WORKS UNTIL WE START GETTING : ERRORS? INFINITE LOOPS?
(def (p) (p)) ==> runs for ever but does not run out of stack space, because it runs tail recursion.
test ( 0 (p))
call-by-value -> infinite loop
call-by name -> returns 0
practical:
in scheme compiler
(test 0 p) -> returns 0 (test 0 (p))-> loops forever because it tries to evaluate (p) hopelessly
innermost evaluation
-
call-by-value
- application-order evaluation
- eager evaluation
The idea:
if you f (g (h(x),y))) -> you go from inside to outside
most languages use this-> including Scheme, ML, Java, C, Python
but it fails sometimes (returns an infinite loop) , where as call-by-name would not fail.
outermost evaluation
- call-by-name
- call-by-need
- normal-order eval
- lazy evaluation (example: (test 0 (p)) --> it would stop at 0 and returns it, no need to go any further.
Friday April 10, 2009 Lecture#23
ML
functional like scheme but typed
3 * 4 ;
-> val it = 12 = int
3 - 4;
-> val it = ~ 1 (~ uniary minus) = int
case sensitive
- basic types
- bool: true, false
- int: ~3, 0, 100, ...
- real: 0.0, 3.14
- string: "hello"
- char: #"a" #"\n"
- operations
- = < <=
- <> > >=
- = <> are not allowed on reals
- + - * [div mod] int
- [/] real
- strongly typed
- functions
- fun succ n = n + 1;
- -> val succ = f n : int -> int
fun diff ( x, y) = x - y; // diff takes 1 argument, and happened to be a tuple, this is not really two parameters.
val diff = fn: int*int -> int (int*int is a pair, like a tuple in python)
fun swap (x, y) = (y, x);
val swap = fn: 'a * 'b -> 'b * 'a
swap (1,2); -> (2,1) int*int
swap("hi",3.0) -> (3.0, "hi") real*string
diff (3,4) -> ~1
diff swap (3,4) -> 1
fun id x = x;
val id= fun: 'a -> 'a
fun abs n = if n>=0 then n else ~n
- tail recursive: no pending operations to happen after the end of the recursive call, you take the result of the last 1st order call.
- fib n =
if n = 0 orelse n=1 then 1
else fib (n-1)+fib(n-2)
boolean and = andelse
fun or (x, y) = if x then true else y <-- this is not short circuiting
orelse and andalso are short circuits
because ML uses call-by-value
Monday April 13, 2009 Lecture#24local variables and function ch 8.5
let val x = in x + x end;
let val x = E1 in E2 end;
let val x = 3
val y = x + 1
in
y + 1
end;
like let* in shceme
(sequential)
val x = 4;
val y = 5;
let val (x, y) = (2*y, x)
in ... end
____________________
let fun S x = x +1
in S(S 2) end; -> 4
let fun even x =
x<>1 andalso ( x = 0 orelse even(x-2))
in
even (8) -> true
end;
lists 9.1
[1, 2, 3];
val it = [1, 2, 3] : int list
scheme
| ML
|
(null? x)
| null x
|
(car x)
| hd x
|
(cdr x)
| tl x
|
(cons a x)
| a::x
|
()
| [], nil
|
length function
fun len x =
if null x
then 0
else 1 + len (tl x);
val len = fn: 'a list -> int
_________________ ____________________
type
________________ _____________________
[3.0, 4.0] real list
[] 'a list
[3, 5] 3 consed infront of 5 consed infront of 5
append function
fun append a b =
if null a then b
else (hd a)::append (tl a, b);
fun reverse x =
let fun rev(a. b) =
if null a then b
else rev(tl a, (hd a)::b)
fun def n by cases
len [] -> 0
len [] (a::b) -> 1 + len b
fun len [] = 0
| len (a::y) = 1 + len y;
fun append ([], z) = z
| append (a, y, z) = a::append (y, z);
fun sumlist [] = 0
| sumlist (a::y) = a + sumlist y;
tail recursive:
fun sumlistZ z =
let fun sl([], result) = result
| sl(a::y, result) = sl (y, at result)
Wednesday April 15, 2009 Lecture#25
- 1::[2];
val it = [1,2]: int list
- [[1], [2, 3]];
val it = [[1], [2,3]] : int list list
- []
val it = []: 'a list
- [[]]
val it = [[]]: 'a list list
- fun rev2 [] = []
= | rev2 (a::y) = rev2 y @ [a]
- fun fact 0 = 1
= | fact n = n * fact (n-1);
val fact = fn : int -> int
???
- fn sl [] = (0, 0.0)
= | sl ((a,b)::y) = let (xi, xr) = sl y in (a +xi, b+xr) end;
???
Data Types 9.5
datatype gender = female | male;
val x = male;
datatype person = Person of gender * int;
val bill = Person (male, 20)
datatype intlist = Elt of int * intlist
| End;
val x = Elt (1, Elt (2, End)); // like [1, 2]
fun sumintlist End = 0
| sumintlist Elt ( a, y) = a + sumintlist y;
datatype la mylist = Elt of 'a * 'a mylist
| End;
val y = Elt ( "hi", End );
string mylist
datatype bst = Empty
| node of (int * bst * bst)
fun leaf n = Node (n, Empty, Empty);
val t = Node (3, Node (1, Empty, leaf(2)), leaf(4));
3
/ \
| 4
\
2
higher order functions 9.3
fun square (x:real) = x*x
val square = fn: real -> real
map square [2.0, 3.0, 1.2];
val it = [4.0, 9.0. 1.44]: real list
fun mymap (f, []) = []
| mymap (f, a::y) = f(a) :: mymap (f, y);
val mymap = fn : ('a -> 'b) * 'a list -> 'b list
test mymap
mymap (~, [1, ~2, 3]);
val it = [~1, 2, ~3]: int list
mymap ( fn x => x+x, [1.0, 2.0])
fun add x y = x+y;
val add = fn: int -> int -> int
Curried Functions
fun x y = x+y;
val add = fn int -> (int -> int)
Friday April 17, 2009 Lecture#26
val (a, b) = x
#1 x = a
#2 x = b
fun f x = (print "function f called "; x+x);
Output:f 3
function f call val it = 6 fn: int ? not sure?
curried functions
fun add x y = x+y;
fn: int -> int-->int
Output:
add 3 4
->7
val f = add 3;
->partially instantiated function.
f 2 -> 5
val p = [2, 3, 5, 7];
map f p; // val f = add 3 //from above
-> [ 5, 6, 8, 10];
fun map f [] = []
| map f (a y) = (f A)::map f y
type of map: ('a -> 'b) -> 'a list --> 'b list
filter even p ;
-> 2
filter (fn x -> not even x) p
-> [3, 5, 7]
fun filter f [] = []
| filter f (a::y) = if (f a) then a::(filter f y) else filter f y;
type of f : 'a -> bool
type of []. (a::y) : 'a list
type of filter: ('a -> bool) -> 'a list -> 'a list
reduce
p = [2, 3, 5, 7]
reduce add p; -> 17
fun reduce add p;
fun reduce f[a] = a
|reduce f (a::y) =
('a*'a -> 'a) -> 'a list --> 'a
=f
the role of the environment
difference between defining the value and the assignment
x=7 and then x=3; creates a new binding the stack
____________
| x = 3 |
____________
| x = 7 |
| |
| |
| |
functional python
python supports list, but they are not the same thing as in ML
>>> p = [2, 3, 5, 7, 11, 13]
they are implemented as arrays, so we have constant access to any element
>>> p[0]
2
>>> p [1:3]
[3, 5]
>>> p [1:5]
[3, 5, 7, 11]
>>> p[:2]
[2, 3]
>>> p[-1]
13
>>> p[:-2]
[11, 13]
map, reduce, filter are already defined in python
>>> def sq(x): return x*x
>>> map (sq, p)
[4, 9, 25, 49, 121, 169]
>>> def even(x): return x%2==0
>>> map (even, p)
[True, False, False, False, False, False]
>>> filter (even, p)
[2]
>>> lambda x, y: x+y
>>> filter (lambda x:not even (x), p);
[3, 5, 7, 11, 13]
>>> reduce (add, p)
41
* third argument is the start value
>>> reduce (add, [1, 2], 0)
3
>>> reduce (add, [1, 2], 10)
13
>>> reduce (add, [1], 10)
11
>>> reduce (add, [], 10)
10
>>> reduce (add, [], 0)
0
>>> reduce (lambda x, y: x*y, p)
30030
something cool
*equavelant for a map
>>> [x*x for x in p]
[4, 9, 25, 49, 121, 169]
*equavelant to a filter
>>> x*x for x in p if x%2 == 0]
[4]
>>> x*x for x in p if even(x)]
[4]
Monday April 20, 2009 Lecture#27f(x) = x + 3
g(x) = x^2
in math f.g (x) = f(g(x)) x^2 + 3
fun comp f g x = f (g(x));
fun sq x = x * x;
fun p3 x = x+3;
val h = comp p3 sq;
partial insintiation because you provided only 2 arguments.
- Logic Programming
- ideas:
- a program = a set of logic statements
- program execution = controlled deduction (search)
- "Alg = logic + control"
- -> "static" view of programming.
- Advantages
- Disadvantages
- easy to overlook how the solution to be found, and you might find inefficient answers.
- Applications
- in AI
- expert systems
- relational databases
- NL understanding
- Theorem proving
- Planning
- Prolog = Programming in Logic
- Three Parts
- Declare facts
- Declare rules
- Ask questions
- facts, rules and questions are about objects and their relationships.
- example
Facts
- Jen & Lav are sisters
- Elliot loves ice-cream
Rules
- 2 people are sisters if there both females and if they have the same parents
Questions
- in Prolog
Facts:- Likes (elliot, icecream)
- valuable(gold)
- parents (malia, michelle, barrack)
- kingOf (john, UK)
_______________________________________ - (likes, gold, ... ) -> atoms (start with lower case letter)
- a(b, c) -> compound terms (predicates)
Rules
- bird (X) :- animal (x), has_feather(x).
- X: variable
- :- : if
- , : and
- sister Of(X, Y):-
female (X),
parents (X, M, F),
parents (X, M, F).
Questions/Queries
- ? - valuable (gold).
- ?: prompt
- -> yes /true or -> no/false
put facts, rules into myprog.pl
> pl
?- consult (myprog). or [myprog].
Wednesday April 22, 2009 Lecture#28
order of facts matters
; ==> search for more answers
enter ==> finish search
numbers
?- x = 2+3
-> x = 2+3
?- x is 2+3
-> x = 5
operators: + - * /
= means unify
\= means don't unify
a(b,c) = a(c,b)
compares structure
computes numbers
< =<
> >=
2+3<3+3
Example:
6 4 4 5
puzzles
0 1 3 8
4 4 5 2
7 0 7 5
7 4 7 9
prolog lists
[2,3,a, b(c,d),[2,1]]
[]
[1,2] = .(1, .(2,[]))
access list elements
?- use pattern matching: [H|T] = [1,2,3]
H:= 1
T:= [2,3]
member (X, L)
(L=[] -> false) // no need to code because prolog returns false whenever can not find solution
L = [H|T], H= X
code:
member (X,L):- L = [H|T], H=X.
member (X,[H|T]):- H= X.
member (X,[X|_]),
member (X,[_|T]):-
member (X,T);
Friday April 24, 2009 Lecture#29
[2, abc, 7] = [ X | Y].
X = 2
Y = [abc, 7].
member ( X , [X|_] ).
member (X, [_ | T]):- member (X, T)
?- member (3, [3, 4, 5]).
true.
?- member (4, [3, 4, 5]).
true
?- member (X, [3, 4, 5]).
X = 3 ;
X = 4;
X = 5;
false.
?- member (4, X).
... Generate lists of X
append
append ([], Y, Y ).
append ([X|T], Y, [X|Z]) :- append (T, Y, Z).
flatten
reverse
reverse ( [], [] )
reverse ( [H|T], R):-
reverse ( T, RT),
append (RT, [H], R).
_____________________________________________
"tail-recursive" ("iterative" version)
reverse (X, RX) :- reverse ( X, [], RX)
reverse/2 reverse/3
^ ^
| |
**********************
|
different predicates
reverse ( [] , Res , Res ).
/* if x is [] return res */reverse ( [H|T], Res, RX):-
reverse (T, [H | Res], RX).
matching element list
built-in:
delete (List, Elt, Result).
//removes all elements that match Elt our definition
rm (X, [X | T], T).
rm (X, [], []).
rm (X, [H | T], [H | R]) :- rm (X, T, R).
length
length ( [], 0).
length ( [H|T], N) :-
length (T, M),
N is M +1.
"is" goes from right to left, (N is M +1) === (M +1 = N)
BST
Monday April 27, 2009 Lecture#30x=1+1, x is 2 => fails
x=2, x is 1+1 => succeeds
"is" is left to right and this is why the above happens.
delete
root -> nil
root w/ left only -> left
root w/ right only -> right
root w/ left and w/ right -> find predecessor and make it root.
left of predecessor becomes in place of old predecessor
Prolog execution model.
- depth-first search of the goal tree.
- goal order
- rule order
a(1)
a(X)-b(X).
a(2).
b(3).
b(4).
c(3).
?- a(X),..
finds all matching goals of this subgoal "a(X)"
matches are:
a(1) at X=1
b(X) at X=X
b(3) at X=3
b(4) at X=4
a(2) at X=2
if we have another subgoal: say "c(X)"
so we have: a(X), c(X).
we "and" c(X) at all case.
matches are:
a(1)c(1) at X=1
b(X),c(X) at X=X
b(3),c(3) at X=3
b(4),c(4) at X=4
a(2),c(2) at X=2
- hit ";" for more answers.
- c(X),a(X) is much shorter as we only have c(3)
- order of subgoals matter, and order of terms also matter but less. because order of subgoals determines which path/branch to take first. and order of terms determines the permutations within each branch. so it is more important to have a subgoals order that is efficient.
- another example
member(X,[X|_]).
member(X,[_|T]):- member(X,T).
?- member(X, [1,2,3])
Analysis of execution:
at X=1: member(1, [1|[2,3]]) -> true
at X!=1: member(X, [2,3])
at X= 2: member(2,[2|[3]]) -> true
at X!=2: member(X,[3])
at X=3: member(3,[3]) -> true
at X!=3: fails
- Unification
- an instance of a term is the term where (some) variables are replaced by values (subterms)
- instance of g(x) :a(b) or a(b(1)) or ...etc
- instance of b(Y,Y): b(c,c) or b(a(1,2), a(1,2)) or ..etc
- instance of X: a or b(1) or X or Y or ...etc
- two terms unify if they have a common instance
- a(Y) ?= a(c) ---> yes: a(c)
- f(a, X) ?= f(Y,b) ---> yes: f(a,b)
- a(Y) ?= Z ---> yes: a(1) or a(c) or a(Y) <- a(Y) is the most general unifier
- a(X, b(X)) ?= Z -->yes
- a(X, b(X) ?= a(1, b(1)) --> yes: a(1, b(1))
- a(X, b(X) ?= a(Z, b(Z)) --> yes
- a(X, b(X) ?= a(Z,Z) -> no (there is no b(z)= z it will loop forever b(b(z))= z and b(b(b(z)))=z ..etc
- [H|T] ?= [1,H] --> yes [1,1]
- Substitution
- sigma: fn vars->terms
- e.g.
- sigma = { X->f(3), Y->[2,3]}
- Tsigma -> apply sigma to T
- [Z|Y]sigma = [Z, 2,3]
- f(x)sigma=f(f(a))
- U is instance of T
- if U=Tsigma for some sigma
- T1 and T2 unify
- if T1sigma=T2sigma for some sigma
Wed April 29 2009 Lecture#31- Control in Prolog ?? (Ch 11.5)
- starts with query as current goal G call visit(G)
- visit(G)
- if G=nothing (fi math sign) -> succeed
else G=G1, .. , Gx
how?
for each matching rule for G1
A:-B1, .. Bj
1- let (sigma) be
most general :not specifiing # that are not neededunifier of G1, A -> G1(sigma)=A(sigma)
2- visit( B1(sigma), ... Bj(sigma), G2(sigma), ..., Gx(sigma))
- unify z(X, a) and z(b, X):-f(X)
X in z does not have be equal to b only because X is unified to b. ????don't understand
- Cut (Ch 11.6)
- A cut "!" is used to prune part of the search tree.
-> prevents backtracking - example:
G:- A, B, !, C, D.
1- tries to find solution for A
2- tries to find solution for B if it fails goes back to A
3- after the cut, it does not go back to find solutions
once you get sol. past "!" backtrack for other solns before "!"
-> freezes first sols, for A, B
- back of quiz 8 shows how it works
- types of cuts
- green cut: prevents unnecessary search (w/o changing solutions)
>> added efficiency!
>> same solutions!
find(X, node(X, _, _)).
find(X, node(N, L, _)):- X<N, find(X, L).
find(X, node(N, _, R)):- X>N, find(X, R).
these rules are mutually exclusive, so we add cuts to prevent it to look in the right tree if it is less than N, whether it finds it or not.
find(X, node(X, _, _)):-!.
find(X, node(N, L, _)):- X<N, !, find(X, L).
find(X, node(N, _, R)):- X>N, !, find(X, R).
factorial(0, 1).
factorial(N, R):-
N1 is N-1,
factorial(N1, R1),
R is N*R1
?- factorial(4, R).
R=24
if you hit ; it will run forever because it tries the second rule factorial(0,R)
factorial(0, 1):-!.
factorial(N, R):-
N>0, !,
N1 is N-1,
factorial(N1, R1),
R is N*R1
- =:= test equality after evaluation
trysolve(A, B, C, D) :-
solve(A, B, C, D),
!. /* the CUT prevents backtracking for more solns */
trysolve(_, _, _, _) :-
write_ln('---------- no solution').
! prevents it from calling solve again if solve is true
if solve if false it never reaches the ! anyways
if ! is before solve, then whether solve is true or not it will not call the second trysolve so it will give nothing.
Fri May 1 2009 Lecture#32 Mon May 4 2009 Lecture#33
- post script: printer language
- some printers implement postscript language
- main issue: want high resolution, if u send a BMP are huge, --> so let the printer create the picture for you.
- language is stack-based.
- unix machines, there is a simulater for it "gs" ghost script
- extension of file is ".ps"
- type gs in terminal-> has screen = paper
GS>3
GS<1>45
GS<2>4.567
GS<3>=
4.567
GS<2>pop
GS<1>=
3
GS>3 7 add
10
GS>3 4 add 5 mul =
35
GS> 0 0 moveto
GS> 200 100 lineto
GS>stroke
will draw it
GS>0 200 moveto
GS>8.5 72 mul 0 lineto stroke
- postscript files start with %!
- % means a comment
- define values:: x 123 def
- exch : exchanges
- box.ps
Mon May 6 2009 Lecture#34Tcl: Tool Command Language
TK: Tool Kit (GUI)
%tcsh
%tclsh
%wish ==> Tcl/Tk interpreter: wish (window shell)
% set a 10
10
% puts $a
10
% set b [expr 3 * 5] //[] runs what's inside as a Tcl code
15
% set c {expr 3 * 5 }
expr 3 * 5
define procedures
% proc sumupto (n) {
set s 0
set i 0
while {$i<=$n} {
set s [expr $s + $i]
incr i
}
return $s
}
% sumupto 10
55
-- wish --
.b conf
.b conf -text "hi there" -bg red
#!/usr/bin/wish
# simple Tcl/Tk application
# create a label:
label .l -text "********* Hello, World! ***********"
# create a button:
button .b -text "click me" -command {pack .e}
# add the two to the window using the geometry manager (the "packer"):
# by default, pack from top down
pack .l
pack .b -side left
# another button that won't be visible until button .b is clicked:
button .e -text "Quit" -background red -command exit
# set up some key bindings:
bind . q exit
bind . <Any-KeyPress> {puts "Key %K was pressed"}