Wednesday, November 17, 2010

7 Ways to Approach Soundness and Completeness

Soundness and completeness are important concepts that regularly tangle people up for some reason.  So, here's several different ways to think about them.  Choose the one that makes sense to you!

Tuesday, November 16, 2010

Grace for the CS1 Language Wars

We just changed the language for our intro CS course.  That change will probably obscure the underlying pedagogical change we also made for almost anyone outside UBC looking at the courses.

(Side Note: What's the pedagogical change?  From the perspective of someone who has not yet taught the course: A move toward a heavily structured approach to programming in which analysis of the features of a problem naturally leads to the process of solution.)

The language wars in intro CS courses, often called "CS1" courses, are powerful, engaging, frightening, and frequently pointless things.

So, why bother talking about them here?

Because once you start thinking about what you want in a language for your preferred CS1 pedagogy, you rapidly start throwing around words like syntax, semantics, closures, state, mutability, ...  And, understanding and slinging terms like that are part of what CPSC 311 is all about :^)

So, check out Andrew Black, Kim Bruce, and James Noble's thoughts on the syntax of an in-production CS1 language called Grace, particularly the section labeled "Block Semantics".

Grace uses eager evaluation but wants to allow programmers to introduce their own control constructs.  So.. they need to provide a simple syntax for a particular kind of expression.  Which one?

Sounds like an exam question!

Cheers,

Steve

Friday, November 12, 2010

"Little Language" for Elections

I got off topic discussing HCI-related issues in the Alaska senatorial race and valiantly connected (or tried to) that topic with our course by discussing Ka-Ping Yee's PVote, voting machine software as a concise interpreter for a ballot specification language.  I warmly recommend browsing through PVote (and the rest of Yee's work, voting-related or not).  It's a fascinating project that touches on elections, security, and languages.

Cheers,

Steve

Wednesday, November 10, 2010

Daily, 2010/11/10: Why Types?

Today was so exciting!  First, we finished up the (untyped, by the way) lambda calculus.  Everything's a single-argument function definition, function application, or an identifier

Then, we intro'd types.

Tuesday, November 9, 2010

SKIing and the Lambda Calculus

It's an amazing property of computation that we reduce all of our data (of which there is a staggering variety) to sequences of bits.

It is even more amazing that we can reduce the language of computation to a similarly lean representation.

In class, we've reduced lists, numbers, booleans, control flow operators, continuations, and recursion down to three things: single-argument function definitions, single-argument function applications, and identifiers.

We didn't get a chance to discuss the fact that we can go further.

The S, K, and I "combinators" (simple little functions) are one such representation.  Here's their definitions:

I x = x
K x y = x
S x y z = (x z) (y z)

Wednesday, October 20, 2010

Daily, 2010/10/18: call-by-X

One big idea we touched on briefly in class is that identifier binding—which means function application now that we've compiled withs away—is fundamental to several of the design axes we've considered in programming languages.

Clearly, call-by-value and call-by-reference are two different ways to manage binding function parameters during application.  However, both of these, also contrast with lazy evaluation.

Two other names for lazy evaluation are call-by-name and call-by-need.

In call-by-name semantics, binding a parameter just gives a name for the expression supplied to the function (well, the expression closure, anyway).  Any use of the name is replaced by the expression.  That's lazy evaluation without caching.

In call-by-need semantics, the expression bound to a parameter is only evaluated (and subsequently stored and used as a value) if it's needed at some later point.  That's lazy evaluation with caching.

Neither of these corresponds to call-by-reference or call-by-value (although we can think of call-by-value as being like call-by-need except that we artificially "need" the value right away).

Cheers,

Steve

Friday, October 15, 2010

Daily, 2010/10/15: mutable state and scope vs. extent

I'm going to make this short, because I've been laggard with my dailies, and the practical solution is to make them quicker to post!

Today, we finished up our implementation of mutable state using boxes.  We touched again on the crucial idea that state "threads" through evaluation in a very different way from environments, in particular in a dynamic fashion.  Mutable state's dynamic nature makes it both useful and dangerous to use.

In fact, it's even harder to understand where state changes come from than identifier bindings in dynamic scoping.  That's because an identifier instance's binding in dynamic scope must be present in the dynamic context of the instance, the "call stack" in machine-oriented terminology.  However, state changes can propagate from outside the dynamic context.

