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

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
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
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews