Hacker Newsnew | past | comments | ask | show | jobs | submit | astrowilson's commentslogin

It won’t cause a uproar because Ruby/Rails changes APIs on minor versions all the time. Breaking changes are pushed at a yearly rate and everyone is just expected to cope with them.


That’s what I’ve gathered. That still seems stupid to me. Why does the Ruby/Rails community do that?


It definitely has something to do with Ruby and Rails. Ruby and Rails introduces API changes on minor versions all the time, sometimes even without prior warnings, so people shouldn’t expect related gems to be any different.


> This type of library API breaking change on a minor version update basically never happens.

Literally happens all the time with Rails. To the point they decided to call their versioning schema “shifted semver” to afford themselves API changes on minor versions: https://guides.rubyonrails.org/maintenance_policy.html

Good luck if you are using Rails and ecosystem and you expect any sort of sensible versioning.


Rails committer here.

First I get that people are used to SemVer, but it is unreasonable to assume all projects follow it. And yes in semver terms, you can simply assume that Rails X.Y is a major release.

Then, any breaking change in Rails must first emit deprecation warnings, so unless you are jumping one version, this kind of scenario shouldn't happen with Rails itself.

Also note that Ruby (MRI) itself more or less behave the same regarding versioning, deprecations and breaking changes. First emit warnings, then break.


I don't use Ruby.

Are packages that don't follow semver allowed to be released?

Haskell asks for PVP for example.


Yes, you'd need an automated way to catch the API breakage, which would be particularly tricky.

And even with very strict typing, the breaking change showcased in the article wouldn't have been caught, the API stayed the same, it just behave differently. Not every backward incompatible change is as simple as a function signature change.


When I tried to submit a package to Hackage, I was asked if I was aware of the packaging guidelines. The person who I emailed to register also inspected my package and told me that my dependencies were wrong and not compliant.

I really don't think this is a scalable approach and was really surprised that someone took the time to check my dependencies personally. My experience may just be rare.

I meant more on the human side than automated. Haskell doesn't have that much to do with formal verification in usual use. I'm not sure what the best policy for a good yet vibrant package ecosystem is.


That’s precisely my point. With Rails and Ruby breaking APIs on every new minor release, the only realistic expectation is that every minor release of anything may have breaking changes, because that’s the example being set. And it just makes the experience of updating any Rails project even worse than it already is.

The language and framework, by your own statement, are pushing breaking changes at a yearly rate. That’s a horrible developer experience.


No the expectation is that users of projects stop assuming SemVer is followed by every projects.

> pushing breaking changes at a yearly rate. That’s a horrible developer experience.

That's your opinion. I much prefer these bite sized yearly changes to much bigger changes over longer periods. e.g. Ruby with this strategy never had the big divide Python 3 had with its much larger change.


You may not believe this, but there are other ways of versioning software beyond breaking things every year and doing whatever Python 3 did.


> You may not believe this

You may not need to be confrontational...

> there are other ways of versioning software

I'm sure there is. But some features and other improvements sometimes require to deprecate and remove some older features.

Each project will chose its own tradeoff between bringing the improvement faster vs keeping compatibility longer.


Rails never was semver. Their yearly major-minor grand release always, always breaks API all around. It's inevitable. Any rails-only gem will as a result have a strong incentive not to follow several.


Not sure I agree on Phoenix. There are macros, but only around plugs and routing, not much different to what you’d find in Django and definitely less magic than Rails.

Plugs are straightforward function pipelines and a declarative DSL really helps structure your routes.

The controllers and channels, which are responsible for coordinating with your domain layer, don’t really add anything in the macro department. Plus there is no inheritance, which in my opinion is the biggest source of confusion on most OO frameworks, often requiring you to chase a behavior up and down the class chain.


I can’t reply directly to the comment below yours, so it will be as a side comment.

