Should Apple adopt a Functional Programming Language?

jolon
10 min readDec 9, 2021

In Stack Overflow’s 2021 survey, the top four highest paying languages were all functional: Clojure, F#, Elixir, and Erlang. Three of the four most loved languages were also functional: Rust, Clojure, and Elixir.

The top four highest paying programming languages on Stack Overflow in 2021 were functional.

In the 1980s and 1990s the buzz was around object-oriented languages mostly C++ and then Java. In recent times functional programming languages have become more popular, and existing imperative languages are adding more functional features.

Is it time for Apple to go functional ?

Whither functional programming?

Some have asked the question why hasn’t functional programming become mainstream? One explanation is that functional programming languages arrived somewhat later than imperative languages.

For example, the imperative language Fortran was released in 1957, it was some 20 years later in 1977 that ML was released which encapsulates most of the features that people today would describe as a functional language (Lisp was earlier but didn’t support many functional features). By this time Pascal, BASIC, COBOL, and C had been developed and were in widespread use. And object-oriented programming had begun with Simula and Smalltalk. Object-oriented programming captured the worlds imagination and in the mid-1980s Objective-C and C++ were released. It wasn’t until 1996 (after Java and JavaScript) when OCaml was released which added support for object-oriented programming to ML.

So functional languages were behind imperative languages (time-wise) and had missed the major hype train of OOP. As a result they were largely ignored and didn’t receive the focus that imperative programming languages had received. Additionally functional languages were rarely general purpose or suited for systems programming which was a serious limiting factor in those times when performance and memory were important.

However, things are changing. Functional languages are becoming more performant and hardware performance has increased such that higher level abstractions are often more important than raw performance or memory usage (e.g. Python, JavaScript, Swift). In addition they are becoming more general purpose as libraries are added to support general purpose computing.

As a result I think we are very close to functional languages becoming mainstream, and certainly programmers are using more functional features in existing imperative languages. Is it time for Apple to consider adopting a functional programming language?

A short history of Apple’s programming languages

Here is a list of the programming languages Apple has used by decade:

  • 1970s — Assembly, BASIC, Pascal
  • 1980s —Object Pascal, C/C++, HyperTalk
  • 1990s — AppleScript, Dylan, NewtonScript, Objective-C, Java
  • 2000s — MacRuby, JavaScript
  • 2010s — Swift

I’ve highlighted in bold, the programming languages that were created at Apple, rather than adopted.

We can see that Apple has had 15 different programming languages over the last 45 years, that’s a new language every 3 years!

These are the basic themes of each decade:

  • 1970s — Procedural
  • 1980s — Object-oriented
  • 1990s — Dynamic
  • 2000s — Web
  • 2010s — Halfway functional
  • 2020s — Functional??

We can see to an extent that Apple has followed the major trend in each decade, which points to the next language being a functional language.

Why a new language?

Many existing languages are adding functional features. Objective-C added code blocks. Swift has many functional features such as pattern matching, optionals, and algebraic data types. Why not just extend an existing language to be completely functional?

However if a language isn’t functional from the start it is difficult to use it properly in a functional manner. For example, Swift’s control structures don’t return a value which makes it virtually impossible to write a function in a functional style. It is also difficult to update the language to be more functional. For example, it may not be possible to allow Swift to have control structures return a value without making breaking changes.

Neither Objective-C or Swift can be made into true functional languages, as a result a new language is most likely required.

Create or Adopt?

An interesting question is whether Apple should create a brand new language, as it has done for over a third of the languages it has used, or adopt an existing one.

I think we can answer this by looking deeper at the languages that Apple created. Object Pascal, HyperTalk, and Swift were created by passionate individuals within the company, namely Larry Tesler, Bill Atkinson, and Chris Lattner, respectively (each a legend in their own right). I think it is safe to say that none of these languages would exist if it weren’t for those individuals. Creating a new language is no small task and it requires a special individual to bring a language to fruition that a major company would adopt.

