Recent Evolution of Programming Languages

Recently I’ve used Typescript, Scala, and Wolfram Language. Since these have features I haven’t found in other languages, I decided to survey some distinctive language features I’ve encountered. There is no attempt to cover every language and feature. The reader is assumed to be a programmer.

Data Structures

Scala, Java, and Typescript feature static typing (optional in Typescript). Scala and Typescript try to infer an omitted type as in:

val eight: Integer = 8
val nine = 9 // :Integer is unnecessary

This syntax means that Java’s compact:

String s, t;

becomes verbose in Scala:

var s: String, t: String

Scala’s deconstruction allows slightly more compact initializations:

val (one, felix) = (1, “Felix”) // Scala
// Java
Int one = 1;
String felix = “Felix”;

Scala, Java, Typescript, and Ruby feature immutability:

val Pi = 3.14159 // Scala
final float PI = 3.14159; // Java
const PI = 3.14159; // Typescript
PI = 3.14159 # Ruby constants begin with an upper case letter

Scala, Python, and Ruby have multiline strings, which Java lacks. In Scala:

val aMultilineString = """line1
"Line 3""""

Python and Scala have tuples: heterogeneous, immutable, and fixed length. In Scala:

val aTriple = (13, 3.14, "string")
aTriple._1 // 13
aTriple._2 // 3.14
aTriple._3 // "string"

Scala’s Option class is used to avoid NullPointerException:

class Option
class Some extends Option
object None extends Option
val presentGreeting: Option[String] = Option("hi")
val absentGreeting: Option[String] = Option(null)
// or equivalently:
val presentGreeting: Option[String] = Some("hi")
val absentGreeting: Option[String] = None
// or compact:
val (presentGreeting, absentGreeting) = (Some("hi"), None)
presentGreeting.get // “hi”
absentGreeting.get // throws java.util.NoSuchElementException
presentGreeting.getOrElse(“?”) // “hi”
absentGreeting.getOrElse(“?”) // “?”
presentGreeting.foreach(println(_)) // “hi”
absentGreeting.foreach(println(_)) // no output because None is skipped // Some(“HI”) // None

Scala’s lazy val is used to initialize an expensive computation for faster startup or to avoid computing an unused value altogether:

