3 ms·
Performance is a complex story. Elixir is very good at massive amounts of parallel computing, and uses this to handle each request (or socket) in it's own conta
by paradox460 2y ago
Performance is a complex story. Elixir is very good at massive amounts of parallel computing, and uses this to handle each request (or socket) in it's own contained manner, which nets you some simplicity in designing systems and scaling. However it's not very good at single threaded off-the-block performance (but neither is Ruby)
Typing is coming, some is already here, and if you're impatient you can use dialyzer to get half way there. But in my experience you need it less than you'd think. Elixir primitives are rather expressive, and due to the functional nature there really isn't any "new" data structure that isn't easy to dive into. And with each function head being easy to pattern match in, you can dictate the shape of data flow through your application much as you'd do in a typed language.
The ide story isn't great, but it's getting better. There are a few LSPs out there, and an official one coming soon. And I'd say all of them beat solargraph handily
But most of all I'd say that, since it's a bit more strict, elixir saves you and your coworkers from yourselves and each other. There are still several ways to do something, like Ruby, but going out of your way to write very cutesy code that the next programmer will loathe is more difficult. Not impossible, but harder. And with the rock stable concurrency systems in place, a lot of the impetus to come up with clever solutions isn't there
- troad 2y agoMany thanks, I very much appreciate your thoughtful answer. I've added some of the context for my question here: https://news.ycombinator.com/item?id=43144841 https://news.ycombinator.com/item?id=43144841 Re types, I think what I really want is just comprehensive static analysis. Coming from Rust, where I can immediately pull up every single call site for a given function (or use of a struct, etc.), I find refactoring Ruby/Rails code to be comparatively very painful. It is several orders of magnitude more laborious and time-consuming than it should be, and I just don't find the justification for that cost convincing - I'd trade every last bit of Rails' constant runtime metaprogramming cleverness for more static analysis. What I like about Rails is its batteries-included nature, but I honestly could do without those batteries materialising via auto-magic includes and intercepted method calls. I appreciate that that's just the culture of Ruby though, so I don't expect Rails to ever change. The lack of cutesiness in Elixir sounds lovely. I don't know if functional approaches could make up for a lack of typing for me; I think I'd need to try it. I've used and enjoyed Haskell, but of course that's very strongly typed.
- paradox460 2y agoElixir has had some static analysis for a long time, you can use a command to see all call sites of a module and function. It's useful, and most of the LSPs use (or used to use) it. The newer versions also are adding various hooks to the compiler, to allow for better tooling As for magic, elixir can have what looks like magic, but upon closer look it's nothing more than macros, which are generally pretty easy to decipher and follow. It has minimal automatic code generation, what it has is mostly the form of generators you'd run once to add things like migrations
- arrowsmith 2y agoI have the same experience with typing in Elixir. It's hard to explain without experiencing it yourself, but the dynamic typing just doesn't feel like as big of a deal as it might in other languages. Elixir's guardrails (such as pattern matching in function heads, which you mentioned) get you most of the benefits - and you still get the convenience and simplicity of a dynamic language. It's a great balance. I'm looking forward to the upcoming gradual type system - it can only be an improvement - but I would still encourage people to try Elixir now, and let go of their preconceptions about static typing. Wrote about it more here: https://arrowsmithlabs.com/blog/you-might-not-need-gradual-typing-in-elixir https://arrowsmithlabs.com/blog/you-might-not-need-gradual-t...
- troad 2y agoThanks for your article, George, I enjoyed it. I cracked open an Elixir book last night, and with the benefit of a few chapters, I can see how Elixir's pattern matching can obviate some of the issues I have with purely dynamic, Rails style programming. I also note that there appears to already be more static typing going on than I realised. In your add_comment/2 code, for instance, you focus on the {published: true} pattern matching. That is very neat, but what stands out more to me is that all clauses of that function require BlogPost, a struct type. Am I right in thinking that every instance of BlogPost type must be constructed explicitly in your code? I.e. that every possible instance of BlogPost in the code base is knowable at compile time, along with its entire life cycle? Or does Elixir partake of the horror that is duck typing, where any conforming untyped map of indeterminate provenance will pass the guard check for a BlogPost? > Would you like another undefined method exception on that NilClass? *thousand yard stare*
- arrowsmith 2y ago> Am I right in thinking that every instance of BlogPost type must be constructed explicitly in your code? I.e. that every possible instance of BlogPost in the code base is knowable at compile time, along with its entire life cycle? Almost. You can create a struct dynamically at runtime like this: struct(BlogPost, %{title: "The Title"}) # => %BlogPost{title: "The Title"} … but you rarely need to. In fact I'm not sure I've ever used `struct/2` in real life. 99.9% of all the structs you ever create will have their types known at compile-time. > any conforming untyped map of indeterminate provenance will pass the guard check for a BlogPost? Nope. In the `add_comment/2` example, If I pass anything except a %BlogPost{} to that function, I'll get an error.
- cutler 2y agoThe JVM now has virtual threads so Elixir's days as the only game in town for massive parallel computing may be numbered.