Starting from:

$30

Programming Languages Homework II


CS 315 - Programming Languages

Note that plagiarism is not allowed and we will strictly check your homeworks
Homework II
In this homework you will implement currying using OO techniques and operator overloading
in Python. Currying is the technique of transforming a function that takes multiple arguments
in such a way that it can be called as a chain of functions. This is better explained using an
example.
Say we have a function add that adds a bunch of numbers. Rather than writing add(3, 5, 4, 1)
we want to use currying to create an adder function that can be extended using a chain of calls.
We would then have adder(3)(5)(4)(1)(). Let us assume we have the currying function that
can create this adder given the add2 function (the binary version of add) and a start value. Let
us call it curry. Then we have adder = curry(add2, 0).
In the general case, curry(add2, ival) returns us an adder function. That adder function can
return two results:
1. If a parameter is supplied, returns another adder function like itself by adding the parameter value to its current value (e.g. adder(aval)),
2. If no parameter is supplied, returns its current value. A few examples follow:
1 add2 = lambda x, y : x + y
2 adder = curry (add2 , 5) # creates a 5 adder
3 adder = adder (3) # creates an 8 adder
4 print adder () # prints 8
5 print adder (2)() # prints 10
6 print adder (1)() # prints 9
7 adder = adder (3) # creates an 11 adder
8 print adder () # prints 11
Now assume that the curry function takes an optional parameter called kind. If its value is
‘Eager’ (which is the default), then the resulting curried function behaves such that when a
new value is added via (val) the new result is computed right away, eagerly. If the parameter
value is ‘Lazy’, then the resulting curried function behaves such that when a new value is added
via (val) it is just remembered and the entire result is computed lazily, when the () operation
is performed for the first time. Here is an example:
1
1 adder0 = curry (add2 , 0) # Eager
2 adder18 = adder0 (3)(4,5)(6)
3 print adder18 () # prints 18
4 print adder18 (2)() # prints 20
5 print
6
7 lazyAdder0 = curry (add2 , 0, ’Lazy ’)
8 lazyAdder18 = lazyAdder0 (3)(4,5)(6)
9 print lazyAdder18 () # prints 18
10 print lazyAdder18 (2)() # prints 20
The two code segments above would behave exactly the same, because the laziness of the
evaluation does not change the result. However, consider the following alternative:
1 def sleepingAdd(x, y):
2 import time
3 for i in xrange (0, y):
4 print ".",
5 time . sleep (1);
6 return x + y;
7
8 sadder0 = curry ( sleepingAdd , 0)
9 print "Hey",
10 sadder10 = sadder0 (3)(4,2)(1) # sleeps 10 secs ( prints 10 dots )
11 print "Yo"
12 print sadder10 () # prints 10
13 print "Hey",
14 sadder10 () # returns 10
15 print "Yo"
16 print
17
18 lazySadder0 = curry ( sleepingAdd , 0, ’Lazy ’)
19 print "Hey",
20 lazySadder10 = lazySadder0 (3)(4,2)(1)
21 print "Yo"
22 print lazySadder10 () # sleeps 10 secs ( prints 10 dots ) , prints 10
23 print "Hey",
24 lazySadder10 () # returns 10
25 print "Yo"
This time, we replaced the add2 function that was curried with the sleepingAdd function. The
latter is a function with a side e↵ect, as it prints dots to the output. A consequence of this is
that, the two outputs corresponding to the above two code segments would be di↵erent. Here
is what the output looks like:
2
1 Hey .......... Yo
2 10
3 Hey Yo
4
5 Hey Yo
6 . . . . . . . . . . 10
7 Hey Yo
Deliverables
There are two deliverables:
1. Write a report explaining what you understand from eager and lazy evaluation. Describe
why the above example gives two di↵erent outputs.
2. Implement the curry function. Some hints follow:
• The curry function will return an object. This object would be an instance of a
class you write. In fact, you have to write two classes: one for the eager version and
one for the lazy version.
• The class you write will overload the () operator. Depending on the number of
arguments, it will behave di↵erently. If there are no arguments, then the result of
the computation is returned. If there are one or more arguments, then a new object
that incorporates additional values are returned.
• In summary, you would be using objects to emulate functions, via overloading the
() operator.
Note: This homework requires learning about the following things in Python:
• Defining functions and lambdas (only used in the example code above)
• Handling variable number of arguments in functions
• Defining classes, instantiating and using objects
• Operator overloading
Logistics
Put your code and report under a directory named lastname name hw2 and make an archive from
that directory. Your report should be named lastname name hw2.pdf (or .txt). For example,
the following Unix commands could be used:
3
1 $ mkdir lastname_name_hw2
2 $ cd lastname_name
3 ...
4 # ( edit and test your files i n this directory )
5 ...
6 $ cd ..
7 $ tar -cvzf lastname_name_hw2 .tar.gz lastname_name_hw2
Then e-mail this newly generated file (named lastname name hw2.tar.gz) with subject CS315-
HW2 to Arda Unal ([firstname].[lastname]@bilkent.edu.tr]. Reports in formats other than .txt
and .pdf are not accepted.
Note that plagiarism is not allowed and we will strictly control for that.
4

More products