46 points

After years, and many languages, I still have to say Ada. Kotlin, Rust, Julia, and Nim are my current contenders to overtake, but here’s what Ada does well enough to still be my preferred tool when appropriate:

  • strictness: typically my code works the first time it successfully compiles with few or no bugs. Rust is almost on par in this respect.
  • structure: a corollary of the above is that it forces me to “plan ahead” more than just “start coding” which I find fits my programming style better, and leads to better “Unix Philosophy” product designs. I haven’t found any other language that has the same effect other than maybe Haskell.
  • speed: I honestly find that Ada code outperforms C/C++ code most of the time. The only times C/C++ outperform Ada is after optimizations that come at the cost of readability.
  • multitasking: Ada’s first-class tasks and protected objects are the only way I’ve ever been able to write bug-free concurrent programs that are more complex than async/await and/or producer/consumer structures (and I took a dedicated elective on concurrency at university!). Kotlin is almost on par in this respect with its coroutines.
  • hardware: The fact that Ada basically ships with a hard real-time OS built-in and can compile to e.g. AVR means that all my fancy libraries I’ve written or saved work just as well for a desktop game, a website backend, or an embedded microprocessor. Just look into representation clauses and interrupt pragmas to see its unique powers.
  • design: The whole design of the language has lead it to be the only language where I can consistently return to a multiple year old passion project with no attempt to write maintainable code, and fully understand what its doing and modify it with little effort.
  • tooling: While this is the biggest downside of Ada (see below) gprbuild is still my favourite build tool. I have no idea why strongly-typed build systems aren’t more common. Its always a joy to work in gprbuild, once you get gprbuild working of course.
  • static polymorphism: Ada’s generics are some of the best I’ve found. But they have some limitations that leads us into…

There are some situation where Ada shows its age:

  • static calculation: I love Nim (and Zig, etc) for the ability to run arbitrary code at compile time. It allows me to describe what would normally be an opaquely initialized data structure or code path in a clear and descriptive manner.
  • terseness: Ada is verbose, that’s not such a big deal, but I find its just a tad too verbose which can lead to some slight difficulty when parsing code. func/proc (Nim) vs fun (Kotlin) vs fn (Rust) doesn’t make much difference to me, but function X returns Y/procedure X starts to add a lot of visual noise to a file.
  • web compilation: The ability for both Kotlin and Nim to compile to either ASM or JS is AWESOME. If I have to write a “full stack” application, Kotlin multiplatform with ktor every day.
  • operator overloading: Only the built-in operators can be overloaded in Ada. It always makes me wish I could overload arbitrary operators. A small thing, but a symptom of…
  • TOOLING: Ada’s tooling is BY FAR the hardest I have ever seen to get working. It takes the “eat your own dog food” too far. The fact that even in Arch Linux you have to install a bootstrap package, then the real package shows how hard it is to get a consistent build environment. ALR is helping in this respect, but is still not quite mature in my opinion.

Here’s when I use the alternatives, and their biggest weaknesses:

  • Kotlin: anything where I want both one or more JS artifacts and one or more JVM/native artifacts. Weaknesses: performance, static analysis, on the fence about tooling (gradle is cool, but sometimes seems too over-engineered), Biggest weakness: IDE dependency, writing Kotlin outside of IntelliJ is a pain, which is somewhat fair given who maintains it!
  • Rust: so close to beating Ada, if not for two things: ugly code - so many operators and glyphs that pollute the reading experience, maybe I’ll get used to it eventually, but for now I can’t scan Rust code, nor pick up and revisit it nearly as easily as Ada; language scale - I find Rust suffers from the C++ design attitude of “we can add this as a language feature” it takes too much mental effort to hold the entire design of the language in your head, which you sort-of have to do to develop software. Java and C are IMHO the undisputed kings in this respect. After reading through the specifications of both languages, neither will ever have any surprises in store for you. There’s no magic under the hood or special case. All the cool features are done by libraries and rely on the same simple syntax. Every time I learn a new cool thing Rust can do, its at the expense of another edge case in the compiler that modifies my conceptual model of the code.
  • Julia: multiple dispatch and mathematics plus clean module design and easy unicode incorporation leads to clean code for math-y/science-y code.
  • Nim: templates and macros are excellent, concept system gives access to Rust-style traits without all of the additional “ugliness” of Rust, excellent performance, tiny executables. I just find that the syntax can get clunky. The UFCS easily cleans up a lot of the mess that Rust creates with its added features, since it keeps the parsing the same even when using some fancy language feature.

Thank you for attending my TED talk :P. Any questions?

permalink
report
reply
14 points

That’s a great opinion piece you’ve written there. You could with a little editing and restructuring turn it into an article.

permalink
report
parent
reply
9 points

I’ve never used Ada (I’ve heard great things, though), and I’ve only used Rust and Kotlin a little bit, but I can at least vouch that Julia and Nim are both supremely lovely languages.

permalink
report
parent
reply
3 points

I learned Ada in the early 90s before being plunged into a world of C/C++. I haven’t heard much about it since, but I’m glad to hear it’s alive and kicking. I’ll have to have another look, see if I recognize any of it!

permalink
report
parent
reply
3 points

Really appreciated this thanks for taking the time to put this together.

permalink
report
parent
reply
37 points

Python, and I like that I know it

permalink
report
reply
2 points

I had to use Python for a bit at work and it was confusing

pipenv, venv, virtualenv, poetry…wtf is all this shit

a.b vs a['b'] vs a.get('b')…wtf is a KeyError

permalink
report
parent
reply
5 points