lazy val lazyVal = {
println(“initializing lazyVal”)
lazyVal // prints “initializing lazyVal”; 13
lazyVal // 13

Wolfram Language’s := is not only lazy, it re-evaluates on each access.

It is handy to have syntactic sugar for Map initialization. Java lacks this:

// Java
HashMap<String, String> joeSmith = new HashMap<String, String>(); joeSmith.put(“firstName”, “Joe”);
joeSmith.put(“lastName”, “Smith”);
// The Guava collections library features the builder design pattern.
Map<String, String> joeSmith = ImmutableMap.<String, String>builder().put(“firstName”, “Joe”).put(“lastName”, “Smith”) .build();
# Ruby hashes are a built-in type.
joeSmith = { “firstName” => “Joe”, “lastName” => “Smith” }
// Typescript is similar.
joeSmith = { “firstName”: “Joe”, “lastName”: “Smith” }
// or equivalently omit “” in keys:
joeSmith = { firstName: “Joe”, lastName: “Smith” }
# Ruby has a Symbol type that is often used as keys.
joeSmith = { :firstName => “Joe”, :lastName => “Smith” }
// Scala uses operator overloading and conversions — covered in the object-oriented programming section below.
val joeSmith = collection.immutable.HashMap(“firstName” -> “Joe”, “lastName” -> “Smith”)

Control Structures

Scala, Typescript, Python, and Ruby feature named parameters to improve correctness and clarity. In Scala:

def bracketedString(value: String = “?”, left: String = “{“, right: String = “}”) = left + value + right
bracketedString(“hi”) // {hi}
bracketedString(right=”>”) // {?>

Scala features multiple parameter lists:

def f(x: Integer)(s: String) = s”$x $s”
f(13)(“of May”) // 13 of May

Scala features implicit parameters, which import free variables:

case class Exponent(n: Double)
def power(b: Double)(implicit n: Exponent) = Math.pow(b, n.n)
val threeSquared = power(3)(3)
// or equivalently:
implicit val square = Exponent(2) // binds to power’s param n
val threeSquared = power(3) // 9

Scala distinguishes between () and empty parameter lists:

def empty = 1
empty // 1
empty() // error
def noArgs() = 2
noArgs() // 2
noArgs // 2

It is convenient to define a block and pass it in an argument list.

// Scala
def doTimes(n: Integer)(f: => Unit) = {
for (i <- 1 to n) {
doTimes(2) { // hi\nhi\n
# Ruby allows one block per function.
def doTimes(n)
for i in 1..n
yield # call block
doTimes(2) {
puts “hi”

Java8 isn’t as terse — a block must be wrapped in a lambda expression. Notice that run() in interface Runnable is not mentioned in the second argument of the call to doTimes() yet run() matches:

void doTimes(int n, Runnable r) {
for (var i = 1; i <= n; ++i) {;
doTimes(2, () -> { System.out.println(“hi”); })

Scala has a powerful match statement:

x match {
case 0 => println(“zero”)
case 1 | 2 => println(“1 or 2”)
case s: String if isMatchStrings => println(s”String $s”)
case _ => println(“unprintable”)

Scala’s catch statement is similar to match:

try {

catch {
case ioEx: => …
case ex: Exception => …

Scala features list comprehensions. Scala features a filter (aka guard) within the for statement:

def even(l: Int, u: Int): List[Int] =
for (i <- (l to u).toList if i % 2 == 0 /*guard*/)
yield i
for (j <- even(0, 20))
print(s”$j “) // 0, 2, 4, …, 18, 20

Javascript generators requires the filter to be in the for statement’s body:

function* even(from, to) {
for (let i = from; i <= to; i++)
if (i % 2 == 0)
yield i;
for (let i of even(0, 20))
console.log(i); // 0 2 4 … 20

String interpolation is available in several languages but not Java. In Scala:

val animal = “dragon”
println(s”$animal”) // dragon

Object-Oriented Programming

Automatic memory management and object-oriented programming are two features I appreciate. It is a relief that ES6 has evolved Javascript’s obscure prototypical inheritance to classic classes.

In Ruby, an instance variable is prefixed by @:

class BracketedString
def initialize(left, val, right)
@left = left
@val = val
@right = right
def toString
@left + @val + @right

In Typescript, an instance variable is referenced by this:

class BracketedString { 
private _left: String, _right: String, _val: String;
public constructor(left: String, val: String, right: String) {
this._left = left;
this._val = val;
this._right = right;
public String toString() {
return this._left + this._val + this._right;

In Java and Scala, there’s no need to qualify instance variables and methods. In Java:

public class BracketedString { 
private String _left, _right, _value;
public BracketedString(String left, value, right) {
_left = left;
_value = value;
_right = right;
@Override/*optional annotation*/ public String toString() {
return _left + _val + _right;

Scala’s primary constructor generates setters (for vars) and getters, and avoids Java’s need to repeat the class name in the constructor declaration. Scala requires overridden methods to be declared as such.

class BracketedString(var value: String = “?”, left: String = “{“, right: String = “}”) /* primary constructor */ {
def this(left: String, right: String) = this(“?”, left, right) // auxiliary constructor
override/*required*/ def toString(): String = (left ++ value ++ right)
val bs = new BracketedString(left = “<”, value = “init”, right = “>”)
bs // <init>
bs.value = “update” // mutable due to var in constructor
bs // <update>
bs.left = “[“ // compile error because immutable

Java, Ruby, and Python classes have static methods and variables as in Java:

class Mathy {
public static final Pi = 3.14159
public static double square(double x) { return x * x; }

In Ruby, static is indicated by @@ for variables while self dot for methods:

class Mathy {
@@Pi = 3.14159
def self.square(x) x * x end

Scala’s singleton object is DRYer:

object Mathy {
val Pi = 3.14159
def square(x: Double) = x * x
Mathy.Pi // 3.14159
Mathy.square(3) // 9

Scala features operator overloading as in:

class EmpoweredDouble(d:Double) {
def ~^(e:Double) = Math.pow(d, e)
val three = new EmpoweredDouble(3)
three ~^ 2 // 9

Scala, Java, and Typescript have interfaces — Scala uses the term trait. Traits can have implementations as in abstract classes in other languages:

trait Similarity {
def isSimilar(x: Any): Boolean
def isNotSimilar(x: Any): Boolean = !isSimilar(x)

Scala’s apply() method is often used for factories and to implement the () operator:

class Account(name: String) {
private var _balance: Double = 0
def apply() = _balance
object Account {
def apply(name: String) = new Account(name) // factory
val anAccount = Account(“account X”) // object Account
// or equivalently:
val anAccount = new Account(“account X”) // class Account
anAccount() // 0

Scala’s case class is a shorthand for the value object design pattern:

case class Person(firstName: String, lastName: String) // immutable
case class Person(var firstName: String, var lastName: String) // mutable

Scala’s implicit class is used to extend a class by boxing:

case class Person(name: String)
implicit class Professor(private val _p: Person/* primary constructor must have one parameter */) {
def printName() = println(s”Professor ${}”)
Person(“Poor”).printName // Professor Poor
// compiles to (new Professor(Person(“Poor”))).printName()

Here is another example extracted from the scala.Predef object that is always imported by the compiler on your behalf. It implements the syntactic sugar for Map initialization described above.

implicit final class ArrowAssoc[A](private val self: A) extends AnyVal {
@inline def -> [B](y: B): Tuple2[A, B] = Tuple2(self, y)
def →[B](y: B): Tuple2[A, B] = ->(y)



Go’s goroutine is a construct for executing a function concurrently:

package main
import (
func say(s string) {
func main() {
go say(“world”)

Java’s synchronized is a modifier for mutex execution of class instances:

public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
public synchronized void decrement() {
public synchronized int value() {
return c;


Inspired by Erlang, Scala bundled the actor design pattern for thread-safe messaging. This was abandoned in favor of a library called Akka. In keeping with highlighting language constructs, the reader probably expects an Erlang example. Since I don’t know Erlang, here is an Akka example (based on this) of a coffee-drinking actor ordering from a barista actor. The ActorSystem provides messaging services like dispatching and Actor factory. The receive method matches a message type — similar to the match statement. The ! method sends a message.

Before listing the code for a demo, here is the message flow:

ActorDemo — CaffeineWithdrawalWarning-> Customer — EspressoRequest-> Barista — Bill-> Customer
ActorDemo — ClosingTime-> Barista

Here’s the code:

import{ActorSystem, Actor, ActorRef, Props}
// declare message types
case class Bill(cents: Int)
case object ClosingTime
case object EspressoRequest
case object CaffeineWithdrawalWarning
// declare Barista Actor
class Barista extends Actor {
var espressoCount = 0 // state
def receive = {
case EspressoRequest =>
sender/*Customer*/ ! Bill(200)
espressoCount += 1 // count
println(s"Let’s prepare espresso #$espressoCount.")
case ClosingTime => context.system/*ActorSystem*/.shutdown()
// declare Customer Actor
class Customer(caffeineSource: ActorRef) extends Actor {
def receive = {
case CaffeineWithdrawalWarning => caffeineSource/*Barista*/ ! EspressoRequest
case Bill(cents) => println(s"I must pay $cents cents, or else!")
object ActorDemo extends App {
// start an ActorSystem to manage the Actors
val actorSystem = ActorSystem(“Coffee World”)
  // instantiate Actors with the factory
val barista = system.actorOf(Props[Barista], "Bonnie Barista"/*any id*/)
val customer = system.actorOf(Props(classOf[Customer], barista/*constructor’s ActorRef param*/), "Charlie Customer"/*any id*/)
  customer ! CaffeineWithdrawalWarning // prompt Customer to order
Thread.sleep(2000) // give Barista time to fulfill
  barista ! ClosingTime // tell Barista to end his shift
actorSystem.awaitTermination() // wait for Barista to shutdown ActorSystem
// non-Actors can participate using Futures
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
implicit val timeout = Timeout(2.second)
implicit val ec = system.dispatcher
val f: Future[Any] = barista ? EspressoRequest
f.onSuccess {
case Bill(cents) => println(s"Will pay $cents cents for a cappuccino")

The akka-camel package integrates actors with non-actor messaging systems.
Transparent/Orthogonal Persistence and Embedded Query Languages
The Napier language, invented in 1988, explored persistent objects. From a cursory reading of the paper:

let myEnv = environment() !I don’t know how to load an existing store
if myEnv contains Y then drop Y from myEnv
in myEnv let X = 13

LINQ (Language INtegrated Query), invented in 2007 by Microsoft, embeds a query language in C# and Basic. Given that it isn’t in Typescript, it doesn’t seem to have caught fire.

List<Person> people; // in memory data source
// or:
people = db.GetTable<Person>() // SQL data source
var adultNames = from person in people where person.Age >= 18 select person.Name;

In contrast to a functional filter (collection.filter(…)), a query optimizer can use primary/secondary indexes automatically. LINQ doesn’t appear to cover the CUD parts of CRUD at the language level.

Given the importance of persistence and many languages building in collection types (like arrays, maps, lists), it surprises me that transparent persistence seems dead.

Exotic Data Types


Lisp is the only language I’m aware of where data and programs have the same syntax. This feature suits Lisp to program generation and analysis. In this example, a 2-element list is CONStructed by a Lisp statement expressed as a 3-element list. The first element is the CONS function and the rest of the elements are its parameters.

(CONS 1 2) ; (1 . 2)

In this example the same statement is treated as data and passed to the Lisp interpreter EVAL:

(EVAL ‘(CONS 1 2)) ; (1 . 2)


There isn’t space to do it justice but Prolog computes first order logic (aka FOL).

likes(alice,bob). /* fact */
?- likes(alice,bob). /* true */
?- likes(alice,X). /* X = bob. */
love_compatible(X, Y) :- likes(X, Y), likes(Y, X). /* AND rule */
?- love_compatible(X, Y). /* X = james, Y = mary ; X = mary, Y = james. */


Scala features XML processing. {id} is replaced by id’s binding. The scala.xml package contains classes to manage XML trees.

object XMLTest2 extends App {
import scala.xml._
val df = java.text.DateFormat.getDateInstance()
val dateString = df.format(new java.util.Date())
def theDate(name: String) =
<dateMsg addressedTo={ name }>
Hello, { name }! Today is { dateString }
println(theDate(“John Doe”).toString())

Wolfram Language

Wolfram Language is the language of the powerful computation app/workbench Mathematica by Wolfram Research. One could argue its power stems from a vast, implicitly-imported library and that other languages have similar importable libraries. Even so, its unusual features are worth visiting.

A function’s parameter list is bracketed by [] instead of the prevalent (). A list is bracketed by {}. A comment is bracketed by (* *).

Wolfram Language is symbolic:

Table[1, 3] (* {1, 2, 3} *)
Table[x, 2] (* {x, x} *)
Reverse[Reverse[x]] (* true *)
⅕ (* ⅕ *)
N(⅕) /* .2 */
Expand[(x + y)^2] (* x^2 + 2xy + y^2 *)

Besides the conventional collections (list, map), there is graph and data set (akin to R’s data frame):

Dataset[<|"a" → <|"x" → 1, "y" → 2, "z" → 3|>,
"b" → <|"x" → 5, "y" → 9, "z" → 7|>|>]
| x y z
a | 1 2 3
b | 5 9 7

A vector (matrix) is expressed as a list (list of lists).

There are multimedia data types: SoundNote, Image, GraphicsObject, Color, Style, GeoPosition, GeoPath, GeoDisk. These can be visualized with functions Style[Color, fontSize], Graphics[Shape], Sound[SoundNote], GeoListPlot[{GeoPosition, …}], GeoGraphics[GeoPosition|GeoPath|GeoDisk].

Wolfram Entities have many types (termed entity classes) to represent real world knowledge. Entities have properties that are accessed with Wolfram’s function[params] syntax.

EntityProperties["Country"] (* {"Flag", "Population", …} *)
UnitedStates(country)["Flag"] (* query multiple entities *)
EntityValue[{UnitedStates(country), Switzerland(country)}, "Flag"] (* reflect a class’ properties *)
Entity["Country", "Population"→GreaterThan[10^6]] (* countries with population >1M *)
Entities[Planets(planets)] (* entities of Planets class *)
InputForm[NYC(city)] (* Entity["City", {"NewYork", "NewYork", "UnitedStates"}] *)
Interpreter["City"]["the big apple"] (* NYC(city) *)

Many functions recognize entity classes. Here the City class’ GeoLocation property is accessed transparently:

GeoDistance[NYC(city), LA(city)] (* 2432.07mi *)

Wolfram Language can express units of measure:

InputForm[2.6hr] returns Quantity[2.6, "Hours"]
UnitConvert[2.6hr, "Minutes"] (* 156min *)

Super functions choose the best algorithm for the input. For example, machine learning is encapsulated in Classify:

Model = Classify[{input→label, …}]
Model[data, "Probabilities"] (* map of prediction→probability *)


Programming languages continue to evolve albeit slowly. This document highlighted language constructs introduced along the way.

Dynamic typing has been popular but languages with type inference bridge the gap between dynamic’s brevity and static’s self-documentation and safety. Functional style and collection libraries with an immutable option are popular.

Rich data types, real world knowledge, and system services (concurrency, persistence, messaging) can be offered as language constructs or in libraries.


Thanks to Daniel Westheide (scala wiz who wrote the very informative The Neophyte’s Guide to Scala) & Bill Paseman (founder of Daisy and Calico) for careful review.