Worksheet Lox
Table of Contents
1. Lox
From the schedule tab of the course homepage, download the lox interpreter for chapter 13. Because we deal with many versions of the language, I will sometimes identify them by chapter. Thus, the lox interpreter of chapter 13 will be called lox13.
Follow the instructions on the resources page to compile and run lox13. Play with the interpreter. Type in the programs from chapter 3 of the book and watch them execute.
Note that lox does not print anything unless you have an explicit print statement:
$ java -cp target/classes com.craftinginterpreters.lox.Lox lox13> 1+3 [line 1] Error at end: Expect ';' after expression. lox13> 1+3; lox13> print 1+3; 4
Multi-line programs must be included in a file, such as this:
fun returnFunction() { var outside = "outside"; fun inner() { print outside; } return inner; } var fn = returnFunction(); fn();
$ java -cp target/classes com.craftinginterpreters.lox.Lox returnFunction1.lox outside
Enter CTRL-D to exit the Lox REPL.
2. Scala
Here is a Scala version of the returnFunction
from lox. This time, it
returns a pair of functions rather than a single function. This is not easy
to express in lox because it does not have built-in pairs.
def returnFunction() : (()=>Unit, ()=>Unit) = { var outside = "outside"; def inner() = { println (outside); } def changeInner() = { outside = "something else"; } return (inner, changeInner); } def main (args:Array[String]) = { var (fn1, fn2) = returnFunction(); fn1(); fn2(); fn1(); }
$ scala returnFunction2.scala outside something else
You can also run it like this:
$ scala Welcome to Scala 3.4.1 (21, Java OpenJDK 64-Bit Server VM). Type in expressions for evaluation. Or try :help. scala> :load returnFunction2.scala def returnFunction(): (() => Unit, () => Unit) def main(args: Array[String]): Unit scala> main(Array()) outside something else
Here we are invoking the main function with an empty Array.
Enter CTRL-D to exit the Scala REPL.
3. Lexical Structure
Take a look at the lexical structure of scala by examining the Language Reference
4. Visitor Pattern
Compare and contrast the following three versions of the same code.
4.1. Simple Java
abstract class Pastry { public void printMe (); } class Beignet extends Pastry { @Override public void printMe() { System.out.println ("It's a beignet"); } } class Cruller extends Pastry { @Override public void printMe() { System.out.println ("It's a cruller"); } } class PastryTest { public static void main (String[] args) { var ps = new Pastry[] {new Beignet(), new Cruller()}; for (var p : ps) { p.printMe(); } } }
$ javac PastryTest.java $ java PastryTest It's a beignet It's a cruller
4.2. Scala match
enum Pastry: case Beignet case Cruller import Pastry.* def printPastry (p: Pastry) = p match case Beignet => println("It's a Beignet") case Cruller => println("It's a Cruller") def main(args:Array[String]) = var ps = List(Beignet, Cruller) for (p <- ps) do printPastry(p)
$ scala Pastry.scala It's a Beignet It's a Cruller
4.3. Java Visitor
interface PastryVisitor { public void visitBeignet(Beignet beignet); public void visitCruller(Cruller cruller); } abstract class Pastry { public abstract void accept(PastryVisitor visitor); } class Beignet extends Pastry { @Override public void accept(PastryVisitor visitor) { visitor.visitBeignet(this); } } class Cruller extends Pastry { @Override public void accept(PastryVisitor visitor) { visitor.visitCruller(this); } } class PastryPrinter implements PastryVisitor { public void visitBeignet(Beignet beignet) { System.out.println ("It's a beignet"); } public void visitCruller(Cruller cruller) { System.out.println ("It's a cruller"); } } public class PastryTest { public static void main (String[] args) { var printer = new PastryPrinter (); var ps = new Pastry[] {new Beignet(), new Cruller()}; for (var p : ps) { p.accept(printer); } } }
$ javac PastryTest.java $ java PastryTest It's a beignet It's a cruller