What happens in other languages you use when you try to access a non-existing key for a hash/map/dict?

What language do you use that accessing an object attribute is the same that accessing a dict key?

What knowledge do you have (or not) that KeyError is a mistery to you?

permalink
report
parent
reply
3 points

What language do you use that accessing an object attribute is the same that accessing a dict key?

Javascript / Typescript.

permalink
report
parent
reply
1 point

Return undefined.

Typescript.

Why error? Just return undefined. Simple, no try/catch needed.

permalink
report
parent
reply
4 points
*
Deleted by creator
permalink
report
parent
reply
1 point

People love to complain about npm and node_modules, but I think they were on to something with the simplicity of it.

permalink
report
parent
reply
2 points

I’m an embedded systems C programmer with passing familiarity with Python. To me it seems ridiculous that a language relies on whitespace for blocking. Is that true?

permalink
report
parent
reply
8 points

It only requires consistent indentation inside blocks, which is what any good code does anyway for readability. So the main difference then is just that you no longer need the redundant curly braces.

permalink
report
parent
reply
-1 points

Yes, unfortunately. There is a lot of tooling around it but it still feels bizarre after years of using it.

permalink
report
parent
reply
1 point
*

I’m anal about curly braces in C. I never code without them because I don’t like being ambiguous.

I never do

if(i=0) return 0;

or worse

if(i=0) return 0;

I do

if(i=0) { return(0); }

permalink
report
parent
reply
37 points

Python for its versatility.

Rust for its strictness and speed.

permalink
report
reply
11 points

Try Julia, it has both

permalink
report
parent
reply
10 points
*

By versatility, I’m also including the ecosystem. Julia doesn’t seem to be anywhere near python on that.

However, I’ve heard good things, it’s on my to-do list.

permalink
report
parent
reply
37 points
*

I’m a big fan of Rust.

  • Excellent tooling. The package/build manager (cargo) just works, the compiler’s error messaging is simply unmatched and the IDE story is excellent thanks to rust-analyzer.
  • Rich ecosystem. There’s a crate for almost anything you could need, and endless piles of learning resources.
  • You get the speed and low-level control (if necessary) of C/C++ without all the pain and legacy baggage.
  • The community tends to care a lot about correctness and API design, which is reflected in both the core language and the ecosystem. Rust doesn’t try to hide complexity and pretend things are simple (like Go) - instead, it gives you the tools to manage it head-on.
    • Example: if a function can fail, then it returns a Result and you have to explicitly handle the possibility that something went wrong. There’s no forgetting a null check and slamming face-first into a NullReferenceException or segfault in some other part of your code.
  • It’s expressive. Iterators, generics/traits and other language features make it easy to communicate what’s going on to both the machine and other humans. Even the syntax is designed to support this - you can tell a lot just by looking at a function signature.

Obviously it’s not all perfect, however.

  • Compile times can drag you down. (rustc is always getting faster, of course, but it’ll probably never be as fast as Go or JVM/NET.)
  • It can be difficult to read at times, especially when code starts leaning heavily into generics and lifetime annotations.
  • Speed and control comes at a cost. No garbage collector means that anyone coming from a managed language (which, hello, that was me) is going to have to rewire their brain to deal with lifetimes, ownership and mutability XOR aliasing. You eventually develop an intuition for how to structure your code to play nice with the compiler, but that takes time.
  • New language features can take a long time to be stabilized and released. The advantage is they tend to be baked all the way through from day one, but the slow pace can be infuriating, especially when big ecosystem advancements are hung up on key additions.
permalink
report
reply
8 points

And much time is saved from debugging. It makes a lot of sense that we let the computer/compiler keep an eye on lifetimes, allocations and access so the code is much more correct once it compiles.

I feel like my old colleagues and I have spent a far too large part of the last 20 years chasing memory issues in C++. We are all fallible, let the compiler do more.

permalink
report
parent
reply
2 points
*

I like the way the compiler doesn’t just tell you there’s a problem, but also gives you advice on ways you may be able to fix it. That’s a smart compiler.

And I like the way I can write something that runs fast but not feel faintly anxious all the time I’m doing it.

permalink
report
parent
reply
22 points

Go. It’s high level enough in terms of syntax that it’s easy to build complex apps in, and low level enough that I’m able to control pointers, manually run the garbage collector, and benefit from the runtime performance.

It’s the best of python and JS.

permalink
report
reply
2 points
*

Hell yea. Can’t forget those compile times and that parallelism handling. I can’t think of a language that has a better dev cycle to performance ratio.

permalink
report
parent
reply
1 point

amen, brother

permalink
report
parent
reply

I really want to learn it, and I understand the basic syntax and patterns. What apps did you make with it to learn it? I can’t think of anything big to make.

permalink
report
parent
reply
1 point

I made quite a few. Most of the apps on my portfolio use Go on the backend.

permalink
report
parent
reply

Asklemmy

!asklemmy@lemmy.ml

Create post

A loosely moderated place to ask open-ended questions

Search asklemmy 🔍

If your post meets the following criteria, it’s welcome here!

  1. Open-ended question
  2. Not offensive: at this point, we do not have the bandwidth to moderate overtly political discussions. Assume best intent and be excellent to each other.
  3. Not regarding using or support for Lemmy: context, see the list of support communities and tools for finding communities below
  4. Not ad nauseam inducing: please make sure it is a question that would be new to most members
  5. An actual topic of discussion

Looking for support?

Looking for a community?

Icon by @Double_A@discuss.tchncs.de

Community stats

  • 8.3K

    Monthly active users

  • 5.5K

    Posts

  • 302K

    Comments