CPS 343/543 Lecture notes: Course reflection

Homoiconic languages

  • a homoiconic language is one which uses the same representation for programs and data, thus, permitting programs to be created, modified, and executed at run-time [PLP] p. 552
  • homoiconic languages facilitate metaprogramming (developing programs which create and manipulate other programs or extend themselves) by obviating the need to translate between internal (data structure) and external (syntactic) representations of programs [PLP] p. 575
  • LISP, PROLOG, XSLT, Tcl, FORTH, and Snobol are homoiconic languages
  • on the other hand, ML and Haskell are not homoiconic languages

Languages for designing languages

  • we studied how to build recursion into a language without recursion using the applicative-order Y combinator
  • we studied how to build any control abstraction (e.g., iteration, conditionals, repetition, co-routines, threads, lazy-evaluation, gotos) using first-class continuations ([OCWC])
  • ``...we must not use recursion in the implementation language to implement recursion in the language being interpreted. ... The reason for this is that if the implementation language does not support certain kinds of control structures, then we will not be able to effectively interpret them. Thus, for example, if the control frame structure in the implementation language is constrained to be stack-like, then modeling more general control structures in the interpreted language will be very difficult unless we divorce ourselves from the constrained structures at the outset'' ([SIELC], p. 428).

UD house diagram

Course themes

  • relationship between languages and the capacity to express ideas about computation
  • static (rigid and fast) vs. dynamic (flexible and slow) properties
  • cost/speed of execution vs. cost/speed of development
  • simple and powerful languages (LISP, Smalltalk) vs. complex and weak languages (so called kitchen-sink languages [PLPP] (e.g., C++))
  • languages evolve: the influence of language design and implementation options on current trends in programming practice and vice versa (iPod, GPS in car)
  • shift in modern times towards more functional, dynamic languages (speed of execution is less important as a design goal as it once was)

Slow paradigm shift

(common thread: dynamism)
  • first-class procedures: Scheme, ML, Haskell → Fortress, Ruby, Python
  • first-class closures: LISP → Ruby
  • higher-order and anonymous (λ) functions: LISP → Ruby, Python, R, C++, C#
  • first-class continuations: Scheme → Ruby
  • dynamic scoping: LISP → Perl, Tcl/Tk
  • call-by-name/need: Algol60 → Haskell (call-by-need), R (call-by-need)
  • list comprehensions: Haskell → Python
  • strong typing: ML, Haskell → Java, C#
  • implicit dereferencing: LISP, Smalltalk → Java
  • pure OO language: Smalltalk → Ruby
  • dynamic binding: Smalltalk → Java, Python
  • reflection: Smalltalk → Java, Ruby, Perl, Python, Tcl/Tk, C#
  • homoiconic: LISP, PROLOG, FORTH → Tcl, XSLT
(e-mail me with updates when available)

Ruby is the closest language to encompassing all of these concepts.

Why are we seeing a trend toward more dynamic languages?

Software engineering, extreme programming, and so on. Efficiency is no longer the overriding design goal.

We should not think of LISP and Smalltalk as languages, but rather research projects which pioneered paradigms and language concepts.

Course objectives

  • establish an understanding of language concepts through the implementation of interpreters
  • improve ability to understand new languages and technologies, and improve background for selecting appropriate languages
  • expose students to alternate styles of programming and exotic ways of affecting computation

Advantages of this course of study

(or `why bother with this stuff anyway?')

  • see [COPL] §1.1 (pp. 2-5)
  • improve background for choosing appropriate languages
  • ability to easily learn new languages and technologies as they arrive (ability to focus on the big picture and not the details)
  • some things cannot be expressed as easily in certain languages
  • increase capacity to express ideas about computation (thinking out of the box)
  • why these languages?
  • increase ability to design and implement new languages
  • to better appreciate the historical context
  • to become a well-rounded computer scientist
  • in summary, this course will make you a better programmer, in any language


    [OCWC] C.T. Haynes, D.P. Friedman and M. Wand. Obtaining Coroutines With Continuations. Computer Languages, 11(3/4), 143-153, 1986.
    [PLP] M.L. Scott. Programming Language Pragmatics. Morgan Kaufmann, Amsterdam, Second edition, 2006.
    [SIELC] G.J. Sussman and G.L. Steele Jr. Scheme: An Interpreter for Extended Lambda Calculus. Higher-Order and Symbolic Computation, 11, 405-439, 1998.

Return Home