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
- 2 Definitions
- 3 How to Play With a New Language
- 4 Old Busted Hotness vs. New Hotness
- 5 Smalltalk
- 6 Lisp: Common Lisp, Scheme
- 7 Forth
- 8 Assembly
- 9 Clojure
- 10 Scala
- 11 Erlang
- 12 Go
- 13 Haskell
- 14 OCaml
- 15 IO, Self
- 16 Ruby
- 17 Python
- 18 Groovy
- 19 PHP
- 20 JavaScript
- 21 CoffeeScript
- 22 Objective C
- 23 F#
- 24 Frameworks
- 25 Takeaways
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.
REPL
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.
REPL
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
loop(State) %% ... loop(NewState). %
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.
Cross-machine.
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
No Framework Needed: http://37signals.com/svn/posts/3103-no-framework-needed 37signals
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
Date: 2012-04-11 14:35:56 EDT
HTML generated by org-mode 6.33x in emacs 23