Blog Archive February 2009

Lexical scope

(Note, it is probably easier to read this post on the blog, and not in the version that is emailed to you.)

Consider a simple Java class, Foo.

20090223-foo

This class has multiple scopes. The outermost scope defines a field, x, that is initialized with the value 5. This declaration puts x in the scope of all subsequent code, including all method definitions.

20090223-foo2

Now, within the method fun, we see that a parameter x is declared as well. The scope of this particular instance of x is more limited.

20090223-foo3

This is an example of nested scopes. It is no different, in many regards, from our usage of with in the language of our interpreter. In fact, it is identical: the nested use of x completely shadows the declaration of x at the top level of the class. (You can read a bit more about lexical scope on the Wikipedia.)

As it happens, Java gives us a special way of breaking out of our lexical scope.

20090223-foo4

Through the use of this, we can can refer to this.x, which allows us to "break out" of the current scope, and refer to a binding of x that is at the top level of the class. Without this keyword, we would have no way of breaking the lexical scope of either fun or main, and as a result, x would be completely shadowed. 

From lexical scope to De Bruijn indices

In response to James's question from class today: the concept of scope has nothing to do with whether Scheme is object-oriented, or whether Java is functional (like Scheme, ML, Haskell, or Erlang) or procedural (like Pascal and C). As a language designer and implementer—as one who studies languages—we should be concerned with the syntax and semantics of languages (and perhaps more importantly, the semantics). 

In the case of scope, we see that nested scopes in Java behave the same as they do in our interpreter for WAE. That said, our interpreter does not have a notion of this. Java lets us reach out of the current scope and refer to a variable that was defined in an outer scope. We can implement this, if we want.

In the environment-passing interpreter (the interpreter of deferred substitutions), you could add a new production to the language:

WAE := {outer <id>}


Instead of resolving to the value of the first value of <id> in the current environment, we could define outer to force the <id> to resolve to the next value in the environment. That would be similar, unless we had more than two levels of nesting... if that was the case, simply adding an outer to our language would not solve the problem fully. 

Perhaps we could instead use an index:

WAE := {ndx <id> <num>}


With the ndx form, I could write code like this:

(with (x 3)
  (with (x 5)
    (with (x 8)
      (- x (+ (ndx x -1) (ndx x -2))))))


In the semantics of WAEN (adding in the ndx form), I expect this to evaluate to zero: it should be the same as saying (- 8 (+ 3 5)).

Now, I have a way of referring to a particular variable name and at a particular level of lexical scope. The reference {ndx x -2} would mean the binding for x two levels of scope out from where I am now. (Confused yet? You should be. This strikes me as a confusing way to write code.)

In doing this, I've practically invented De Bruijn indices. You can read about those either in the course text, or you can read about them on the Wikipedia. Either way, I would claim that this does not make our code clearer (we have the ability to give different variables different names... why refer to the same variable over and over by a number?). However, this can be a very useful transformation to help guarantee uniqueness when you're writing, say, an interpreter or compiler.

NOTE ABOUT WIKIPEDIA:

I'm referring to the wikipedia because it is convenient. If you want a more definitive treatment of these ideas, you should go into the library and pick up any of a number of texts on programming languages. We are studying these concepts through their implementation; if you would like additional readings to support your implementation efforts, I'm happy to recommend some from the library in Alden Hall.

First look at closures

I wanted to point out that I may have confused some of you with the Java example. This is because I got ahead of myself. I will make that clear on Wednesday.

To reiterate:

20090223-closure01

The function add3 is defined in one environment and applied in another. When defined, we say that the variable x is free in the function body. 

20090223-closure02

As Brian suggested, we need a way of knowing what the environment is at the time of function definition. This way, when we apply the function we can look in the function's environment for the value of x as opposed to the current environment.

