Elixir

Elixir

Elixir Core Team

This release requires Erlang/OTP 27+ and is compatible with Erlang/OTP 29.

1. Enhancements

EEx

  • [EEx] Optimize compiler by flattening expr list only once

Elixir

  • [Base] Optimize Base validation functions by using SWAR techniques
  • [Float] Optimize Float.round/2 by avoiding big integers
  • [Inspect] Increase inspect limit to help print deeply nested data structures
  • [Inspect] Support printing Erlang records (using Erlang notation)
  • [Kernel] Add occurrence typing on case, cond, and with
  • [Registry] Switch {:duplicate, :key} key_ets to ordered_set with composite keys
  • [String] SWAR-optimize ASCII fast paths in String.length/1 and String.slice/3

ExUnit

  • [ExUnit] Show remaining runs when using --repeat-until-failure

IEx

  • [IEx.Helpers] Add source/1

Mix

  • [mix app.tree] Support --output option
  • [mix deps.tree] Support --output option
  • [mix help] Support printing docs for types and callbacks
  • [mix format] Support --no-compile option
  • [mix source] Add mix source MODULE to print or open a given module/function location

2. Potential breaking changes

Elixir

  • [Kernel] Disallow raw CR line ending in strings, comments and after ? for security reasons

3. Bug fixes

Elixir

  • [Kernel] Fix a compiler crash when importing a module with only: :sigils option when the imported module exports non-sigil symbols with sigil_ prefix
  • [Kernel] Reject negative Duration in to_timeout/1
  • [Macro] Fix generation of heredocs in Macro.to_string/1 with escaped trailing newline
  • [Path] Consistently return path as binary in Path.relative_to_cwd/2
  • [Stream] Raise in Stream.cycle/1 when enumerable reduce call yields no elements
  • [String] Support empty pattern list in String.count/2

Logger

  • [Logger] Persist log level to app env in Logger.configure/1

Mix

  • [Mix] Use non_executable_binary_to_term on loopback pubsub
  • [mix compile.elixir] Fix scenario where Elixir would tag mtimes in the future

Showing Posts 1 to 10

josevalim

josevalim

Creator of Elixir

As usual, this release has additional type checks and performance improvements. Please give it a try. We expect only one additional RC after this one with any pending fixes, so we can release v1.20.0.

17
Post #2
vkryukov

vkryukov

Congratulations on the release! Are you interested in false positive type warnings - should we report them as bugs? E.g., I have a piece of HEEX where the type checker complains but stop complaining if I simply change the order

                  <.yinsh_score_ring
                    :for={index <- 1..3}
                    # no complaints if `earned?` is placed here instead
                    # earned?={index <= player.yinsh_rings_removed}
                    id={"#{@id}-#{player.color}-ring-score-#{index}"}
                    color={player.color}
                    earned?={index <= player.yinsh_rings_removed}
                  />

The type warning:

     type warning found at:
     │
 270 │                 earned?={index <= player.yinsh_rings_removed}
     │                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     │
     └─ lib/playgipf_web/components/game_components.ex:270: PlaygipfWeb.GameComponents."game_topbar (overridable 1)"/1

     warning: comparison with structs found:

         index <= player.yinsh_rings_removed

     given types:

         dynamic(
           %{
             ...,
             __struct__:
               Date or DateTime or Decimal or NaiveDateTime or Phoenix.LiveComponent.CID or Postgrex.Copy or
                 Postgrex.Query or Postgrex.TextQuery or Time or URI or Version or Version.Requirement
           } or atom() or bitstring() or empty_list() or float() or integer() or
             non_empty_list(term(), term())
         ) <= dynamic()

     where "index" was given the type:

         # type: dynamic(
           %{
             ...,
             __struct__:
               Date or DateTime or Decimal or NaiveDateTime or Phoenix.LiveComponent.CID or Postgrex.Copy or
                 Postgrex.Query or Postgrex.TextQuery or Time or URI or Version or Version.Requirement
           } or atom() or bitstring() or empty_list() or float() or integer() or
             non_empty_list(term(), term())
         )
         # from: lib/playgipf_web/components/position_components/position_panel.ex:441
         to_string(index)

     where "player" was given the types:

         # type: dynamic(%{..., game_type: term()})
         # from: lib/playgipf_web/components/position_components/position_panel.ex:431
         player.game_type == :yinsh

         # type: dynamic(%{..., game_type: :yinsh})
         # from: lib/playgipf_web/components/position_components/position_panel.ex:431
         player.game_type == :yinsh

         # type: dynamic(%{..., game_type: :yinsh, yinsh_setup?: false})
         # from: lib/playgipf_web/components/position_components/position_panel.ex:431
         not player.yinsh_setup?

         # type: dynamic(%{
           ...,
           color:
             %{
               ...,
               __struct__:
                 Date or DateTime or Decimal or NaiveDateTime or Phoenix.LiveComponent.CID or Postgrex.Copy or
                   Postgrex.Query or Postgrex.TextQuery or Time or URI or Version or Version.Requirement
             } or atom() or bitstring() or empty_list() or float() or integer() or
               non_empty_list(term(), term()),
           game_type: :yinsh,
           yinsh_setup?: false
         })
         # from: lib/playgipf_web/components/position_components/position_panel.ex:441
         to_string(player.color)

     Comparison operators (>, <, >=, <=, min, and max) perform structural and not semantic comparison. Comparing with a struct won't give meaningful results. Structs that can be compared typically define a compare/2 function within their modules that can be used for semantic comparison.
josevalim

josevalim

Creator of Elixir

That’s unexpected, please file a report!

slouchpie

slouchpie

I think this warning was introduced with this version:

warning: use `or` instead of `||` for boolean checks
is_nil(id) || Enum.member?(deleted_ids, id)

I think this is not good. || wil short-circuit but or will evaluate the right-hand side.

If right-hand side is computationally intense, this is encouraging less performant code.

sodapopcan

sodapopcan

Weird, I think I always thought both short-circuited :flushed_face:, but it seem neither do?

iex(1)> false or IO.puts("hi")
hi
:ok
iex(2)> false || IO.puts("hi")
hi
:ok
jswanner

jswanner

Requires only the left operand to be a boolean since it short-circuits.

jswanner

jswanner

Need to use true for short-circuit:

iex(1)> true or IO.puts("hi")
true
iex(2)> true || IO.puts("hi")
true
sodapopcan

sodapopcan

LOL… oh boy, uhhhh… who are you responding to? I never said anything!

:upside_down_face:

They both seem to short circuit, though:

iex(3)> true or 0..100_000_000 |> Enum.map(& &1)
true
iex(4)> true || 0..100_000_000 |> Enum.map(& &1)
true

Both of those return instantly, in IEx, at least.

Am I just completely misunderstand what short circuiting is?

jswanner

jswanner

They do both indeed short-circuit, and the docs for both say they do. The difference is or requires the left side to be a boolean and it can be used in guards, while || does a “truthy” check of the left hand side and cannot be used in guards.

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
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
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 &amp; Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews