Live data from Hacker News

Elixir v1.20: Now a gradually typed language

elixir-lang.org

361–370 of 426 posts

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

#361

Earlier quoted context omitted.

Having been at a several places that have gone from framework-makes-us-fast to too-massive-for-the-framework, engineering velocity works as a function of how much mental context is needed and how many people/teams have to collaborate. As orgs grow, the only way to maintain velocity is to reduce mental context. Humans have to reason about their systems. In the half a dozen engineering orgs I have worked, each and ever…

> 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.

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

#362
post #101

Earlier quoted context omitted.

What were the inaccuracies? I'm not aware of any, but we can fix any that are found right away.

There are two possible locations for comparison that I can see: https://gleam.run/frequently-asked-questions/#Elixir Here’s a non-exhaustive list of differences: Elixir is gradually typed, while Gleam is fully statically typed. Elixir's type system does not have generics, while Gleam's type system does. Elixir has a powerful macro system, Gleam has no metaprogramming features. Elixir’s compiler is written in Erlang a…

We should really remove the cheatsheets, they have not been maintained in many years.

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

#363

Earlier quoted context omitted.

That’s very exciting! Is there anywhere I could follow you for updates? If you don’t want to share it publicly, and is ok with sharing it privately, my email is my username on gmail. Thank you!!

We're hoping to have a preprint ready at the end of the month, I'll send it to you then!

Lovely!!!

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

#364

Earlier quoted context omitted.

That’s a good point! And I suppose you don’t have willy-nilly reassignment of properties like you do in ruby/php/js.

Also, as I kept forgetting to mention, there are no overloaded operators (`+` only works on numbers, for example... unfortunately it does work on both ints and floats but that's another story). The one pain point is that comparriason operators works across all types, but the compiler has already been warning against doing that for at least a year now.

Ok dang. Well. I guess I have no reason not to dive fully into the elixir now.

I’ve toyed around with it a handful of times and I really like it. I like the clojure-ey immutability and threading operators and such. And of course I’ve heard so much about the magic of the BEAM and the phoenix framework. But between typescript and clojure I’ve never felt like I needed anything else.

But if the type system is pretty good, that’s a huge plus over clojure in my book.

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

#365

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…

>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 struggle with). I used to hold similar opinion but D language, and this article by Patrick Li (HN JITX co-founder) who's the original author of little known but very powerful language Stanza changed my mind [1],[2]. He argue…

> Groovy also deserved a special mention, and the pudding is Grails.

I vaguely remember that when Groovy became more typed (statically typed that is. I believe you could always put the types in but they were not checked.) there was a theory that it kind of hurt possible uptake of the language.

The reason being is that people felt well if we are adding types and a project is requiring it why don't we just use: Java, Scala, Kotlin etc. Like did Java getting more features or Kotlin coming really hurt Groovy or just that it became more of a typed language.

An analog (typed language stealing users) could happen to Elixer but I'm not really sure which language it would be.

> I think the new self-distillation technique for LLM and code generation as proposed by Apple

Speaking of Apple and eventual typing Dylan was an amazing language that just never got traction. Open Dylan still exists but few know about it. Its eventual typing is unique because Dylan does CLOS-like multimethod dispatch instead of pattern matching.

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

#366

Earlier quoted context omitted.

I’ve been using Ruby and Elixir for over a decade. Pre-AI I used them for aesthetic reasons. The code was beautiful, and I disliked dealing with types. People without experience in dynamic languages tend to overestimate the number of bugs their type system is saving them from. It’s pretty rare that I run into a bug in production that a type system would have caught. They also overstate how much types help their AI ag…

> It’s pretty rare that I run into a bug in production that a type system would have caught. Wow, how different our experiences are. In Javascript/Typescript land, so so many bugs are null/undefined-related and really should have been caught at type level. In fact, I'd say (without actually measuring it) that _most_ bugs I've ran into in Typescript are due to someone having bypassed the typing (casting, ts-ignore...)…

Not all dynamically typed systems are equal. Just like not all statically typed systems are equal. Python and Javascript are a mess. But languages like Elixir aren't just Java without types.

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

#367
post #289

Earlier quoted context omitted.

> I keep itching to design a compiled functional language for games Jank wants to be this, right? IIRC its author and chief maintainer was a game dev before he dedicated himself to the language. https://jank-lang.org/ Maybe porting your engine would be a great way to prove out Jank 1.0 when it arrives ;)

Thanks for the pointer, never heard of this!

Awesome! Maybe it's even a language you could enjoy contributing to. :D

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

#368

Earlier quoted context omitted.

[1] https://phoenix-live-view.hexdocs.pm/security-model.html There's a guide in the LiveView docs that walks you through the security model. To be clear, you need to always assume that the user can send you anything . That's a fact of any networked system: Clients need to be assumed to be completely under the control of an evil user, because at the end of the day it is impossible to know whether you're talking to the…

I am well aware of that, its much much easier to account for this with regular HTTP handlers in other stacks though. The issue here is that you can call random functions if you guess the signature correctly. Even authorized/authenticated users can and will missbehave if given the chance.

To clarify, when you say "random functions", do you mean arbitrary event handlers like "handle_event("my_event")", despite the intended UI not presenting a way to call that event at the moment? Or do you mean any function in the LiveView module?

The latter doesn't seem to be the case, and if it is would be alarming. The former is absolutely the intended behavior. The client can send events to the server, that's how the whole thing works. If certain events shouldn't be available at certain times, you need to check that server side, and that's going to be true in any http handler.

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

#369

Earlier quoted context omitted.

I think Elixir is interesting and there is real value but some stuff being sold as "all these libs/packages that haven't had any updates for over a year is fine because Elixir" I just don't buy it and to that point around typing feels like the same wish-washy hand waving from the community that is very off putting BEAM has genuine use cases but its not as wide as its made to believe. There are very good places where…

So you prefer language communities where libraries have a constant stream of fixes, new breaking change releases every six months and entirely new framework ecosystems ascending every three years?

Yes because it addresses security vulnerabilities and remains competitive.

You think all software breaks every 6 months, what happened Im curious

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

#370

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? This probably controversial, but personally I consider untyped languages as technical debts that need to be fixed sooner or later, and the OP article is partly addressing this very issue. Rewriting critical software i…

> 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…

One thing something like AutoCodeBenchmark cannot demonstrate is what happens when you have human-written type definitions defining the domain before the LLM writes a line of code.

That is something I have found very effective in F#, that I model the domain with types, I know what the type signatures of the functions I need are, and the LLM does the work of actually implementing those functions.

Here is a concrete example:

I have been playing around with a program to assist me with projects I make at home on my hobby-grade CNC router, which does not have an automatic toolchanger. I use a mix of Vectric VCarve and some older handwritten programs to generate GCode files. I end up with a USB drive with maybe 6 to 12 GCode files on it and a model in my head of "to make this product, I start with a board here, gotta install this square nose end mill and zero on this corner of the board, run files A and B. Then install a ball nose end mill and run file C. Then flip the board over lengthwise, switch to a smaller square nose end mill, zero here, run file D. etc. etc."

Although I try to name the GCode files in a self documenting way like 01_TopSide_25square.ngc, if I come back in 1 year and want to make the same thing again, I pretty much always have to open VCarve and eyeball what the hell all the files did and confirm where to zero, what size board to use, etc. So I'm making a tool where I can define those human-operator steps that go with the G-Code files, save it as a "project file", preview in 3d what each step will look like, and export to a printable PDF with screenshots and step-by-step instructions. Hopefully this will reduce the amount of rot that these projects suffer and the cognitive overhead of picking up an old one.

Modeling the steps as F# types was the very first step, like (small excerpt):

    type WorkpiecePlacement =
        {   Id : WorkpieceId
            /// Corner of the workpiece we'll attach to the machine.
            WorkpieceCorner : WorkpieceSpace.Corner3D
            /// Point in machine-space we'll anchor this corner to.
            MachinePoint : MachineSpace.Point
            /// Which face of the workpiece is on top.
            FaceUp : WorkpieceSpace.Face
            /// Rotation around the up-axis.
            Yaw : WorkpieceSpace.Yaw
        }

    type OperationType =
        | PlaceWorkpiece of placement : Operation.WorkpiecePlacement
        | InstallTool of id : ToolId * slot : int option
        | ZeroAt of point : MachineSpace.Point
        | RunGCode of source : GCode.Source
        | RemoveWorkpiece of id : WorkpieceId

For the GCode simulator I needed a parser for GCode files, which produces a type with 1:1 equivalence to the GCode instruction set:

    type GCodeInstruction =
        // --- Motion ---
        | G0_RapidMove of axisMoves : (Axis * float) array
        | G1_Move of feedRate : float option * axisMoves : (Axis * float) array
        | G2_ClockwiseArc of ArcParams
        | G3_CounterClockwiseArc of ArcParams
        | G4_Dwell of seconds : double

        // --- Plane selection ---
        | G17_SelectXYPlane
        | G18_SelectXZPlane
        | G19_SelectYZPlane

        // --- Unit selection ---
        | G20_Inches
        | G21_Millimeters

        // --- Distance mode ---
        | G90_AbsoluteDistance
        | G91_RelativeDistance
        // ... etc truncated, more instructions in real code

But my tool supports doing transforms on toolpaths, like rotating 90 degrees or offsetting so I can easily define that I want to make tiling copies of the same project. To implement those transforms straight up as GCodeInstruction[] -> GCodeInstruction[] is a bad call. GCode is very stateful and lets you switch units, relative vs. absolute coordinate spaces, etc. in instructions. That makes the transform awkward and tricky to write.

So I have a ToolPath type that makes the transforms clean. It normalizes the many ways of expressing the same toolpath in GCode to a single representation with all absolute coordinates in metric units.

    type ToolPathInstruction =
        | Rapid of From : Point * To : Point
        | Linear of From : Point * To : Point * Feed : FeedRate
        | Arc of
            From : Point *
            To : Point *
            Center : Point *
            Plane : Plane *
            Direction : ArcDirection *
            Feed : FeedRate
        | ... etc truncated
That is the appropriate level for the transforms like offset, rotate, scale, etc. to operate on.

Yet there is still ANOTHER level of toolpath-related operations that deserves its own type. When I'm doing simulation of material removal to check for crashes, or rendering the toolpath in 3d, I don't want to deal with arcs! The rendering/simulation is inherently an approximation. It will break down each arc into line segments. So sim code and rendering code shouldn't take a toolpath, it should take basically a line segment list, or in other words...

    type ApproxMove =
        {   From : Vector3
            To : Vector3
            FeedRate : double
            IsRapid : bool
        }

    type ToolPathApproximation =
        {   StartPosition : Vector3
            Moves : ApproxMove[]
        }
Having defined all these types it's clear that I need operations like:

    parse: string -> GCode
    serialize : GCode -> string
    normalizeToToolPath : GCode -> ToolPath
    denormalizeToGCode : ToolPath -> GCode
    offset : Vector3 -> ToolPath -> ToolPath
    rotate90 : ToolPath -> ToolPath
    scale : Vector3 -> ToolPath -> ToolPath
    approximate : ToolPath -> ToolPathApproximation
    simulate : ToolPathApproximation -> MachineState -> MachineState
    renderToolPathWireframe : ToolPathApproximation -> VBO
    renderMachineState : MachineState -> VBO
And so on. An LLM is absolutely awesome at one-shotting the implementations.

I would find it quite frustrating trying to model the same domain without any types, either having all methods working on a single toolpathy data structure that's not really the right fit for any of the places it's used, or having them work on multiple data structures without any clear delineation of which layer is expecting which toolpathy-thing that are all subtly but importantly different.

Post reply on HN