Our tree-labeling example illustrated that.  Consider this tree:

  (node (leaf 0) (leaf 0))

When we label it, we'll make a recursive call on the left branch.  The recursive call sets the leaf's contents to 1 and updates the counter's state.  That function call is then over and gone: no longer "on the call stack", no longer part of the dynamic context of the program's evaluation.  Then, we make a recursive call to label the right branch, and the label is 2 (not 1) because of changes that occurred in a function that's already over and done with.

The other important idea we discussed stems from the dynamic, threaded nature of the store.  Identifiers have static scope (which we want), but the contents of the store have dynamic extent because they can escape the static scope in which they are created.

In our interpreter, we have no problem because we never remove anything from the store.  So, values in the store have unlimited extent.

In C and C++, memory that is allocated "on the stack" (generally space associated with local variables of functions) is reclaimed when the function that allocated it terminates, at the same moment that the variable's name also goes out of scope.

This can cause serious problems with code like this from class:

  int * next(int * x)
  {
    int y = *x + 1;
    return &y;
  }

This code compiles and may even run correctly, but it may also cause immediate or distant errors, depending on the structure of the program in which it is called and the implementation details of the compiler and machine used.  Yuck!

(My version of gcc warns me about returning &y. Good for it!  But it gives no warning when I change return &y; to return next(&y); or even if I call a different function expecting an int*.)

Lastly, I made a rather muddled point about whether we store values or store locations in the environment.  I may defer discussion of this to tutorial on Tuesday.

Cheers,

Steve

Tuesday, October 5, 2010

Daily, 2010/10/04: recursion via state and "applying yourself"

Announcement items:
  • A3 partners: no new e-mails; object now!
    • Send e-mail NOW!!!!
    • Steve assigned all others randomly to partners
  • Reminder: the exam will be CLOSED BOOK but "open wiki appendix"
    • Appendix is up: READ it; edit it!
    • First 10 substantive edits: +1 BP!  [[well on the way!]]
High-level comment:

We covered recursion, which was great.. except I think I biffed the motivation for even talking about recursion through state change.  More below!

Details:

Daily, 2010/10/01: caching and high-level thoughts

Announcement items:
  • A#3 pairings: 12 people still need partners [list elided]
  • Steve will assign partners after Monday's class if not already chosen
  • Study session this weekend thanks to Ray: Sun 1-4; Steve should be there; +1BP to all!
  • Reminder: the exam will be CLOSED BOOK but "open wiki appendix"
    • Appendix is up: edit it!
    • First 10 substantive edits: +1 BP!
High-level comment:

Up to now, we've been moving at a rapid clip.  Today, we savoured caching and reflected on the term.