Does Apple have an employee at the moment who would create a new language, or has created a new language?

You may be wondering about the other languages in bold. AppleScript is actually a more generalised successor to HyperTalk. Dylan and NewtonScript were created for the Newton platform which was ultimately disbanded when Apple acquired NextStep (and hence the switch to Objective-C). MacRuby is not in bold as it isn’t a new language, however it was a project by an employee at Apple, which ultimately was no longer supported when the employee left.

Whither the Objective-C runtime?

An interesting challenge Apple has is how much the OS frameworks revolve around the Objective-C runtime. Objective-C isn’t just a programming language it is also a runtime and it is so ingrained in the frameworks that Swift also is designed to work with the Objective-C runtime.

Objective-C was designed in the early 1980s, some 40 years ago. In the context of functional programming languages should we reconsider whether the Objective-C runtime is still the right approach?

Keep in mind that the Objective-C runtime allows you to do things like create classes, create instances of classes, and send messages to those instances which run code and mutate data. How does that fit in with modern functional programming?

I think for the transition period some bridge to the Objective-C runtime is necessary however it shouldn’t hold back the functional language going forwards.

As an aside, there was a language called F-Script which was designed to interact with the Objective-C runtime but is no longer maintained (even though not developed at Apple it was used internally by Apple engineers as it turned out to be quite good for debugging their frameworks).

Functional language features

These are the features I think Apple requires:

The first feature is the ability to compile to native code. There is no reason why a high-level language can’t compile to native code and given Apple is focussed on performance and efficiency, there should be the ability for native code compiling. This is commonly available in functional languages such as Haskell, OCaml, and Rust.

Static typing. Some functional languages like Clojure and Elixir don’t have static typing. This can make the languages more approachable at the start but almost always is more painful later on. This points to languages like OCaml, Haskell, and Rust.

Impure. I think at this stage, systems level programming still needs to be somewhat pragmatic. The developer, the compiler, and the runtime can tie themselves in knots trying to be pure. Having the flexibility to be able to call code with side effects is probably required at this stage. So this rules out Haskell, whereas OCaml and Rust are still on the list.

OCaml or Rust?

This is a tough one. Rust’s syntax is more familiar. However, I’m not sure that the low-level memory semantics is required by most programs.

My ideal language would be something like Rust, with a more OCaml-like semantic layer. For example, if Rust had a library of immutable data types, then the low-level memory semantics wouldn’t be required because the data isn’t mutable. At the moment though, even if you have an immutable library you still need to know the memory semantics to use it properly. The low-level memory semantics are handy though for software that really needs the raw performance so Rust would be the most general language.

There are other dialects of OCaml such as ReasonML and ReScript which make the syntax more familiar to JavaScript developers. This shows that it is relatively easy to make the OCaml syntax more familiar.

There are other more obscure languages that Apple could embrace. An interesting one is Unison which represents all functions as a hash of its AST, effectively forming a global universal database of functions, which also allows functions to be passed to distributed nodes for execution (and cached).

Server-side Programming

An interesting factor to consider is server-side programming. I raise this for two reasons. Firstly, historically, functional programming languages have mostly been used on the command line rather than for desktop or mobile apps and bring interesting server capabilities, e.g. Erlang/Elixir. And secondly, server-side programming is so popular these days it’s hard to imagine a programming language becoming mainstream if it isn’t also suitable on the server, even if that isn’t Apple’s main intention for the language.

It may not be apparent but many of Apple’s languages have had some relationship with server programming…

Objective-C, at NextStep, was used on the server with WebObjects, which was also used by Apple for their website and online store. However it never really took off outside of Apple. When Apple bought NextStep, initially the goal was to switch from Objective-C to Java, which is well known to be a server language today (although originally was meant to also be for desktop applications), however Apple eventually dropped support for Java.