I don’t think anyone is arguing Elixir isn’t niche, we are just explaining why Elixir gets attention on HN even though it is top 50 on TIOBE. HN itself is focused on certain domains and tends to be early adopters.


I think a lot of Elixir devs think or want to believe Elixir is bigger than it really is. That's what I understand from the guy I made the comment to. Now I don't enjoy popping people's bubbles but I think it's better for everyone to acknowledge the truth and then think how to deal with it.


> Now I don't enjoy popping people's bubbles but I think it's better for everyone to acknowledge the truth and then think how to deal with it.

How to deal with what? That Elixir isn't as popular, so I should tell my company to drop it? I should stop enjoying programming in it?

Sorry, sounds like you don't want to accept that Elixir is on the up, for whatever reason.

Yes, it's not super popular. Yes, people are being productive with it. I don't get the point of your comment.


I won't tell you what to do with it, but the fact is Elixir is not on the up, it's very niche (nichier than even Rust is) and it's probably starting to decline already. Look at Linkedin jobs

Lisp - 142 Clojure - 700 Elixir - 828 Rust - 3160 Golang - 9205 Ruby - 24353 PHP - 68444 Java - 132606

So Elixir, at its peak, has about the amount of jobs Clojure has (never knew anyone using Clojure btw). That's quite a niche, ±800 jobs in the entire U.S is very very little. You might not care or have any action items from these facts, others may. As for companies - I would never choose something like Clojure/Elixir for my startup that's quite crazy considering the small eco system.


Sorry, where's your proof Elixir's at his peak? How can you tell from these numbers it's on the decline?

> I would never choose something like Clojure/Elixir

Then don't, nobody is making you. I still don't see why you want to stress so much Elixir is not a top language. From what I can tell, you have a bone to pick with the language and being confrontational with no discernible reason. Good day.

EDIT: checked your post history, you're definitely being a troll on purpose on most Elixir posts.


I don't think I was confrontational at all, I only listed facts on this thread. Other threads have zero relevance. Good day to you too!


You keep bringing up “Elixir has peaked” but you don’t provide any concrete evidence for that. The only mention so far is Stack Overflow, which is not used by the community, and such was explained to you on separate occasions.

Someone mentioned Elixir has just passed top 50 on TIOBE - that’s growth. It also just crossed top 20 on GitHub by number of pull requests on Q1/2021.

I am not disputing it is niche. I am not disputing the job market is tiny. But for someone who mentions acknowledging the truth, you don’t seem to be very truthful on your claims the language has peaked, especially given the last time you claimed so, you used a milestone (Top 50 on TIOBE) that has been reached since then.


The problem with Elixir is it's too small to get good data on (I'm not being mean, that's the truth). Tiobe has trends only for the top 20 languages so can't use that.

The best I've got is Stackoverflow survey (are you saying Elixir devs don't use Stackoverflow at all? I find it bizarre. Even if you use Elixir forum a modern dev has questions on many things he needs answered (css, javascript, sql etc).

So please compare https://insights.stackoverflow.com/survey/2019#most-popular-... With https://insights.stackoverflow.com/survey/2020#most-popular-... Elixir was dropped from the list. That's definitely a sign of decline. Now it could be that on absolute terms Elixir is keeping it's usage but only dropping on relative terms but I find it a bit hard to believe. I have a feeling Elixir devs who look for the next gig use other tech more often than not.


It is a data point, not definitive.

The language could be shrinking in comparison to everything an still be growing. I don't think that's the case but it wouldn't change anything for me. I don't work with a proportion of client according to trends. I work with particular companies and I'm at capacity doing Elixir as are many I know.

I believe it has a stronger trend then you believe it does. But neither of us have strong data.


Aren't clients considering migrating to different tech? I'm not trying to be annoying, genuinely interested. My current company considered it and they're a Ruby shop (luckily for them they rejected the idea). The thinking was something along the lines of Ruby is declining and how will they find developers 10 years from now. So if people can get this paranoid about Ruby I'm interested how it is on Elixir land.


