crbelaus
a day ago
The progressive introduction of automated type checking in Elixir should serve as a reference on how to improve a programming language gracefully without breaking changes.
So many examples of programming languages have huge breaking changes between versions that end up creating a split in the ecosystem that takes years to resolve.
Thankfully José has been very clear about Elixir being done since at least 2018. The language is stable and the language/core foundation is not changing anymore.
https://www.youtube.com/watch?v=suOzNeMJXl0
Truly outsanding work and stewardship.
bryanlarsen
17 hours ago
> So many examples of programming languages have huge breaking changes between versions
I can only think of 2: python 3 and perl 6.
Those two were very traumatic so it's not surprising it feels like more.
pjmlp
10 hours ago
.NET Framework => .NET
While C#, F#, VB and C++/CLI were kept compatible, it doesn't help when the library stuff you want to call isnt' there any longer.
C++ removal of exception specifiers, GC API,
C VLAs got dropped in C11, function prototypes changed meaning in C23, and K&R declarations were dropped from the standard.
Java, already someone else mentioned.
D, the whole D1 => D2 transition, and Tango vs Phobos drama.
lelanthran
3 hours ago
> C VLAs got dropped in C11, function prototypes changed meaning in C23, and K&R declarations were dropped from the standard.
Not so sure I'd call these huge breaking changes. They're breaking, sure, but I'd expect them to be trivial to fix in any existing codebase.
Maybe VLAs are a huge breaking change? Most code never used it due to no way at all to use them safely, so while it is a pain to replace all occurrences of them, the number of usages should be really low.
pjmlp
3 hours ago
It was breaking enough for the Linux kernel, and the money Google sponsored to the effort remove them,
https://www.phoronix.com/news/Linux-Kills-The-VLA
Breaking changes are breaking changes, even if it is only fixing a comma, someone has to spend part of their time making it compile again, which many times maps to actual money for people working at a company, their salary mapped into hours.
lelanthran
2 hours ago
> Breaking changes are breaking changes,
No disagreement there, but the context ITT was specifically about huge breaking changes. I consider those breaking changes, but not necessarily huge ones.
aw1621107
8 hours ago
> GC API,
Bit of a quibble but I'm not sure I'd call that a "huge breaking change" given that that feature wasn't really implemented in the first place, let alone actually used.
pjmlp
8 hours ago
It could have been implemented privately by someone, but yeah I kind of agree.
https://cppreference.com/w/cpp/compiler_support/11.html
It was a bad feature, as the two main C++ commercial products that make use of GC, namely C++/CLI and Unreal C++, were never taken into account while designing it, a good example how WG21 often does PDF driven design.
isodev
13 hours ago
Swift! Multiple times introduced fundamental changes that were not only breaking but required semantic rewrites of code. The most recent breakage being Swift’s latest version adding concurrency features.
agrounds
13 hours ago
Scala 3 has failed to be widely adopted, and now the language as a whole is more or less dead. Not that that’s due to the 2-to-3 transition entirely.
pjmlp
8 hours ago
That happens to all guest languages unless that have unique selling points that make that differention happen and take off on their own, as genesis for their own platform.
See all platforms that have their identity tied with a specific language, the platform's language always has a guaranteed future as long as the platform continues to be industry relevant.
The others on top, come and go.
patates
9 hours ago
I haven't been following, now I'm sad to hear... Scala is really dead? What'd be the JVM alternative?
codr7
8 hours ago
Don't know about Scala alternative, but the language I've found most enjoyable on the JVM is definitely Kotlin.
orthoxerox
8 hours ago
It's not dead dead, but no new projects are choosing it. Those that chose Scala as the better Java can now just use the better Java from the latest JDK.
spooky_deep
7 hours ago
Scala still offers lots over modern Java.
The issue for me is that Scala design lacks focus. They say yes to too many features.
dustingetz
6 hours ago
the OO/FP fusion hypothesis resulted in a complicated language on the OO side (too complicated for enterprise application layer) and on the FP side an autistic culture war at the seam between FP frameworks. Functional Scala remains world class at high reliability services such as video streaming at Disney+ and Comcast, and Amazon search but not so much the Java everyman use case that I recall it being marketed for 15 years ago. And now the Scala leadership and the industry frameworks are pulling in different directions, Scala is academically funded.
myth_drannon
3 hours ago
Kotlin?
jameslars
14 hours ago
Java 8 -> anything 11+ wasn't great at scale. It's been smooth sailing for a long time again though.
patates
9 hours ago
What started as a "this should be just a few namespace changes" might have cost thousands of person days in my current job. So many tests red, the whole CI/CD broken, and when all "fixed" and done, there were still some uncaught production bugs haunting us for many months... Simply horrible.
On paper, it really was just a few changes. In practice, it forced a massive transitive dependency and technical debt cleanup for many companies.
pandemic_region
9 hours ago
I don't remember anything significantly bumpy for about 30 large-ish applications we migrated from 8 to 11, guess the mileage varied. JDK is serious stable stuff.
ffsm8
14 hours ago
Uh, wasn't the only breaking change a rename/changed path in some standard lib path?
pjmlp
10 hours ago
Introduction of modules, closing down of APIs that no one should be using, since Java 9 deprecated methods actually get removed a few versions later.
Also breaking changes do happen, see list of removed methods
https://docs.oracle.com/en/java/javase/17/migrate/removed-ap...
cesarb
3 hours ago
On top of that, there was the removal of built-in J2EE; you needed to add external copies of the J2EE pieces, and some of them (like CORBA) weren't available as separate packages. And later versions of these external J2EE packages changed the namespace of all their classes, which is especially painful in Java due to its common use of dynamic loading of classes by name and lazy linking (and lazy linking errors do not inherit from Exception, which allows them to escape from catch-all "catch (Exception e)" clauses). The rest of the ecosystem is starting to depend on these new versions, so staying with old versions of these J2EE packages is not an option.
cess11
10 hours ago
Deprecations, which also affects libraries, i.e. the dusty one you were chugging along on top of might need to be replaced or adopted because the original maintainer gave up years ago.
nasmorn
7 hours ago
Ruby 1.8 to 2.0 with a layover in 1.9 was also not fun. Compared to python it is chicken shit of course
tobyhinloopen
8 hours ago
NodeJS with its commonjs vs modules, it's a huge mess IMO. Add typescript and build systems for bonus clusterf*cks.
agos
2 hours ago
the whole commonjs vs modules is there precisely because they chose not to introduce a breaking change.
Typescript has introduced breaking changes but they're not that bad
chillfox
15 hours ago
Ruby 1.8.7 -> 1.9.0 caused a lot of problems in the sysadmin space that took years to get resolved.
thibaut_barrere
10 hours ago
Ruby 1.8 to 1.9 has been fairly hard, despite being a minor version change. Strings became Unicode, this broke tons of stuff. Also hash ordering.
This caused quite a lot of work on the apps I worked on.
dragonwriter
10 hours ago
> Ruby 1.8 to 1.9 has been fairly hard, despite being a minor version change.
Ruby 1.8 to 1.9 was a major version change in the semver sense; Ruby wasn't using Semver before, IIRC, 2.1.0, it was using a scheme that was basically loosely like Semver with an extra prefix number. Ruby minor versions were equivalent semver major (and also had a less-stable implication for odd numbers, more stable for even, Ruby “tiny” versions were equivalent to semver minor, and Ruby still had patch versions.
throwawaymaths
12 hours ago
ruby 1.8 -> 2 was miserable, especially as the linux distros kept 1.8 and gems started requiring 2.
dgfitz
17 hours ago
C++11 fucking with strings also comes to mind.
Blackthorn
13 minutes ago
C++20 too but luckily basically every compiler has added a switch to turn that insanity off, saving the language.
pjmlp
8 hours ago
That was more a GCC problem, but yeah.
jen20
14 hours ago
Although it was somewhat optional, adding async to Rust had a similar feel. Also various Swift versions had source breaking changes back in the day.
codr7
8 hours ago
I gave up on Swift when the next release suddenly required actor annotations all over the place. They've been making weird decisions lately.
laszlokorte
16 hours ago
php
TomBers
a day ago
Completely agree. I feel no pressure to constantly upgrade my Elixir versions. I just look at the changes and there is often useful features that make me want to upgrade, as opposed the feeling of dread when I am pushed to upgrade.
atonse
a day ago
Yea each time I’ve upgraded (been using elixir in production since 2017), it’s gone way smoother than I had anticipated.
I usually find the Erlang/OTP upgrades to be a bit more problematic compatibility-wise.
So I’m often in the latest elixir but one Erlang/OTP version behind cuz I wait a few months for all the kinks to be worked out.
flux293m
3 hours ago
That's definitely the right way to do it, I've had exactly the same experience.
burnt-resistor
a day ago
Elixir still seems kind of rough and missing creature comforts, needs stabilization and guides to accomplish goals. There's a lot of broken/under-maintained packages and unhelpful guides that don't work because there's so much Phoenix ecosystem churn. It could get better but all the things™ need curation and approachable documentation. Not everyone wants LiveViews or to use their component system, and the learning curve for compatibility with other tools and technologies is still way too steep.
Python 3 was really, really needed to fix things in 2. Hence 2 became 3. They managed it pretty well, vaguely similar to Go, with automated update tools and compatibility-ish layers. It had its speed bumps and breakages as not everything went smoothly.
OTOH: Ruby 3 went the wrong way with types separate files and fragmentation of tools. And that's not mention having to opt-in with boilerplate to change how String literals work. Or: gem signing exists but is optional, not centrally-managed, and little-used. Or: Ruby Central people effectively stole some gems because Shopify said so. PS: many years ago Hiroshi Shibata blocked me from all GH Ruby contributions for asking a clarifying question in an issue for no reason. It seemed agro, unwarranted, and abrupt. So the rubygems repository fragment drama seems like the natural conclusion of unchecked power abuse lacking decorum and fairness, so I don't bother with Ruby much these days because Rust, TS, and more exist. When any individual or group believe they're better than everyone else, conflict is almost certainly inevitable. No matter how "good" a platform is, bad governance with unchecked conduct will torpedo it. PSA: Seek curious, cooperative, and professional folks with mature conflict-resolution skills.
It's a good idea™ to think deeply and carefully and experiment with language tool design in the real world before inflicting permanent, terrible choices rather than net better but temporarily-painful ones. PSA: Please be honest, thoughtful, clear, and communicate changes in advance so they can be avoided or minimized to inflict least net pain for all users for all time.
Honestly, I hope more development goes into making Phoenix/Elixir/OTP easier, more complete, more expressive, more productive, more testable, and more performant to the point that it's a safe and usable choice for students, hobbyists, startups, megacorps, and anyone else doing web, non-web, big data, and/or AI stuff.
Plug for https://livebook.dev, an app that brings Elixir workbooks to a desktop near you. And https://exercism.org/tracks/elixir
_susanoo
a day ago
> PSA: Please be honest, thoughtful, clear, and communicate changes in advance so they can be avoided or minimized to inflict least net pain for all users for all time.
> Honestly, I hope more development goes into making Phoenix/Elixir/OTP easier, more complete, more expressive, more productive, more testable, and more performant to the point that it's a safe and usable choice for students, hobbyists, startups, megacorps, and anyone else doing web, non-web, big data, and/or AI stuff.
Seriously, this has been the case all the time. It's a great fit for AI, web (Phoenix), non-web (Nerves), students (Pragstudio), hobbyists (hi), megacorps (Discord, bleachereport).
What do you mean it's not testable, productive, expressive enough? Do you mean the entire elixir community is just fiddling about with unsafe software?
This comment seems just like a giant ragebait.
abrookewood
15 hours ago
"Python 3 was really, really needed to fix things in 2. Hence 2 became 3. They managed it pretty well".
I don't know how you can say this honestly - it was turbulent and fraught with trouble and angst. It most certainly was NOT handled well.
dmix
17 hours ago
Our transition to Ruby 3 was very smooth. The actual PR was pretty tiny considering how big our project was. Nothing like the crap I dealt with in JS framework upgrades for much smaller projects. Even Rails is pretty easy to upgrade these days, both are very mature.
bmitc
a day ago
The Phoenix churn is definitely real. It's so much so that I've never gotten into it. It's also extremely macro heavy, and so it's its own DSL or collection of DSLs. A concrete example of the churn is that the LiveView book has been "about to release" for five years now.
Although, what parts of Elixir itself are rough or missing creature comforts? I generally feel it's stable and fine, but I admittedly haven't written Elixir code in a couple of years, sadly.
josevalim
18 hours ago
LiveView was still before v1.0, hence the churn, but Phoenix itself did not introduce breaking changes since v1.0, released more than a decade ago. Our skeleton for new applications change, as best practices around web apps are still evolving, but it is completely up to you to migrate. As a reference point, most other web frameworks have gone through several major versions in the same time, changing how new apps are built but also breaking old ones.
The idea that Phoenix is also mostly macros does not hold in practice. Last time this came up, I believe less than 5% of Phoenix' public API turned out to be macros. You get this impression because the initial skeleton it generates has the endpoint and the router, which are macro heavy, but once you start writing the actual application logic, your context, your controllers, and templates are all regular functions.
dnautics
12 hours ago
> The idea that Phoenix is also mostly macros does not hold in practice
no, but the Framework does push you into using them. A good example is the `use MyAppWeb` pattern. That's a macro that nests other macros. the good news is that you can pretty much excise that and everything works fine, and LLMs have no problem even! (i think they slightly prefer it)
a few cognitive pain points with phoenix macros:
plug: (love it dearly) but a bit confusing that it creates a conn variable out of whole cloth. a minor complaint. worth it, otherwise.
phoenix.router: is a plug but isnt quite a plug.
anyways that's it! the rest is ~fabulous. i think to find a framework where you have two minor complaints is a blessing. remember how activerecord automagically pluralized tables for you?
oxidant
an hour ago
What do you mean, "creates a Conn variable out of whole cloth"?
Conn is just a pipeline of functions, the initial Conn struct is created at request time and passed through to each function in the pipeline.
ch4s3
14 hours ago
“It’s all regular functions” should be on our collective bumper sticker.
bmitc
2 hours ago
Thanks for the clarifications!
> I believe less than 5% of Phoenix' public API turned out to be macros.
The idea may still be right, but I'm curious if that addresses the majority of the public API that users are greeted with. I have unfortunately not written Elixir in a few years (cries), and I've never fully grokked Phoenix, so perhaps I'm still wrong.
giraffe_lady
a day ago
> It's also extremely macro heavy, and so it's its own DSL or collection of DSLs.
I mean this describes every full stack web framework right? Like sure if the underlying language doesn't have macros or macro-like tools that limits how perverted the syntax can get but the line between "DSL" and "API" gets really blurry in all of these massive frameworks.
bmitc
a day ago
That's true for languages that have macros. I just don't like macros, as they get over-abused in every language that has them. I'd much rather deal with just boilerplate and tedious syntax but still straightforward and completely in the language over macros, for the most part. Some macros are indeed useful, like in Rust with `println`, but they still get thrown everywhere.
giraffe_lady
a day ago
Frameworks in langauges that don't use macros have this problem too that's what I was getting at with the DSL vs API thing. I don't want to litigate the worthiness of macros for a given purpose here. But if you don't use them for this you have to use something for this the problem doesn't go away.
Wherever rails or phoenix has macro-defined syntax to handle a specific task, laravel or whatever will have a collection of related functions that need to be used in very specific ways to accomplish the same thing. Whether this collection is a "class" with an "api" or whether it is a "language" defined around this "domain" you will have the abstraction and the complexity.
Having a preference for one approach of managing this abstraction & complexity seems fine but "a collection of DSLs" is pretty much what a web framework is so that can't be the problem here.
zdragnar
14 hours ago
It really depends on how good your inspecting tools are. Using runtime methods and functions instead of macros mean the code is all right there, and what you're debugging is what you see in your editor (setting aside silly things like reflection shenanigans).
With macros, even language servers may need customization if they introduce new syntax. The code that runs doesn't exist until it runs, so you can't see it ahead of time.
This doesn't sound like too big a problem if you're familiar with the tooling already, but trying to figure out where some random method comes from in a rails code base when you're new to Ruby is somewhere between a nightmare and impossible without debugging and using the repl to tell you where the source is.
React has a JSX macro, and I love using it, so there's definitely room for them. There is a world of difference in developer experience when macros are used versus when not, however, and it is wrong to say that it is all the same.
cess11
10 hours ago
The counterpart in Laravel or Spring Boot or whatever would be annotations. As I understand it, that's how they're doing things on the .NET side too.
It's kind of the standard way to paper over the protocol grit of HTTP and make people able to quickly pump out fresh plumbing between outbound socket and database.
bmitc
16 hours ago
> Frameworks in langauges that don't use macros have this problem too that's what I was getting at with the DSL vs API thing.
You mean in the sense that the language's built-in syntax and available abstractions get abused so much that it approximates a DSL?