On the latter: we started class by discussing tradeoffs along (and sample languages lying at different points on) the static and dynamic typing design axis.  Our familiarity with the notion of static vs. dynamic scope already makes a fabulous entry to deep understanding of the discussion of static and dynamic typing.  (We framed the conversation in terms of some work a friend of mine at UW is doing, which I'll blog about later.)

Details:

Friday, October 1, 2010

Braces in Python? No way.

In Python, whitespace is significant and used to delineate code blocks.  Many other languages use braces (or BEGIN and END or some other matched pair of tokens).  Will Python ever have braces?
cascade:~> python
Python 2.4.6 (#1, Dec 13 2009, 23:45:11) [C] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import braces
  File "<stdin>", line 1
SyntaxError: not a chance
>>> 
Take a close look.  Hilarious.

Hat-tip to PEP 3099, a fascinating laundry list of Python language design ideas deemed so bad they're non-starters.

Cheers,

Steve

Wednesday, September 29, 2010

Daily, 2010/09/24-2010-09-29: closures and laziness

I got a bit behind this week, and being out of town on the weekend exacerbated the problem!  Here's three dailies in one, albeit short! 

Announcement items:
  • A#3 out; pairings due TOMORROW evening!
  • Reminder: the exam will be CLOSED BOOK but "open wiki appendix"
    • Appendix is up: edit it!
    • First 10 substantive edits: +1 BP!

  • A#3 out by tomorrow; pairings due by Thursday evening!
  • Important A#2 update: {- x y z} in example should have been {- {- x y} z}.
  • Reminder: the exam will be CLOSED BOOK but "open wiki appendix"
  • Vote on Dereck's office hours time (see Vista "assessments" area)
     
  • Wiki appendix or open-notes/text? WINNER IS APPENDIX
  • KEY midterm material today: closures (will make many practice Qs make more sense)
  • Vote on Dereck's office hours time (see Vista "assessments" area)
High-level comment:

We built and admired closures, detoured to the fascinating power of lazy languages, and then came back to implementing laziness.. only to discover that closures gave us everything we needed for laziness!

Meanwhile, I continue to minimize the new code I write in class, which is making it easier to get to the key ideas, although I still find myself running a minute or two over!  It's hard not to linger on interesting bugs we run into as we proceed.  I could certainly fix these more rapidly without discussing them, but each one is an opportunity to model debugging practice and to explore the semantics of programs.  Ah.. the temptation!

I'm wondering how you all are doing with respect to the instructional style, particularly since I've been doing fewer active learning exercises (and, probably consequently, getting less class participation).  So, it's about time I did a survey.  Maybe Friday or Monday..

Details:

Wednesday, September 22, 2010

With Considered Harmful (But Not OUR With)

I've been promising this post for a week already, but having trouble getting around to it.  So here's a short, sweet version.

Douglas Crockford has a fabulous discussion of how JavaScript's designers messed up on JS's with statement.   JS's with is much like our with, except naturally (but not sufficiently carefully!) extended to an OOP context. 

Daily, 2010/09/22: scope!

Announcement items:
  • A#1 feedback should have been mailed; A#1 grades on Vista (both raw and actual)
  • Go to next tutorial (and you should have gone to the last) or A#2 may be VERY HARD
  • Practice Midterm out on Vista
High-level comment:

We hit our second big design axis today: static vs. dynamic scope.  As with lazy vs. eager evaluation, we'll dive much deeper into this axis once functions are first-class, but we've already seen how the choice can change the semantics of a program (with freevar).  More generally, the contrast between static and dynamic properties of programs will come up again and again, not just in this course but in many other courses and in your CS career.  (And life.  After all, you are a dynamic expression of the static code in your DNA!)

On the practical side: I'm going to try to work from more pre-written code.  Today (and last class), we delayed some key points too late in class.  (OK, 1.5 minutes after the end!)  I'll try to skip past the inessentials in the future.


Details:

Monday, September 20, 2010

Daily, 2010/09/20: revisiting substitution + functions

Announcement items:
  • Tutorial #2: Resolving lazy scope error WITHOUT deep substitution (A#2 mat'l!)
  • A#1 update: Please keep an eye on or forward your @ugrad.cs.ubc.ca e-mail!
    (For forwarding: http://www.cs.ubc.ca/ugrad/facilities/accounts/email_news.shtml )
  • TestFest: available, helpful, but NOT required!  (Only set up for eager version)
  • Extended office hours this week; see Vista Announcements
  • Practice Midterm out by end of day today (final tuning in progress)
High-level comment:

I'm not sure today's redefinition of our core semantics for WAE made as much sense in class as it did to me before class.  I still think it's a lovely approach to define "ground truth", however.

Meanwhile, we got a bit cut off on functions.  I'll take a moment to revisit the code at the start of class Wednesday so we all see what I did wrong.  (A small, simple coding error, when in our discussion of the idea we had gotten that right.)


Details:

Sunday, September 19, 2010

README summaries

I just read through the Assignment #1 README files.  Thanks for your input, everyone!  I thought I'd summarize what I read and respond to just a few issues people brought up. 

(When I quote people here, I won't use names in case people prefer to remain anonymous.  If you want me to credit you for a quote, drop me a line, and I'll do so.)

Comments I wanted to respond to:

Saturday, September 18, 2010

Daily, 2010/09/17: semantic play!

Announcement items:
  • Last A#1 thoughts: Haven't read Ch 3?  Do so, EVEN NOW!
  • A#2: out later today, due in 1 to 1.5 weeks
  • "TestFest" for A#2: out later today
  • Advice for A#2: work from the textbook!
High-level comment:

I got so swept away with the fun yesterday that I forgot to actually do the announcements.  For what it's worth, they're above.

What had me swept away?  This was our first chance to do some really exciting exploration of semantics!  (More on that below.)  In a few short lines of code, we repeatedly and radically altered the semantics of our language.  The code we came up with encapsulates very succinctly what it means to "get identifier binding right". 


Details:

Wednesday, September 15, 2010

Daily, 2010/09/15: multi+ and with

Announcement items:
  • Thoughts on Reading, Lectures, and Assignments
  • A#1 due FRIDAY; it would help A LOT to read Chapters 1, 2, and 3
  • Thoughts from interactions with students over A#1 (notes to be posted below)
High-level comment:

Today was practice with Racket and parsers: no profound message!  (Well, except the request to think hard about whether (interp (parse '{with {x {+ 1 2}} 2})) should ever cause the interpreter to add the numbers 1 and 2.)  Thus, the details section just contains the notes promised above.

I did try to model how to build a function based on the types the function operates on (e.g., breaking down our parser into cases for each of the types of AE we'll generate).  This is useful, especially to answer (or avoid ever asking) questions like "Why did (second sexp) cause an error here?  Oh, because (second sexp) is not an AE, but I have a function that consumes sexps and produces AEs: I can recursively call parse!"  See How to Design Programs for an extensive introduction to programming using templates like this one (but better).

One other critical thing that happened: a student answered one of my polls by saying he didn't know why we were asking the poll, the single most useful answer.  I'll post more about this on Vista.


Details:

Little Languages Kill; News at 6

The little languages paper we discussed earlier mentions the idea that any interface defines a language.  In that sense, we can apply the principles of language design to a user's interaction with any interface.  Harold Thimbleby's recent article in Interactions (ACM's HCI magazine) gives a fascinating and (literally) deadly example of just that, emphasizing problems arising from a mismatch between the users' perception of the language semantics and the language's actual semantics.  Take a look at the brief example on page 54 of "Ignorance of Interaction Programming is Killing People" in the sections A Fatal Overdose and Calculators Are Mad, Bad, and Dangerous.


Cheers,

Steve

Monday, September 13, 2010

Daily, 2010/09/13: define-type, type-case, and our first "programming language"

Announcement items:
  • Tutorial registration resolution: 3 add'l seats in each tutorial
  • Reminder: A#1 due FRIDAY; started?
  • Is the blog required? No, but tell me if I put something critical there.
  • Can I get access to ACM papers like the one linked from the blog?  SHOULD be possible from any campus connection, including right here.
High-level comment:

We built our first interpreter and learned a couple more key Racket (actually, PLAI) forms.  My scattered whiteboard use (I grab whatever space is available and write on it) and teaching-with-code style may have made it hard to keep up, and may also have masked some of the big picture ideas in the course.  I hope not!  Have to see what I can do to ameliorate this.


Details:

Friday, September 10, 2010

Daily, 2010/09/10: Procedures as Values, Things, and Other Stuff

Announcement items:
  • Old announcement items: see blog 
  • Web redirect fixed (http://www.ugrad.cs.ubc.ca/~cs311 should work) 
  • Tutorial registration issue 
  • Your TODO items: see notes page of website 
  • Tutorial collab policy update + minor add'l update
High-level comment:

We've finished what I really wanted to show in Racket: programming lessons on the basics you'll need and some emphasis on the extraordinary power of "first-class functions" (functions that can be used as normal values).  We'll discuss two remaining Racket constructions (define-type and type-case) as we explore the AE mini-language on Monday.

However, I was disoriented from running to and from my office before class and may have been occasionally incoherent, particularly answering your questions and comments!  I'll avoid hyperventilating before class in the future.  Help me out as long as I have this ear infection by making your contributions loud!

Details:

Another Answer to "Why Interpreters?": Microsoft Does Continuations

Note: The parts of this post in parentheses may make no sense (fleegly-dee floo).  You can skip those parts and still get the point!

Yesterday, I chatted about 311 with my friend Dutch Meyer, a systems grad student at UBC and a very sharp person.  He pointed me at a systems/software engineering article about closures and continuations—two powerful concepts we'll run into this term—that he's returned to many times when thinking about concurrent system design.

Wednesday, September 8, 2010

Daily, 2010/09/08: Whirlwind Start

I write "dailies" (but call them "post-mortems" in my head) after lecture, at least when I'm eating my spinach. These are records of how things went and where we stopped as well as aides to the TAs to track lecture.

This term, at a student's suggestion, I'll try posting these publicly (with my students as my explicit audience: "you"). I apologize in advance for self-censorship.

Announcement items:
  • Introductions: Steve and Dereck (Ben at tutorial)
  • Office hours
  • Extra office hours next week: see Vista announcements
  • Tutorial registration issue
  • Prereq letters
  • Your TODO items
    • Skim PLAI preface, READ PLAI prelude (Friday)
    • Install DrRacket on your computer (Friday)
    • Do Racket exercises 1-15 (website assignments page)
    • Skim/Read Scheme/Racket resources as needed
  • My philosophy on announcements
High-level comment:

I enjoyed the energy and hope that you did, too. I'm glad we made a hefty start on Racket. Oh, and I talked too fast. (Too excited to be back in the classroom after a summer recovering on my rocking chair.)


Details:

Monday, August 30, 2010

Why Is the Web Page Taking So Long?

Someday this blog will be linked in with the webpage so you can actually find it and read it.  So, why is it taking so long to get the website up?  At this point, I'm back at work regularly, but I'd like to have drafts of the assignments and many exam questions written before I create the website. 

Why? 

I hope we're all in this course to learn.  I certainly am!  However, grades can sometimes make a habit of getting in the way of learning.  Therefore, I'd like to at least prototype the assignments and exam questions before committing to the course's other parameters so that I can ensure that the graded assessments feed into our learning. 

Once I have them prototyped, I intend (among other things) to pre-post sample exam questions specifically designed to prepare you effectively for the real exams.  I'd like the specific questions on an exam to be a surprise—so you show that you can reason with the concepts we learn in a novel situation. However, I'd like the type of question you face to mostly be familiar—so you spend little or no time agonizing about what the question is actually asking you to do.

Hopefully, I'll finish all that in the next few days and have the course website up before the start of the term, at least!

Cheers,

Steve

Thursday, August 26, 2010

View from the Other Side: Larry Wall and Perl

In CPSC 311 this term, we'll be exploring design axes of programming languages.  This is an incredibly powerful way to view languages, but it is not the One True Way.

So, when you feel like some counterculture, try Larry Wall, Perl's designer.  Rather than categorizing languages by their design choices around functions, scope, continuations, evaluation, state, and so forth.  He scatters them by their "whipuptitude" and "manipulexity".  (But, do note that in that presentation, he does mention lexical (static) scoping!)

Cheers,

Steve

OOPLAI: OOP Intro in the Style of PLAI

In recent terms, we haven't discussed OOP in CPSC 311.  It's not clear whether we'll be doing it this term.  If you'd like to explore the underlying concepts of OOP in the PLAI style, Eric Tanter has posted a PLAI-style intro to OOP.

By the end of the term, you should have seen all the concepts you need to work through Tanter's chapter except possibly macros.  Happily, with respect to macro definitions, Tanter's work hews to the classic axiom from Mathematical Writing by Knuth, Larrabee, and Roberts:
Many readers will skim over formulas on their fi rst reading of your exposition. Therefore, your sentences should flow smoothly when all but the simplest formulas are replaced by "blah" or some other grunting noise.
Cheers,

Steve

P.S. OK, maybe this was in part just an excuse to share that lovely quote from Knuth et al.

Wednesday, August 18, 2010

Little Languages Review

It's surprising to think that Jon Bentley published this paper in 1986.  It feels current to me today and, as I think back over my education and career, current for each stage of my discovery of computer science.

On my first read, I take three main sets of lessons away.

Little Languages
 
First are Bentley's explicit lessons about little languages.

Bentley motivates little languages from several perspectives:
  1. A powerful way to accomplish specific tasks (like drawing pictures) that you need to accomplish, if someone else has done the work for you.  I need to do a better job of taking advantage of such things!  (Up front, mostly p711-713.)
  2. A framework for describing data for use in your own systems, including quite varied purposes for the data, which is powerful yet accessible to your users.  (Point mostly made in the sidebar, p714-715.)
  3. A technique to create abstraction layer boundaries in multi-layer systems (including compilers).  (p716-719)
Each of these is a profound example of the impact of languages on our tasks as programmers and users of computers.

Powerful Programmers