So what is your action plan? To keep commenting that Elixir is niche on many threads even though most people here aren’t saying otherwise?

And even if they think that’s true, do you think being antagonistic to them on forums is what is going to change their mind?

I remember a recent comment from you saying that Elixir has probably peaked without even crossing top 50 on TIOBE... and yet here we are.


Look if you wanna shoot your career in the face go ahead stick to Elixir, the rest of us have bills to pay.


That’s only an issue if you define your career by a single programming language... I don’t.

Regarding bills, I made my biggest salary bump after I jumped to Elixir, but I appreciate the concern.


Not yet. It only supports Elixir for now (there is an issue for supporting other languages) and the notebook formats are different, so someone would also need to write a nbconvert to Markdown (.livemd).


The 3+ years ago is a good reference, thanks for sharing. The issue could also be Ecto related. Ecto 3, which might not have been out at the time, had a bunch of improvements on this front.


> and perhaps there could be a more concise enhancement of Erlang which would get the job done

Erlang already is a more concise language than Elixir but also noisier as there are more punctuation characters. I would love if Erlang would drop some of its punctuation, as some of it is frankly unnecessary.

Elixir syntax is definitely simpler than Ruby’s. Probably in the same ballpark as Python complexity wise: Elixir has less keywords and less rules thanks to the macro system but on the other hand more affordances, such as optional parenthesis.


> Erlang already is a more concise language than Elixir but also noisier as there are more punctuation characters.

What?

Here's more-or-less the entirety of Erlang's "noisier syntax with more punctuation characters"

  -spec f(A :: any(), B :: some_type(), C :: list()) -> any().
  f(A, {B}, [C | _]) ->
    A1 = fun() -> io:format(a, []) end,
    A1(),
    case C of
       <<1, _/binary>> -> 1;
       _ -> #person{ok = ok, field = C}
    end.
Edit:

  %% plus map syntax

  #{"tuple" => {1,2}}
  M#{"key" := "new_value"}

  %% plus list comprehensions

  [X || X <- List, X /= 10].

Elixir has all that plus more. The equivalent in Elixir is something along the lines of

  @spec f(a :: any(), b :: some_type(), c :: list()) :: any()
  def f(a, {b}, [c | _]) ->
    a1 = fun() -> IO.inspect(a) end,
    a1.(),
    case C do
       <<1, _ :: binary>> -> 1
       _ -> %Person{ok: :ok, field: c}
    end
  end

  ## and don't forget the capture and pipe syntax
  
  x |> (&f(y, {&1}, list)).()

  ## and default function parameters

  def f(a, b, c \\ []), do: something()

  ## and sigils

  String.replace(str, ~r".*", "")

  ## and Ecto adds its own characters

  id = 1

  (from p in Person, where: p.id == ^id, select: p) |> Repo.all()

  ## and dropping down to Erlang is a function call on an atom

  :io.format(x, y)

And I'm definitely forgetting more...

Edit:

  ## and string interpolation

  a = 1
  
  s = "The value is: #{a}"

  ## and two different map syntaxes

  %{a: :map, with: "various", keys: "as", atoms: 0}

  %{"another" => "map", "but" => "keys", "are" => "strings"}

  ## and different map access

  map[key]

  map.key

  ## and map update

  %{ map | key: "new_value" }

  ## and list comprehensions

  for x <- list, x != 10 do
  end


Your Elixir example is literally wrong. It won’t compile unless you do many changes. You are keeping -> instead do. You are still using commas after each expression. The fn syntax is wrong and also using parens for args. So you forgot to remove most of the punctuation noise.

You are conveniently not showing many examples where Elixir is considerably less noisier such as keywords, utf-8 binary strings, etc. Module definitions in Erlang use -(). while Elixir doesn’t use a single punctuation character. Erlang has special syntax for list and binary comprehensions while Elixir has unified both and uses no special syntax. Maps in Erlang also have two syntaxes, more ways of doing try/catch, etc.