In the 2000s Apple began to build some of their cloud services with Ruby on Rails. In fact Apple even bundled Ruby on Rails with Mac OS X Leopard. On the client-side, still web-related, Apple released the SproutCore JavaScript framework for Mac-like UI in the browser. I’m not sure if it was related but the MobileMe monumental failure may have been the death knell for Ruby and JavaScript at Apple.

Apple made a concerted effort to get Swift on the server with a major deal with IBM. The thinking was to code the app in Swift and the backend in the same language. However, ultimately that hasn’t really taken off.

So Apple has shown some interest in server-side programming. I guess you could say that Swift ultimately isn’t ideal for that application. So when deciding on a functional language Apple may want to take into account server and distributed capabilities so that it finally might have a language that is also suitable on the server.

Migrating to functional

One challenge with migrating to functional is that it can be a more significant change than say moving from procedural to object-oriented.

Procedural is effectively a subset of object-oriented which results in a gentler transition because both are still imperative languages. The transition from imperative to functional though is a more serious change that many developers have yet to make.

Having said that, even with Swift, Apple has made drastic changes. SwiftUI for example is pretty much an entirely new API and way of doing things which relies on language features that operate very differently to how the language operated previously, such as ResultBuilders and state decorators (in fact this is quite a functional technique).

Conclusion

I really think that Apple has to at least investigate whether it should move to a functional language. The fact that Swift already has some functional features added and the fact that SwiftUI is pretty much a tour de force approach to functional GUIs, surely developers inside Apple must be thinking: Why don’t we just go the whole hog and adopt a functional language rather than wrestling with Swift?

It is interesting to enumerate the languages Apple has used. One every 3 years. The last new language from Apple was Swift in 2014, so even if Apple was only to start investigating a new language now with potential release to the public in 5 years time, that would put it way overdue compared to it’s previous regular introductions of new languages.

Historically Apple has moved with the times with languages. Object-oriented, user-level scripting, Java, MacRuby, JavaScript, and now Swift. The times certainly are moving towards more functional languages. It will be interesting to see what Apple does here.

Afterthoughts — Apple’s failures

Apple has made an unfortunate series of bad decisions with their programming languages.

Object Pascal, influenced by Smalltalk, led to C++. If you used a Mac in the 1990s you knew that whole system freezes occurred extremely frequently, saving frequently was standard practice.

Dylan was a modern language based on Lisp. Dylan is still a more modern language than Swift, but unfortunately it wasn’t ready in time and instead NewtonScript was hacked together. As a result Dylan never saw the light of day in an Apple product. Steve Jobs canned Dylan when he returned preferring Objective-C and Java. Java might’ve been better as now there are good functional languages that compile to the JVM such as Scala and Clojure. But for some reason Java was canned.

MacRuby and JavaScript had their day at Apple. MacRuby and/or JavaScript would probably still be good options today. MacRuby does lack static data types though. I think part of the issue for Apple is that while desktop computers had plenty of power and memory, Apple’s biggest selling product in the late 2000s was the iPhone which had restricted memory and performance. To give users the best Apple experience, there wasn’t really an option other than Objective-C. Some may remember how slow early JavaScript apps were.

Objective-C continued to take root leading to Apple’s next major error. Chris Lattner had built LLVM, a replacement for GCC, and LLVM had excellent static memory analysis. So incredible was its memory analysis skills that the same technique was used to take care of memory automatically through automatic reference counting (ARC). This suddenly made Objective-C an impressive and robust language. But Lattner wanted to modernise it and make the syntax more approachable (always an issue with Objective-C). Lattner began working on Swift. There were two things going for Swift when it was announced: 1) Lattner, and 2) Non-Objective-C syntax. Lattner had such a great reputation, who wouldn’t want to use a language designed by the guy who had just revolutionised the compiler tool chain to the point of making Objective-C robust? It had to be good, right? And using more Java-style syntax instead of Objective-C was almost a done deal. But unfortunately Swift has turned into a mess. I won’t elaborate on Swift’s failings here, but it really is an embarrassment of a language.

So Apple unfortunately seemed to make these bad decisions at each stage. Will they get it right next time?

--

--