To achieve this, we build a closure, a data structure with two fields that contains both the function body as well as the environment at the time that it is defined. We must evaluate the body of the function in the environment that we closed over as opposed to the environment we are in at the time of application. (Of course, we have to evaluate the function's argument in the application environment... we have, in some regards, two environments to manage.)

I will explore how closures can be used to model objects on Wednesday after reviewing this briefly. Please feel free to ask questions before then or at the start of class. Wikipedia is not a completely useless source on the definition of closures.

Project Planning

I'm going to suggest that, by the end of the week, you try to have a 1-paragraph project proposal and an outline for what you think you'd like to do. If you have this sooner, please feel free to hand it to me either before/after class, or drop it in an email. I'll provide you with any thoughts/reflections/resources that come to mind that might help get you started. I'm happy to meet with you to discuss/refine/brainstorm on project ideas.

Why? The goal is to get you moving, so you can begin being productive in your explorations and thinking about the project. Also, I'd like to help you scale the project appropriately, so that you aren't trying to bite off more than you can chew.

This doesn't bind you to your project—you might come up with an idea that is more interesting to you—but I would like to see you go into the break with your project clear in your mind and a course of action for the end of the term that is outlined in writing. Getting something in writing sooner rather than later seems like a good way to start moving towards that goal.

Error Handling from Friday, Feb 13th

Error handling on Friday the 13th! I never even realized!

The code from Friday is now linked in.

Tests for Basic Interpreter

I've linked in some tests for your basic interpreter; they should continue to be useful in the next lab as well.

UPDATED: Also, I've uploaded the code we will use in class in both PDF and textual form.

Reading, Video, Gators

I'll save the fun bit for last.

First, I'd like to point out that it would be useful to read PLAI with respect to functions and deferred substitution. That will be our next laboratory. I'll be talking about some of this material this week.

Second, for Monday, February 23rd (that's a week from Monday), I'd like it if we could discuss three articles in class. The first, Worse is Better, is followed by a rebuttal from the same author some years later. The third article, Beating the Averages, is about the use of Lisp in a production environment. In all three cases, you are tasked with reading these articles as language designers. The articles are Lisp/Scheme-centric, but I want you to read past that and consider what it means to design a language, and how our decisions effect the spread and utility of that language.

Third, on the topic of languages as interfaces, I thought I'd share this video with you:

What is a language, and what is an interface? David and the others he works with are doing some really neat work in exploring this question. And, for those of you in Junior Sem: this is an example of an absolutely excellent presentation. (Even if you're not in Junior Sem: this is an example of an absolutely excellent presentation.)

Lastly, I hope you are enjoying your Hallmark(tm) Holiday, and I want to remind you that the Gators have both men's and women's basketball games going on this afternoon, as well as a production of Cabaret this evening that you might enjoy.

3D Printing @ Allegheny

I thought I'd post this message from Maja Sweeny, a senior Art major here at Allegheny:

I have a project this semester that you may be interested in.  I am building a 3D printer from a kit with Professor Matt Jadud, and we would like to invite you to join us!  We are holding weekly meetings every Wednesday night at 7 PM, starting the 18th of this month.  The first meeting will be at Grounds For Change.

You may join us to help build and test the 3D printer, or to discuss and feed your curiosity.  If you have any questions, we have a website and a facebook group which you can check out:

Our site: http://www.baseplate.org 
Facebook group

You can also email me at sweenym [at] allegheny [dot] edu

Hope to see you at the first meeting!


I suppose that says most everything, really.

eToys (Smalltalk)

I will be updating requirements for the final project later today. However, I wanted to follow up Friday's discussion with a possible project idea. Because videos are better than words, here is an example of the eToys Squeak environment being used to simulate the solar system.

eToys is a programming environment included on the One Laptop Per Child XO-1. It is a Squeak environment, which is a modern implementation of the language Smalltalk. For a variety of reasons, I would be interested in seeing a group dig deeply into the programming language Smalltalk (it is an old object-oriented language with a long history), and perhaps the eToys/Squeak implementation in particular.

The power of pairs

A number of you have decided you would rather work solo. I allowed this, largely for one reason: culture.

CMPSC 220 is made of a combination of students who have taken anywhere from one to almost all of the department's course offerings. My impression is that you have not been encouraged (in the past) to work closely with your classmates on your programming assignments. You most definitely have not been encouraged to engage in pair programming, and it is not something many of you are comfortable with. I heard you say that the scheduling is difficult, or that you feel you "slow down" your partner, or... but that's all part of the process. 

The coming laboratories require you to think hard about the structure of data. You need to write an interpreter that handles everything from

{+ 3 5}


to

{with {{x 3} {y 5}}
    {with {{z {+ y x}}
           {w {with {{r {* x x}}}
                {+ {* r r} x}}}}
      {+ w x y z}}}


The second expression looks complex: it kinda is. There are simpler examples that represent programs you should be working to write an interpreter for. However, if you get those right, then the above code will "just work." 

All of that is to say: use your colleagues. I encouraged pair programming from the start (and encouraged you to practice it properly, with constant communication and no one being along for a "free ride") because you were headed here. And here is where you are now in a position to be working with, and discussing, and drawing pictures of trees of code with your programming partner. Saying "we are here" means "we are now digging into the really cool stuff." And that's where you want someone to help you dig. 

Don't be afraid to ask questions, but also, don't be afraid to work with someone else, as long as you're doing it in a way that benefits both of you. 

I'll be away most of today (potentially reachable by phone), and will be more accessible for questions on Sunday. Ask questions, and I'll do my best to answer.

New test, new test function

So, two things I missed:

New Test

In my template code, I missed a test case. Now, you could have (perhaps) caught this yourself. (My tests were not promised to be complete.) You might want to consider adding the following to your "flatten" test suite:

(check-equal? (list 1 2 3 4 5)
                 (flatten (list (list 1 (list 2))
                              (list 3 (list 4 (list) (list 5)))))
                 "Tierney's case.")


This is called "Tierney's case" because it was her code that illustrated the fact that my test suite could have been more complete. (If everything is/was working for you, then adding this test to your test suite shouldn't matter. Up to you.)

New Test Function

Again, I honestly thought this was in your template code. You may have noticed that you cannot compare two structures in Scheme with equal?. I've posted some code that will compare two trees. Take a look at binary-tree-check.ss if you want to be able to compare trees in your test suite.

Introducing Interpreters

I've posted the screencast of Monday's lecture as well as the code.

My intention is not to provide a screencast of every lecture. I thought today represented a new enough idea/combination of enough ideas that I should try capturing it. In the long run, I would rather produced more focused screencasts that explore specific questions you have, as opposed to just capturing 45 minutes of lecture. 

Either way, it's an experiment. Enjoy.

Code Walk from Friday

red-penI would have included this in the previous post, but my brain stopped working.

I have uploaded a scan of the code walk notes from Friday. You know, all those marks I made with the Red Pen of Harshness? 

This PDF also has a screencast associated with it. The screencast reviews the comments we made as a group in class on Friday. 

Screencast downloads, update to XML lab

There are a few things noted in this post; visit the post if you want easier navigation to the various screencasts, etc.

Screencasts

I have two old and three new screencasts up. They are all available for download directly from this site as opposed to uploading them elsewhere. Let me know if they don't work for you for any reason.


The last three of those are new.

So far, I've been producing screencasts that I think might be useful. If you have questions that you'd like answerd as a screencast, please let me know. I'm happy to expand on any of those, or focus in on some particular aspect of the screencast if any of them make things less clear.

XML Lab Update

Lastly, I made a small change to the XML lab. In particular, I clarified a statement I made about the length of solution. I claimed my solution was "only 13 lines of code." My clarification points out that my solution would probably not pass a code walk. Yours might be longer, but as a result it will be clearer and better documented. "Longer" here does not mean an order of magnitude.