If you take examples of actual code implemented in both languages, instead of cherry-picked invalid gibberish, you will find that Erlang has more punctuation per character than Elixir.


> Your Elixir example is literally wrong. It won’t compile unless you do many changes.

I was typing this inside the HN comment box. And no, not many changes.

> So you forgot to remove most of the punctuation noise

For the two examples you could come up with for my entire text Elixir adds half a dozen new punctuation characters on top of Erlang.

> If you take examples of actual code

Of course. Here you go:

  Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) < byte_size(&2)))
I mean, Erlang doesn't even have `&` as a part of syntax, but sure, "Erlang has more punctuation".

Besides, Erlang's syntax is significantly more consistent than Elixir's. Just take Elixir's two separate syntaxes for maps, for example. Or the dichotomy between syntax for functions and lambdas (both for declaration and invocation).

The only reason Elixir feels like it has less punctuation is that Erlang is actually more terse than Elixir.

Just having pipes and function captures everywhere makes Elixir code have more punctuation than Erlang.


The example that you picked and wrote translates to this in Erlang:

    lists:sort(
      fun(X, Y) -> byte_size(X) < byte_size(Y) end,
      [<<"some">>, <<"kind">>, <<"of">>, <<"monster">>]
    ).
I will let others decide which one is noisier.

(And no, using Erlang strings here is not the same, especially when popular libraries like Hackney and Cowboy work only with binary strings)

> Erlang is actually more terse than Elixir

Which was my point since the beginning but you quoted only part of my reply. It is clear Elixir has more syntax than Erlang. The function definition delimiters (->/.) vs (do/end) is a good example in itself of how Erlang is more compact and using punctuation.

I stand with my position that if you take actual code, a file or a project, and write it in both idiomatic Erlang and Elixir, Erlang will have more punctuation per character and will feel noisier.

