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

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews