11 ms·
Am I the only one who never tried Elixir just because it has no strict typing? Seems very hard for me to go back to a language with dynamic typing. Maybe I'm ju
by Einenlum 1y ago
Am I the only one who never tried Elixir just because it has no strict typing?
Seems very hard for me to go back to a language with dynamic typing. Maybe I'm just wrong and I should give it a try.
- michaelterryio 1y agoI mean, lots of extremely talented and successful engineers, e.g., DHH, think strict typing is actually a negative. I think if you think strict typing is an absolute disqualifier, you should steelman the opposing side.
- Einenlum 1y agoI tried both and I respect different opinions about this. I feel like TS' type system makes me crazy because it's going too far. But no typing makes me anxious. I guess there is a sweet spot to find for me personally.
- Towaway69 1y agoI prefer something like specs[1] that define a function’s signature but isn’t enforced by the compiler, instead the linter enforces them. This is what Erlang has and it’s very convenient since once a design is fixed, I end up writing a spec to remind me what types the function expects. [1] = https://www.erlang.org/doc/system/typespec.html https://www.erlang.org/doc/system/typespec.html
- conradfr 1y agoI really don't get how having to write @spec foo(String.t()) :: String.t() def foo(bar) is better than def foo(String.t() bar): String.t()
- AstroBen 1y agoAnxious about what? What's your issue with dynamic typing? Thorough tests of the behavior of your system (which should be done whether the language is dynamic or not) catch the vast, vast majority of type errors. "More runtime errors" in a well designed codebase don't mean errors for the user - it means tests catch them Seriously.. the secret to writing great dynamic code is getting very good at testing
- theonething 1y agoThe thing is most useful for me about types is it serves as forced documentation. I look at function signature with types and know what kinds of values it accepts and what it returns.
- AstroBen 1y agoFor sure. The biggest advantages of static types I see is the better tooling + faster feedback for type errors. They're advantaegs but not that big of a deal and they're equal to the tradeoffs you're making to where it doesn't matter much I see dynamic codebases being written differently though. We all know those tradeoffs - so conventions pop up to deal with them. A method that ends in a ? in ruby - like user.admin? - always returns a boolean. You get better at naming to make types clearer I definitely miss the perfect automated refactorings though
- Einenlum 1y agoI come from a PHP and Python background. I can see how progressive addition of types has changed the way we deal with code. Working on a big old project without types is not even possible for me anymore. Refactoring things with types is already such a tedious task. Without it it's barely possible.
- ralphc 1y agoI knew TS's type system went too far when I saw the 8 queens problem solved in just the type system, not the actual language. Me, I just want to get stuff done, not fight my type system. And that was even before someone wrote DOOM in TS's type system.
- blipmusic 1y agoHis "argument" for strict typing on the Lex Fridman podcast was also that it's mostly if you have "hundreds or (of?) thousands of engineers collaborating", which "strictly" puts his opinion in the bin in my case. I have absolutely, positively become more productive as a single developer due to strict typing. Parsing various kinds of binary data was enough to convince me. A.k.a. each to their own. On the whole, Elixir and BEAM seem really cool though, and there's work being done on typing, as well as the new Gleam language. Note: I've not yet done any serious web-development, mostly command line tools, which I realise is not DHH's main focus.
- williamdclt 1y agoI used it being a big proponent of the TS type system and I definitely missed it greatly. They are actively shipping a type system for Elixir though, which as far as I understand is pretty similar to TS so, great!
- codyb 1y agoType systems in this space seem to take a long time and never quite reach completeness. At least that's the experience I've taken away from occasionally glancing at Erlang's Dialyzer project every now and again which I don't think has ever reached any semblance of the maturity of something like TypeScript. But pattern matching in Erlang does do a lot of the heavy lifting in terms of keeping the variable space limited per unit of code which tends to reduce nesting and amount of code to ingest to understand the behavior you care about at any moment.
- lknuth 1y agoIt is alleviated quite a bit bz its pattern matching capabilities combined with the "let it crash" ethos. They have a success typing system (which isn't very good) and are working on a fuller system (which isn't very mature). If typing is the only thing keeping you out, have a look at Gleam. Having worked with Elixir professionally for the last six years now, it is a very mature platform, very performant and offers many things that are hard in other languages right out of the box.
- Einenlum 1y agoThanks for your answer! I already checked Gleam several times and it looks amazing. The ecosystem just doesn't feel mature enough for me yet. But I can't wait for it to grow.
- lknuth 1y agoTrue. There is inter-op with both Elixir and Erlang, but thsts like early TypeScript. If you're at all interested, I'd suggest doing the basic and OTP tutorials on the Elixir Website. Takes about two hours. Seeing what's included and how it works is probably the strongest sails pitch.
- crabmusket 1y ago> combined with the "let it crash" ethos I see this phrase around a lot and I wish I could understand it better, having not worked with Erlang and only a teeny tiny bit with Elixir. If I ship a feature that has a type error on some code path and it errors in production, I've now shipped a bug to my customer who was relying on that code path. How is "let it crash" helpful to my customer who now needs to wait for the issue to be noticed, resolved, a fix deployed, etc.?
- zdragnar 1y agoLet it crash definitely wasn't meant to be a cover for poorly typed code. It's much more suitable as a replacement for adding try / catch everywhere and having to manually bubble exceptions.
- the_gastropod 1y agoElixir is a strongly typed language (as opposed to a weakly typed language like JavaScript or Perl). You cannot, for example, do `"4" - 1` in Elixir. Dynamic vs static typing is a mostly orthogonal scale, where Elixir is (mostly) dynamically typed. There are some very sharp Computer Scientists who believe static typing is unnecessary. Joe Armstrong (co-designer of Erlang) once said: "a type system wouldn't save your system if it were to get hit by lightning, but fault tolerance would"
- dminik 1y agoTbh, the strongly typed and dynamically typed combination seems like the worst option. You get zero help and punished hard for failing.
- throwawaymaths 1y agonah you just get log lines. crash is not as bad as you think it is.
- dminik 1y agoI mean, it is a kind of a bug that is easy to prevent with a static type checking, but also one that will always (or almost always) get triggered. Log lines are whatever, but a system that goes into a crash loop or fails on most requests isn't great.
- em-bee 1y agohow so? most dynamically typed languages are also strongly typed. that includes python, ruby, common lisp, smalltalk... if it was the worst option, this would not be the case.
- dminik 1y agoA casual look at the history of basically anything will tell you that the best option isn't necessarily always the one that succeeds.
- rendaw 1y agoI tried it for a job interview, and it was awful - because of no static typing. I spent most of my time tracking down dumb type errors, compounded by various language footguns (I can't remember exactly, but I think for example making a typo on a field name in a for loop condition is treated as "condition false" and so the for loop just doesn't do anything, no error). It seems like the Elixir/Erlang community is aware of this, as is Ruby, but it's a rather large hole they have to dig themselves out of and I didn't feel particularly safe using the tools today. I've heard a lot of good things about the Erlang runtime and I did really like Elixir's pipe operator, so it was unfortunate.
- kingofheroes 1y agoPattern matching makes up for the lack of static typing to me. It provides nearly all the same benefits especially when used with guard clauses.
- recroad 1y agoYou can also peek inside objects and check for types and values of nested properties. In other languages you’d need to create composite types or even duplicate or extend types. In Elixir, all that is for free. I see that as much more powerful than types.
- jamauro 1y agoGenerally I find static typing to be overrated, even more so with elixir due to pattern matching and immutability. I think elixir’s set-theoretic types will be a nice addition and will provide some compile-time safety checks without needing to explicitly define types for everything. It remains to be seen how far they’ll take this approach.
- throwawaymaths 1y agoreally you wind up making only a handful of type errors that make it into prod. there are other things that contribute to this like pretty universal conventions on function names matching expected outputs and argument ordering. it does suck hard when library authors fail to observe those conventions, or when llms try to pipe values into erlang functions, and yes, it WOULD be nice for the compiler to catch these but you'll usually catch those pretty quickly. you're writing tests (not for the specific reason of catching type errors), right? right?
- victorbjorklund 1y agoI let the LLM write my tests. And when they fail it just rewrites the tests to pass.
- Muromec 1y agoBiggest benefit of typing in TS is just autocomplete that knows to filter down suggestions to field name of the object type before the dot. That and constants without typos. That, exhaustive maps and interface implementations are really good to not forget things that have to be done outside of the currently open file.
- davidclark 1y agoWell written typespecs + dialyzer catches most things you’d want to catch with a type system: https://hexdocs.pm/elixir/typespecs.html https://hexdocs.pm/elixir/typespecs.html There is also pattern matching and guard clauses so you can write something like: def add(a, b) when is_integer(a) and is_integer(b), do: a + b def add(_, _), do: :error It’s up to personal preference and the exact context if you want a fall through case like this. Could also have it raise an error if that is preferred. Not including the fallback case will cause an error if the conditions aren’t met for values passed to the function.
- conradfr 1y agoWriting typespecs (+ guards) feels really outdated and a drag, especially in a language that wants you to write a lot of functions. It reminds of the not-missed phpspec, in a worst way because at least with PHP the IDE was mostly writing it itself and you didn't need to add the function name to them (easily missed when copy/pasting).
- bevr1337 1y agoI wouldn't lump guards and typespecs together. Guards are a runtime feature of erlang/elixir's excellent pattern matching. Typespec is an opt-in type hint for develop and build time.
- conradfr 1y agoTrue but by using guards + pattern matching structs you can approximate type hinting, but it feels cumbersome and more of a workaround than a real solution.
- bevr1337 1y agoI'm of the opinion that Erlang/Elixir are terrible for repeat tasks like a standard CRUD server over a SQL database. Because yes, it IS cumbersome! Behaviors and type hints only get so far, and it is exhaustingly slow to sit with epgsql in the REPL to figure out what a query actually returns. I find them much better suited for specific tasks where there is little overlap or repetition.
- arrowsmith 1y agoImo this complaint is really overrated: https://arrowsmithlabs.com/blog/you-might-not-need-gradual-typing-in-elixir https://arrowsmithlabs.com/blog/you-might-not-need-gradual-t...
- Jonovono 1y ago> But honestly, I’ve always felt like this objection was overblown. I’ve got nothing against static typing; some of my best friends use statically-typed programming languages. lol
- vwwvwwv 1y agoI liked the article, but I found it a bit strange that it presented pure functions as a feature of Elixir rather than as a general good practice. Surely there's nothing particularly unique about Elixir in this regard compared to other languages?
- spooky_deep 1y agoThere are auxiliary language features such as pattern matching that make pure functions viable at scale.
- victorbjorklund 1y agoMaybe try Gleam? 80% of the goodies of Elixir is the BEAM anyway and you get that in Gleam too.
- harrisi 1y agoI believe you meant static typing. There's active ongoing work in this space, and Elixir is actually gradually typed now. You can read more about it in the docs: https://hexdocs.pm/elixir/gradual-set-theoretic-types.html https://hexdocs.pm/elixir/gradual-set-theoretic-types.html
- ludicity 1y agoIt's not so bad in Elixir for various reasons. Firstly, they're doing some work on set-theoretic types. https://hexdocs.pm/elixir/main/gradual-set-theoretic-types.html https://hexdocs.pm/elixir/main/gradual-set-theoretic-types.h... There's also tooling like dialyzer, and a good LSP catches a lot too. The language itself has some characteristics that catch errors too, like pattern matching and guard clauses. With all that said, I'm still very keen for static typing. In the data world we mostly start with Python without mypy, and it's pretty hard to go back.
- bsder 1y agoOne of the problems with strict typing is that it makes it very difficult to hot upgrade a function to a different signature. Erlang OTP relies on being able to swap to new functions to do upgrades without downtime.
- crabmusket 1y agoIf you're trying to hot swap a function for a version with a different type signature, how was the new code going to run successfully anyway? Unless the type signature changes aren't reflecting the runtime behaviour changes?
- Muromec 1y agoIt's a solved problem in gen server actually. Kinda. You migrate in-memory data and if something doesn't align, it restarts.
- bsder 1y agoYou can have a tag so pattern matching can discriminate. You can have new function parameters. You can append to the end of a data structure. All of these would nominally be considered a type signature failure.
- iLemming 1y ago> Maybe I'm just wrong Yes you are. First of all there isn't such a thing as "strict typing", types are either static/dynamic and/or strong/weak. I suppose you meant Elixir has no static types. It is however a strongly typed language. And just like it usually happens, static typing enthusiasts often miss several key insights when confronting dynamically typed languages like Clojure or Elixir (which was inspired by ideas implemented in Clojure). It's not simply "white" and "black", just like everything else in the natural world. You have to address: - Runtime flexibility vs. compile-time safety trade-offs — like most things, things have a price to it, nothing is free. - Different error handling philosophies. Sometimes, designing systems that gracefully handle and recover from runtime failures makes far more resilient software. - Expressiveness benefits. Dynamic typing often enables more concise, polymorphic code. - Testing culture differences. Dynamic languages often foster stronger testing practices as comprehensive test suites often provide confidence comparable to and even exceeding static type checking. - Metaprogramming power. Macros and runtime introspection enable powerful abstractions that can be difficult in statically typed languages. - Gradual typing possibilities. There are things you can do in Clojure spec that are far more difficult to achieve even in systems like Liquid Haskell or other advanced static type systems. The bottom line: There are only two absolutely guaranteed ways to build bug-free, resilient, maintainable software. Two. And they are not static vs. dynamic typing. Two ways. Thing is - we humans have yet to discover either of those two.
- zdragnar 1y agoYou act like OP has never experienced dynamic type programming. They clearly said they "can't go back to" it, meaning they've experienced both, are aware of the trade-offs, and have decided they prefer static types. > Gradual typing possibilities. There are things you can do in Clojure spec that are far more difficult to achieve even in systems like Liquid Haskell or other advanced static type systems. That's great for clojure and python and PHP, but we're not talking about them.
- iLemming 1y agoYou act as if I said anything about anyone's experience. "they prefer static types" can mean a whole lot of things - there's type inference, soundness, turing-completeness, type classes, GADTs, higher-kinded types, dependent types, gradual typing, structural vs nominal typing, variance annotations, type-level programming, refinement types, linear types, effect systems, row polymorphism, and countless other dimensions along which type systems vary in their expressiveness, guarantees, and ergonomics. Dynamic typing also varies - there's type introspection, runtime type modification aka monkey patching, different type checking strategies - duck typing & protocol checking, lazy & eager, contracts, guards and pattern matching; object models for single & multiple dispatch, method resolution order, delegation & inheritance, mixins, traits, inheritance chains, metaprogramming: reflection, code generation, proxies, metacircular evaluation, homoiconicity; there are memory and performance strategies: JIT, inline caching, hidden classes/maps; there are error handling ways, interoperability - FFI type marshaling, type hinting, etc. etc. Like I said already - things aren't that simple, there isn't "yes" or "no" answer to this. "Preferring" only static typing or choosing solely dynamic typing is like insisting on using only a hammer or only a screwdriver to build a house. Different tasks call for different tools, and skilled developers know when to reach for each one. Static typing gives you the safety net and blueprints for large-scale construction, while dynamic typing offers the flexibility to quickly prototype and adapt on the fly. The best builders keep both in their toolbox and choose based on what they're building, not ideology. In that sense, the OP is wrong - you can't judge pretty much any programming language solely based on one specific aspect of that PL, one has to try the "holistic" experience and decide if that PL is good for them, for their team and for the project(s) they're building.
- Shorn 1y ago> Am I the only one Far from it.
- rubyn00bie 1y agoI’d recommend it. I used to think I needed statically typed languages to write sound code, but after enough time with Elixir (10 years professionally and going) I really don’t believe that to be true… A huge portion of my change of heart is due to Elixir (and Erlang) being functional and only having a handful of types: atom, binary, boolean, function, list, map, pid, reference, integer, float, and tuple There are a few others but they are generally special cases of the ones above. Having so few data types tends to make it much more obvious what you’re working with and what operations are available. Additionally, because behavior is completely separate from data it’s infinitely easier to know what you can and can’t do with a given value. Ruby being dynamic drove me insane at times, but Elixir/Erlang being dynamic has been a boon to productivity and quality of life. I recently had to write some TypeScript and was losing my mind fighting the compiler, even though I knew at runtime everything would be fine. Eventually I slathered enough “any” on to make the burning stop… But! That’s something I haven’t had to do in years, and it was 100% due to type system chicanery and not preventing a bug or making the underlying code more sound. There are still some occasions where having some static typing would be nice— but they’re pretty rare and often only for things that are extremely critical or expensive to fix. And IMHO even in those cases, Elixir’s clarity and lack of (implicit) state generally make up for it.
- tekkk 1y agoHere's my take as TS dev. You just never learned to use types in the first place where there is very little ambiguity on any types anywhere because there is close to no any's used. Sounds like you guys get high and mighty on your tunnel-visioned copium—I mean I used to write JS for god's sake and thought it was okay. And I remember when I first tried TS felt annoyingly hampered by having to actually use interfaces properly. Sure, the nature of Elixir probably makes it easier but I find little joy in dynamic whack-a-mole and mental gymnastics to infer types instead of fricking actually being able to see them immediately. I could go commando in TS as well and switch to JS and JSDoc, leaving everything gradually typed and probably be fine but I'd feel terribly sorry for anyone else reading that code afterwards. It'd be especially silly since I can now just infer my auto-generated Postgres zod schemas with little effort. Moreover, a good type system basically eliminates typing-related bugs which you guys apparently still have. So please, don't over-generalize just because you think you got it figured out.
- Rapzid 1y agoNot just you; my standards for typing and tooling are quite high these days. Happy with C# and TypeScript, avoid Ruby and Python these days if I can.
- conradfr 1y agoYou can have strict typing with dynamic typing, like PHP with declare(strict_types=1);
- sethammons 1y agoI went from a Go shop to an Elixir shop and a year or two later went back to a Go shop. The eng department velocity will slow as code complexity grows and teams change. Dynamic typing makes this worse.