>
CSCI 555 (Functional Programming, in Scala)
Lecture Notes
CSci 555: Functional Programming
Spring Semester 2016
Lecture Notes
Sections
Schedule, Lecture Notes, and Examples
- (26 Jan) Examine syllabus and discuss class organization.
- Discuss programming paradigms
- (26 Jan) A programming paradigm is "a way of
conceptualizing what it means to perform computation, of structuring
and organizing how tasks are to be carried out on a computer."
-- from: Timothy A. Budd. Multiparadigm Programming in
Leda, Addison-Wesley, 1995, page 3
- (26 Jan) Programming
Language Paradigms, section 1.3, pages 5-6, from the
instructor's Notes on Functional Programming with
Haskell
Note: I use the phrase "programming language paradigms" in
this document. More correctly, I should only say "programming
paradigms" and differentiate among different styles of programming
but not among languages. A language typically supports more than one
style although some styles may be more directly supported than
others.
Concepts: programming language paradigm, imperative
language, declarative language, functional language, relational or
logic language; program state, implicit versus explicit state;
sequencing versus recursion, execution of commands versus evaluation
of expressions, "how" versus "what" to compute.
- Peter Van Roy's Programming
Paradigms Poster website
- Motivate the study of functional programming
- (28 Jan) Excerpt from
Backus' 1977 Turing Award Address, section 1.2, pages 2-4, from
the instructor's Notes on Functional Programming with
Haskell
From the 1977 Turing Award Address, John Backus. Can Programming Be Liberated from
the von Neumann Style? A Functional Style and Its Algebra of
Programs, Communications of the ACM 21.8 (1978):
613-641.
Concepts: von Neumann computer, bottleneck; von Neumann
language, world of expressions versus world of
statements. Functional programming.
- (28 Jan) Reasons for
Studying Functional Programming, section 1.4, pages
6-10, from the instructor's Notes on Functional Programming
with Haskell
Concepts: referential transparency, abstraction,
higher-order function, first-class function, eager versus lazy
evaluation, separation of data from control
- (2 Feb) Objections
Raised to Functional Languages, section 1.5, pages
11-12, from the instructor's Notes on Functional Programming
with Haskell
- Introduce Scala to Java programmers
- (2-9 Feb) Notes on Scala for Java Programmers
[HTML]
[PDF]
Michel Schniz and Philipp Haller, A Scala Tutorial for Java Programmers
Concepts: basic syntax and semantics of Scala from the
perspective of a Java programmer; includes singleton objects, val
and var identifiers, type inference, infix method calls,
higher-order and first-class functions, anonymous functions,
argumentless methods, classes, overriding, case
classes, pattern matching, traits, generics, etc.
- (4 Feb, for Assignment #1) Arithmetic expression tree program skeletons
- (9 Feb) Scala
Class Hierarchy
Concepts: Unification of Java/Scala primitive value types
under type AnyVal
, Java/Scala reference types under
AnyRef
, and both under Any
.
- (for reference) A Tour of Scala
- (for reference) Martin Odersky. Scala by Example, June 11,
2014.
Original at
http://www.scala-lang.org (Documentation, Older Documentation,
Scala By Example).
- Explore recursion in Scala
- (11 Feb) Recursion Concepts and Terminology: Scala Version
[HTML]
[PDF]
[Elixir]
[Lua]
Concepts: recursion, linear and nonlinear
recursion, tree recursion, backward and forward recursion, tail
recursion, tail recursion optimization (also know as tail call
elimination or proper tail calls), auxiliary functions,
accumulating parameter (i.e. accumulator), nested functions, time
and space complexity of recursive functions, termination arguments
for recursive functions, preconditions and postconditions, Scala
function definitions.
- (for reference) Tail call (on
Wikipedia)
- Examine functions adapted from SICP
- Background reading: Chapter 1 of the classic textbook SICP
-- Harold Abelson and Gerald J. Sussman with Julie
Sussman. Structure and Interpretation of Computer
Programs, Second Edition, MIT Press, 1996:
[book site at MIT
Press]
[HTML book]
[SICP ebook site]
[local copy of source code]
- (9-11 Feb) First-order functions in Scala
Concepts: Reinforces the concepts noted above for the "Notes
on Scala for Java Programmers" and the notes on "Recursion Concepts
and Terminology." Scala object as module, appropriate use of type
inference and explicit typing of public features.
- (11 Feb) Higher-order functions in Scala
Definition: A higher-order function is a function that
takes other functions as input and/or returns a function as its
output value.
Related definition: A first-class function is a
function that is a first-class value in the language. It can be
stored in a variable or some other data structure, passed to a
function, or returned by a function.
Concepts: Higher order functions allow us to capture the common
aspects of a computational pattern in the fixed part of a function
and pass in the variable aspects as functional arguments.
- (for reference) Other versions
- Study functional data structures
- Background reading: "Functional Data Structures," Chapter 3,
Paul Chiusano and Runar Bjarnason, Functional Programming in
Scala
- (16-18 Feb, 25 Feb, 1-3 Mar) Functional data structures lecture notes to accompany
Chapter 3 (primarily on the
List
data type)
[HTML]
[PDF]
Scala source code from notes: List2.scala
Big ideas: Using algebraic data types and pattern
matching and implementing functional (immutable) data
structures.
Concepts: referential transparency, side effect,
immutable; algebraic data type, composite type, sum type (tagged,
disjoint union, variant), product type (tuple, record), enumerated
type, algebraic data type versus abstract data type, syntax,
semantics; list, head, tail, constructor, sealed
,
case class
, case object
, distinction
between case and regular objects, singleton object; polymorphism,
ad hoc polymorphism, overloading, subtyping (subtype or inclusion
polymorphism), parametric polymorphism (generics), type class,
early versus late binding; variance, covariant, contravariant,
invariant (nonvariant), variance annotation; companion object;
form of the data guides the form of the algorithm, following types
to implementations, pattern matching; associativity, identity
element, monoid, zero element; variadic functions,
apply
method in companion object; data sharing,
persistent data structure; when to throw exceptions, when not;
backward recursion, tail recursion, accumulating parameter,
auxiliary function; higher-order function, anonymous function
(function literal), underscore notation in anonymous functions;
fold functions, map function, filter function, flatMap function;
local mutation; type inference, currying, partial application,
upper and lower type bounds, view bounds; insertion sort, merge
sort, total order pattern of computation, generalizing function
definition; stack overflow error; method chaining, train wreck.
- (23 Feb) No class because of instructor illness
- Examine a natural number arithmetic package
- (for reference) Background on Peano arithmetic:
[Wikipedia]
[Wolfram
MathWorld]
- (3 Mar) Scala versions
Concepts: Natural numbers, Peano arithmetic;
object-oriented design patterns (Composite, Singleton, Null Object);
reinforcement of previous Scala and functional programming concepts.
- (for reference) Other versions
- Examination #1 on 10 March over the material above
- Enjoy Spring Break 14-18 March
- (22 Mar) Discuss graded examination #1
- Explore abstract data types (ADTs)
- (for reference) Background on abstract data
types
- Nell Dale and Henry Walker. "Abstract
Specification Techniques," Chapter 1, In Abstract Data
Types: Specifications, Implementations, and Applications,
pp. 1-34, D. C. Heath, 1996.
- Abstract data
type (on Wikipedia)
- William R. Cook. Object-Oriented Programming Versus Abstract Data Types, In
Proceedings of the REX Workshop/School on the Foundations
of Object-Oriented Languages (FOOL), LNCS 489, pp. 151-178,
Springer-Verlag, 1990. [local]
- William R. Cook. On
Understanding Data Abstraction Revisited, In
Proceedings of OOPSLA, October 2009: [local]
- (8, 22-29 Mar) Lecture Notes on Data Abstraction
Big ideas: Defining abstract data types as coherent,
meaningful "mathematical" entities and implementing them flexibly,
hiding the details behind stable interfaces.
Concepts: abstraction, procedural and data
abstraction, procedure, function, method, concrete and abstract data
structure, interface, information hiding, secret, encapsulation,
state, instance, type, abstract data type (ADT), ADT operation, ADT
specification (name, set, signatures, semantics), axiomatic
(algebraic) semantics, constructive semantics (abstract model),
axiom, invariant, interface and implementation invariants,
preconditions and postconditions, constructor, mutator, accessor,
destructor, atomic operation, generic parameter, total and partial
functions, client-supplier contract, ADT design criteria.
- (for reference)
Lecture notes on Data
Abstraction--Java Supplement -- gives nongeneric Java
implementations, circa 1997, of the Stack and Day ADTs specified in
the Data Abstraction notes above.
- (for reference) Older mutable Java abstract data type
implementations. These use nongeneric Java implementations done
during the 1997-98 timeframe.
- Queue ADT -- gives a
specification for a Queue ADT and implements the ADT directly as
< two concrete classes.
- Ranked Sequence ADT --
gives a specification for a Ranked Sequence ADT (similar to
ArrayList or Vector).
- (8, 24-29 Mar) Examine the CookieJar ADT case study
- Cookie
Jar ADT Problem Description
Purpose: The CookieJar case study illustrates
design and implementation methods for abstract data types (ADTs)
and information hiding modules in Scala. It gives formal interface
implementation invariants for the ADT module and precondition and
postcondition assertions for each function (operation).
Concepts: Information-hiding module, interface,
specification of abstract data types, abstract model, mathematical
bag, interface and implementation invariants for ADTs,
preconditions and postconditions for ADT operations, immutable
versus mutable objects, use of Scala traits and generics to
define ADT interface, use of builtin Scala functions for
collections
- Description of Bag
Concept (used in specification)
- Immutable CookieJar ADT Implementation in Scala
(
ICookieJar
) -- uses method chaining functional style
with immutable objects
- Mutable CookieJar ADT Implementation in Scala
(
CookieJar
) -- uses object-oriented style with mutable
state
- (for reference) Carrie's Candy Bowl ADT in Lua -- gives the
specification of a Candy Bowl ADT (similar to the Cookie Jar
above) and two implementation using Lua modules.
- (for reference) Carrie's Candy Bowl ADT Scala
-
(29-31 Mar) Examine the Labeled Digraph ADT case study
- (for reference) Background
- Nell Dale and Henry Walker. "Directed Graphs or Digraphs,"
Chapter 10, In Abstract Data Types: Specifications,
Implementations, and Applications, pp. 439-469 ,
D. C. Heath, 1996.
- Conrad Barski. "Building a Text Game
Engine,", Chapter 5, In Land of Lisp: Learn to Program in
Lisp, One Game at a Time, pp. 69-84, No Starch Press, 2011.
The Common Lisp example in this chapter is similar to the classic
Adventure game; the underlying data structure is a labeled
digraph.
- Scala solutions using method-chaining abstract
data type API
Concepts: Use of Scala trait and generics to define
ADT interface, applying ADT specification concepts, using
mathematical concepts to model ADTs (sets, sequences, bags,
functions, relations), graph data structure. Scala constructors
(private, auxiliary), builtin List and Map (HashMap) data structures,
extensive use of functions such as map, filter, and flatMap.
- Examining the instructor's set of
operations for the Labeled Digraph ADT in the Digraph trait according to the Design Criteria for
ADT Interfaces (last) section of the Data Abstraction notes.
Note: There is some possible redundancy and lack of atomicity
in the way the "labels" are set and in having the
update_edge
operation, but otherwise it seems to be a
reasonable set.
- (for reference) Haskell solutions using a module and
algebraic data type (needs a few bug fixes, including remove_vertex
on map version)
- (for reference) Elixir solutions
- (5-12 Apr) Explore functional error handling
- Background reading: "Handling Errors without Exceptions," Chapter 4,
Paul Chiusano and Runar Bjarnason, Functional Programming in
Scala
- Handling Errors
without Exceptions lecture notes to accompany Chapter 4
[HTML]
Option
and Either
implementations from notes:
[Option2.scala>]
[Either2.scala]
Big idea: Using ordinary data values to represent
failures and exceptions in programs. This preserves referential
transparency and type safety while also preserving the benefit of
exception-handling mechanisms, that is, the consolidation of
error-handling logic.
Concepts: Option
and
Either
algebraic data types, referential
transparency, type safety, error handling, exceptions, type
variance, parameter passing (by-value, by-name), thunk, free
variables, closure, strict and nonstrict parameters/functions,
eager and lazy evaluation, lifting, for-comprehensions, syntactic
sugar, (generators, definitions, guards), desugaring.
- (7 Apr) Discuss Mealy Machines for Assignment #3
Concept: In the theory of computation, a Mealy
Machine is a finite-state automaton whose output values are
determined both by its current state and the current input. It is a
deterministic finite state transducer such that, for each state and
input, at most one transition is possible.
- (12-19 Apr) Explore strictness and laziness
- Background reading: "Strictness and Laziness," Chapter 5,
Paul Chiusano and Runar Bjarnason, Functional Programming in
Scala
- Strictness and
Laziness lecture notes to accompany Chapter 5
[HTML]
[PDF]
Stream
implementation from notes: StreamC.scala
Big idea: Exploiting nonstrict function to increase
efficiency, increase code reuse, and improve modularity
Concepts: Strict and nonstrict (lenient)
functions/parameters, termination, bottom, call-by-name, thunk,
forcing, call-by-need, lazy evaluation, lazy lists or streams,
Stream
data type, smart constructors, memoization,
`lazy` variables, purity of functions, separation of concerns,
information hiding, design secret, abstract interface, business
logic, Model-View-Controller (MVC) design pattern, keeping program
description separate from evaluation, incremental computation, prime
number, Sieve of Eratosthenes, recursive, corecursive (guarded
recursion), productivity (cotermination).
- Reference: John Hughes, Why
Functional Programming Matters, Computer Journal,
Vol. 32, No. 2, pp. 98-107, 1989.
(21 Apr) Discuss problem-solving techniques.
- Concepts: George Polya's four phases of problem
solving; problems-solving strategies (solve a more general problem
first, solve a simpler problem first, reuse off-the-shelf solutions
to standard subproblems, solve a related problem, separate concerns,
divide and conquer)
- Chapter 10 of Notes on Functional Programming with Haskell,
pages 105-108
(21 Apr) Discuss the changes in computer systems over past 70
years and their implications for programming and programming language
design.
- Effect of
Computing Hardware Evolution on Programming Languages,
instructor's lecture notes
- (for reference) Nathan Ensmegner's Early History of
Computing, The Franklin Institute`<
- (for reference) Wikipedia article on the History of Computing Hardware
- (for reference) Wikipedia article on the Timeline of Computing
(21 Apr) Discuss history
of programming languages over past 60-plus years, calling
attention to the emergence of paradigms and major languages. See instructor's notes.
(21-28 Apr) Discuss domain-specific languages and Sandwich
DSL case study
- Concepts: domain-specific languages (DSLs); DSLs
versus general-purpose programming languages; external versus
internal DSLs; shallow versus deep embedding of internal DSLs; use
of algebraic data types to implement DSLs
- Domain-Specific
Languages, instructor's lecture notes
- Sandwich DSL Implementation
- (for reference) Sandwich DSL in Lua (similar but not
identical to Haskell description)
(briefly discussed, 26 Apr) Discuss Computer Configuration DSLs
(28 Apr) Examination #2
(3 May) Discuss graded Examination #2 and Assignment #2
(5 May) Discuss graded Assignment #3 (Mealy Machine) and
Instructor's solution
(5 May) Discuss Final Exam and Optional Assignment #4; final
thoughts for semester.
(12 May, 8:00 a.m.) Final Exam
MISCELLANEOUS UNSTRUCTURED MATERIALS FROM PREVIOUS
COURSES
Survey modular design
- Lecture Notes on Modular Design
Concepts: module, modular specification and design,
independent development, changeability, comprehensibility,
commonality and variability, information hiding, secret, interface,
signature, syntax and semantics, abstract interface, two-phase
specification, callback, design by contract, software or program
family, software product line, software framework, table ADT, key,
total and partial orderings.
- (for reference) H. C. Cunningham, Y. Liu, and
J. Wang. "Designing a
Flexible Framework for a Table Abstraction," In Y. Chan,
J. Talburt, and T. Talley, editors, Data Engineering: Mining,
Information, and Intelligence, pp. 279-314, Springer, 2010.
- (for reference) Parnas papers on modular
specification
- Information hiding: D. L. Parnas. "On the Criteria to Be Used
in Decomposing Systems into Modules," Communications of the
ACM, Vol. 15, No. 12, pp.1053-1058, 1972.
- Software families: D. L. Parnas. "On the Design and
Development of Program Families," IEEE Transactions on
Software Engineering, Vol. SE-2, No. 1, pp. 1-9, March
1976.
- Extensible system design: D. L. Parnas. "Designing Software
for Ease of Extension and Contraction," IEEE Transactions on
Software Engineering, Vol. SE-5, No. 1, pp. 128-138, March
1979.
- Abstract interfaces: K. H. Britton, R. A. Parker, and
D. L. Parnas. "A Procedure for Designing Abstract Interfaces for
Device Interface Modules," In Proceedings of the 5th
International Conference on Software Engineering,
pp. 195-204, March 1981.
- Modular specification of large systems: D. L. Parnas,
P. C. Clements, and D. M. Weiss. "The Modular Structure of
Complex Systems," IEEE Transactions on Software
Engineering, Vol. SE-11, No. 3, pp. 259-266, March 1985.
Use the Digraph ADT module (to build a game)
- (for reference) Wizard's Adventure,
Version 1 game from Chapter 5, 6, and 17 of Conrad Barski's
Land of Lisp: Learn to Program in Lisp, One Game at a
Time, No Starch Press, 2011.
Concepts: Importing Elixir modules, use of Elixir features
such as atoms, maps, pipes, and complex pattern matching, designing
functional programs to handle global state; use of Elixir API
modules Enum
, Dict
, List
,
Keyword
, String
, IO
, etc.).
- (for reference) Wizard's Adventure, Version 2 that uses a higher order function
to generate game actions and improved handling of the game state
Note: I pointed out the use of the higher-order factory
function (i.e., set_game_action
) on 2 March, so that
concept was covered on the 4 March exam. I planned to cover this
example more on the next class; the next class turned out to be 16
March.
Additional concepts: Use of higher-order factory function to
generate functions from first- and higher-order arguments; storing
functions in a data structure, calling functions stored in a data
structure; use of mutator (setter) and accessor (getter) functions
for the data structure.
Notes on Functional
Program Evaluation Concepts
Develop a Email Message Building Internal DSL using Method Chaining with
Progressive Interfaces:
Develop a State Machine Model and "Secret Panel" Controller External DSLs
H. C. Cunningham. "A Little Language for Surveys: Constructing an
Internal DSL in Ruby," In Proceedings of the ACM SouthEast
Conference, 6 pages, March 2008.
[manuscript]
[presentation]
[Ruby source code]
[test DSL input file]
[test DSL input file with errors]
Lua versions similar to Martin Fowler's Lair Configuration
domain-specific language (DSL) examples from his book chapter "One Lair
and Twenty Ruby DSLs," Chapter 3, The ThoughtWorks
Anthology: Essays on Software Technology and Innovation, The
Pragmatic Bookshelf, 2008: [book site]
Note: The DSL patterns mentioned are from the DSL patterns catalog from
Martin Fowler's book Domain Specific Languages
(Addison Wesley, 2010:
Shared modules
- Class support module (same as in Movable Objects case study)
[class support module (class_support.lua)]
- Semantic Model
[model module (model.lua)]
[test driver (rules00.lua)]
Internal DSLs
- Global Function Sequence
[builder module (builder08.lua)]
[dsl script (rules08.lua)]
[test driver (test08.lua)]
- Class Method Function Sequence with Method Chaining
[builder module (builder11.lua)]
[dsl script (rules11.lua)]
[test driver (test11.lua)]
- Expression Builder with Method Chaining
[builder module (builder14.lua)]
[dsl script (rules14.lua)]
[test driver (test14.lua)]
- Nested Closures
[builder module (builder03.lua)]
[dsl script (rules03.lua)]
[test driver (test03.lua)]
- Expression Builder with Object Scoping and Method Chaining
[builder module (builder17.lua)]
[dsl script (rules17.lua)]
[test driver (test17.lua)]
- Literal Collection
[builder module (builder22.lua)]
[dsl script (rules22.lua)]
[test driver (test22.lua)]
External DSL
- LPEG Parser/Builder (no corresponding example in Fowler paper)
[builder module (builderLPEG1.lua)]
[dsl script (rulesLPEG1.dsl)]
[test driver (testLPEG1.lua)]
CRuby version of Fowler's DSL framework.
- DSL Reader Framework module:
[ReaderFramework.rb source code]
- DSL Reader Utilities module, a mix-in used several places:
[ReaderUtilities.rb
source code]
- Simple test data files:
[Data input file]
[Text DSL description]
[XML DSL description]
[Ruby DSL description]
- Direct configuration and testing of Reader:
[BuilderDirect.rb source code]
- Single-pass text DSL configuration and testing:
[TextSinglePass.rb source code]
- Two-pass text and XML DSL configuration and testing:
[TwoPass.rb source code]
[class BuilderExternal source code generated by TwoPass.rb]
wef- Ruby internal DSL configuration and testing:
[RubyDSL.rb source code]
Overview object-oriented programming in Scala
- Introduction to Object-Orientation (not updated for 2016)
- Simple, silly Employee hierarchy example:
[Scala source]
[listing]
[output]
- Scala translation of Frog dynamic composition example:
[Scala source]
[listing]
[output]
- Modified Philosophical Frog example from Odersky et al:
[Scala source]
[listing]
[output]
- Modified Stackable traits example (IntQueue) from Odersky et al:
[Scala source]
[listing]
[output]
Frameworks, based on Timothy Budd's An Introduction to
Object-Oriented Programming, Third Edition, Chapter 21.
Cunningham group "Using Classic Problems..." paper.
- H. C. Cunningham, Y. Liu, and C. Zhang. "Using Classic Problems
to Teach Java Framework Design," Science of Computer
Programming, Special Issue on Principles and Practice of
Programming in Java (PPPJ 2004), Vol. 59, No. 1-2, pp. 147-169,
January 2006. doi: 10.10.16/j.scico.2005.07.009.
[preprint PDF]
- Related tutorial: H. C. Cunningham, Y. Liu, and
C. Zhang. "Teaching Framework Design Using Classic Problems,"
Journal of Computing Sciences in Colleges, Vol. 21,
No. 5, pp. 10-12, CCSC, May 2006. [abstract]
[presentation]
Scala Divide-and-Conquer Framework, similar to the Java framework
in the "Using Classic Problems..." paper.
- Template-based Divide-and-Conquer Framework
(DivConqTemplate):
Scala source]
Strategy-based Divide-and-Conquer Framework (DivConqStrategy):
[Scala source]
Traits for Problem and Solution descriptions for both frameworks (DivConqProblemSolution):
[Scala source]
- Application of Template-based framework to QuickSort (QuickSortTemplateApp):
[Scala source]
[program output]
Application of Strategy-based framework to QuickSort (QuickSortStrategyApp):
[Scala source]
[program output]
Descriptor for QuickSort state for both QuickSort applications (QuickSortDesc):
[Scala source]
Scala Binary Tree Framework, similar to the Java framework in the
"Using Classic Problems..." paper:
- Straightforward translation of the Java program to Scala.
Top-level framework (BinTreeFramework) [Scala source]
Second-level Euler tour framework (EulerTourVisitor)
[Scala source]
Second-level mapping framework (MappingVisitor)
[Scala source]
Second-level breadth-first framework (BreadthFirstVisitor)
[Scala source]
Application of BinTree frameworks (BinTreeTest)
[Scala source]
- Generic implementation of BinTree framework in Scala.
Top-level framework (BinTreeFramework)
[Scala source]
Second-level Euler tour framework (EulerTourVisitor)
[Scala source]
Second-level mapping framework (MappingVisitor)
[Scala source]
Second-level breadth-first framework (BreadthFirstVisitor)
[Scala source]
Application of BinTree frameworks (BinTreeTest)
[Scala source]
John Vlissides. "Designing with Patterns," In Pattern
Hatching: Design Patterns Applied, Addison-Wesley, 1998.
[slides]
Pipes and Filters Architectural Pattern
[notes]
[slides]
Mary Shaw. "Some Patterns for Software Architecture," In John M
Vlissides, James O. Coplien, and Norman L. Kerth, editors,
Pattern Languages of Program Design 2, Addison
Wesley, 1996, pages 255-270.
[manuscript]
Develop a list module in Lua
- Purpose: This Lua case study illustrates (i) functional
programming principles, (ii) design and implementation methods for
abstract data types and information hiding modules, and (iii) Lua
programming techniques (linked lists, stateless iterators,
closures, metatables, etc.)
- General programming language concepts: information-hiding
module, interface, secret, changeability, data representation,
interface and implementation invariants for modules (or abstract
data types), preconditions and postconditions for functions,
primitive operation (function), convenience operation (function),
function closure, proxy
- Background reading on Lua: Chapter 11 on data structures (pages
107-116) and Chapter 15 on modules (pages 151-161) of
Programming in Lua (PiL)
- Background reading on modular programming: Data Abstraction lecture notes
- Lua Module Design Principles, instructor's lecture notes
- Cell-based list module:
[module source]
[test driver]
- Closure-and-table-based list module variant:
[module source]
[test driver]
- Function-based cell list module variant:
[module source]
[test driver]
- Lazy list module variant using C
preprocessor (cpp -P)
[module source]
[source after cpp]
[test driver]
[driver after cpp]
[sh script]
- Lazy list module variant using
LuaMacro 2.5
[macro definitions]
[module macro source]
[source after luam -o]
[macro test driver]
[driver after luam -o]
[sh script]
Develop complex number arithmetic modules in Lua
adapted from SICP Section 2.4.
- Background reading: Section 2.4 of Abelson and Sussman's Structure and Interpretation of Computer
Programs, Second Edition, MIT Press, 1996
Modules are repeated in each package in which they are used
- Rectangular coordinates modules
[arithmetic]
[rectangular representation]
[utilities]
[test driver]
- Polar coordinates modules:
[arithmetic]
[polar representation]
[utilities]
[test driver]
- Tagged data modules:
[arithmetic]
[data tagging]
[utilities]
[test driver]
- Data-directed programming modules:
[arithmetic]
[rectangular representation]
[polar representation]
[data tagging]
[utilities]
[test driver]
- Object-oriented modules:
[arithmetic]
[utilities]
[test driver]
Examine the Dice of Doom game program in Elixir. This is
adapted from chapters 15 and 18 of the book: Conrad Barski. Land
of Lisp: Learn to Program in Lisp, One Game at a Time, No
Starch Press, 2011.
- Background reading on
Enum
and
Stream
collections used extensively in this case study:
- Version 1a: Basic eagerly
evaluated version (similar to that developed on pages 303-325 of
Land of Lisp). This version supports either two human
players or a human player and a simple, minimax search-based "AI"
(artificial intelligence) opponent.
Concepts: Game tree, decoupling game rules from rest of
game, game loop, minimax search, eager evaluation, use of Erlang modules
(specifically, :random
) from Elixir, extensive use of
Elixir Enum
, Dict
, String
,
and List
modules.
Definition: Eager evaluation (or greedy
or strict evaluation) is an evaluation strategy that
evaluates an expression as soon as it is bound to a variable.
[adapted from Wikipedia article on eager evaluation,
2015-03-23]
- Version 1b: Eager version above with an attempt at memoization
of functions
neighbors
and game_tree
using
the Elixir Agent
modules.
Concepts: Memoization, Elixir
Agent
module and processes.
Definition: Memoization is a programming technique
that stores a previously computed values of a function to avoid
recomputing it when the function is called again with the same
arguments. In general, the storing of the function's values should
be hidden from the caller of the function.
Note: An Elixir Agent works reasonably well for functions
such like neighbors
that require small amounts of data
to be sent in messages to and from the agent process. It does not
work well for functions like game_tree
that require
huge amounts of data to be transferred. I plan to experiment with
the Erlang Term Storage (:ets
) system to implement
memoization, but I expect this approach to have similar issues. Most
likely the eager algorithms and data structures will need to be
modified to work well with Erlang and Elixir.
- Version 2a: Lazy version using Elixir
Stream
data
structures (but without the memoization optimizations). This is
based on version 1a above plus the discussion from pages 384-389 in
chapter 18 of Land of Lisp. This version implements a
limited depth minimax search, but it does not implement the
artificial intelligence heuristics given in the last part of chapter
18.
Concepts: Lazy evaluation, Elixir Stream
data
structure, limited depth minimax search.
Definition: Lazy evaluation (or
non-strict evaluation or call-by-need) is an
evaluation strategy that delays the evaluation of an expression
until its value is needed and that also avoids repeated
evaluations. [adapted from the Wikipedia article on lazy evaluation,
2015-03-23]
Movable and Named Objects case study (in Lua but
based on a Haskell case study by Thompson)
- Purpose: The Named and Movable Objects case study explores use
of inheritance hierarchies and multiple inheritance in Lua. I also
extracted a "class support module" from the initial version of this
code; this module was used in later case studies (e.g., Lair
Configuration DSL).
- General object-oriented programming language concepts:
prototype object, class, subclass (child) class, superclass (parent
or base class), abstract and concrete classes, single and multiple
inheritance, abstract (deferred) methods, constructor (factory
method), accessor and mutator methods, proxy object, method
injection, template method pattern (template and hook methods)
- Background reading on object-oriented programming languages:
Introduction to Object-Orientation,
instructor's lecture notes through the section titled "An Object
Model"
- Background reading on case study: Section 14.6 of Simon
Thompson. Haskell: The Craft of Functional Programming,
Third Edition, Addison Wesley, 2011
- Note: We should readdress the design and implementation of this
case study and the class support module. The latter may be too complex
for our purposes in this course.
- First Lua version: [source
(movable.lua)]
- Modularized version with improved class support
[class_support module]
[using class-support (movable2.lua)]
[test driver (movable2Test.lua)]
- Other older versions:
[Haskell source]
[Scala source (partial) ]
Lua Parsing Expression Grammar (LPEG) library
- Roberto Ierusalimschy's talk LPEG: A New Approach to
Pattern Matching [PDF slides]
[video]
- (For reference) Roberto Ierusalimschy's paper "A Text
Pattern-Matching Tool Based on Parsing Expression Grammars,"
Software: Practice & Experience 39 #3 (2009) 221-258: [PDF]
Parsing arithmetic expression trees using LPEG (Lua Parsing
Express Grammar) library:
- Parser with captures
- Parser with
semantic actions
Kamin Interpreters in Lua Toolset (KILT)
[Compressed tar file]
- Language/Interpreter-independent modules:
[REPL Module (repl.lua)]
[Environment Module (environment.lua)]
[Function Table Module (funtab.lua)]
[Utilities Module (utilities.lua)]
[Opcodes Factory Module (opcodes.lua)]
[Values Factory Module (values.lua) ]
[Parser Factory Module (parser.lua)]
[Evaluator Factory Module (evaluator.lua)]
-
Kamin Chapter 1 Core language interpreter:
[Core Interpreter (Core.lua)]
[Core Opcodes (opcodes_core.lua)]
[Core Values Module (values_core.lua)]
[Core Parser Module (parser_core.lua)]
[Core Evaluator Module
(evaluator_core.lua)
-
Kamin Chapter 2 Lisp language interpreter:
[Lisp Interpreter (Lisp.lua)]
[Lisp Opcodes (opcodes_lisp.lua)]
[Lisp Values Module (values_lisp.lua)]
[Lisp Parser Module (parser_lisp.lua)]
[Lisp Evaluator Module (evaluator_lisp.lua)
[A few Lisp examples]
-
Kamin Chapter 4 Scheme language interpreter:
[Scheme Interpreter (Scheme.lua)]
[Scheme Opcodes (opcodes_scheme.lua)]
[Scheme Values Module (values_scheme.lua)]
[Scheme Parser Module (parser_scheme.lua)]
[Scheme Evaluator Module
(evaluator_scheme.lua)
[A few Scheme examples]
Reference Materials and Other Resources
- Scala Documentation
site
- H. Conrad Cunningham. Notes on Functional Programming with
Haskell.
[ PDF ]
[ CODE ]
- Haskell Simple mathematical expression recognizer
[source]
[54 lines per page listing]
- Framework
Design Using Function Generalization
- Haskell Type Inference
- Overloading and Type Classes
UP to CSCI 555 root document?
Copyright © 2016, H. Conrad Cunningham
Last modified: Sun Apr 9 23:01:21 CDT 2017