"It's an issue that doesn't exist in other languages" was also funny. But on a serious note, it doesn't exist in other languages only because those other languages don't care about proper error handling. In cases like Rust or Gleam what he was doing with the "let if" and "match" syntax did work, and it was proper error handling. There's no skill issue. The skill issue only appears because the language provides a more "idiomatic" or less verbose way that you haven't learned yet. The extra idiomatic feature just raises the skill ceiling, without actually taking away from the more verbose syntax. So it's still hard to call it a skill issue. Other languages would be happy with just a single try...catch around the entry point saying "nice, handled error 🥴"
As zig is pre-1.0, it moves very quickly and the LSP targets the nightly version so it probably didn't work for 0.11. Once it hits 1.0, the idea is to not change the language much and things will settle down a bit. Sorry you had a bad experience with Zig. It really is a great language. If you ever try again, use the nightly!
that’s not true, the lsp has tagged builds for each release, including 0.11. As it is the lsp doesn’t work anywhere that comptime is involved, which is pretty much everything
I like zig, but I find the standard library to be lacking and its documentation is an insult. The vast majority of functions and flags are completely undocumented and many are not obvious (what is std.macho about ?), there are very few examples of usage. There are no functional programming primitives (map/reduce, not talking about filter, fold, zip, etc as there are no closures in zig), and no regex. This is a bit annoying.
@@InXLsisDeo But strangely enough, it has cryptographic primitives. Not something I expected to find in the std of such young language, but good for me I guess since I needed those.
I use Nim at work for exactly a kind of use-case it excels in: Fast native-compiled statically-linked data processing that needs to be portable to embedded platforms (my giant program compiles as-is on ARM using musl-libc), with ergonomic Pythonic syntax that ensures you don’t need to worry about memory issues. It can be best described as either: Very fast native-compiled Python, or extremely, unrecognizably ergonomic C++. Take your pick.
@@eduardabramovich1216 There's a free book by Stefan Salewski. There's also NimDays which is a collection of mini programs made in Nim, and also How I Start which is implementation of Brainf*ck interpreter in Nim. Also the creator of the language has recently released his own book.
Nim starts getting good when you look into metaprogramming. See some of the DSL libraries like Jester or HappyX. Also its ability to compile into C, C++, or JS makes it good for pretty much any domain. Also note Nim's memory management model nowadays isnt really a traditional GC, but the memory is automatically managed at compiletime.
@@yuitachibana8829 I think the standard library is very consistent with one way to do something. Where C++ feels like you have to read a book on every individual subsection, Nim is pretty straightforward and you can read anything that only uses std. That's what makes me appreciate Nim more and want to distance myself from C++. Plus, macros still use Nim's standard calling conventions so it never feels jarring.
@@blaisepascal3905 same, I've been working in R for the last few years and it's wonderful for stats and plotting, but I was able to get some really complex genetic epidemiological modelling done with Julia pre-2020 which R would have choked on. Two languages that seem to scare people off, but are so nice to use once you get the hang of them.
Yeah he basically ignored all the real use cases for Julia which makes it seem like a glorified bash. But try doing complicated math in bash and you'll quickly see where Julia excels.
I like Dart the most! It has such clean and logical language features, it just feels nice to write! It doesn't have stupid pitfalls and shortcommings. Also, since it has a big Company behind it, it evolvs very rapidly and gets good improvenents regularly! Since version 3 it got big improvements on the functional side, with pattern matching and exhaustive switch statements. And it has null safety since version 2.
The problem with dart is tooling. You can write a dart executable, but you cannot write a library with C ABI linkage (in fact you cannot write a library and ship it in binary form at all). Another drawback is that it is by nature a programming language for single-threaded applications. It has async/await, but running multiple threads using the dart standard features is awful. It's biggest plus in my eyes: when you come from Java, Dart is a weekend job to learn. It's a less verbose version of Java with Null-Safety and free-standing functions and variables. It does a pretty good job to support the Flutter Frontend Framework, where multi-threading isn't needed that much, but asynchronous operations are all over the place.
@@olafschluter706 Yes, that you cannot bind C libraries easily is a big problem that just did not get enough attention, also because it works in Flutter and Flutter was the primary focus for a long time. But the team behind Dart is actively working on a solution, it is called native assets and it is behind a experimental flag at the moment. Of course, that it does not support multi threading easily is a drawback. Though, the use of isolates encourages the use of message passing to pass data, which is often thought to be a safer method to handle data, than for example a shared state. But I do use Dart very often and I rarely find myself actually spawning additional isolates, because for the use cases Dart is designed for, it is often just not needed. Partly because async/await works so well. Of course for use cases like Webservers it would be beneficial to implement multithreading and I think a well designed Framework could very well work around Darts limitations. And comparing to other languages, it is not worse than for example Node.js (it works essentially the same), which is one of the primary Webserver runtimes today... Only God knows why... And for example Python cannot do any real multithreading at the moment, because of the GIL... Overall I think Dart has great potential to replace many current solutions like Javascript (in front and backend), Python (as a scripting language, for Webservers, or even for algebraic and ML use cases), Java, C# and probably more! It is just, that the Frameworks are missing...
@@olafschluter706 Dart has multi threading using isolates. And there is even a simplified implementation for flutter called compute. I find it to be very straightforward and I used to write multi threaded code in C almost a decade ago. As for compiling to binaries, there is a dart2native package as well as flutter being able to compile into every native platform mobile, desktop, and web.
How is it different from js/node? I think they handle concurrency the same. Theyre not designed with other applications than backend for apps and apps themselves.
@@adriankal Yes, Dart handles Concurrency in a very similar way than node js and is also in other ways pretty similar to node js. But I think Dart is the superior language feature, safety and experience wise. It could very well be a replacement for node js. It is just that it does not have such a big ecosystem like node js does, yet. This is where the community has to step in. The only reason why every one hopped on the train when node js came around is that you could use the same language that you use in the browser, in your backend too. But Dart can offer this too! It's just that there is currently no great priority for that by the Dart team. Flutter is it's main selling point at the time. But non the less it gets improved independently all the time with WASM support coming up next! "They are not designed with other applications than backend for apps and apps themselves." I don't get that part.
Zig fan here. The reason why you struggled so much with Zig might be this language's innate low-levelness. Sometimes writing Zig feels like writing LLVM IR, and for an untrained hand this is almost a chore. Tho it gets easier over time. Also comptime comptime comptime. It is incredible, and i get immeasurable high when it works the way i want. You can pretty much have every single feature of any language, have it as a zero-runtime, and have it not being a macro. This is nothing but witchery, atleast it feels like it.
@@AGAU1022 Zig is pre 1.0, it is clearly not stable for now. Things move fast. People are bound to face issues but still many are adopting it. While Rust has been around for a while now. The creator of zig was frustrated to write his program in C++/Rust/C so he started creating zig. So can't really complain about a premature language
9:08 Sad truth😔I feel Swift is such a beautiful language with so much potential. And while it is open-source and Apple is doing something, it's not that widely adopted because: 1) Still needs a good cross-platform IDE 2) Apple Documentation is terrible 3) It lacks APIs for so many general-purpose things
Agree entirely and re 1) I was gutted when Jetbrains dropped support for it last year! Their AppCode IDE is still a better Swift exploration and coding environment than XCode.
My experience with Swift is just that, it is beautiful. But I find it very unenjoyable to work with it. I keep struggling with compiler errors that feel unnecessary. Even Rust is less patronizing than Swift. It also feels like it's a dead end as a general purpose language. It's tied to and controlled by Apple. Given the choice between Rust and Swift, if both were free, I would choose Swift. Given that there is Zig, I go for Swift, even if it's not quite comparable to Rust and Swift.
Swift is good on Linux and while I agree the documentation is terrible, I would mostly say it is because of the features that caused me friction (C FFI, Packages, and Concurrency) Although a tiny thing is, Swift does have some things that most languages do not have. Steadiness. I dont see Swift blowing up like either Zig and Rust. I see it more like Java or C#. It is ‘get things done’ language. Also to the person above, I think the compiler messages for Swift are fine, but yeah, some errors are definitely loaded and kind of rhetorical. Surprised it got the bronze medal though. Swift is definitely a language that grows on me the more I use it. But…I really just wish apple would show me how to do FFI with C man. Nim, D and even Zig have better examples of how to use with C. Swift? Basically, Apple gives you the finger and tells you are on your own, go make a modulemap or package.swift, or something. Also minor pet peeve since you mentioned 3. Is it just me, or is just the API usage that trips people up? Not just for me and the standard library, but it just seems like how the documentation is generated, much of the code is kind explained with doc strings and most of the time, the actual usage and code implementation is kind of just abstracted away. That is my big issues. It took me a while to find out Swift has pointers, it is just hidden away in the Standard Library API. It basically shows you the what, but rarely how, the why or even the when. (When do i use this function or that function for pointer deferencing?)
@@twenty-fifth420 Couldn't agree more. Although I could well live with the few quirks Swift has, considering how well balanced the advantages and disadvantages are. But the fact that Swift is an Apple product and the consequences make it irrelevant. It's a bit like C#. There was a time when it could have been a great choice and it actually is a decent choice in some circumstances today. But being subject to the whims of MS made it unfit for me and many others. I would love to see Zig thrive as a low level language and see a new high level language use Zig as a backend. I dislike Rust because its scope is too wide. It's not a great low level language and its not a high level language.
Thanks for taking the time to do all this coding and evaluation. It's very nice to see the implementation in diff. languages. IMHO, Rust code is the most unreadable, by far.
Well, a 20+ minutes vidéo I actually watched from beginning to end, no fast forward, no need to rewind. That's become so f'in rare these days! Clear sections of the video where you setup your goal, testing protocol, evaluation criterias. Then doing it with examplification, biased opinions and objective comments both for each. Then a summary and an acknowlegement of your biases and a humble recommandation of which to choose in your opinion depending on your preferences. Rust only got an 18/20, but you get a 20/20 note as far as I'm concerned! *DING* Subscribed
Nim is way, way, waaaaaaaayyyyy faster than Python, so of course there is an advantage. Regarding Nim's identity, I've heard people saying that and I don't understand the point. What's python's identity? Everything, it's used for everything. Web, desktop, data analysis, data engineering, scientific dev, scripting, sec tools... But nobody complains about that.
Yeah but that’s great, because you can learn one language and do anything you want. It may not be fast but being able to do anything is quite convenient
Python has such a massive following that it has packages with thousands or millions of active users in basically every sector possible. That’s very different than nim not having a niche
Yeah, I love this video but for many of these languages the big benefit that he missed is their performance, and for some like Gleam performance is one of the biggest downsides. It seems like a bit of a waste to build something as good as Gleam in a way that limits performance so much. I guess he left it out because it didn't make a significant difference for his use case, but should at least be mentioned as a known benefit or downside.
That can be misleading tho. 1-5 scale comparison in terms of tooling makes sense but comparing a runtime optimized compiled language with something like javascript may yield 500x difference in performance which doesn't make sense. I would keep things to compare for paradign support, tooling stuff.
I don't really understand why Dart got such a low score. It feels like it gets a lot of things right, and I had a blast using it to maintain a production Flutter app. It feels like your grades don't align with your feedback :D
he actually didn't use the nice parts of Dart. the `..` operator is pure genius for initialisation, making dependency injection work without any clunky library or "bag of globals". the automatic parameters make robust initialisators look like magic. like with Zig, it requires more than just a glance to appreciate. I bet he had previous experience with some of the most highly rated ones, which helped him find the best parts of those.
I use dart since 5 years and I love it, I think he treated dart fairly. There is still stuff we want and don't have yet in dart. Static metaprograming (it is coming very soon), error as value not exception (no plan to change this at all, so you have to import fp library like fpdart and use either type). For some reason they don't want to let us configure line length on a per project basis, and default line length is 80... I find the pattern matching syntax to be a bit confusing (particularly when using switch expression) but it might be me I don't know. Except that, the toolings is just awesome. I use flutter (so dart) at work because I in charge of the mobile team, but I have to work with python for backend, I feel so miserable when I have to use python, the tooling is horrible, the language is horrible, nothing works, it is probably the worst language I ever used.
@@JavierGuerra_g It is the second time someone mentioned the '..' operator as an exceptional feature of dart and I don't get it, if you embrace immutability you cannot use this operator 99 percent of the time when initialising a class, or I am missing something. Could you also elaborate how it helps for Dependency injection please? Always eager to learn new stuff about this language I love, even if I would feel dumb having missed incredible feature usage for so long
@@gaxkiller there's so much to be said about how DI is great when you don't use a library and so disastrous when you do. and for most languages, the syntax gets in the way, making complex initialisations either complex and hard to read, or a whole API in itself. to make that last option somewhat more palatable, somebody invented "fluent APIs" which are nice, but tedious to implement, and create other limitations. in flutter, the '..' operator gives all the benefits of fluent without having to create all those initialiser methods, and thus you get those multi-line, deeply nested, but nicely-indented and very readable initialisation stanzas, where you can do all the DI you wish.
Pretty sure idiomatic Kotlin error handling is much closer to Rust then Java. You would use Result type to return error as value and throw for panic. I dont really know tho, I am in the process of learning Kotlin. Overall Kotlin seems like an extremely pragmatic yet expressive language, with a module system to avoid common oop pitfalls. With the mutliplatform enetring stability, it just might be a killer app of Kotlin ecosystem.
The MAJOR issue with Kotlin is exactly that there is no idiomatic error handling. The official Result Type was only added after years, and they threw out checked exceptions without giving us a good, standard library alternative. Meaning, everyone did their own thing. You also lack convenience of a "try-catch"-like structure for Result types, meaning you end up having to manually check every Result.
@@MarcelRiegler Right, it's a shame. If would much prefer an idiomatic way like Rust. But at least Kotlin has enough features like Sealed Classes and Trailing Lambdas, to easily implement a rust-like error handling. It's not perfect, but still much better than dealing with exceptions.
I have tried Kotlin for Advent of Code, AoC is an excellent way to have a good taste of a language and how it would fare in real work. I found Kotlin was a pleasant experience. Its library is comprehensive and very well done.
I picked up Dart for Flutter in its beta days and stuck with it because it just felt really nice to write. I could mostly just do as you said: imagine what I want the code to do, write it, then move on with my life.
"Nim is the least opinionated language" - I agree. Been using it for a bit. On the surface it's a statically typed python with even more stuffs like metaprogramming capabilities etc etc. I like the freedom but I also appreciate what other languages have to offer in this list.
Very interesting video. Just an idea for next similar ones: you should also compare these with "classical" languages that everyone has to use at everyday work such as Java, JavaScript, Python or C#... This would give the insight about the language evolution from the classics to the modern ones. Btw. I am a Kotlin fan. As I do not mind using JetBrains tooling (which is perfect!) I would give it much more points in tooling category which would make it almost a winner. :) I was surprised by Gleam, I have never heard of it... but I will definitely find out more.
I’ve working with Bun and I am really liking it. The tooling is awesome and not require external dependencies do to the basics. The websocket module is awesome and easy to use
I love Julia, it's my favourite language now (apart from maybe R or Scheme). I find it elegant and aesthetically pleasing. That said, I primarily do mathematical modelling and statistics, rather than making apps, so I don't really know what it's like from that perspective. The 1-based indexing is something you'll find in a lot of programming languages popular among mathematicians (see also Fortran, R, Matlab, GNU Octave, Maple, Mathematica, and Maxima), I guess we just prefer it that way.
As a mathematician, I don't. And I always prefer to index my sequences from 0. Whenever I read a text that features a sequence with index starting at 1 I have a harder time grasping proofs. Good thing about programming in mathematics is that languages tend to be functional, so you don't often try to directly access some index or do index arithmetic. Also, Python has 0-based indexing so that's cool for me.
@@renato360a every time I see Python's "range" function, and know you have to say "1 to n+1" to get "1 to n" (instead of 1:n like any 1-based language) it makes me irrationally angry. Especially when numpy's "arange" function has the exact same behaviour for non-integer sequences, which makes it so much more difficult to specify the end point. I don't like Python.
@@spacelem yes, I would expect that! 😅But that's a very rare case as I see it. 99% of the time I'm not specifying the starting point, so I'm just reading "range(n)" as "give me _n_ terms of a sequence", which if we start from zero, naturally should end at _n-1_ . For non integer sequences I tend to use "linspace" more anyway, which does include the endpoint.
@@renato360a I'm a mathematical modeller, dealing with epidemiological and genetic models. I frequently need to simulate from t=[0..T] (end points included), but also when doing intervals it might be X(t) for t=[t1.. t2], and the next interval I need X(t2) as the initial conditions (this is absolutely the case with my current project, which involves a virus spreading between chickens, which one group being added to the previous group for a period, then moved back, and being the source of infection for the next group). When doing sensitivity analysis on parameters I often need linspace or logspace (or their language equivalents). It's much easier to drop the final point if I don't need it than to try to guess a value past the end that doesn't get me too many points. When it comes to accessing data (so integer values for an index), I just like the 1st point to be x[1], and the Nth point to be x[N], not x[0] and x[N-1]. It's less to have to think about. I know there are times when 0-indexing has helped with certain algorithms in C++ dealing with n-dim arrays, but R or Julia usually already provide the tools to not need to think about it.
@@spacelem Hm. I guess it's more like to which camp does one belong to, Naturals start from 0 or from 1. Mathematicians don't make up our minds about it so you see models starting sequences from either. And you and I are from different camps... Personally I love subtracting 0 (does nothing) and hate subtracting 1 (shifts everything), so I'd much rather start at zero and end at N-1. A long time ago I had to get it through my head at great pains that when you subtract two integers, the result has to be increased by 1 to yield the total number of elements including the endpoints. That made it very natural for me to see a sequence to N-1 as having N elements.
It's kind of sad that Dart's sound null safety wasn't even mentioned. Also, Dart 3 has a much more modern syntax than Dart 2 with pattern matching, destructring etc...
I appreciate you being clear and upfront about how you'll be ranking the languages. Also, you might enjoy Roc! Although TCP server might be too low-level (in Roc those things are usually handled by platfroms), so I would recommend making something else with it
First 10 seconds had me dying laughing. Also subscribing. Love the deadpan humor. I’m Rust/Go as situation dictates. I love rewriting Python in Rust and running comparative benchmarks. It’s stupid how slow Python is. Also minor maintenance of legacy Java and C++.
11:17 on the top, there is the compile command, below is in what module the error occured, below again is the error, basically, in zig, you can only access active field of unions, there are also tagged union which you can use switch on them. here you try to access "Pointer" while the union field "Struct" was active. what you can do is check if the field is active: if (taggedUnion == .Field) { . . . } or use a switch statement: switch (taggedUnion) { . . . }
The thing is that if you look closely, the message says that error occurred inside "Allocator.zig", which is part of Zig standard library. I think that message is not full, and there was more info cut below.
For what it's worth, kotlin has runCatching in the standard library, which effectively gives you either successful result or exception as a value if that's what you need. So it's more a style choice in kotlin. And if can allow 3rd party libraries, there's one that allows you to get even more functional (namely Arrow)
I think you should look into nim more. While I do agree it has some strange stolen features that don’t feel like they mesh well together. It’s actively developed and isn’t afraid to add new patterns. Honestly I would love to see you’re criticisms more in the nim community and I would love if you got involved.
Love ur refreshing take. Very solid video. Thank u very much. I enjoyed this very much. U helped cut thru the type and showed me the warts of zig nim etc
Some nice languages that will never reach the attention of mainstream. 1. D (OOP language with optional GC) 2. C3 (Procedural language that deserves Better C) 3. Odin (Improved C with pascal & Go style)
Great choice of languages. I personally would have added C# and Elixir. I would love to see a followup video with the languages people have mentioned in the comments. I've been a php dev for a while, so I've been looking for a new language to pick up because I'm a bit bored. I was originally attracted to rust and gleam, but they were proving to be a bit of a challenge, so I went with Go because it seems to be learnable and popular. One day though I will pick up Rust or Gleam.
I was very interested in Elixir too, then I saw it is not statically typed. From personal experience, the developer experience regarding dynamic language is subpar vs statically typed language so I did not bother investing time in it. There are adding type step by step apparently but it did not solve the problem for other dynamic languages that did that.
FWIW, coming from C++, golang and python, I have been using Elixir exclusively for the past couple of years, and I couldn’t be happier. Engineering productivity is through the roof.
One thing I did not like, is how readability is being rated? For me, readability is the ability to read a code from someone else and know what it does. Why for example, rust with it's vast syntax is more readable than go? I don't get the justification. If I write code in golang, I will know what it do instantly, if I show it to anyone, they will know exactly what it does without effort. I wouldn't be so sure of that in the case of rust. Some libraries in rust is unreadable compared to others. Everyone have their own writing styles. It should be less readable than go.
I was a bit confused about the readability and ergonomics ratings for Nim as well. I get that Nim is unsafe but it seems pretty readable and ergonomic and had the fewest lines of code.
readability is a matter of familiarity, I don't think it can be rated since it would be unfair, for example, i write Go more than Rust and i never wrote Gleam, therefore gleam is not as readable to me compared to rust and go and rust is not as readable as go, it's unfair to rank it
@jamlie977 no body said x is unreadable, but it should be a meteric of how much experience it requires. A code written by a senior go engineer will be readable for a junior dev. But rust won't.
@@lazyh0rse i get you, that's why i said it's unfair for him to rank them based on readability as it's a matter of familiarity, if he doesn't have much experience with a language he would assume it's not as readable which might be false
@@jamlie977 It's unfair to rank it by your own subjective ability to read the language. But there is objectively readability in the sense that some languages are easier to learn when adjusting for that bias, like for beginners who have no experience in any language, and juniors with no experience in either language. A language is objectively more readable (on average when including beginners) when it more closely resembles natural language expressions of the same logic, more real words and natural grammar, less esoteric abbreviations, esoteric symbol use, and bloated non-grammatical boilerplate to declare things that should just be a default. Basically: how easily can someone without experience read it out loud in a way that accurately conveys the code.
Thanks! Great idea. Here are the lines of code (including any blank lines): Nim - 150 Kotlin - 163 Julia - 170 Swift - 180 (with dependencies) Crystal - 187 Dart - 190 Go - 264 Gleam - 278 (with dependencies) Zig - 338 Rust - 354 Anecdotally, Go and Dart definitely felt the quickest to write and Zig took me the longest. Interesting that I enjoyed some of the verbose languages. I wonder if that's just Stockholm syndrome and less lines is actually just easier
@@tom-delalande Thanks! Yeah very interesting, especially how few LOC nim took. I guess some of it could be attributed to "skill issues" :D But also more LOC could mean more resilient code because of error handling So yeah very cool
LOC is the most useless metric. You can write s**t very quick in python, with zero error reported by your IDE and zero error handling. But then you would need 123124124 LOC of unit test to be sure that true = true
I'm confused. You are saying that safety is important for you, things like exhaustive switch statements, immutability, and null-safety. And then you give Go and Kotlin the same score 3. Even though Kotlin has many of the safety features mentioned while Go doesn't.
The man explains why - he dislikes try catch and prefers errors as values. He is lazy and will ignore exceptions while writing code without the compiler complaining. Go enforces error handling, and Kotlin uses unchecked exceptions.
@@TJackson736 the toInt method for strings in kotlin may throw an exception yet he praised it even though it doesn't tell you that it's may throw an exception since it uses java.lang.Integer.parseInt under the hood, it's really weird how he hates unchecked exceptions but not always
Dart has exhaustive switch expressions (even for types), you can enforce immutability via the final modifier, it has sound null safety... In my view it's definitely safer than you made it look
@@mikkelens obviously elements of personal preference, but Rust is well known for correctness not for being a joy to read. Ruby is a joy to read, APL is a nightmare, and Rust lies somewhere in between. My 2c.
@@mikkelens Rust is basically impossible to read if you are newer to the language, especially when it introduces new concepts like borrowing and lifetimes. Meanwhile, most programmers can just see Go and understand what it does even if they barely use the language. Other than that, it's preference. I come from a Python background, so I found nim to be easy for me to read while zig being the hardest in these examples. Other people may prefer verbose language with more information, or c-style curly braces. It's all what you grown familiar with. However, if you remove that, my point still stands that Go is probably the easiest in general for anyone to read here.
saying kotlin inherited unchecked exceptions from java feels weird when java is the only mainstream language with checked exceptions and kotlin specifically chose not to include them because "muh annoying"
damn the end was too real. I just finished watching this on my lunch break where I will have to go back to writing spring boot on java 8 and angular js 💀
I think modern c++ (c++23) also deserves a mention. It’s come a long way even from c++17. It has features like optional and expected and other features similar to other modern languages in that list (although they are not strictly speaking enforced due to it still allowing for the old style). Although I must admit that the syntax is still ugly af in some cases and it can get extremely difficult to read very quickly even for basic tasks. It’s also extremely verbose but it’s still fast with zero cost abstraction and tries to modernize (good attempt imo) and became much safer.
Simply Rust is so good when you undestand how types work, traits, unlock full match power, iterators, you can do a lot of stuffes with just references, neither touch lifetimes or more complex memory management things
Java has Checked Exceptions and Kotlin deliberately moved them to Unchecked for a reason. Maybe you read about why. ALso, Jetbrains IDE is the best tooling there is and Kotlin support is superb. I would rank Kotlin first for tooling and safety.
I used a lot of Zig lately so I might be bias but giving one on tooling is questionable. Setting up a project with zig build is so much cleaner than using CMake, Make, pkgconf or any other external tool bs when I have to use C or C++. Also the LSP gives a tutorial even for Sublime Text on how to set it up even though it's not the most used editor. The error messages most of time are much more readable than what you get when a C++ template code fails.
> The error messages most of time are much more readable than what you get when a C++ template code fails. Which doesn't say much, given those errors are hundreds or thousands of lines of mostly complete garbage, easily the worst in all the existing programming languages.
Programming languages really are subjective. Most of the things you had as confusing about Crystal are super obvious to me and it's by far the easiest to understand/read language for me. Compared to Go or Kotlin which I find hard to read/follow. I feel like most modern languages requires an LSP to use, except for Crystal where I never use one, or really any other tooling other than syntax highlighting. Dart especially feels unwritable without an LSP.
Julia is my favorite language! I think you basically correctly described it, it's excellent for REPL programming and a few other things, but it's not the right choice for most projects. I especially like how you put it at rock-bottom on the safety scale! That is exactly correct, there are very few languages that will let you overwrite almost everything in the language, even to the point where there isn't really anything you can do but restart your REPL. It doesn't come up often, but when you want it, it's nice to have such a ridiculous brute-force solution. In my opinion, it is the perfect prototyping language. It lets you focus on exactly the things you care about specifying while ignoring ALL the rest, whether that be expressive types, data structures, performance (to an astonishing degree, actually), even concurrency... everything except for correctness. If you can write it in less than 1000 lines of code, and it doesn't have to be perfect, then you're going to have a good time with Julia. Also, the array broadcast notation makes me feel like I have superpowers. Working with collections in Julia is so freeing compared to everything else I've used. But yeah. Rewriting yet another Julia program in Rust right now (this time, for WASM support) :P
I switched from using primarily PHP to writing most code in Rust. I made the switch about half a year ago and been using it as a first choice since then. For most of the tasks I have, Rust is more concise, quicker to write and obviously much, much quicker to execute. Often it's not by a little bit, but a massive improvement. An example I did last week was a tool for configuring a mobile device on an external carrier (I work at a small telco). The PHP code was about 1400 LoC and spread across about 40 files. In Rust this could be reduced to 450 LoC and 5 files. The rich enums are fantastic. The ability to define traits and impl-blocks for types you don't own saves massive amounts of boiler plate. The JSON parsing and encoding with serde is immensely superior to anything PHP has to offer.
I’d like all those way more if they weren’t GC’d. I want to try haskell just bc its haskell, but if I wanted to write something in a GC’d language I think I’d try Gleam instead
I’m implying here that 1) none of these could ever be compile time gc’d like rust and 2) I think runtime, stop-the-world GC is kind of unnecessary and bad, and 3) I see little reason to adopt a GC’d language in spite of this
@@mikkelens If you google "Oxidizing OCaml" you'll find some interesting work going on in OCaml moving it closer to Rust's memory ownership, borrowing etc. But I don't know any details on the status and progress. Regardless, all mentioned languages have modern generational & incremental GCs with very short pauses (OCaml was quite famous for its good GC on a single core). Unless you make video games or something like them, the fear of GC might be rather irrational. Gleam might enjoy Erlang's thread-local GC that doesn't stop the whole world, but it's still just interpreted bytecode, so overall performance of actual code might be much worse than in mentioned languages.
@@mikkelens Beam OTP gives you a nearly pauseless GC expereience. So with Gleam, Elixir or Erlang, you wouldn't really have stop the world GC problem. Hell, even JDK has a pauseless GC now called ZGC. I think the place where no-GC languagesreally outshine others is edge computing and embedded devices. Thanks to their deterministic memory management .
I really think Swift has the right balance of features, safety, expressibility, I am glad to see it well represented here. BTW It does not use GC. One thing I would like to have seen is a discussion of generics handling. I think Swift shines here.
+1 for Gleam, but wish Clojure had been in here. I guess 2007 is a too old, but 1.0.0 was much more recent. I think it would be interesting to compare some 'old' languages still in use, but with their newer features. Think Fortran, C, Common Lisp, Erlang, Haskell, Ada, Smalltalk, Pascal for example. For example, I think CL's tooling is superb, and Haskell's is now good even though it had a bad reputation. Smalltalk is OOP, but not as you know it, and Erlang has some of the cleanest loveliest code I've ever seen. Fortran is quick and I find it quite simple to read for whatever reason. If you need the list to be 10, then perhaps add Forth, Cobol, Eiffel or Prolog if you're up for a challenge.
hey tom I was thinking of this video and I just had the idea that if you extend those same examples trying to getting deeper into optimization for them, you would dive deeper into the languages, review what they provide for performance and so on. Lets be real that is the type of thing that everyone subscribed here would watch more than an hour easily. It would be epic, all of luck!
And then there is a third group, array (and/or stack) languages, like Uiua. The most elegant solutions, assuming your inputs are integer sequences copy-pasted into the interpreter.
I was a huge advocate of Swift and had such high hopes for it. However, I've given up on Swift as a general purpose language because Apple isn't investing enough in the tooling
Honestly, I really like rust but working when I have to write a bunch of just regular regular code is absolutely by far. The best option for me. It’s easy, it’s readable, The standard library is great and super quick to just get things done.
I had the same issue with Swift where my imports weren’t being recognized. I too have been trying to use Swift for general purpose with the Zed IDE. Crazy enough, I couldn’t find any solution or posts about this because it seems everyone using Swift sticks to Xcode. The solution I found that worked for me is that after specifying the dependencies in the Package.swift file, build your project using the swift package command. This forces the dependencies to be downloaded, after which, suddenly the LSP realizes your dependencies exist. Anytime you make changes to your dependencies, you need to build the project even if it fails for the LSP to actually see the changes. Xcode loves to do this automatically upon launching a project for the first time, this is why no one else questioned or complained about this.
Swift’s sourcekit lsp works with dependencies after you build the whole project, because it does not have a background indexing unfortunately I use it daily with neovim, it’s still not perfect (for example renaming does not work and you have to rebuild the project sometimes for it to be able to use dependencies) but it’s good and definitely better than using an Xcode If you have any issues with setting it up with vim, I’ll be happy to help
Thanks for the help, I did rebuild the whole project. I think something went wrong with my tool-chain where the one used in the CLI was different to the one used by the LSP. I reinstalled Xcode from scratch and the whole toolchain. But I still couldn't get it working. I think this issue was a weird combination of Sonoma + something running on Rosetta + Xcode conflicting with the toolchain. I definitely will keep trying to fix it because I want to keep using Swift
@@tom-delalandeAlso a correction: Swift doesn’t have exceptions. It has errors as values. But it has syntax sugar to make it look like exceptions. It has a similar syntax sugar around it’s Maybe type by giving you a first-class nullable type.
@@tom-delalandeAnd a correction for what felt like an implicit assumption: Swift does not have a garbage collector. It uses automatic reference counting by default, and you can opt into some ownership features or unsafe manual pointers for performance.
TLDR; I would argue Swift has the same level of safety as Rust. This was not true for multi-threaded swift until recently. Since v5.10, there is a flag for strict concurrency checking.
19:50 Just a quick note, because I think you borrowed that from Blow (pun intended), but I also think while it can take "10% more time to write" (even when this statement is so blank) it also can make your code "10% or more easier to write bug-free" which will save you time. So I think it is a net gain generally, but this depends on the scope and the project.
i'm most likely late af, but this error you've encountered in zig is most likely due to following things happening: 1. you dereference a variable X, but X is not a pointer but a struct 2. you pass a struct X as an anytype function parameter, and this function expects a pointer and various other reasons, but these two are the most probable ones. the stack traces are not always pointing at your code, that is true especially for std.fmt, but the thing is that you can 'unwrap' the full stack trace with -freference-trace arg lassed to zig build. hope you find it helpful.
i tried zig recently, and i completely agree. string manipulation is often the first thing people try with a new language, and it's easily the worst part of zig, which gave me a really bad impression. the concept is brilliant, but actually using the tools feels like pulling teeth.
"It is a skill issue but an issue nonetheless."
I died when I heard him say it
Hearing "skill issue" and it being treated like a real issue rather than an excuse to ignore a problem felt oddly refreshing.
So, dont blame the language with skill issues! Learn it properly.
"It's an issue that doesn't exist in other languages" was also funny.
But on a serious note, it doesn't exist in other languages only because those other languages don't care about proper error handling.
In cases like Rust or Gleam what he was doing with the "let if" and "match" syntax did work, and it was proper error handling. There's no skill issue. The skill issue only appears because the language provides a more "idiomatic" or less verbose way that you haven't learned yet.
The extra idiomatic feature just raises the skill ceiling, without actually taking away from the more verbose syntax. So it's still hard to call it a skill issue. Other languages would be happy with just a single try...catch around the entry point saying "nice, handled error 🥴"
In case of Rust, skill Issue is really serious issue. It gets harder and harder to comprehend as the project grows
Timestamps for folks:
1:00 Golang
3:25 Crystal
5:47 Kotlin
7:33 Swift
9:28 Zig
11:38 Gleam
14:07 Nim
15:30 Dart
16:50 Julia
18:01 Rust
elixir?
@@AttrakoNull Bro needed static types.
Vlang
As zig is pre-1.0, it moves very quickly and the LSP targets the nightly version so it probably didn't work for 0.11. Once it hits 1.0, the idea is to not change the language much and things will settle down a bit. Sorry you had a bad experience with Zig. It really is a great language. If you ever try again, use the nightly!
Thanks for the mention. If the tooling does work on nightly that's my mistake. I will definitely try it again, there's so much to like about it.
that’s not true, the lsp has tagged builds for each release, including 0.11. As it is the lsp doesn’t work anywhere that comptime is involved, which is pretty much everything
I like zig, but I find the standard library to be lacking and its documentation is an insult. The vast majority of functions and flags are completely undocumented and many are not obvious (what is std.macho about ?), there are very few examples of usage. There are no functional programming primitives (map/reduce, not talking about filter, fold, zip, etc as there are no closures in zig), and no regex. This is a bit annoying.
@@InXLsisDeo But strangely enough, it has cryptographic primitives. Not something I expected to find in the std of such young language, but good for me I guess since I needed those.
@@InXLsisDeodude, we’re on 0.1, what did you expect?
I use Nim at work for exactly a kind of use-case it excels in: Fast native-compiled statically-linked data processing that needs to be portable to embedded platforms (my giant program compiles as-is on ARM using musl-libc), with ergonomic Pythonic syntax that ensures you don’t need to worry about memory issues. It can be best described as either: Very fast native-compiled Python, or extremely, unrecognizably ergonomic C++. Take your pick.
Did you learn it just by reading the docs?
Damn
@@eduardabramovich1216 There's a free book by Stefan Salewski. There's also NimDays which is a collection of mini programs made in Nim, and also How I Start which is implementation of Brainf*ck interpreter in Nim. Also the creator of the language has recently released his own book.
Gleam mentioned!!!
Great language! Thank you so much man
Beyond cringe 😂 just learn Rust or Go
@@ccriztoff RUST MENTIONED! LETS GO
@@jamlie977 Rusty and Crabpilled
I know this guy
can't wait to see this when zig is at 1.0+ like the other languages on the list.
Nim starts getting good when you look into metaprogramming. See some of the DSL libraries like Jester or HappyX. Also its ability to compile into C, C++, or JS makes it good for pretty much any domain.
Also note Nim's memory management model nowadays isnt really a traditional GC, but the memory is automatically managed at compiletime.
It seems like need to put some more dedicated time into Nim. Thanks for the advice
Imo nim has the same problem with modern c++, too many ways to do 1 thing and unopinionated so each project has a completely different structure
@@yuitachibana8829 I think the standard library is very consistent with one way to do something. Where C++ feels like you have to read a book on every individual subsection, Nim is pretty straightforward and you can read anything that only uses std.
That's what makes me appreciate Nim more and want to distance myself from C++. Plus, macros still use Nim's standard calling conventions so it never feels jarring.
Julia and Nim, such wonderful but underrated languages. Both in my top 3!
What is your other top 3?
@@patrickmoehrke4982 ok, don't freak out. It's R, I am a researcher. And R do the job really well.
@@blaisepascal3905 Haha I also use R! It doesn't get enough credit outside statistics and academia.
@@blaisepascal3905 same, I've been working in R for the last few years and it's wonderful for stats and plotting, but I was able to get some really complex genetic epidemiological modelling done with Julia pre-2020 which R would have choked on. Two languages that seem to scare people off, but are so nice to use once you get the hang of them.
Yeah he basically ignored all the real use cases for Julia which makes it seem like a glorified bash. But try doing complicated math in bash and you'll quickly see where Julia excels.
Nim also supports checked exceptions btw. And the default GC is refcounting like swift.
My job literally involves Java 8 and JavaScript... I got called out so hard
Sike! We use more and more Rust now because of me >:D
lol I would be so happy to have a job writing Rust
could be worse, my job is mostly Matlab/Simulink code generation. But I am also introducing more tooling in rust so at least thats nice
@@owndampu1731 I despise matlab, although someone in the research lab who I work with has to write Fortran lol.
C89 and some pre-C89 and Java 8
Damn sucks that you downgraded!!
Great video! I would like to see a follow-up video analyzing Elixir, F#, Haskell, PureScript, Clojure, and OCaml.
And Lobster.
And Elm!
and D !
And Scala, Scala & ZIO
And Common Lisp. And Racket.
You do an excellent job. All that was left to do was take into account the quantity and maturity of the library ecosystem.
I like Dart the most! It has such clean and logical language features, it just feels nice to write! It doesn't have stupid pitfalls and shortcommings. Also, since it has a big Company behind it, it evolvs very rapidly and gets good improvenents regularly! Since version 3 it got big improvements on the functional side, with pattern matching and exhaustive switch statements. And it has null safety since version 2.
The problem with dart is tooling. You can write a dart executable, but you cannot write a library with C ABI linkage (in fact you cannot write a library and ship it in binary form at all). Another drawback is that it is by nature a programming language for single-threaded applications. It has async/await, but running multiple threads using the dart standard features is awful.
It's biggest plus in my eyes: when you come from Java, Dart is a weekend job to learn. It's a less verbose version of Java with Null-Safety and free-standing functions and variables.
It does a pretty good job to support the Flutter Frontend Framework, where multi-threading isn't needed that much, but asynchronous operations are all over the place.
@@olafschluter706 Yes, that you cannot bind C libraries easily is a big problem that just did not get enough attention, also because it works in Flutter and Flutter was the primary focus for a long time. But the team behind Dart is actively working on a solution, it is called native assets and it is behind a experimental flag at the moment.
Of course, that it does not support multi threading easily is a drawback. Though, the use of isolates encourages the use of message passing to pass data, which is often thought to be a safer method to handle data, than for example a shared state. But I do use Dart very often and I rarely find myself actually spawning additional isolates, because for the use cases Dart is designed for, it is often just not needed. Partly because async/await works so well. Of course for use cases like Webservers it would be beneficial to implement multithreading and I think a well designed Framework could very well work around Darts limitations. And comparing to other languages, it is not worse than for example Node.js (it works essentially the same), which is one of the primary Webserver runtimes today... Only God knows why... And for example Python cannot do any real multithreading at the moment, because of the GIL...
Overall I think Dart has great potential to replace many current solutions like Javascript (in front and backend), Python (as a scripting language, for Webservers, or even for algebraic and ML use cases), Java, C# and probably more! It is just, that the Frameworks are missing...
@@olafschluter706 Dart has multi threading using isolates. And there is even a simplified implementation for flutter called compute. I find it to be very straightforward and I used to write multi threaded code in C almost a decade ago.
As for compiling to binaries, there is a dart2native package as well as flutter being able to compile into every native platform mobile, desktop, and web.
How is it different from js/node? I think they handle concurrency the same. Theyre not designed with other applications than backend for apps and apps themselves.
@@adriankal Yes, Dart handles Concurrency in a very similar way than node js and is also in other ways pretty similar to node js. But I think Dart is the superior language feature, safety and experience wise. It could very well be a replacement for node js. It is just that it does not have such a big ecosystem like node js does, yet. This is where the community has to step in. The only reason why every one hopped on the train when node js came around is that you could use the same language that you use in the browser, in your backend too. But Dart can offer this too! It's just that there is currently no great priority for that by the Dart team. Flutter is it's main selling point at the time. But non the less it gets improved independently all the time with WASM support coming up next!
"They are not designed with other applications than backend for apps and apps themselves." I don't get that part.
Zig fan here. The reason why you struggled so much with Zig might be this language's innate low-levelness. Sometimes writing Zig feels like writing LLVM IR, and for an untrained hand this is almost a chore. Tho it gets easier over time. Also comptime comptime comptime. It is incredible, and i get immeasurable high when it works the way i want. You can pretty much have every single feature of any language, have it as a zero-runtime, and have it not being a macro. This is nothing but witchery, atleast it feels like it.
He didn't struggle as much with Rust though.
@@AGAU1022 i dont think Rust is nearly as low level as Zig.
@@AGAU1022 Zig is pre 1.0, it is clearly not stable for now. Things move fast. People are bound to face issues but still many are adopting it. While Rust has been around for a while now. The creator of zig was frustrated to write his program in C++/Rust/C so he started creating zig. So can't really complain about a premature language
i find it odd that he had a hard time with zig, but no problem with rust.
@@androth1502 so true lol, Rust group bias I guess
9:08 Sad truth😔I feel Swift is such a beautiful language with so much potential. And while it is open-source and Apple is doing something, it's not that widely adopted because:
1) Still needs a good cross-platform IDE
2) Apple Documentation is terrible
3) It lacks APIs for so many general-purpose things
Agree entirely and re 1) I was gutted when Jetbrains dropped support for it last year! Their AppCode IDE is still a better Swift exploration and coding environment than XCode.
My experience with Swift is just that, it is beautiful. But I find it very unenjoyable to work with it. I keep struggling with compiler errors that feel unnecessary. Even Rust is less patronizing than Swift.
It also feels like it's a dead end as a general purpose language. It's tied to and controlled by Apple. Given the choice between Rust and Swift, if both were free, I would choose Swift. Given that there is Zig, I go for Swift, even if it's not quite comparable to Rust and Swift.
Swift is good on Linux and while I agree the documentation is terrible, I would mostly say it is because of the features that caused me friction (C FFI, Packages, and Concurrency)
Although a tiny thing is, Swift does have some things that most languages do not have.
Steadiness. I dont see Swift blowing up like either Zig and Rust. I see it more like Java or C#. It is ‘get things done’ language.
Also to the person above, I think the compiler messages for Swift are fine, but yeah, some errors are definitely loaded and kind of rhetorical.
Surprised it got the bronze medal though. Swift is definitely a language that grows on me the more I use it. But…I really just wish apple would show me how to do FFI with C man. Nim, D and even Zig have better examples of how to use with C. Swift? Basically, Apple gives you the finger and tells you are on your own, go make a modulemap or package.swift, or something.
Also minor pet peeve since you mentioned 3. Is it just me, or is just the API usage that trips people up? Not just for me and the standard library, but it just seems like how the documentation is generated, much of the code is kind explained with doc strings and most of the time, the actual usage and code implementation is kind of just abstracted away. That is my big issues. It took me a while to find out Swift has pointers, it is just hidden away in the Standard Library API. It basically shows you the what, but rarely how, the why or even the when. (When do i use this function or that function for pointer deferencing?)
@@twenty-fifth420 Couldn't agree more. Although I could well live with the few quirks Swift has, considering how well balanced the advantages and disadvantages are. But the fact that Swift is an Apple product and the consequences make it irrelevant. It's a bit like C#. There was a time when it could have been a great choice and it actually is a decent choice in some circumstances today. But being subject to the whims of MS made it unfit for me and many others.
I would love to see Zig thrive as a low level language and see a new high level language use Zig as a backend. I dislike Rust because its scope is too wide. It's not a great low level language and its not a high level language.
Thanks for taking the time to do all this coding and evaluation. It's very nice to see the implementation in diff. languages. IMHO, Rust code is the most unreadable, by far.
ChatGPT can convert the given code to any language that existed before 2019 ;)
@@YT.Nikolay not really? when trying to get chatgpt to convert to more obscure languages (like D for example) it makes a lot of mistakes.
@@thezipcreator not entirely perfect, but for majority of cases, it did work for me
Well, a 20+ minutes vidéo I actually watched from beginning to end, no fast forward, no need to rewind.
That's become so f'in rare these days!
Clear sections of the video where you setup your goal, testing protocol, evaluation criterias.
Then doing it with examplification, biased opinions and objective comments both for each.
Then a summary and an acknowlegement of your biases and a humble recommandation of which to choose in your opinion depending on your preferences.
Rust only got an 18/20, but you get a 20/20 note as far as I'm concerned!
*DING* Subscribed
Nim is way, way, waaaaaaaayyyyy faster than Python, so of course there is an advantage. Regarding Nim's identity, I've heard people saying that and I don't understand the point. What's python's identity? Everything, it's used for everything. Web, desktop, data analysis, data engineering, scientific dev, scripting, sec tools... But nobody complains about that.
Tbf these days I think Nim's identity is "the hacking language"
And that's why I don't like either
Well, taking python as a reference speaks a lot, if you eat s**t everyday, dirt might taste good to you
Yeah but that’s great, because you can learn one language and do anything you want. It may not be fast but being able to do anything is quite convenient
Python has such a massive following that it has packages with thousands or millions of active users in basically every sector possible. That’s very different than nim not having a niche
I would have added performance as a criteria.
Yeah, I love this video but for many of these languages the big benefit that he missed is their performance, and for some like Gleam performance is one of the biggest downsides. It seems like a bit of a waste to build something as good as Gleam in a way that limits performance so much.
I guess he left it out because it didn't make a significant difference for his use case, but should at least be mentioned as a known benefit or downside.
That can be misleading tho. 1-5 scale comparison in terms of tooling makes sense but comparing a runtime optimized compiled language with something like javascript may yield 500x difference in performance which doesn't make sense.
I would keep things to compare for paradign support, tooling stuff.
Very agreeable takes, thanks for your efforts!
I don't really understand why Dart got such a low score. It feels like it gets a lot of things right, and I had a blast using it to maintain a production Flutter app. It feels like your grades don't align with your feedback :D
Dart got a high score and came in fourth.
he actually didn't use the nice parts of Dart. the `..` operator is pure genius for initialisation, making dependency injection work without any clunky library or "bag of globals". the automatic parameters make robust initialisators look like magic. like with Zig, it requires more than just a glance to appreciate. I bet he had previous experience with some of the most highly rated ones, which helped him find the best parts of those.
I use dart since 5 years and I love it, I think he treated dart fairly. There is still stuff we want and don't have yet in dart. Static metaprograming (it is coming very soon), error as value not exception (no plan to change this at all, so you have to import fp library like fpdart and use either type). For some reason they don't want to let us configure line length on a per project basis, and default line length is 80... I find the pattern matching syntax to be a bit confusing (particularly when using switch expression) but it might be me I don't know.
Except that, the toolings is just awesome. I use flutter (so dart) at work because I in charge of the mobile team, but I have to work with python for backend, I feel so miserable when I have to use python, the tooling is horrible, the language is horrible, nothing works, it is probably the worst language I ever used.
@@JavierGuerra_g It is the second time someone mentioned the '..' operator as an exceptional feature of dart and I don't get it, if you embrace immutability you cannot use this operator 99 percent of the time when initialising a class, or I am missing something. Could you also elaborate how it helps for Dependency injection please? Always eager to learn new stuff about this language I love, even if I would feel dumb having missed incredible feature usage for so long
@@gaxkiller there's so much to be said about how DI is great when you don't use a library and so disastrous when you do. and for most languages, the syntax gets in the way, making complex initialisations either complex and hard to read, or a whole API in itself. to make that last option somewhat more palatable, somebody invented "fluent APIs" which are nice, but tedious to implement, and create other limitations.
in flutter, the '..' operator gives all the benefits of fluent without having to create all those initialiser methods, and thus you get those multi-line, deeply nested, but nicely-indented and very readable initialisation stanzas, where you can do all the DI you wish.
Pretty sure idiomatic Kotlin error handling is much closer to Rust then Java. You would use Result type to return error as value and throw for panic. I dont really know tho, I am in the process of learning Kotlin. Overall Kotlin seems like an extremely pragmatic yet expressive language, with a module system to avoid common oop pitfalls. With the mutliplatform enetring stability, it just might be a killer app of Kotlin ecosystem.
The MAJOR issue with Kotlin is exactly that there is no idiomatic error handling. The official Result Type was only added after years, and they threw out checked exceptions without giving us a good, standard library alternative.
Meaning, everyone did their own thing. You also lack convenience of a "try-catch"-like structure for Result types, meaning you end up having to manually check every Result.
@@MarcelRiegler Right, it's a shame. If would much prefer an idiomatic way like Rust. But at least Kotlin has enough features like Sealed Classes and Trailing Lambdas, to easily implement a rust-like error handling. It's not perfect, but still much better than dealing with exceptions.
I have tried Kotlin for Advent of Code, AoC is an excellent way to have a good taste of a language and how it would fare in real work. I found Kotlin was a pleasant experience. Its library is comprehensive and very well done.
I picked up Dart for Flutter in its beta days and stuck with it because it just felt really nice to write. I could mostly just do as you said: imagine what I want the code to do, write it, then move on with my life.
Im forever a Julia boi. I just love it. It is absolutely perfect. But maybe that’s because I’m a physicist. But it’s just a breeze.
Indeed, the fact that you are a scientist may be a bias... but, Julia is just amazing like you said!
As a physicist as well as a software engineer, I entirely agree. Julia just has the best syntax.
@@SystemAlchemist begin and end are two words that don't do it for me personally.
Nice comparison! Good job. Try also OCaml next time:) I'm sure you will enjoy it as it's like a rust with GC.
"Nim is the least opinionated language" - I agree. Been using it for a bit.
On the surface it's a statically typed python with even more stuffs like metaprogramming capabilities etc etc. I like the freedom but I also appreciate what other languages have to offer in this list.
Bro went from "I don't like errors as values is like a chore" to "I would much prefer errors as values"
Very interesting video. Just an idea for next similar ones: you should also compare these with "classical" languages that everyone has to use at everyday work such as Java, JavaScript, Python or C#... This would give the insight about the language evolution from the classics to the modern ones.
Btw. I am a Kotlin fan. As I do not mind using JetBrains tooling (which is perfect!) I would give it much more points in tooling category which would make it almost a winner. :)
I was surprised by Gleam, I have never heard of it... but I will definitely find out more.
Java, JavaScript and Python some of the worst shit 😂
@@ccriztoff Yes, I understand why he didn't even loose time trying them >
I’ve working with Bun and I am really liking it. The tooling is awesome and not require external dependencies do to the basics. The websocket module is awesome and easy to use
I love Julia, it's my favourite language now (apart from maybe R or Scheme). I find it elegant and aesthetically pleasing. That said, I primarily do mathematical modelling and statistics, rather than making apps, so I don't really know what it's like from that perspective. The 1-based indexing is something you'll find in a lot of programming languages popular among mathematicians (see also Fortran, R, Matlab, GNU Octave, Maple, Mathematica, and Maxima), I guess we just prefer it that way.
As a mathematician, I don't. And I always prefer to index my sequences from 0. Whenever I read a text that features a sequence with index starting at 1 I have a harder time grasping proofs. Good thing about programming in mathematics is that languages tend to be functional, so you don't often try to directly access some index or do index arithmetic. Also, Python has 0-based indexing so that's cool for me.
@@renato360a every time I see Python's "range" function, and know you have to say "1 to n+1" to get "1 to n" (instead of 1:n like any 1-based language) it makes me irrationally angry. Especially when numpy's "arange" function has the exact same behaviour for non-integer sequences, which makes it so much more difficult to specify the end point. I don't like Python.
@@spacelem yes, I would expect that! 😅But that's a very rare case as I see it. 99% of the time I'm not specifying the starting point, so I'm just reading "range(n)" as "give me _n_ terms of a sequence", which if we start from zero, naturally should end at _n-1_ . For non integer sequences I tend to use "linspace" more anyway, which does include the endpoint.
@@renato360a I'm a mathematical modeller, dealing with epidemiological and genetic models. I frequently need to simulate from t=[0..T] (end points included), but also when doing intervals it might be X(t) for t=[t1.. t2], and the next interval I need X(t2) as the initial conditions (this is absolutely the case with my current project, which involves a virus spreading between chickens, which one group being added to the previous group for a period, then moved back, and being the source of infection for the next group).
When doing sensitivity analysis on parameters I often need linspace or logspace (or their language equivalents). It's much easier to drop the final point if I don't need it than to try to guess a value past the end that doesn't get me too many points.
When it comes to accessing data (so integer values for an index), I just like the 1st point to be x[1], and the Nth point to be x[N], not x[0] and x[N-1]. It's less to have to think about. I know there are times when 0-indexing has helped with certain algorithms in C++ dealing with n-dim arrays, but R or Julia usually already provide the tools to not need to think about it.
@@spacelem Hm. I guess it's more like to which camp does one belong to, Naturals start from 0 or from 1. Mathematicians don't make up our minds about it so you see models starting sequences from either. And you and I are from different camps...
Personally I love subtracting 0 (does nothing) and hate subtracting 1 (shifts everything), so I'd much rather start at zero and end at N-1. A long time ago I had to get it through my head at great pains that when you subtract two integers, the result has to be increased by 1 to yield the total number of elements including the endpoints. That made it very natural for me to see a sequence to N-1 as having N elements.
It's kind of sad that Dart's sound null safety wasn't even mentioned. Also, Dart 3 has a much more modern syntax than Dart 2 with pattern matching, destructring etc...
Didn't understand a word you said. Video is great tho. Am in awe of your programming capabilities ^^
I appreciate you being clear and upfront about how you'll be ranking the languages. Also, you might enjoy Roc! Although TCP server might be too low-level (in Roc those things are usually handled by platfroms), so I would recommend making something else with it
First 10 seconds had me dying laughing. Also subscribing. Love the deadpan humor.
I’m Rust/Go as situation dictates. I love rewriting Python in Rust and running comparative benchmarks. It’s stupid how slow Python is.
Also minor maintenance of legacy Java and C++.
Mojo is the new faster Python. From the creator of LLVM and Swift, Chris Lattner.
@@spht9ng no its the faster Rust written in pythonic syntax. Time for rust to pack uup the bag cuz we say not to ugly syntax
I'd love to see you review Clojure the same way, and if you do, I'm looking forward to a shockingly low "tooling" score
11:17 on the top, there is the compile command, below is in what module the error occured, below again is the error, basically, in zig, you can only access active field of unions, there are also tagged union which you can use switch on them. here you try to access "Pointer" while the union field "Struct" was active. what you can do is check if the field is active: if (taggedUnion == .Field) { . . . } or use a switch statement: switch (taggedUnion) { . . . }
The thing is that if you look closely, the message says that error occurred inside "Allocator.zig", which is part of Zig standard library. I think that message is not full, and there was more info cut below.
I think I've seen a similar error in my practice. He probably tried to allocate a wrong thing and error was confusing.
For what it's worth, kotlin has runCatching in the standard library, which effectively gives you either successful result or exception as a value if that's what you need. So it's more a style choice in kotlin. And if can allow 3rd party libraries, there's one that allows you to get even more functional (namely Arrow)
I think you should look into nim more. While I do agree it has some strange stolen features that don’t feel like they mesh well together. It’s actively developed and isn’t afraid to add new patterns. Honestly I would love to see you’re criticisms more in the nim community and I would love if you got involved.
21:17 Bro insulted me without even knowing me 😀
me too! 😅😅
Love ur refreshing take. Very solid video. Thank u very much. I enjoyed this very much. U helped cut thru the type and showed me the warts of zig nim etc
You might(or might not) like D or Odin
Thank you for the recommendation
@@tom-delalande yeah. Np
Some nice languages that will never reach the attention of mainstream.
1. D (OOP language with optional GC)
2. C3 (Procedural language that deserves Better C)
3. Odin (Improved C with pascal & Go style)
Great choice of languages. I personally would have added C# and Elixir. I would love to see a followup video with the languages people have mentioned in the comments.
I've been a php dev for a while, so I've been looking for a new language to pick up because I'm a bit bored. I was originally attracted to rust and gleam, but they were proving to be a bit of a challenge, so I went with Go because it seems to be learnable and popular. One day though I will pick up Rust or Gleam.
I was very interested in Elixir too, then I saw it is not statically typed. From personal experience, the developer experience regarding dynamic language is subpar vs statically typed language so I did not bother investing time in it. There are adding type step by step apparently but it did not solve the problem for other dynamic languages that did that.
FWIW, coming from C++, golang and python, I have been using Elixir exclusively for the past couple of years, and I couldn’t be happier. Engineering productivity is through the roof.
the biggest issue is that there are way too many languages and instead of fixing the established languages we keep adding new ones.
One thing I did not like, is how readability is being rated?
For me, readability is the ability to read a code from someone else and know what it does. Why for example, rust with it's vast syntax is more readable than go? I don't get the justification.
If I write code in golang, I will know what it do instantly, if I show it to anyone, they will know exactly what it does without effort. I wouldn't be so sure of that in the case of rust. Some libraries in rust is unreadable compared to others. Everyone have their own writing styles. It should be less readable than go.
I was a bit confused about the readability and ergonomics ratings for Nim as well. I get that Nim is unsafe but it seems pretty readable and ergonomic and had the fewest lines of code.
readability is a matter of familiarity, I don't think it can be rated since it would be unfair, for example, i write Go more than Rust and i never wrote Gleam, therefore gleam is not as readable to me compared to rust and go and rust is not as readable as go, it's unfair to rank it
@jamlie977 no body said x is unreadable, but it should be a meteric of how much experience it requires. A code written by a senior go engineer will be readable for a junior dev. But rust won't.
@@lazyh0rse i get you, that's why i said it's unfair for him to rank them based on readability as it's a matter of familiarity, if he doesn't have much experience with a language he would assume it's not as readable which might be false
@@jamlie977 It's unfair to rank it by your own subjective ability to read the language. But there is objectively readability in the sense that some languages are easier to learn when adjusting for that bias, like for beginners who have no experience in any language, and juniors with no experience in either language. A language is objectively more readable (on average when including beginners) when it more closely resembles natural language expressions of the same logic, more real words and natural grammar, less esoteric abbreviations, esoteric symbol use, and bloated non-grammatical boilerplate to declare things that should just be a default. Basically: how easily can someone without experience read it out loud in a way that accurately conveys the code.
Rust is just so much joy to use, that's why I use it in all my personal projects.
great video! It'd be interesting to compare the LOC it took in each language
Thanks! Great idea.
Here are the lines of code (including any blank lines):
Nim - 150
Kotlin - 163
Julia - 170
Swift - 180 (with dependencies)
Crystal - 187
Dart - 190
Go - 264
Gleam - 278 (with dependencies)
Zig - 338
Rust - 354
Anecdotally, Go and Dart definitely felt the quickest to write and Zig took me the longest.
Interesting that I enjoyed some of the verbose languages. I wonder if that's just Stockholm syndrome and less lines is actually just easier
@@tom-delalande Thanks! Yeah very interesting, especially how few LOC nim took. I guess some of it could be attributed to "skill issues" :D But also more LOC could mean more resilient code because of error handling
So yeah very cool
LOC is the most useless metric. You can write s**t very quick in python, with zero error reported by your IDE and zero error handling. But then you would need 123124124 LOC of unit test to be sure that true = true
@@tom-delalande pin 📍
I'm confused. You are saying that safety is important for you, things like exhaustive switch statements, immutability, and null-safety. And then you give Go and Kotlin the same score 3. Even though Kotlin has many of the safety features mentioned while Go doesn't.
same, he said he dislikes Go's error handling but said gleam had it really good, it's almost as verbose as Go's way
The man explains why - he dislikes try catch and prefers errors as values. He is lazy and will ignore exceptions while writing code without the compiler complaining. Go enforces error handling, and Kotlin uses unchecked exceptions.
@@TJackson736 the toInt method for strings in kotlin may throw an exception yet he praised it even though it doesn't tell you that it's may throw an exception since it uses java.lang.Integer.parseInt under the hood, it's really weird how he hates unchecked exceptions but not always
it would be much more difficult to compare if allowing dependencies, he might like the result type from ArrowKt
Go is simply better though
Dart has exhaustive switch expressions (even for types), you can enforce immutability via the final modifier, it has sound null safety... In my view it's definitely safer than you made it look
Nice vid, informative: would love to see this across different tasks. Rust being a joy to read is a bit on the nose however.
Not sure what you mean about that last part. Is rust really bad to read? Compared to what?
@@mikkelens obviously elements of personal preference, but Rust is well known for correctness not for being a joy to read. Ruby is a joy to read, APL is a nightmare, and Rust lies somewhere in between. My 2c.
@@mikkelens Rust is basically impossible to read if you are newer to the language, especially when it introduces new concepts like borrowing and lifetimes. Meanwhile, most programmers can just see Go and understand what it does even if they barely use the language.
Other than that, it's preference. I come from a Python background, so I found nim to be easy for me to read while zig being the hardest in these examples. Other people may prefer verbose language with more information, or c-style curly braces. It's all what you grown familiar with.
However, if you remove that, my point still stands that Go is probably the easiest in general for anyone to read here.
saying kotlin inherited unchecked exceptions from java feels weird when java is the only mainstream language with checked exceptions and kotlin specifically chose not to include them because "muh annoying"
I like swift, the keyword arguments in particular. But, the rust ownership model and errors as results/values are the best.
damn the end was too real. I just finished watching this on my lunch break where I will have to go back to writing spring boot on java 8 and angular js 💀
Seeing all those indentations is killing me
Thank you man, this was very valuable
I came across this video in the r/gleamlang subreddit. Fantastic work : ) I think Gleam might be my new favorite non-array language.
“There are no strings in zig, everything is an array of u8s”
Welcome to the real world my friend
I think modern c++ (c++23) also deserves a mention. It’s come a long way even from c++17. It has features like optional and expected and other features similar to other modern languages in that list (although they are not strictly speaking enforced due to it still allowing for the old style). Although I must admit that the syntax is still ugly af in some cases and it can get extremely difficult to read very quickly even for basic tasks. It’s also extremely verbose but it’s still fast with zero cost abstraction and tries to modernize (good attempt imo) and became much safer.
Simply Rust is so good when you undestand how types work, traits, unlock full match power, iterators, you can do a lot of stuffes with just references, neither touch lifetimes or more complex memory management things
Java has Checked Exceptions and Kotlin deliberately moved them to Unchecked for a reason. Maybe you read about why. ALso, Jetbrains IDE is the best tooling there is and Kotlin support is superb. I would rank Kotlin first for tooling and safety.
I used a lot of Zig lately so I might be bias but giving one on tooling is questionable. Setting up a project with zig build is so much cleaner than using CMake, Make, pkgconf or any other external tool bs when I have to use C or C++. Also the LSP gives a tutorial even for Sublime Text on how to set it up even though it's not the most used editor. The error messages most of time are much more readable than what you get when a C++ template code fails.
> The error messages most of time are much more readable than what you get when a C++ template code fails.
Which doesn't say much, given those errors are hundreds or thousands of lines of mostly complete garbage, easily the worst in all the existing programming languages.
Zig error messages are fucking horrid.
Programming languages really are subjective.
Most of the things you had as confusing about Crystal are super obvious to me and it's by far the easiest to understand/read language for me. Compared to Go or Kotlin which I find hard to read/follow.
I feel like most modern languages requires an LSP to use, except for Crystal where I never use one, or really any other tooling other than syntax highlighting. Dart especially feels unwritable without an LSP.
Julia is my favorite language! I think you basically correctly described it, it's excellent for REPL programming and a few other things, but it's not the right choice for most projects.
I especially like how you put it at rock-bottom on the safety scale! That is exactly correct, there are very few languages that will let you overwrite almost everything in the language, even to the point where there isn't really anything you can do but restart your REPL. It doesn't come up often, but when you want it, it's nice to have such a ridiculous brute-force solution.
In my opinion, it is the perfect prototyping language. It lets you focus on exactly the things you care about specifying while ignoring ALL the rest, whether that be expressive types, data structures, performance (to an astonishing degree, actually), even concurrency... everything except for correctness. If you can write it in less than 1000 lines of code, and it doesn't have to be perfect, then you're going to have a good time with Julia.
Also, the array broadcast notation makes me feel like I have superpowers. Working with collections in Julia is so freeing compared to everything else I've used.
But yeah. Rewriting yet another Julia program in Rust right now (this time, for WASM support) :P
Julia was designed primarily for scientific computing.
With that feature list at the start, I was thinking f# would be a perfect match
I’m most excited about Gleam. Feels like the love child of Rust and F#
I switched from using primarily PHP to writing most code in Rust. I made the switch about half a year ago and been using it as a first choice since then. For most of the tasks I have, Rust is more concise, quicker to write and obviously much, much quicker to execute. Often it's not by a little bit, but a massive improvement. An example I did last week was a tool for configuring a mobile device on an external carrier (I work at a small telco). The PHP code was about 1400 LoC and spread across about 40 files. In Rust this could be reduced to 450 LoC and 5 files. The rich enums are fantastic. The ability to define traits and impl-blocks for types you don't own saves massive amounts of boiler plate. The JSON parsing and encoding with serde is immensely superior to anything PHP has to offer.
With your preferred features, I guess F#, Haskell and OCaml could shine here.
I’d like all those way more if they weren’t GC’d. I want to try haskell just bc its haskell, but if I wanted to write something in a GC’d language I think I’d try Gleam instead
I’m implying here that 1) none of these could ever be compile time gc’d like rust and 2) I think runtime, stop-the-world GC is kind of unnecessary and bad, and 3) I see little reason to adopt a GC’d language in spite of this
@@mikkelens If you google "Oxidizing OCaml" you'll find some interesting work going on in OCaml moving it closer to Rust's memory ownership, borrowing etc. But I don't know any details on the status and progress.
Regardless, all mentioned languages have modern generational & incremental GCs with very short pauses (OCaml was quite famous for its good GC on a single core). Unless you make video games or something like them, the fear of GC might be rather irrational. Gleam might enjoy Erlang's thread-local GC that doesn't stop the whole world, but it's still just interpreted bytecode, so overall performance of actual code might be much worse than in mentioned languages.
@@mikkelens Haskell is a far more involved language than Gleam. If I am to compare the learning curve Haskell ranks above Rust.
@@mikkelens Beam OTP gives you a nearly pauseless GC expereience. So with Gleam, Elixir or Erlang, you wouldn't really have stop the world GC problem. Hell, even JDK has a pauseless GC now called ZGC. I think the place where no-GC languagesreally outshine others is edge computing and embedded devices. Thanks to their deterministic memory management .
should add f# it’s old but evolving
I've mostly written F# for the last few years, and I have to say I really like the look of Gleam. Will have to install it and play around some
Cool video, you could try Rescript or more FP oriented languages to see if it's more to your liking
I've been thinking about Rescript a lot, I'm tossing between trying to learn either that or Elm.
@@tom-delalande both are awesome, I believe there is more people using Rescript nowadays thought (it might not be a valid criteria for you)
@@tom-delalandeyou should try Clojure, though you might not like it since it’s dynamic
@@tom-delalande Elm wouldn't be a wise choice if you ever intend to do server side rendering (or program for nodejs/bun)
I always wondered why Kotlin seemed to be so loved and simultaneously underutilized. What a bizzare own goal by JetBrains.
Gleam needs more packages and then I will use it all the time. But it's new so that should happen as more start to use it.
"You can go back to work where you're forced to use JavaScript" hits me hard, rofl
Nim needs more love! It makes me so sad that it's still not used for more important projects.
Great video and thanks for trying all of these languages
From a ten foot view, all these 10 programming languages are the same.
Dart is awesome and very underused, prob. because people think it can only be applied to Flutter
I really think Swift has the right balance of features, safety, expressibility, I am glad to see it well represented here. BTW It does not use GC. One thing I would like to have seen is a discussion of generics handling. I think Swift shines here.
+1 for Gleam, but wish Clojure had been in here. I guess 2007 is a too old, but 1.0.0 was much more recent.
I think it would be interesting to compare some 'old' languages still in use, but with their newer features.
Think Fortran, C, Common Lisp, Erlang, Haskell, Ada, Smalltalk, Pascal for example.
For example, I think CL's tooling is superb, and Haskell's is now good even though it had a bad reputation. Smalltalk is OOP, but not as you know it, and Erlang has some of the cleanest loveliest code I've ever seen. Fortran is quick and I find it quite simple to read for whatever reason.
If you need the list to be 10, then perhaps add Forth, Cobol, Eiffel or Prolog if you're up for a challenge.
hey tom I was thinking of this video and I just had the idea that if you extend those same examples trying to getting deeper into optimization for them, you would dive deeper into the languages, review what they provide for performance and so on. Lets be real that is the type of thing that everyone subscribed here would watch more than an hour easily. It would be epic, all of luck!
And then there is a third group, array (and/or stack) languages, like Uiua. The most elegant solutions, assuming your inputs are integer sequences copy-pasted into the interpreter.
I love BQN 😁
Try F# too ! If you like rust or gleam or DSL in kotlin, you should find it nice as well 🎉
For Go you should have used scanner instead of reading the file and splitting by line
I was a huge advocate of Swift and had such high hopes for it. However, I've given up on Swift as a general purpose language because Apple isn't investing enough in the tooling
Honestly, I really like rust but working when I have to write a bunch of just regular regular code is absolutely by far. The best option for me. It’s easy, it’s readable, The standard library is great and super quick to just get things done.
Nice. But flexibility and GC are good things… Plus Julia looks better than a crab 😊
you need to dig more to understand nim, its more of a wizard thing
You're probably right, I'll have to dedicate more time to it to learn it probably. Based of the comments I think Nim was a big skill issue for me
I like mundane programming for work, fun programming for side projects
I had the same issue with Swift where my imports weren’t being recognized. I too have been trying to use Swift for general purpose with the Zed IDE. Crazy enough, I couldn’t find any solution or posts about this because it seems everyone using Swift sticks to Xcode.
The solution I found that worked for me is that after specifying the dependencies in the Package.swift file, build your project using the swift package command. This forces the dependencies to be downloaded, after which, suddenly the LSP realizes your dependencies exist. Anytime you make changes to your dependencies, you need to build the project even if it fails for the LSP to actually see the changes.
Xcode loves to do this automatically upon launching a project for the first time, this is why no one else questioned or complained about this.
Thank you for adding gleam🎉🎉
I love Rust in principle... Python if I want something that just works and doesn't enormously matter if it's not super-robust or performant
Swift’s sourcekit lsp works with dependencies after you build the whole project, because it does not have a background indexing unfortunately
I use it daily with neovim, it’s still not perfect (for example renaming does not work and you have to rebuild the project sometimes for it to be able to use dependencies) but it’s good and definitely better than using an Xcode
If you have any issues with setting it up with vim, I’ll be happy to help
Thanks for the help, I did rebuild the whole project. I think something went wrong with my tool-chain where the one used in the CLI was different to the one used by the LSP. I reinstalled Xcode from scratch and the whole toolchain. But I still couldn't get it working. I think this issue was a weird combination of Sonoma + something running on Rosetta + Xcode conflicting with the toolchain. I definitely will keep trying to fix it because I want to keep using Swift
@@tom-delalandeAlso a correction: Swift doesn’t have exceptions. It has errors as values. But it has syntax sugar to make it look like exceptions. It has a similar syntax sugar around it’s Maybe type by giving you a first-class nullable type.
@@tom-delalandeAnd a correction for what felt like an implicit assumption: Swift does not have a garbage collector. It uses automatic reference counting by default, and you can opt into some ownership features or unsafe manual pointers for performance.
TLDR; I would argue Swift has the same level of safety as Rust. This was not true for multi-threaded swift until recently. Since v5.10, there is a flag for strict concurrency checking.
you definitely should give Vlang a try!
19:50
Just a quick note, because I think you borrowed that from Blow (pun intended), but I also think while it can take "10% more time to write" (even when this statement is so blank) it also can make your code "10% or more easier to write bug-free" which will save you time. So I think it is a net gain generally, but this depends on the scope and the project.
i'm most likely late af, but this error you've encountered in zig is most likely due to following things happening:
1. you dereference a variable X, but X is not a pointer but a struct
2. you pass a struct X as an anytype function parameter, and this function expects a pointer
and various other reasons, but these two are the most probable ones.
the stack traces are not always pointing at your code, that is true especially for std.fmt, but the thing is that you can 'unwrap' the full stack trace with -freference-trace arg lassed to zig build.
hope you find it helpful.
Dart + Go + ScyllaDB = win
i tried zig recently, and i completely agree. string manipulation is often the first thing people try with a new language, and it's easily the worst part of zig, which gave me a really bad impression. the concept is brilliant, but actually using the tools feels like pulling teeth.
Yes, zig doesn't have proper strings, because it has to be compatible with C in that regard, and it's a real PITA.
It would have been nice to get some information about the popularity and who uses the more exotic languages
Damn that closing statement hits close to home
To be fair, I don't know if there was a much better way to handle that rust match nest. The language kinda seems to promote it