Elixir v1.7.0-rc.0 released

Hi everyone,

We have just released v1.7.0-rc.0.

The CHANGELOG and precompiled files are here: https://github.com/elixir-lang/elixir/releases/tag/v1.7.0-rc.0

Please give it a try! You can either compile the v1.7 branch from source OR use the precompiled files, as described in our install page.

Note that you will need {:ex_doc, "~> 0.19-rc"} if you want to generate docs using the release candidate.

Happy coding!

55 Likes

Documentation metadata

This is awesome idea! When I firstly saw related github issue I was so surprised, because I did not expect such useful change. I believe that it will simplify lots of things.

compile_time_purge_matching

I really love this. I will use it definitely in already maintained projects!

–failed flag

It will definitely help. Fortunately my tests are really fast. :smile:

[Code] Add Code.purge_compiler_modules/0 that purges any compiler module left behind. This is useful for live systems dynamically compiling code

Added on personal TODO list for rewrite plan of ex_api library! :smiley:

[IO.ANSI] Add cursor movement to IO.ANSI

Awesome! It will definitely help creating console scripts.

I will try to find a time to test those changes in this weekend. Good work!

2 Likes

[Code] Add Code.purge_compiler_modules/0 that purges any compiler module left behind. This is useful for live systems dynamically compiling code

Does this mean that this call is recommended for projects that use fastglobal? Probably immediately after calling FastGlobal.put?

Apologies if it’s a stupid question.

1 Like

This is generally only required if the compiler cannot automatically release the compiler modules - this is the case if the module body contain anonymous functions (because we don’t know if they wen’t used for spawning processes or stored somewhere). I don’t think it’s required for fastglobal.

EDIT: I’ve just checked the fastglobal code and it compiles the data modules using Erlang compiler and not the elixir one, so it does not affect it in any way.

4 Likes

The new --cover seems to work well. :slight_smile:

1 Like

Hey @josevalim it seems that Absinthe schemas are entirely broken on the RC, I’m trying to trace down what the root issue here, but I’m not seeing any notable changes to macros or module attributes.

I have a __using__ macro that returns

quote do
  Module.register_attribute(__MODULE__, :foo, accumulate: true)
end

which seems to be behaving differently now. If I change that call to Module.register_attribute(__CALLER__.module, :foo, accumulate: true) in the macro body it seems to work better, although that doesn’t totally fix the issue.

1 Like

@benwilson512 We did refactor this part of the codebase, so I will gladly take a look if you have failing tests in Absinthe’s suite or a small file I can run with mix run inside Absinthe.

1 Like

Thanks! Use the 1.7-issue branch which disables certain validations, otherwise the project doesn’t compile. Then in iex -S mix do:

defmodule Foo do
  use Absinthe.Schema.Notation

  object :user do
    field :foo, :string
  end
end

You’ll get some debug output from an IO.inspect function I’ve added here: https://github.com/absinthe-graphql/absinthe/blob/1.7-issue/lib/absinthe/schema/notation/writer.ex#L75

If you mess with that file you’ll run into Bug #1 we’ve actually had a while, where editing the Writer module file requires rm -rf _build or you get a compilation error for some reason.

The new issue however is that if you look at the debug output, the definitions list is empty. “there should be stuff but there isn’t stuff” is one of the less easy things to debug I realize. You can find the first usage of that module attribute here: https://github.com/absinthe-graphql/absinthe/blob/1.7-issue/lib/absinthe/schema/notation.ex#L25

I’ll apologize ahead of time for the complexity of the module, the schema building code is some of the oldest in Absinthe. We’re in the middle of reworking it to be simpler and more data driven but it’s still a ways from being ready to ship.

@benwilson512 Thanks. I will investigate. You should probably consider have an optional build on Travis for Absinthe that runs on Elixir master. This way we can find this failures earlier. :slight_smile:

Very cool! :heart_eyes:


Question about the changelog:

In ‘Documentation metadata’, the following example is used:

@moduledoc "A brand new module"
@moduledoc authors: ["Jane", "Mary"], since: "1.4.0"

Right below that, it states that Elixir currently supports the keys :deprecated and :since.

What about the :authors-key that is used in the example?

We support any metadata but only the keys :deprecated and :since are printed in ExDoc and IEx and so on. We will clarify the examples.

