# CSC 123 Ruby-Scheme Lab and Assignment # Due one week from date assigned # -------------------- Part I. Ruby Basic Drills. -------------------- #0. Euclid's algorithm for computing the gcd of two numbers can be # written in C as # int Gcd(int a, int b) {if (a==0) return b; else return Gcd(b%a,a);} # # Write this function in Ruby. Write AT LEAST two distinct versions: # for example, one using recursion and one using a while loop, or one # using 'def' and one using 'lambda'. Try to experiment with various # Ruby features. For example, simultaneous assignment is possible in the # form x,y = y,x. Use the ruby interactive interpreter (irb) to try out # features. #1. Write a function to reverse a list/array. You should write this function #constructively (don't try to change the original list, which can be #garbage-collected anyway). Recursion is optional. Basic list operations: #[1,2] + [3,4] --> [1,2,3,4]; appends two lists constructively. #Given list/array A, A.push(5) adds element to end of list DESTRUCTIVELY. #A[2..5] will return the sub-array consisting of elements A[2] to A[5]. #A.length is the length of the array. # type A.methods to see all the methods that are available on array/lists. #Your function should work like follows: reverse([1,2,3]) returns [3,2,1]. # 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 (lambda term): def forall(a,p) for x in a if p[x] then return false end # note the [] in application end # for loop true end ## This function can be called as in puts forall([2,4,6], lambda{|x| x%2==0}) ## The following is an alternative, but which obviously embodies the same idea: def all(a) for x in a if !yield(x) then return false end end # for loop true end ## This version uses what are called "coroutines", and is called as in puts all([2,4,8]) {|x| x%2==0} # The keyword "yield" calls the coroutine, which occurs as a "block" # Note the slight syntactic differences: () instead of [], and no "lambda" # 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 Ruby version of the "howmany" higher-order function # for array/lists. For example, howmany([3,6,2,8,1], lambda {|x| x>5}) # should return 2, because there are two numbers in the list that are # greater than 5. #4. To prepare for a style of oop in ruby, # write the following Scheme closure-function in Ruby: # # (define (makecounter) # (let ((x 0)) (lambda () (begin (set! x (+ x 1)) x)))) # # Consult the "bank accounts" 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 Ruby program must emulate this structure. # ------------------ Part II. OOP with Closures -------------------- # The rest of the assignment can be completed with EITHER SCHEME OR RUBY. # Do the exercises from the handout "Modularity, Objects, and State", # numbers 3.1-3.5, page 174.