cs245 -- hw3 -- Go: Names, Scopes and Bindings

Throughout this assignment, all programming should be done in Go. In addition, all printing should be done using fmt.Printf rather than fmt.Println (or just println). For the String() method (see below) use fmt.Sprintf.

The programs written for this assignment may be quite short (perhaps less than 20 lines of code, each). Nonetheless they should be properly commented.

In some cases below, it may be that the question is answered by providing a program that does not compile. This is OK, but in such cases you need to carefully explain why not compiling proves your point.

Part 1 -- Static and Dynamic Scoping

Write a program -- or two -- that that conclusively demonstrates whether Go uses static or dynamic scoping. (Yes, I know that Go uses static scoping; you program should "prove" that.)

Associated with this part should be a textual description of your program(s) describing exactly why and how they prove the form of scoping used by Go. The discussion is worth at least as much as the actual programs.

Part 2 -- Functions and Closures

Write a function (I will call this function "maker") that returns a function (I will call the returned function "nextInSeries") for an computing the values of arbitrary numeric series whose state is given by a single integer. nextInSeries should take no parameters and return an integer that is the next value in the series.

maker should take 2 parameters:
  1. a function (I will call this function "computer") which takes one integer parameter that computes values of the series given the "state" integer. I.e. the type of this function is:
                    func(int) int
                
  2. an integer, the initial state for the series.

For instance, suppose that the series to be computed is a standard geometric series: 1,4,9,16,25, ... then you might do the following
        nextInSeriesG := maker(geometricComputer, 1)
        fmt.Println(nextInSeriesG())
        fmt.Println(nextInSeriesG())
        fmt.Println(nextInSeriesG())
    
(you would have to write the "geometricComputer" function) The output of this code snippet would be:
        1
        4
        9
    
Alternately your program could compute the arithmetic series: 5, 10, 15, 20, 25, ... using almost identical code, the only difference is the function passed into the maker function.
        nextInSeriesA := maker(arithmeticComputer, 1)
        fmt.Println(nextInSeriesA())
        fmt.Println(nextInSeriesA())
        fmt.Println(nextInSeriesA())
    
Where the output would be
        5
        10
        15
    

You program should be able to have an unbounded number of these nextInSeries functions; and they should not interact with each other.

In addition to writing the maker function, write tests that demonstrate the use of your maker and nextInSeries; and that multiple nextInSeries do not interact. Your testing code should implement the two series shown above as well as one other series of your own creation. (Note that you cannot use this system to compute a function like the fibonacci sequence that uses two state variables.)

Finally, on a Linux machine, collect a "script" file for the execution of your testing code. One way to collect a script file is the following:

  1. UNIX> script XXX
    Replace XXX with the name of a file you want to make. That is, at a unix prompt enter the word script followed by the name of a file you wish to create.
  2. You should get back a response like "Script started, file is XXX"
  3. Execute your Go program, perhaps multiple times to illustrate what you want to illustrate. Everything that is going to the screen will also go into the file
  4. UNIX> exit
  5. You should get back a response like "Script done, file is XXX"
  6. Check the contents of the file
    UNIX> cat XXX
"script" also works on a mac, I do not think there is a similar capability from the command line in Windows . There are lots of other ways to do something similar in Unix. (I assume you are all using the link to a Unix machine from your laptop as created in HW1, in which case you are effectively running on Unix, so this limitation of Windows should not be a problem.)

Associated with this part should be a textual description of your output file describing exactly why and how your tests and the output show that the nextInSeries functions do not interact (and that you can have an unbounded number of nextInSeries functions).

Part 3 -- Closures as iterators

Given a slice, Go provides an "iterator" which makes it easy to write a for loop to iterate through the values in the slice. For instance:
        a:=[]int{1,2,3,4,5,6,7}
        for i,v:=range a {
            fmt.Printf("index:%v value:%v\n", i,v)
        }
    
In this part of the assignment, write your own iterator function, and an iterator generating function to accomplish much the same thing that Go provides with range. Similar to above (part 2), the iterator generating function should take a slice as its single parameter and return an iterator function. Also as with the nextInSeries above, the returned iterator function should take no arguments. Unlike the nextInSeries, the iterator should return a tuple, where the values returned are: the value of the next element in the slice and whether that value returned is valid. The value is not valid only if all of the elements in the slice have already been returned by the iterator. Once the iterator has indicated that the return value is not valid, it should never return an indication of validity.

(Side note) Go recently introduced Generics but we have not gotten there (and may not). So your functions should work on only slices of integers.

To repeat, your iterator should just work on slices containing items of type int.

In addition to writing the iterator and iteratorGenerator, write a set of code that illustrates the use of your iterator by doing the following things:

As with part 2, provide a script of the output of your part 3 program. Your script should show the iterator working on slices of at least 5 items (but no more than 10).

Finally, write a brief analysis of you iterator. In your analysis:

Electronic Submissions

Your submission will be handed in using the submit script.

If you write your program on computers other than those in the lab, be aware that your program will be graded based on how it runs on the department’s Linux server, not how it runs on your computer. The most likely problem is not submitting everything or hard coding file locations that are not correct on the Linux servers.

Make a README

Once you have finished coding (commenting your code) make a README file. This file should follow the format of this sample README. This is your opportunity to tell me what went well or poorly, what is still broken and why, etc. I will read, and often respond to, everything you write in the README.

Answers to the questions posed in each part of the assignment may be in the README or in a separate document.

Submit

Following the pattern from assignment 2:
  1. On the linux computer:
            cd 245
    
    I assume that you already have a directory named HW3.
  2. When all of the files you want to submit are in the HW3 directory and you are still in the 245 directory
            /home/gtowell/bin/submit  -c 245 -p 3 -d HW3
    
    This says to submit for project 3 (-p) everything in the directory HW3 (-d) for the class 245 (-c). You should see listing of all the files you submitted and a message that says "success".
  3. You can submit multiple times. I will grade only the last submission -- unless you tell me otherwise. The submission process attaches a timestamp so I know when you submitted (down to the second). The closest submission I have ever received to the deadline is 3 seconds.

The submission should include the following items:

README:
This file should follow the format of this sample README
Source files
All of them
Question answers
If separate from readme.
Data files used:
Be sure to include any non-standard data files uses. (Rare)
DO NOT INCLUDE:
Data files that are read from the class site. Do include any of your own data files.
If this worked you will get a message with the word "success". If you cannot achieve success and the deadline is approaching, send me email. We can set up a meeting to work out your problems. The email will establish that you intended to submit. Once you send the email, do not change the files that you were trying to submit.