How hard would it be to have a static typing system in Elixir?

I think we need to be clear that we talking about static strong typing.

My impression is that it’s related to ROI/opportunity costs.

Hypothetically any process can send data to any other process based on a pid. But the value of that pid is allocated at runtime. So static analysis would have to superimpose some (artificial) static constraints on the process structure in order to check whether data being sent from one process is an accepted type in the destination mailbox.

But given that interprocess communication is typically about protocols there is a temporal aspect that static typing can’t cover. A perfectly “well formed” message in the mailbox about to be pulled out can still be “invalid” with respect to the current runtime state of the process.

Then there is the cultural aspect:

https://elixirforum.com/t/what-do-you-think-is-missing-or-needs-improving-in-elixir/2369/47

And I must say that personally type errors are the errors I very rarely make. :smile:

i.e. how much value could improved static typing add to the ecosystem - considering the potential cost of going beyond what dialyzer is capable of doing right now and might that effort be more productively spent elsewhere in the ecosystem?

It’s easy as a technology consumer to want static typing but from the technology provider perspective the cost could be viewed a prohibitive in relation to the perceived benefit (and the potential collateral damage via additional complexity).

Microsoft started developing TypeScript in 2010, 14 years after the introduction of JavaScript. It was made public in 2012 but really didn’t gain significant traction until some time in 2016 likely spurred on by the announcement of Angular 2 in 2015.

TypeScript/Dart/CoffeeScript

TypeScript/Dart/CoffeeScript/JavaScript

React + TypeScript seems to have only really become a thing around 2017. Visual Studio Code was likely another factor helping TypeScript adoption.

TypeScript/Dart/CoffeeScript/Visual Studio Code

To some extent TypeScript adoption has more to do with tooling (VS Code IntelliSense, Webstorm Refactoring Support, Resharper) rather than deliberate adoption of static typing.

This comes at the complexity cost of language constructs (Advanced Types) that exist solely so that the (library/framework) developer can compile-time-programmatically describe to TypeScript how to extract the types necessary for successful type inference.

This isn’t typically a problem for library/framework users but can put a significant additional burden on the library/framework developers. Given the things that you can do in JavaScript (and therefore TypeScript) one will have to become extremely competent with TypeScript’s “type extraction/manipulation language” or perhaps revert one’s code to a more mundane, less elegant, more restrictive, less generic version.

In statically typed languages like OCaml it usually works the other way around. You have to become a competent type wrangler before you get to use some of the more advanced techniques (hopefully safely, as there is typically an unsafe escape hatch).

All of this should create a sense of how much time and effort it took to get TypeScript to the point of where it is today - and this is in an ecosystem with significantly more resources to throw at the problem than the BEAM ecosystem.

And TypeScript doesn’t have to deal with complexities of code replacement or concurrently collaborating runtime processes with mailboxes that can receive messages from any other process in possession of their pid.

So the effort required to push beyond the current capabilities of Dialyzer should not be underestimated - and must be carefully weighed against any potentially gained benefits.

// UnknownMessage is a type that has no values, it can never be constructed!

But UnknownMessage is acknowledging a fundamental limitation:

  1. You can only type the messages you expect to receive.
  2. It also implies that you cannot put a stop to an unexpected message from being sent to you.

And it is (2) that most static typing advocates would have a problem with.

People wouldn’t be too happy with TypeScript if there was no error when a function is called with the wrong data type - and instead of raising a compile time error the function call is simply excluded from the generated source code.

15 Likes