# CSC 123 Perl-Scheme Assignment # Due one week from date assigned # -------------------- Part I. Perl Drills. $%&\*@! -------------------- #0. Euclid's algorithm for computing the gcd of two numbers can be # written in C as # int gcd(int a, int b) # { while (a!=0 && b!=0) # { if (a>b) a=a%b; else b=b%a; } # return a+b; // one of a,b will be zero # } # # Write it in Perl. This exercise is just warmup for Perl syntax. # Don't forget that the {}'s are required in if-else expressions. # Most of the operator symbols such as % are the same as in C. #1. define a function "doubles," that , given a list L, will return # a list with every element in L repeated, e.g: # doubles(1,2,3) should return (1,1,2,2,3,3). # In Scheme, I would write this as # (define (doubles m) (if (null? m) m # (cons (car m) (cons (car m) (doubles (cdr m)))))) # However, in Perl you don't have to do this recursively. # You can use "push". The empty list is just (). Try the foreach loop. # The function should be non-destructive: it should construct a new list. # 2. Here's how I would implement a function "forall", which checks if all # elements of an array satisfies a boolean property, which is passed in # as a function: sub forall { my ($f,@A) = @_; # first argument is the function, second is the array my $answer = 1; # default answer is true foreach my $x (@A) # read: "for each element x in array A ..." { if (!($f->($x))) {$answer = 0;} } $answer; } # recursive version: sub forall { my ($f,@A) = @_; if (@A==()) {1} else { my ($carA,@cdrA) = @A; $f->($carA) && forall($f,@cdrA) } } # usage: print forall( sub{$_[0]>0}, (3,5,-2,1,0,4) ), ": is false because not all numbers in the list are positive\n"; # Note that a sub (lambda) can be inlined in Perl, as you should expect. # Now implement the complementary function "thereexists" which should return # true if and only there is an element in the list that satisfies the property. #3. Write the Perl version of the "howmany" higher-order function # for array/lists. For example, # howmany( sub{$_[0] > 5}, (3,6,2,8,1) ) # should return 2, because there are two numbers in the list that are # greater than 5. Be sure you understand that the sub is a PARAMETER: # howmany( sub{$_[0]%2==0}, (3,6,2,8,1) ) # should return 3 because there are three even numbers in the list. #4. To prepare for a style of oop in perl, # write the following Scheme closure-function in Perl: # # (define (makecounter) # (let ((x 0)) (lambda () (begin (set! x (+ x 1)) x)))) # # You need to understand the last section of the tutorial, and read # the "bank accounts in perl" example. Note that you cannot use # a global variable for x since makecounter must be able to create # different "instances" of the counter function, each with its own # local x to count up from. Spend some time to think about this! # Note the "lambda" that occurs inside the function definition. # Your Perl program must emulate this structure. # # After you've written the function and tested it, take a moment # to be proud of yourself, then change the word "my" in your program # to "local." Observe and explain what happens. # --------------- Part II. OOP with Closures in Perl ------------------- # The rest of the assignment can be completed with EITHER SCHEME OR PERL. # Do the exercises from the handout "Modularity, Objects, and State", # numbers 3.1-3.5. You can start with some of the code I have posted # on the class homepage. Recommendation: do it in both languages.