The Polyglot Programmer

This talk was presented to the CT CTO Club in March of 2012. These were the notes myself. I don't claim they'll make sense to anybody who wasn't there.

Table of Contents

1 Introduction

A language that doesn't affect the way you think about programming, is not worth knowing.
– Alan J. Perlis

Ruby and Smalltalk and dynamic runtimes,
Emacs and shell scripts and UNIX command lines,
Macros and lambdas and networking pings,
These are a few of my favorite things.
– me

These are my notes for a talk given to the Connecticut CTO Club on March 21, 2012.

Title of this talk should not be "Emerging Platforms and Frameworks" but perhaps "Playing With Languages", or "The Polyglot Programmer", or "Jim's completely personal, subjective look at some cool programming languages." I've played with some of these languages for a few days, others on and off for a few decades.

This presentation is a subjective look at programming languages that I think your developers should be investigating, playing with, and learning from. Will look at both old, busted hotness and new hotness.

Also an ultra brief mention of some frameworks and development tools for those languages.

Why bother playing with new languages? Learning a new language helps you use the languages you already know even better. Helps you understand strengths and weaknesses. Sapir-Whorf hypothesis?

See Paul Graham's Beating the Averages for an introduction to Blub.

1.1 Risks of Playing

Big risk: prototype goes into production, as happens so often.

Go ahead and use these languages in production. Most of them are very mature and stable. Many of them interact with or run on existing tech (JVM, CLR).

Will you be able to find developers to support this new code and expand on it? Let your developers use some of these and I claim you'll be beating away good developers with a stick. Have only mediocre developers? Let them get better — or cut away dead wood that refuses to learn new things and keep the ones that enjoy learning and applying their new-found knowledge.

2 Definitions

2.1 Typing

2.1.1 Dynamic vs. Static Typing

  • Type checking performed at run time (dynamic) vs. compile time (static)

2.1.2 Strong vs. Weak Typing

  • Strong: practically speaking, can't cast to another non-related type

2.2 Meta-programming

The ability to change, at run time, the way the language works (for example, message passing a la method_missing), the way that types behave, or change the way the type system behaves. Examples: method_missing, using Class#inherited to add methods to a class at run time.

Remember: metaprogramming is jus tprogramming.

2.3 Functional Programming

Program is a series of mathematical functions. No side effects, state, or mutable data.

No side effects means after the execution of a function nothing else in the system has changed — no state changes, and to the ultimate extreme no input or output!

Makes code easier to test and easier to verify correctness.

2.4 Object Orientation

2.5 Actors / Agents

Message passing between independently running chunks or objects. Autonomous individuals.

2.6 Parallel and Concurrent

The difference doesn't matter for this talk.

Concurrent code is made up of multiple streams of execution. Streams can communicate and interact with each other. Concurrent code may be executed in parallel. Concurrent programs may use shared memory or message passing to communicate between concurrent subsystems.

2.7 Software Transactional Memory (STM)

Database transactions for memory.

2.8 Immutability

State that can not change. Makes it easier for compilers and runtimes to reason about the code and what side-effects it may have, and make optimizations.

2.9 Distributed Programming

Software runs on different machines but acts as if it's running on one machine.

2.10 REPL

Read-Eval-Print Loop.

2.11 Macro

Code that writes code.

2.12 Homoiconicity

Code and data are stored in the same format. Lisp is the most famous example. Makes many things like code manipulation easy.

2.13 Pattern Matching / Destructuring

2.14 More

Defined below.

3 How to Play With a New Language

  • Follow along with the tutorials, line by line
  • Write a small utility
    • Will immediately start diving into libraries
  • Clone an existing small app
    • Almost literal transliteration from old language
    • Iterate, improving what you've written
      • Start using new language features
      • Start making better use of existing standard libraries
      • Start using new idioms
    • At this point you'll find yourself starting to think differently
  • Write something larger
    • Ask on mailing lists

4 Old Busted Hotness vs. New Hotness

There's something to be said for learning a few key languages that have influenced the design of many others. My list:

  • Assembly
  • C
  • Smalltalk
  • Lisp

5 Smalltalk

Core concept: message passing between objects that have no other knowledge of each other. Ask another object to do something or tell you about itself. From biology: "cell" holds data (state) and responds to messages.

Alan Kay, inventor of OO, co-developed Smalltalk as a language for "human-computer symbiosis" and education.

