Lectures
Lecture 1: The Essence of Objects
Lecture 2: Unions of Objects
Lecture 3: Classes of Objects:   Data Definitions
Lecture 4: Classes of Objects:   Interface Definitions
Lecture 5: Interface Design:   Independent and Extensible
Lecture 6: Parametric Interface Definitions and Methods
Lecture 7: Introducing Java:   Syntax and Semantics
Lecture 8: Union, Interfaces, and Lists in Java
Lecture 9: Testing in Java
Lecture 10: Parametric Interfaces in Java
Lecture 11: Computations on Many Structural Arguments:   Double Dispatch
Lecture 12: Parameterized Types and Double Dispatch; Abstracting Values
Lecture 13: Abstracting Computation with Function Objects
Lecture 14: Function Objects & Parameterized Types; Anonymous Classes & Lambda
Lecture 15: The Fundamental List Abstraction:   Fold
Lecture 17: Midterm Review
Lecture 16: Properties of Equality:   Reflexive, Symmetric, Transitive, and Total
Lecture 19: Structural Equality with Double Dispatch; Abstracting and Overridding
Lecture 18: More Double Dispatch
Lecture 22: Optional, Maps, Sets, and Lifting Default Code to Abstract Classes
Lecture 23: The Visitor Pattern
Lecture 24: Implementing Visitors; Bank Accounts
Lecture 25: Imperatives:   Implicit Communication via Side-Effects
Lecture 26: Aside:   List Exercises
Lecture 27: Imperatives:   Cyclic Data
Lecture 28: Imperatives:   Methods over Cylic Data
Lecture 29: BSTs, Maps, The Law of Hash  Code, and Comparable vs Comparators
Lecture 30: Random access and Array  Lists
Lecture 31: Implementing Hash Tables
Lecture 32: Resizing Hash Tables
Lecture 33: Simple Iterators
Lecture 34: List Iterators and Iterator Combinators
Lecture 35: List Iterators and Iterator Combinators
Lecture 36: Zippers
Lecture 37: Naive Tree Iterators
Lecture 38: Efficient Pre-Order Tree Iterators
Lecture 39: Drills
Lecture 40: Drill Solutions
Lecture 41: Wrap-up
6.12

Lecture 7: Introducing Java: Syntax and Semantics

Video.

Introducting Java Syntax

You’ve now seen several programming languages: BSL, ISL, ISL+, and class/0. Now time for one more: Java. Let’s start by looking at the syntax, the way Java programs are written.

Here’s a comment in class/0:
;; Hi there

Here’s a comment in Java:
// Hi there

Here’s a block comment in class/0:
#| Hi
   there |#

Java:
/* Hi
   there */

A class definition in class/0:
;; A Coord is a (new coord% Integer Integer)
(define-class coord%
  (fields x y))

A class definition in Java:
class Coord {
Integer x;
Integer y;
}

Notice here that the convention for class names in Java is to capitalize them. Also notice that, because Java is a typed language, it requires us to specify the type of the fields. In this case, the fields x and y are both objects belonging to the Integer class. So in Java, some of the information that we’re used to writing down as part of data definitions becomes part of the actual program text; not just a comment.

The above class definition defines a new class of values, called Coords. A Coord value is an object with an x and y field, both of which hold Integer objects.

One thing that Java requires us to write explicitly is a constructor, whereas class/0 made the constructors for us. The way constructors work in class/0 is to say new, a class name, and then give the appropriate number of expressions (one for each field); the value of these expressions are used to populate the fields of the object. We can write such a constructor in Java by revising the class definition:

class Coord {
Integer x;
Integer y;
 
Coord(Integer x, Integer y) {
this.x = x;
this.y = y;
}
}

This constructor definition says if you call the constructor (we will see how in a moment) with two integers, it will populate the fields of a Coord object with the given integers.

To make a Coord in class/0, you write:
(new coord% 3 4)

To make a Coord in Java, you write:
new Coord(3, 4)

In general, the arguments of the constructor can be arbitrary expressions that produce integers, e.g.
new Coord(2 + 1, 2 * 2)

In class/0, if you have a coord% object o and want to extract the value in the x field, you write:
(send o x)

In Java, the notation for send is a “dot” written between the object expression and the field name:

o.x

So for example:
new Coord(2 + 1, 2 * 2).x
would produce 3 when run.

To add some functionality to Coord objects in class/0, we’d write:
;; A Coord is a (new coord% Integer Integer)
(define-class coord%
  (fields x y)
 
  ;; Integer Integer -> Coord
  (define (move dx dy)
    (new coord% (+ (send this x) dx) (+ (send this y) dy))))

To write the same thing in Java:
class Coord {
Integer x;
Integer y;
 
Coord(Integer x, Integer y) {
this.x = x;
this.y = y;
}
 
Coord move(Integer dx, Integer dy) {
return new Coord(this.x + dx, this.y + dy);
}
}

There are a few things to note here. First, all of the peices from the class/0 definition are present, but the signature that existed in comments is now part of the code. The part of the signature to the right of the -> is now to the left of the method name in Java. The other thing to note is the use of the return keyword and ; around the expression in the body of the method; this is signalling that the method produces whatever the expression evaluates to.

Invoking the method uses the send notation similar to accessing a field:

new Coord(3, 4).move(1, 2)

The above expression will produce new Coord(4, 6) when run.

To actually run programs, we will have to either run the programs from within a programming environment, like DrRacket but for Java, or use a Java compiler and run the Java interpreter from the command line. These will be covered in demos in class.

Grammar: Simplest Java

Taking a step back, we can characterize the syntax of Java, or at least the small bit of Java we’ve covered so far, with the following grammar:

 

program

 ::= 

class-defn*

 

class-defn

 ::= 

class class-name { field-decl* constructor method-defn* }

 

field-decl

 ::= 

class-name field-name ;

 

constructor

 ::= 

class-name ( param-list ) { constr-body }

 

param-list

 ::= 

 

  |  

class-name id [, param-list]

 

constr-body

 ::= 

field-init*

 

field-init

 ::= 

this . field-name = id ;

 

method-defn

 ::= 

class-name meth-name ( param-list ) { return expr ; }

 

expr

 ::= 

number

 

  |  

this

 

  |  

expr   +   expr

 

  |  

expr   *   expr

 

  |  

expr   .   field-name

 

  |  

expr   .   meth-name   (   arg-list   )

 

arg-list

 ::= 

 

  |  

expr [, arg-list]

 

class-name

 ::= 

id

 

meth-name

 ::= 

id

 

field-name

 ::= 

id

 

id

 ::= 

any name except for reserved words like class, this, return, etc.