Ask HN: What would be your “perfect” programming language?
Looking for opinions on what you think are the actual issues with languages. Ive heard toolchains and documentation are a pretty big part. If say, there was a language like rust + go + scala, with an exceptional package manager and documentation, would you feel compelled to try it out?
181 comments
[ 4.0 ms ] story [ 225 ms ] threadSince the GC is fairly light and snappy, I find it's best of both world to only resort to Unsafe for the performance critical parts, and leave the GC deal with the rest.
For more serious performance requirements, consider using jemalloc: https://dgraph.io/blog/post/manual-memory-management-golang-...
I guess the "perfect" language would have far less bugs.
By the way this already kind of exists. https://github.com/JunSuzukiJapan/macro-lisp Lisp syntax that translates to real rust at compile time. I love rust!
I wish they had considered Ruby interop from inception. I am sure it's a really, really hard problem, but it would have/could have done wonders for Crystal's adoption to be able to tap into the wealth of Ruby's existing ecosystem while layering types directly in the language.
But generally speaking, after 14 years of Ruby... and also trying many more languages - I do know what I want. It's not speed. It's not memory safety. It's not paradigms. It's not static or dynamic typing. It's not the packages and the community. Nope.
I want easy code navigation. I only currently know of one language, that hasn't even been fully released yet, that achieves this task to a degree. But even then, it's only 30% there.
You answered your own question ><
> I want easy code navigation.
Static types makes this a much, much more solvable problem. But I'm curious about what you mean here, because modern code navigation tools are pretty good - even for Ruby - but perhaps I am not fully understanding what it is that you are after.
Have thought about this a lot, I really want it. I even started messing around with implementing it, but it's just a toy (an abandoned toy, even) for now.
I think the 'ingredients' for my ideal language are more or less the following, in decreasing order of importance:
- Quality of the ecosystem. You can't buy or engineer this, it kind of has to happen naturally. Good FFI and trying not to be a "let's rewrite the world" language help immensely. It's controversial to put this as the most important bullet point, but the world we have to program in is much more complicated than it was even just 20 years ago. Programs live in an environment and have to interact with databases, networks, etc. I just don't see myself programming in a language where I have to rewrite my own data structures or network code or postgres integration, it's way too much work for way too little gain.
- Tooling. Just look at Java and Go (also Python and JS, albeit to a lesser extent). It's a massive, massive productivity gain to have modern, effective tooling that supports modern workflows.
- Language features. I'm partial to the ML family, but I'm not a radical in this respect, I'll program in almost anything as long as it's sufficiently expressive and doesn't have insane semantics.
A few _very wild_ ideas:
- A configurable type system. I'm sold that stronger and more articulate type systems are the future, but sometimes, especially in smaller projects, it's incredibly annoying to have to prove to the compiler that the code you wrote is actually allowed. There's an inherent expressivity vs. correctness tradeoff that it would be interesting to have "different settings" for.
- A dependency system based on functional semantics rather than names. Imagine to reduce each function to a canonical representation (for example: its De Brujin encoding). Now you can design a dependency system where you can import a function based on its representation rather than its name.
- First-class algebras. Imagine being able to program user-defined structured sets. Strings as monoids, Vec3 as vector spaces, calendar as affine spaces, etc.
A TypeScript where (for example) string methods make sense, with all the number types and not just floats, with only null or only undefined and a lot of other things I can't think of right now.
Maybe add some pattern matching on top.
TypeScript's type system is so nice and ergonomic to use, it's a shame the basic objects of JavaScript (Object & co) are so "fickle" to work with.
To answer OP's question, I don't think there could be a "perfect" programming language.
And then one feature that I like which few languages support are some kind of contexts. Scala does this really well for example, but even in Scala it could be improved.
What I mean is that code that looks the same can mean different things in different contexts. The typesystem then ensures that it cannot be used wrongly though.
An example would be how "5 ± 3" can mean different things depending on the context, such as "1 or 8" or "mean of 5 with variance of 3" (in statistics).
Without such a feature it's hard to translate thoughts into code as easy in certain domains.
Like what this macro does https://github.com/JunSuzukiJapan/macro-lisp
Wait maybe what I want already exists
https://github.com/JunSuzukiJapan/macro-lisp
https://github.com/carp-lang/Carp
To really get good performance you probably need the ability to drop down and write more procedural style code in hot code paths and expose it with a functional interface. The details of what exactly that would look like in a way that integrated nicely would be important. I'd also want to be able to easily move code to the GPU or incrementally vectorize it.
I'd also like to see the one language / runtime support everything from C++ constexpr style compile time programming through native compilation, JIT runtime and an interpreted mode for scripting with it being easy to interoperate between levels and reuse the same code across contexts.
A good ecosystem of tools and libraries with a sane package manager and build system would also be important. F# is decent there but could still use improvement.
I'd also like to see less impedance mismatch between serialization and runtime data structures and with database / relational data. Hoon is pretty interesting in how there is no real distinction between runtime and serialized data in many contexts but its harder to see how to do something like that and meet the other goals above.
Much of the above is driven by the needs of games and VR. I'm interested to see what comes out of Simon Peyton Jones working at Epic as it seems it may lead to something along these lines.
* Good package management.
* Good, easy to reason about build system.
* Popular enough to find jobs with it.
Probably a lot more, but I don't really remember my annoyances unless they're in front of me.
Push the concurrency and distribution machinery into the language runtime. Developer can neither see nor influence it. Program just runs faster when put on more parallel hardware.
The price appears to be dropping mutation, severely limiting I/O and coming up with a domain independent scheduler for the runtime. So it's expensive but not impossible.
This is completely unworkable. It's based on the assumption that nodes have zero failure rate and networks have zero latency and packet loss and infinite bandwidth.
Distributed system programming is hard because you want to control the failure modes of your system as closely as possible. The opposite of hiding it.
It's also assuming that the runtime can make a good enough guess at when the ratio of data size to compute time for a task makes distribution profitable.
Distributed systems programming is indeed hard. That's why I want it pushed out of my applications.
...which is false, especially on large scale systems. Unmanaged cascading failures are the kind of thing that caused big downtimes in various FAANGs many times.
> Distributed systems programming is indeed hard. That's why I want it pushed out of my applications.
Companies hire good software and system engineers to do this stuff.
There are general purpose languages (say, java, go, rust, ts, and c -- one is better than another for specific tasks), and then there are HDLs, DSLs, constraint and SAT solvers, and many more I don't even know about.
- versatility: create desktop apps, mobile apps, websites, CLI
- quality of IDE / tooling
- lots of libraries to deal with all sort of corner problems
- lots of knowledge I can google
- if used professionally: lots of talents available
For the language itself, I only really care about one thing: statically typed, just because it eliminates all sort of silly bugs and makes refactoring and navigating the code so much easier. But I am not dealing with hard computer science problems.
But the most important thing is muscle memory: not having to even think of how to solve something, just do it. We can probably adapt to any major language, but you aren't productive until you develop muscle memory. That's why I am not looking to switch to any shiny new thing unless I have a really compelling reason to do so.
- good developer tooling, e.g. a language server
- This is not yet possible, but a good optimiser which can turn an abstract representation of the code into optimal code for a given hardware (CPU or GPU). Currently we are far from this, there is probably a 10x improvement that current compilers can't achieve. See for example a FizzBuzz implementation achieving ~10x throughput improvement after months of optimisation work:
https://codegolf.stackexchange.com/questions/215216/high-thr...
More complex code is likely much more improvable.
I like that last point too, as copilot I think is going in the right direction with "step 1" of full optimisation. Maybe step 2 would be some AI based optimiser scheme to transform IR into optimal cpu/gpu ISA. Though maybe stability would be a problem
Jose announced that they are working on it but I can’t wait :p
Elixir is already strongly typed (e.g. I think you can't use a number where a string is needed and doesn't automatically coerce).
I'd also like higher performance numerics in Elixir.
I’ve tried F# briefly and quite liked it too. I would like to get into it more later.
In the bulk of the code I want the syntax to be as terse as possible so the business logic is as clear as possible even if it comes at a perf cost. This is where Rust often fails. The logic of something where I don’t care about perf is obscured by token salad for Box’es and similar.