A description of a fictitious future programing language.
People who know me closer know that I have an obsession with finding the perfect programing language.
This obsession goes through phases: Sometimes I am disillusioned about the state of affairs. Then I hear about a new exiting language and read the whole reference in one night. Then I realize that compromises have to be made and go back to writing Haskell.
Currently I am a little bit in the disillusioned state. Yeah, no programing language is perfect … But to cope with it I thought I could try some cherry-picking and tell you what I hope the future of programing should look like.
I would like to have a programing language, that is
Of course what you also always want from a programing language is a nice community, a rich ecosystem, good tooling and obviously a fast execution, but I won’t be talking about those here …
I think in the last years static, strong typing has increasingly become mainstream. Examples include type annotations for Python, Typescript and Rust. Of course it is not enough to have static types, they also need to be sufficiently expressive. For me that means that you at the very least need Algebraic Data Types.
Still, in this post I am dreaming, and so I would like to have dependent types (with type erasure). I know a lot of people are apprehensive of the “dark type level magic” Haskell offers today. But I am quite convinced that type level programing will get easier and more intuitive once reasoning on the type level works exactly the same as on the term level.
One application for which I personally would like good dependent types support is tracking matrix dimensions at the type level, this is currently possible but tedious in Haskell. But of course there are lots and lots of other use cases for dependent types.
I wont argue much for this. But in my opinion it is absolutely a must have. Tracking side effects and having referential stability change how you think about a program and enable declarative programing.
I remember, when I first heard about functional programing I was very confused about this and wondered what use a language without side effects can have. But the aim is of course not to avoid any side effects but have an explicitly way of tracking were they happen. Of course you need a type system which can support this.
This is an exiting one. I have only programmed a few hours in Unison but the experience was amazing. You work with a database of functions. Every functions tracks all other functions it uses by hash. When you change a function you create a new one and change the name to point to the new function. Unison records all your changes so that you can later update other code depending on yours by changing the hashes and guiding you through semantically resolving conflicts. This work flow solves so many problems with programing that I especially disliked:
As a nixpkgs maintainer I am haunted by the conceptual difficulties of finding a working build plan and packaging it. With content-addressed code and dependency tracking on the level of single functions packaging this is a solved problem. Conflicts will rarely happen and always be resolved by the author of the code, when they decide to update.
Git merges can only do so much to help you with creating working code. If version tracking is built into your code database merging will happen on a semantic level.
Naming stuff is hard and prone to bike shedding. Deciding in which file which function goes is also hard. Renaming and moving code to other files needs at least very good tooling. (Haskell is not there yet, for example.) And when you have a public API you just can‘t do it. With content addressed code that’s a thing of the past.
Every Haskell Module starts with a ton of import. You always have to decide if you want to import everything into scope, import qualified or import single functions. With content-addressed code this becomes much less important, much like formating it becomes something the database manager takes care of for you.
Now this one is maybe the most futuristic. One of the reasons Haskell is not suited for very resource constrained scenarios is the fact that it’s garbage collected. On the other hand while I think that Rust is a great language, and one reason for that is its safe static memory management, it is my opinion that for most use cases the developer shouldn‘t be bothered with manual memory management. That’s why I prefer garbage collected languages. In a perfect world the developer should never be bothered with manual memory management, but currently that won‘t fly for quite a few use cases. So why not have our cake and eat it too? There is this promising thesis about As Static As Possible Memory Management by Raphaël L. Proust. It basically suggest to have the compiler generated a small garbage collector optimized for each individual program via static code analysis. If this approach could actually bring a real benefit in practice is an open research question, but I recommend having a look in there anyways, because it neatly lays out the problem space.
Now, there are a lot of properties, which I am unsure about. Should the language be strict or lazy, do we need typeclasses, linear types, what’s the best syntax? And don‘t get me started on the right effect system …
I am pretty sure to have strong guarantees and good runtime performance a compiled language will be desirable, but I am not 100% certain about that. (But using ASAP memory management and talking about type erasure implies a compiled language.)
How could we get there?
Haskell is great and soon it will hopefully have dependent types. The very promising GRIN Compiler Project could bring us closer to better runtime performance and maybe even static memory management. Also it has the potential to bring interopability between functional languages. Maybe Idris, Haskell, Unison and others could share an ecosystem of libraries? That would be great and would maybe make it easier to profit from the dependent types in Idris.
Unison has a beautiful concept with going all in on the content-addressed idea and I really like the syntax, but it’s still very young and I am not sure, that it will move in the direction of dependent types. Still if Unison could oneday be compiled with the GRIN Compiler that would be pretty amazing.
Another project to be aware of is fragnix which implements content-addressed code for Haskell, but it is also in a very early stage.
Still all the puzzle pieces are there and I am exited to be there when they will all come together.
Have any feedback? You can reply to this post on Mastodon or contact me some other way (see above)
We are used to a lot of decisions in this world being made by people with money. I think this is bad, especially if it kills us.
When you are confronted with a tough choice, it might be helpful to accept that you have been disappointed. Disclaimer: This post contains ideas about how one could think. I do not claim that reading this article will help with thinking this way.