josevalim

josevalim

Creator of Elixir

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 release candidate a try. Since this is a pre-release, you may not find it in package manager, so you will have to use the precompiled packages, a version manager, or compile from source.

Happy coding!

Showing Posts 1 to 10

Eiji

Eiji

@josevalim: Formatter, Dynamic Supervisor, helper for guards, new attributes and more - it’s a really big list of changes that will be really useful for lots of projects!
I definitely need to test this RC soon.
Keep going on! :heart:

sergio

sergio

@josevalim I ran mix test on our project with around 400 unit tests and only two failed, both with easy fixes. Great stuff.

The formatter is priceless as well and resulted is much easier to read code. Definitely excited for this release.

Do you know if 1.6 will come with any performance enhancements not mentioned in the changelog?

josevalim

josevalim OP

Creator of Elixir

Can you please report those? Unless you were relying on a bug, everything should just work™.

We always do small changes that improve performance but I don’t believe we have anything that would be easily noticeable.

sergio

sergio

Do you prefer I open an issue on the Elixir github repo or just paste them here?

Eiji

Eiji

@josevalim: I’m trying defguard now

My current version

Here is my version of guard for rgb(a) check:

defmodule Example do
  defguard is_rgb(rgb)
           when is_tuple(rgb) and elem(rgb, 0) in 0..255 and elem(rgb, 1) in 0..255 and
                  elem(rgb, 2) in 0..255 and
                  (tuple_size(rgb) == 3 or
                     (tuple_size(rgb) == 4 and elem(rgb, 3) >= 0 and elem(rgb, 3) <= 1))

  def sample(rgb) when is_rgb(rgb), do: :ok
  # Let's do not remove comment line for now
  # def sample(_rgb), do: :error
end

Extra

With call like:

Example.sample(5)

as expected returns error:

** (FunctionClauseError) no function clause matching in Example.sample/1    
     
    The following arguments were given to Example.sample/1:
    
        # 1
        5
    
    iex:8: Example.sample/1

but … is it possible to describe which guard part fails like in normal function guards?

My question

Is it possible to write it somehow nicer? I would like to separate:
a) rgb check (in 0..255) of all elements
b) rgba check

I would like to have it looks like:

# Note: this example is only to show what I want to achieve in much more cleaner - not working way
defmodule Example do
  # strict 3-element tuple check
  defguard is_rgb_strict({red, green, blue}) when red in 0..255 and green in 0..255 and blue in 0..255
  # alpha check
  defguard is_css_alpha(alpha) when alpha >= 0 and alpha <= 1

  # rgba
  defguard is_rgba({red, green, blue, alpha}) when is_rgb_strict({red, green, blue}) and is_css_alpha(alpha)
  # 3-element tuple guard for is_rgb
  defguard is_rgb(rgb = {red, green, blue}) when is_rgb_strict(rgb)
  # 4-element tuple guard for is_rgb
  defguard is_rgb(rgba) when is_rgba(rgba)
end

Any ideas?
Note: Of course I know that defguard does not work like I invented it and I don’t ask to change it. I just want to ask for better (if any) version than my original.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Unfortunately can’t reproduce this in a fresh clone, but I’m getting

** (FunctionClauseError) no function clause matching in IO.chardata_to_string/1    
    
    The following arguments were given to IO.chardata_to_string/1:
    
        # 1
        {"src/absinthe_parser.erl", []}
    
    (elixir) lib/io.ex:461: IO.chardata_to_string/1
    (elixir) lib/file.ex:968: File.rm/1
    (elixir) lib/enum.ex:737: Enum."-each/2-lists^foreach/1-0-"/2
    (elixir) lib/enum.ex:737: Enum.each/2
    (mix) lib/mix/compilers/erlang.ex:165: Mix.Compilers.Erlang.clean/1
    (mix) lib/mix/tasks/clean.ex:30: anonymous fn/2 in Mix.Tasks.Clean.run/1
    (elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
    (mix) lib/mix/tasks/clean.ex:27: Mix.Tasks.Clean.run/1

after the upgrade. Did the usual rm -rf _build deps thing.

josevalim

josevalim OP

Creator of Elixir

Here is great!

I have tried it locally and it did show which guards failed, albeit the expanded version of is_rgb.

I could reproduce it on gettext. Fixed on master and v1.6 branches, thanks!

chrismcg

chrismcg

Congrats on the RC! I’ve played with the new formatter and have a couple of questions about what it’s doing.

-  @spec setup_customer(TwitterApi.oauth_creds, map) :: %Account.Customer{}
+  @spec setup_customer(TwitterApi.oauth_creds(), map) :: %Account.Customer{}

Why does oauth_creds get () added when map doesn’t?

Likely related to above:

   def sync_finished(customer) do
-    Logger.info "[SYNC] #{customer.id} (#{customer.twitter_id}) finished"
-    GenServer.cast({:via, Registry, {Account.ManagerRegistry, customer.twitter_id}}, :sync_finished)
+    Logger.info("[SYNC] #{customer.id} (#{customer.twitter_id}) finished")
+
+    GenServer.cast(
+      {:via, Registry, {Account.ManagerRegistry, customer.twitter_id}},
+      :sync_finished
+    )
   end

The .cast call change is fine by me, but I’m definitely not used to/don’t like the Logger call having to have brackets. Same with Ecto macros e.g.:

   def oauth_creds(twitter_id) do
     query =
-      from c in Customer,
-      where: c.twitter_id == ^twitter_id,
-      select: {c.oauth_token, c.oauth_token_secret}
+      from(
+        c in Customer,
+        where: c.twitter_id == ^twitter_id,
+        select: {c.oauth_token, c.oauth_token_secret}
+      )
+
     Repo.one!(query)
   end

and:

   schema "customers" do
-    has_many :relationships, Twitter.Relationship
-    has_many :users, through: [:relationships, :user]
-    has_many :lists, Twitter.List
+    has_many(:relationships, Twitter.Relationship)
+    has_many(:users, through: [:relationships, :user])
+    has_many(:lists, Twitter.List)

I realise that I could just type the non bracket version and have an editor plugin format it but I find the non bracket form easier to parse as a human (this is just my personal opinion of course). In general I’ve found the formatter:

  • Does a lot of nice things with e.g. too long lines, case statements
  • Adds brackets in a lot of places I don’t consider them useful/necessary

Thanks again to everyone involved in the new RC for all the hard work.

Eiji

Eiji

@josevalim: I tried it with asdf:

$ asdf current
elixir ref-v1.6.0-rc.0 (set by /home/eiji/.tool-versions)
erlang 20.2 (set by /home/eiji/.tool-versions)
rust stable (set by /home/eiji/.tool-versions)

So I compiled it from source from git tag v1.6.0-rc.0.
I tried it both in iex shell and after creating new project mix new example (of course after update).

What could I miss?

josevalim

josevalim OP

Creator of Elixir

The default in the formatter is to always add parens except for:

  1. variables, such as map in your specs. If we changed it to map(), we would change the AST, which means the code before and after are no longer equivalent - and that’s a no-no for a code formatter

  2. local calls listed in your .formatter.exs under :locals_without_parens. So if you don’t want has_many and friends to have parens, you just need to list them in your .formatter.exs file. See the docs for mix format and Code.format_string!

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
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
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
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

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews