Elixir

Elixir

Elixir Core Team

1. Enhancements

Elixir

  • [Regex] Raise error message when regexes are used as default values in struct fields for compatibility with Erlang/OTP 28
  • [Registry] Add key-based partitioning of duplicate registries

2. Bug fixes

Elixir

  • [Kernel] Address issue with type checking not completing on protocol consolidation

ExUnit

  • [ExUnit] Do not crash on empty test unit groups

Mix

  • [mix help] Add mix help app:APP
  • [mix test] Fix module preloading in mix test --slowest-modules=N

Showing Posts 1 to 10

josevalim

josevalim

Creator of Elixir

Alright folks, in a nutshell, this release addresses all feedback from the previous RCs:

  1. Fully compatible with Erlang/OTP 28.1+

  2. Struct update syntax has been adapted into a type assertion operator

  3. Addresses issues with projecting taking too long to compile

This should be our final stop before v1.19, please give it a try!

46
Post #2
neilberkman

neilberkman

Looking good!

belaustegui

belaustegui

While compiling the following functions I’m getting a warning that did not show in Elixir 1.18.x.

@impl Event
def to_payload(%GameTransactionCompleted{} = e) do
  # ...
end

def to_payload(%GameTransactionCompleted.ExternalTransaction{} = e) do
  # ...
end

def to_payload(%GameTransactionCompleted.InternalTransaction{} = e) do
  # ...
end

def to_payload(%GameTransactionCompleted.Stake{} = s) do
  # ...
end

def to_payload(%Game{} = g) do
  # ...
end

The Event protocol defines the callback as:

@spec to_payload(struct()) :: map()
def to_payload(struct)

And this is the warning that I get:

Compiling 1 file (.ex)
     warning: the 1st pattern in clause will never match:

         %Dragonara.Outbox.GameTransactionCompleted.ExternalTransaction{} = e

     because it is expected to receive type:

         dynamic(%Dragonara.Outbox.GameTransactionCompleted{})

     typing violation found at:
     │
 101 │     def to_payload(%GameTransactionCompleted.ExternalTransaction{} = e) do
     │                                                                    ~
     │
     └─ lib/dragonara/outbox/game_transaction_completed.ex:101:68: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1

     warning: the 1st pattern in clause will never match:

         %Dragonara.Outbox.GameTransactionCompleted.InternalTransaction{} = e

     because it is expected to receive type:

         dynamic(%Dragonara.Outbox.GameTransactionCompleted{})

     typing violation found at:
     │
 120 │     def to_payload(%GameTransactionCompleted.InternalTransaction{} = e) do
     │                                                                    ~
     │
     └─ lib/dragonara/outbox/game_transaction_completed.ex:120:68: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1

     warning: the 1st pattern in clause will never match:

         %Dragonara.Outbox.GameTransactionCompleted.Stake{} = s

     because it is expected to receive type:

         dynamic(%Dragonara.Outbox.GameTransactionCompleted{})

     typing violation found at:
     │
 140 │     def to_payload(%GameTransactionCompleted.Stake{} = s) do
     │                                                      ~
     │
     └─ lib/dragonara/outbox/game_transaction_completed.ex:140:54: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1

     warning: the 1st pattern in clause will never match:

         %Bluelabs.Game{} = g

     because it is expected to receive type:

         dynamic(%Dragonara.Outbox.GameTransactionCompleted{})

     typing violation found at:
     │
 144 │     def to_payload(%Game{} = g) do
     │                            ~
     │
     └─ lib/dragonara/outbox/game_transaction_completed.ex:144:28: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1

     warning: the 1st pattern in clause will never match:

         nil

     because it is expected to receive type:

         dynamic(%Dragonara.Outbox.GameTransactionCompleted{})

     typing violation found at:
     │
 171 │     def to_payload(nil) do
     │     ~~~~~~~~~~~~~~~~~~~~~~
     │
     └─ lib/dragonara/outbox/game_transaction_completed.ex:171: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1

Generated dragonara app

Looks like the compiler is not able to understand that this is a multiclause function that acts differently depending on the struct that it receives. It is true that from the outside this function is only called with the %GameTransactionCompleted{} struct but that call also uses the other clauses for nested structs.

EDIT: I also want to note that if I rename the problematic clauses so they are not part of the same function (for example payload instead of to_payload) the warnings go away. While this workaround fixes the issue I still wonder if this should happen and why the compiler is not able to detect that the other clauses are also being called with the proper structs.

josevalim

josevalim

Creator of Elixir

Can you please provide a code snippet that reproduces the issue? Thank you.

josevalim

josevalim

Creator of Elixir

Oh, I think I got it. You literally have a protocol and then in one of the implementations, you define additional clauses.

Yes, the warning is expected. The type system is enforcing that you are implementing the protocol exactly for the type of that implementation. We could not emit any warning, but then it means someone may accidentally define additional clauses, and they won’t get any help from the type system. So we chose to enforce that the first argument matches the implementation.

If the description above is not correct, then please provide a way to reproduce this or post a larger code snippet. Thanks.

idyll

idyll

I have verified across multiple projects now. We did hit the issue in rc.1 :wink:
But rc.2 seems solid.

I am deploying to some QA ENVs right now but things look really good.
Probably 20k unit tests across the projects we’ve updated. All passing.
Huge improvements.

THANK YOU SO MUCH!!!

jswanner

jswanner

1.19.0-rc.2 is working great for me, thanks everyone for their amazing work on this!

Note: I too was having trouble with rc.1 where our test suite would just hang, not having that issue with rc.2

stefanluptak

stefanluptak

Exactly the same here. rc2 seems solid.

idyll

idyll

Someone should probably ask the hex team to push a docker image of 1.19.0-rc.2 to docker hub so we can test the image as well…

I don’t expect any issues, but I can’t fully test end-to-end without that.

They have an Erlang 28.1 image already.

joshknz

joshknz

I just updated NervesHub (UI and API) and the test suite is passing. Elixir 1.19 helped pick up a few things that needed addressing, which was nice.

I then ran dialyzer but got a bunch of errors. Should I report any of the errors here?

Where Next? Top

Trending in News Top

ericmj
Release: Release v2.6.0 · hexpm/hex · GitHub Announcement: Hex v2.6 released | Hex Backwards incompatible changes Require --key in mix...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
kip
In 2021 I started a new library called Tempo with the objective of modelling time as a set of intervals - not as instants. In 2022 I gave...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews