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
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
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