Like the game of Go: small number of rules, powerful combinations. You can learn Smalltalk in five minutes. The standard class library, however…

Coder spends 80% of time reading libraries and other code, then writes the one or two lines that takes advantage of all of that.

Incredibly mature libraries and core classes.

VM with image. Everything in memory, everything saved to disk when image is saved: code, objects, state. Live debugging. Debugger is an editor. Halt, edit, resume. Ultimate TDD.

No files. Code browser and editor built in.

Blocks/closures. Even "if" is implemented as message passing. obj ifTrue: block.

Not the best for multi-developer development.


Free implementations: Pharo (for developers), Squeak (for experimentation and education), Gnu Smalltalk (file based).

6 Lisp: Common Lisp, Scheme

Two opposite ends of a spectrum. Common Lisp is the Emacs of the Lisp world. Scheme is the "ed" (pure, minimalist).

Macros: code that writes code. Homoiconicity: code is data and vice versa. That means you can create or manipulate code as if it were data. Do so during "read time" (sort of like compile time) and you can easily write code that writes code.

Common Lisp is a language that can be used with pretty much any style of programming: functional, procedural, OO (CLOS, the Common Lisp Object System, with classes, instances, generic functions, and multimethods with multiple dispatch).

A few different implementations of CL: SBCL, ABCL, CLISP, CMUCL. I mainly use SBCL when playing with CL.


7 Forth

Stack based. Again like game of "Go". Build up "words" (subroutines). Procedural, weakly typed.

8 Assembly

Learn how your machine really works! Understand memory and pointers like you never have before!

9 Clojure

9.1 List, Map, Vector, Set

More syntax to support them. All implement a common supertype "sequence".

9.2 Java interoperability

Runs on the JVM. Fewer parens than Java!

9.3 Functional

9.4 Sequences

Unified set of functions that works on all seq-able types

9.5 Lazy

Infinite lists

9.6 Recursion

JVM doesn't support recursion directly (yet), so have loop/recur and supports trampolining.

9.7 Destructuring

A.k.a. pattern matching. Pull pieces out of data structures (lists).

9.8 State vs. Identity

State: your age Identity: who you are

In Clojure, identities (variables, references, actors) reference different descriptions of state over time.

Changes in state over time can be implemented very efficiently because of immutability. Values are immutable, persistent data structures. Updating an identity does not destroy old values.

9.9 Software Transactional Memory

9.10 STM

  • Reference (coordinated, sync access)
  • Atom (uncoordinated, synchronous)
  • Agent (async, fire (pass a function) and maybe forget)
  • Vars (thread-local)

Coordinated vs. uncoordinated, synchronous vs. asynchronous.

Transients let you break out of strict rules around synchronized STM access, for efficiency's sake.

9.11 Data types

Define abstract types

9.12 REPL

10 Scala

10.1 C :: C++ -> Java :: Scala

10.2 Functional, Strongly and Statically Typed

10.3 Wrappers around Java classes and primitives

…so pretty efficient

10.4 Also OO, Traits

Traits: methods and field definitions. Mixins. Can mix any trait into any class.

10.5 Mutable and Immutable

10.5.1 Collections, by default immutable

10.5.2 Variables (val vs. var)

10.6 Type inference

  • Hindley-Milner type inference
  • Great for simple cases
  • Overly complex if trying to build a library or for certain types of Java interaction

10.7 Case Classes and Pattern Matching

Pattern matching: destructuring. Used with match statements and case classes.

10.8 Academic

10.9 Java interaction, .NET (CLR) "also available"

10.10 XML

Useful for (X)HTML templating, I suppose.

10.11 Shortcomings (IMHO)

  • type system
  • slow compiler
  • IDE support still weak
  • language still changing, not always backwards compatible
  • docs not the best; books don't always cover everything you need

10.12 REPL / "Scriptable"

Unix and Windows

10.13 Tool for keeping Java running so start up times are eliminated

11 Erlang

Developed at Ericsson for telecom. Influenced by Prolog.

  • Soft real time
  • Distributed
  • High-availability

11.1 Features

  • Functional: can't change var's value after assignment
  • Distributed programming with actors
  • Concurrency
  • Bit and byte stream
  • Pattern matching (destructuring)
    • Used on method params and in match statement
  • Tuples, Records
  • Recursion
  • List manipulation, great — string manipulation, not so hot
  • REPL

