Elixir

Elixir

Elixir Core Team

Elixir v1.20.0-rc.5 released

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

Most Liked

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!

Last Post!

sodapopcan

sodapopcan

Oh for sure, I’ve just always found it odd is all I’m saying. Like it would be nice to know that and and or always return a boolean. My comments around the warning are akin to 1 > :foo being totally legal and documented but now being flagged as a warning (which is nice). Although there are probably good scenarios where you would want bool on the left and get get the return value of the right, I just can’t think of any of the top of my head.

Also, confusion is also because I missed this post of yours due to the way the Discourse notifications work and you replied directly too me after that one.

Where Next?

Popular in News Top

josevalim
In Elixir we are continuously trying to improve the experience for developers learning the language. However, there are still common road...
New
josevalim
Hi everyone, We are glad to announce that the first release candidate for Elixir v1.6.0 is out. Check out the CHANGELOG and give the re...
New
josevalim
Hi everyone, We have just released the second release candidate for the next Elixir version: v1.7.0-rc.1. The CHANGELOG and precompiled...
New
Elixir
Release: https://github.com/elixir-lang/elixir/releases/tag/v1.9.1 1. Enhancements Mix [mix format] Print relative paths in --check-for...
New
Elixir
Release: Release v1.9.2 · elixir-lang/elixir · GitHub 1. Enhancements Mix [mix release] Allow {:from_app, app_name} as a version for re...
New
Elixir
Release: Release v1.11.0-rc.0 · elixir-lang/elixir · GitHub Over the last releases, the Elixir team has been focusing on the compiler, b...
New
Elixir
Note this release includes offline Elixir installers for Windows per supported Erlang/OTP version. 1. Enhancements Elixir [Module] Mark...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49266 226
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 40165 209
New

We're in Beta

About us Mission Statement