1 Like

So I understand the current behaviour and why accumulate did not work in previous Elixir versions.

It seems that you are calling put_definition many times before you invoke accumulate: true. If I do this:

if @absinthe_definitions do
  raise "omg"
end
Module.register_attribute(__MODULE__, :absinthe_definitions, accumulate: true)

You will see that @absinthe_definitions is not nil. The behaviour of setting an attribute to accumulate after it is set is “undefined”. In previous versions, we were still able of keeping whatever has been accumulated (with caveats) but in the new version we discard it.

However, I would say that the previous behaviour (in earlier Elixir versions) is also broken because your put_definition would lead to a bunch of duplicated definitions. When accumulate: true is false, put_definition works fine, but when it is enabled, you would end-up getting the whole list, prepending to it, and then adding it as an entry on top of the existing list. For example, imagine you had definitions x, y and z already stored. In the attribute, they would be stored as [:z, :y, :x]. Now imagine that you add :a, at the end you will end-up with [[:a, :z, :y, :x], :z, :y, :x]. However, it seems accumulate: true is only set too late in your suite, so this doesn’t happen there.

Ahh yes this makes sense, thanks for explaining, I was able to fix the issues via: https://github.com/absinthe-graphql/absinthe/commit/8c622942364c585e30d2ef03256a9a7103861e7d

Any thoughts on the Writer module issue? I’ve hesitated to create an Elixir error before because I couldn’t reproduce it outside the Absinthe project.

1 Like

Folks, please let us know if you tried the release candidate and if everything is fine. Even if you found no regressions, say so in the comments, otherwise we can’t know if everyone is quiet because nobody tried it yet or if because nobody found bugs. Hoping for the latter. :slight_smile:

4 Likes

The Meeseeks tests run fine using the RC and OTP21.

Edit: And a larger Phoenix 1.2 project with a bunch of deps also runs its tests fine (RC and OTP21), though it did complain that I shouldn’t use length(res) > 0 in my tests. :smiley:

2 Likes

Seems to work with Caravan and a Phoenix 1.3 app that we have. My Phoenix project using Abinsthe won’t compile for what l assume are the reasons that Ben mentioned.

2 Likes

I tested it with Conduit. I had to fix a warning related to System.stacktrace(). I was doing the equivalent of:

def try_a_thing do
  # something might fail
rescue error ->
  log_error(error)
end

def log_error(error) do
  Exception.format(:error, error, System.stracktrace())
  |> Logger.error()
end

Which I changed to:

def try_a_thing do
  # something might fail
rescue error ->
  log_error(error, System.stracktrace())
end

def log_error(error, stacktrace) do
  Exception.format(:error, error, stracktrace)
  |> Logger.error()
end

Otherwise everything was fine.

2 Likes

I just tried it on a project of mine and found it to not work with ex_cldr's compiler task:

could not compile dependency :ex_cldr_dates_times, "mix compile" failed. You can recompile this dependency with "mix deps.compile ex_cldr_dates_times", update it with "mix deps.update ex_cldr_dates_times" or clean it with "mix deps.cleanex_cldr_dates_times"
** (FunctionClauseError) no function clause matching in Mix.Dep.loaded/1

    The following arguments were given to Mix.Dep.loaded/1:

        # 1
        [env: :prod]

    Attempted function clauses (showing 1 out of 1):

        def loaded([])

    (mix) lib/mix/dep.ex:156: Mix.Dep.loaded/1
    lib/mix/tasks/compile.cldr.ex:86: Mix.Tasks.Compile.Cldr.compile_cldr_files/0
    lib/mix/tasks/compile.cldr.ex:67: Mix.Tasks.Compile.Cldr.run/1
    (mix) lib/mix/task.ex:316: Mix.Task.run_task/3
    (mix) lib/mix/tasks/compile.all.ex:68: Mix.Tasks.Compile.All.run_compiler/2
    (mix) lib/mix/tasks/compile.all.ex:52: Mix.Tasks.Compile.All.do_compile/4
    (mix) lib/mix/tasks/compile.all.ex:23: anonymous fn/1 in Mix.Tasks.Compile.All.run/1
    (mix) lib/mix/tasks/compile.all.ex:39: Mix.Tasks.Compile.All.with_logger_app/1

Seems like the function is deprecated: @kip