11.2 Actors

  • 300,000 on one machine no problem
  • Pass data and functions
  • Uses a mailbox
  %% ...

11.3 OTP

  • Framework for Slave/Master monitoring and fail over

11.4 Mnesia

  • Distributed database
  • ACID
  • Query using Erlang
  • Cassandra, CouchDB

11.5 Hot code swapping

  • Actors typically run in a loop, calling the loop func recursively at the end. If you pass in a new function that implements an improved version of the loop or even completely new code, your loop can call that function at the end, replacing the old loop with the new code. Voila! Hot code swapping.

12 Go

A better C — systems programming language. Griesemer, Pike, and Thompson. Used at Google (though I hear not for that much).

  • Compiled
  • GC
  • Concurrent
  • Type safety and memory safety
  • New built-in types: maps, Unicode strings, array slices, and channels
  • Multiple value return (often used to return error code along with result)
  • Decent standard libraries

Everything passed as copies. Mostly pass references. For arrays, mostly pass slices.

Go 1.0 just came out.

12.1 Interfaces and Object Model

No inheritance, generic types, or method overloading.

Interfaces are close to duck typing: define a set of functions. If your type implements those methods then you can be used wherever the interface is used. No need to declare that in your type, IIRC.

Trick: generic collections via use of the empty interface. The type of the thing that implements the empty interface is kept.

12.2 Channels

Inter-process communications. "in" and "out" channels produce and consume pieces of data (characters, ints, objects). Often used with goroutines.

Infinite lists, generators.


12.3 Goroutines

Small, lightweight threads. Executed in parallel.

Idiom: channel running in goroutine acting as consumer or producer.

13 Haskell

  • Closest to pure math
  • Types, types, types
  • Pure functional
  • Lazy
  • Monads

14 OCaml

  • "Objective Caml"
  • Dialect of ML

14.1 ML

  • Functional, Hindley-Milner type inference

15 IO, Self

  • Prototype inheritance
  • Slots contain values or methods

16 Ruby

I can't say enough good about Ruby. It's how my brain works.It's my go-to language for almost everything. Path from thought to code is shortest and least painful.

16.1 Making Programmers Happy; Principal of Least Surprise

16.2 Duck typing

16.3 JRuby

16.4 Mirah

16.5 REPL

17 Python

17.1 Jython

17.2 REPL

18 Groovy

18.1 Java devs jealous of Ruby

18.2 Elvis Operator (handle nil gracefully)

18.3 REPL

19 PHP

20 JavaScript

  • Prototype inheritance

21 CoffeeScript

22 Objective C

Subjective C (check that link; is the repo name correct?)

Brad Cox, classes as programmable chips that can be plugged together. NeXTSTEP (or NextStep, or NextSTEP, or NeXtStEp…)

22.1 C + Smalltalk

22.2 Protocols

22.3 Handle nil gracefully

23 F#

24 Frameworks

24.1 Packaging systems

  • Ruby: gems
  • Python: eggs
  • Perl: CPAN
  • Groovy: ??
  • Squeak/Pharo Smalltalk: Montecello
  • Scala: sbaz

24.2 Building, Writing Apps

24.3 Static HTML

24.4 Java, Scala Play

24.5 Roo for Java

REPL for building Spring apps

24.6 Node.js, Backbone.js for Javascript; JQuery

24.7 Lift for Scala

24.8 sbt for Scala

24.9 Scala Pre-forking JVM??

24.10 CL Hunchentoot

24.11 Clojure web app dev still open

24.12 lein and cake for Clojure

  • lein for project management (dependencies, building)
  • cake for pre-forking and more

24.13 Erlang Yaws (?), MochiWeb, webmachine (on top of MochiWeb)

24.14 Go ?

There are a few, but I've read that if you use them you're doing it wrong. The standard library includes HTTP servers, templating, and more.

24.15 Ruby: Rails, Sinatra, more. Rack

24.16 Groovy: Grails, Gradle (build)

24.17 Python: ???

24.18 PHP: Zend, Kohana

24.19 Smalltalk: Seaside

25 Takeaways

  • Play
  • Learn to think different
  • Playing with new languages improves your ability to use the languages you use now

Author: Jim Menard <jim@jimmenard.com>

Date: 2012-04-11 14:35:56 EDT

HTML generated by org-mode 6.33x in emacs 23