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)
    • Prolog
  • 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
        • Syntax error
          • 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 wednesday

how is BNF more powerful than regular expressions?

HW#1

  1. Read Sethi Chapters 1 and 2.

    Sethi pp. 21-22, problems 1.1, 1.9

  2. Sethi pp. 49-52, problems 2.1, 2.2, 2.3, 2.4, 2.10, 2.11, 2.21
  3. 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)

  4. 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 ...
        • ...
        • innovations on FORTRAN
          • 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
          • ALGOL58
          • ALGOL60
          • ALGOL68
        • 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
          • 1975 ..
          • ..
        • ...
    • 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
      • Prolog
  • 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
    • see image
  • 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
      Num
      3
      +
      E
      E
      Num
      4
      *
      E
      Id
      a
      OR
      E
      E
      E
      Num
      3
      +
      E
      Num
      4
      *
      E
      Id
      a
    • 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
    • cd ~schar/cs313
    • comments:
      • { comment here ... }
    • starts with the word "program"
      begin
      {main}
      ....
      end
      {main}
    • compiling: fpc name
    • 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
    • AT LEAST?


Wednesday Feb 18, 2009 Lecture# 5


  • The basic structure of a Pascal program is:

    PROGRAM ProgramName (FileList); //serves to be useful for documentation not a big deal

    CONST
      (* Constant declarations *)
    • you can simply use = instead of := because they are constant an assignment is not necassary. you can just simply equate it.
    • why use constants?
      • easier to modify for the whole program
      • easier to identify what does it mean
      • you do not need to give type
        • the compiler will identify the type of constants
  • TYPE
  (* 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
      • 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.

        • A record Type
          • type
            InfoType=record
            Name: string;
            Age: age;
            City, State: String;
            Zip: integer;
            end
            • 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
    • check it.
  • 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
    • time ./filename
  • 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
      • 13
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


Friday Feb 27, 2009 Lecture #8



Monday Mar 2, 2009 Lecture#9



Wednesday Mar 4, 2009 Lecture# 10


Friday Mar 6, 2009 Lecture #11



Monday Mar 9, 2009 Lecture #12


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: [
        &nbsp;               (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"


/*******************************/
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


Wednesday March 18, 2009 Lecture#16


Wednesday March 18, 2009 Midterm

Friday March 20, 2009 Lecture#17



Spring Break

Monday March 30 Lecture#18

HWs and midterm back, feedback.


Wednesday April 1, 2009 Lecture#19
on my notebook

Friday April 3, 2009 Lecture#20
on my notebook

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

Monday April 13, 2009 Lecture#24
local 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#27

f(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.


                                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#30

x=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.

Wed April 29 2009 Lecture#31



Fri May 1 2009 Lecture#32
Mon May 4 2009 Lecture#33



Mon May 6 2009 Lecture#34

Tcl: 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"}