Live data from Hacker News

Elixir v1.20: Now a gradually typed language

elixir-lang.org

401–410 of 426 posts

Re: Elixir v1.20: Now a gradually typed language

#401

Earlier quoted context omitted.

> people used to write server software in compiled languages feel the need for them because any runtime bug means downtime I keep hearing that but I don't think it's been true in many years? Whether it's Go, Java, C#, Rust... a runtime bug will only fail the request, not the whole server. FWIW, the main reason I like types isn't for the compile-time guarantees (although they're certainly nice). It's for documenting w…

That’s my top issue with Clojure: I see what the function does, but is it expecting a list, a string, either, or a map? The function may apply correctly, but what was it supposed to do? Java may be boring, but it’s surprise-free. In Elixir this is less of an issue because of pattern matching and very clear errors showing the actual arguments passes, that are unbeatable for debugging - you look at the log and can “see…

In Clojure you typically program to interfaces/protocols and not to types

The Clojure docs should be more straightforward about the interfaces that are available and targetted

You can still have a problem of not knowing which is required of an argument, but its usuallt clear contextually

Re: Elixir v1.20: Now a gradually typed language

#402
post #42

It's very nice updating Elixir, having no breaking changes across my many projects and it then the compiler just finds bugs for free. I'm so spoiled.

The stability of the language is such a blessing. I think that's part of the reason that LLMs do so well with it, despite its relative lack of popularity.

I am also quite happy with Elixir output, and it’s much more pleasant to review. Unit test runs are fast, and testing LiveView is overall more pleasant and effective compared to similar Typescript / React projects I’ve maintained in the past.

I never considered “language stability” until your comment, but I think you are right. I’ve had far fewer dependency upgrade pains and a general feeling that bit-rot is slower overall.

Older apps that depends on Node + trendy npm packages + popular frameworks can be a real nightmare to bring up-to-date.

Re: Elixir v1.20: Now a gradually typed language

#403

Earlier quoted context omitted.

> Elixir, I still had to know my whole call chain to know what I could do with my incoming parameters. The more call sites, the more mental context. but the call chain doesn't have to be long, i.e. it could be just 2 or 3 places; that fits inside my head. less is more

Sure, but it stops being that with multiple teams stepping in the same codebase as business needs expand. You revisit an area of code to find Sam in the billing department (who you don't know) interjected something or other and now there can be assumptions about the shape of data that were different than before. For us, it was data report shapes. Elixir is amazing when the system fits in your head.

ah yes, this is why Ash is great! :D

Re: Elixir v1.20: Now a gradually typed language

#405
post #397

Earlier quoted context omitted.

> Honest question, in the era of vibe and AI assisted coding is there any advantages of using untyped programming languages, apart from the fact that non-typed languages has more traning data for the LLM? Author here. Type systems restrict which programs can be expressed and increasing expressiveness often requires increasing type-system complexity (which, speaking from experience, both humans and agents will struggl…

Types replace entire classes of tests that coverage metrics wouldn't detect [0]. Types are also documentation! They also decrease the degrees of freedom LLMs have to make mistakes [1]. [0] https://kevinmahoney.co.uk/articles/tests-vs-types/ [1] https://john.regehr.org/writing/zero_dof_programming.html

I don't think these articles fully cover (pun intended) the claims being made.

First of all, we need to separate "types" from "static type checking". Elixir always had types and types by themselves won't eliminate tests. You can combine types with type checkers, as well as tests themselves (as described in the first article), to aid software verification. Plus many of the techniques discussed in the article (property-based testing, static analysis, etc) are available to dynamically typed languages too.

Some notes on the first article:

> For example, there is no test we could write that would show that our function never throws an exception or never goes in to an infinite loop, or contains no invalid references. Only static analysis can do this.

Static analysis is doing a lot of heavy lifting here. When applied to type checking, where it can prove absence of exceptions depends entirely on how expressive the type system and checker are.

For example, this Haskell function can fail at runtime even though it type checks:

    maxPosInteger :: (Ord a, Num a) => [a] -> a
    maxPosInteger xs = maximum (filter (> 0) xs)
If `xs` contains no positive elements, maximum fails. The type system does not rule this out.

As the article itself later discusses, proving stronger properties requires more expressive type systems, such as dependent types. Those systems can prove the absence of additional classes of failures, but they come with their own costs in complexity, ergonomics, inference, compile times, and so on. My recent ElixirConf talk touched on these trade-offs: https://www.youtube.com/watch?v=Ay-gnCqDw9o

But overall the article does not discuss coverage. Under some of the scenarios it presents, such as finite domains, exhaustive testing guided by coverage can prove the absence of bugs too. Additionally, some of the concerns the article has about Python, such as runtime redefinition and excessive polymorphism, do not really apply to dynamic languages like Elixir and Clojure.

> Correctness oracles abound. We have test suites, fuzzers and property-based testers, runtime sanitizers, static analyzers, linters, strong type systems, and formal verifiers. Any time such a tool can be made available to the LLM, we’ll reap the benefits in terms of not dealing with bugs the hard way, later on.

I completely agree with that framing. Static type systems are valuable tools, but they're one tool among many. My overall point is that I wouldn't draw the line at static typing as the "must have" mechanism for software quality, especially in the context of AI-assisted development where multiple correctness oracles can be composed together.

Thanks for sharing, those were great reads!

Re: Elixir v1.20: Now a gradually typed language

#406

Earlier quoted context omitted.

IMO OCaml is mind-bending (e.g. go figure out the 'in' keyword, I still don't understand it), F# is much easier/simpler.

The 'in' keyword is purely syntax, like semicolons/newlines or braces in your language of choice.

Yeah and it's fucking ugly and unreadable, it shouldn't be allowed.

Re: Elixir v1.20: Now a gradually typed language

#407

Earlier quoted context omitted.

I agree that actor languages are the purest form of OOP as Alan Kay has expressed it. And unlike Smalltalk, Erlang just accepts that some things are naturally functions, not messages.

Erlang's Joe Armstrong and Alan Kay did a talk/interview together: https://www.youtube.com/watch?v=fhOHn9TClXY

a great rabbit hole to fall into; thank you!

Re: Elixir v1.20: Now a gradually typed language

#408

The past month I have been going through the Elixir exercism.io track https://exercism.org/tracks/elixir It is really excellent!

whats so excellent about it? i tried their ruby, swift and python tracks and i was left with a meh. i tried 30% of the Ruby path for instance and its just "do this" and " if you get stuck here are the docs".... and it calls itself " a learning path", there is nothing to learn.

What's excellent about it is that almost all exercises do not just include the problem statement, but also an explanation of Elixir syntax and standard libraries. There's also a ton of resources to in-depth resources. And there are extensive dependencies configured between exercises so you learn everything in a gradual way.

So all in all, a lot of love and effort has been poured into the Elixir track specifically.

Re: Elixir v1.20: Now a gradually typed language

#409

Every modern language must have every feature. Does this come from GitHub centric development where every proposal is eventually asked for?

No, this comes from interacting with the community, companies, and large projects throughout the years, followed by research, publishing of papers, and careful analysis on the costs and benefits of introducing said feature! Only then we added it.

I reflected more and I think I just prefer languages with a formal spec. The GitHub projects are just going to evolve over time to wherever the wind blows, while a spec captures a concerted effort to unify in time.

Re: Elixir v1.20: Now a gradually typed language

#410

Earlier quoted context omitted.

> (people writing dynamically typed languages eventually resort to type comments) This has never been an issue in Elixir, because instead of a comment, you'd just improve the pattern matching in the function definition. def blah(%{students: [%{firstname: firstname, lastname: lastname}|[]], count: cnt}) when is_int(cnt): fullname = firstname lastname Is a valid function declaration, which specifies that blah takes a d…

is_int is doing the work of a type checker? I mean I'm not an Elixer guy (not at all) so it's a bit opaque to me how that's not an enforcement of specific types (albeit the firstname, lastname can be anything?) Once we get into the function itself, if two incompatible types, say a string and a filehandle.. (just random attempt, you may, if you choose, point to why the two types must have some alignment), what happens…

In elixir, processes (these are Erlang "processes", not OS processes) are designed to fail when they encounter errors, and the supervising process will restart it according to various rules you can configure. This isn't dissimilar to how kubernetes restarts jobs when they fail, but at a more fine-grained level.

It's actually intended that your function doesn't try too hard to validate it's input types, and just that it will malfunction and crash when it gets something it doesn't know how to handle, because the supervision tree will rescue it and your program can continue, albeit without whatever input caused the malfunction.

This obviously isn't ideal for many types of software, but for complex backend servers and other long-running operations it works really well.

Of course this is not a guarantee to eliminate bugs, but it's a factor that reduces them more than you'd think when coming from a different programming paradigm.

Post reply on HN