Here is an actual example. I got the hex decoding/encoding code recently committed to OTP in Erlang (https://pastebin.com/qMtj8mSY) and rewrote to Elixir (https://pastebin.com/zUCLeXZG). I ran them through the Whatsapp formatter and the Elixir formatter respectively. Both snippets compile and define proper modules. If you remove all whitespace, the rate of punctuation character per alphanumeric character for Erlang is 35%. For Elixir it is 25%. And FWIW, in this particular case, the Elixir implementation has roughly the same amount of characters as the Erlang one: 718 vs 721.

I will be glad to continue this discussion if you want to use actual code instead of fictional examples.

EDIT: I fixed an error in the Erlang snippet and updated the stats.


I accept that my original sentence was unclear. I mentioned more punctuation characters in the context of conciseness, which obviously takes the amount of characters into account. Other than that, I don’t dispute Erlang has less syntax and I hope it is clear that Erlang is noisier (assuming the definition of noise is punctuation / character).

Regarding the compiler, most compilers have ambiguity. It is the reason why you have to put a space between = and binaries in Erlang. The question is if the compiler is going to pick a side or require the developer to be explicit. Modern compilers prefer to fail early in such cases, rather than letting a syntax error pop up later on.

Furthermore, the use of do/end vs do: is completely up to you. My original draft had only the first, which reduced the amount of punctuation in Elixir further, but I decided to include both styles because you will find both in practice. But if you want to stay consistent, you have the option.

Finally, happy to disagree on the “agglomeration of characters” in the Elixir example. The Elixir code has less punctuation and is clearer, despite the use of “do:” (which, as I said above, is optional).


Let's go back to the original statement:

> Erlang already is a more concise language than Elixir but also noisier as there are more punctuation characters.

Nope. Elixir has more punctuation characters, and I've shown that.

Now, when we talk about "punctuation per characters of code", then yes, Erlang may have more punctuation in this regard. But it has another thing going for it: there's significantly less syntax in general, and it needs less brainpower to disambiguate (BTW, Elixir's syntax is ambiguous to the point that the compiler can't figure it out in certain contexts).

Even in the examples you provided:

  defp encode_hex(<<a::4, b::4, rest::binary>>, acc) do
    a = encode_hex_digit(a)
    b = encode_hex_digit(b)
    encode_hex(rest, <<acc::binary, a, b>>)
  end
 
  defp encode_hex_digit(char) when char <= 9, do: char + ?0
  defp encode_hex_digit(char) when char <= 15, do: char + ?a - 10
Oh, look, it was `f() do ... end` but then all of a sudden `f(), do: ` (with no end). Whereas Erlang's syntax is (mostly) the same forms everywhere.

And where Erlang is consistent due to terseness of syntax:

  decode_hex_char(Char) when Char >= $a, Char =< $f ->
    Char - $a + 10;
Elixir is an agglomeration of punctuation:

  defp decode_hex_char(char) when char in ?a..?f, do: char - ?a + 10
I have complained about Elixir syntax in the past [1] when I knew little to no Elixir (I'm now building a big-ish side project in it), but the complaint mostly remains.

Meanwhile Erlang may look like it uses more punctuation, but that punctuation can be much easier pattern-matched by our brains because it's consistent and means the same in (almost) all cases.

[1] https://medium.com/@dmitriid/in-which-i-complain-about-elixi...


My god, it’s like Perl but somehow worse. How do you even keep track of what’s going on?


That’s not a representative example of none of the languages. It is also just plain invalid for Elixir. I recommend checking actual code examples on their websites to form a better opinion.


It's not that bad, really. As with most languages, syntax is the easy part.

From personal experience:

- You're comfortable with Erlang syntax within half a day. There's just so much less of it

- You're comfortable with Elixir syntax within a day of two of active coding. Function captures may trip you up once or twice more, but then it's fine.


you are conviently forgetting one thing:

The equivalent of "hello world" in erlang is

    <<"hello world">>
Not the best. Keyword lists in erlang are unpretty

    m:f(value, [{foo, <<"bar">>}, {baz, 47}])

Where in elixir you would do:

    :m.f(value, foo: "bar", baz: 47)


> The equivalent of "hello world" in erlang is

is "hello world".

Edit:

I know that "" in Elixir is binaries which are <<>> in Erlang. In Erlang "hello world" is really a list of ["h", "e", "l", "l", ...].

What was surprising to me is how rarely that matters (unless you actually do a lot of text processing). And the functions that matter (like I/O) deal with io_lists anyway.

And since strings in Elixir are binaries, when you actually need to work with binaries, you're back to the same/similar syntax:

  <<0:1, 0:1, 1:1, 1:1>> == <<3:4>> %% Erlang

  <<0::1, 0::1, 1::1, 1::1>> == <<3::4>> ## Elixir


> Keyword lists in erlang are unpretty

Keyword lists in Elixir are nice, that's true.


It depends on what you mean by mainstream and by large company but Clojure, Elixir, and Elm are all languages that are frequently on HN and they were either personal projects or backed by small companies (<40 employees). I think Julia too.


They haven’t backed off from global inference. They did move to require you to type collections, but methods are not inferred at definition but rather at invocation and it happens globally.

There is no solution really. If you want a language to feel like it is dynamically typed but actually has types, something gotta give, and in this case it is compilation times. And it gets quite high fast.


> They haven’t backed off from global inference.

You might know a lot more than me about the subject, so feel free to correct me, but I think it used to be truly global inference - as in you were expected to write the whole program with no annotations. But now you're required to annotate instance and class variable types, because compile times were becoming intractable.


It is still global. Typing collections and instance/class variables help, you can optionally type methods, but anything that is not explicitly typed is going to be inferred during invocation and that needs to happen based on all callers in the whole program. Reducing the amount of type variables do not eliminate the global behavior.

In contrast, local inference considers a predefined context, such as the current module or class, and is much faster, easier to cache, etc.


Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: