wxErlang Hello World ThinkingElixir 102: Machine Learning in Elixir with Sean Moriarity

TypeCheck v0.12.0 released

Version 0.12.0 of TypeCheck has been released! 🚀

Additions:

Per-dependency configuration

The default options used are now fetched from the application configuration. This means that you can configure a default for your app as well as for each of your dependencies(!) by adding config :app_name, :type_check […] to your configuration file(s).

(This configuration can then further be overridden per module, which was already possible in earlier versions.)

Building types and checks for external functions

If you want to use types from modules outside of your control, until now you had to manually recreate them. Now, the TypeCheck.External module allows fetching the ‘normal’ types and specs from a compiled module. Specifically:

  • TypeCheck.External module, with functions to work with typespecs in modules outside of your control.

    • fetch_spec to build a TypeCheck type from any function that has a @spec.
    • fetch_type to build a TypeCheck type from any @type.
    • enforce_spec! to wrap a call to any function that has a @spec with a runtime type-check on the input parameters and return value.
    • apply and apply! to wrap a call to any function with the function spec type that you give it.
iex> TypeCheck.External.enforce_spec!(Kernel.abs(-13))
13
iex> TypeCheck.External.enforce_spec!(Kernel.abs("hi"))
** (TypeCheck.TypeError) At lib/type_check/external.ex:175:
    `"hi"` is not a number.

This functionality is still very new, so we consider it to be a little experimental. In the near future, it might be integrated further with the rest of the library. For instance, we might add syntactic sugar to make ‘type overrides’ easier.

I want to take this opportunity to thank @orsinium greatly. Both the idea and the implementation of this functionality is his work! :star_struck:

Defstruct!

TypeCheck.Defstruct.defstruct!, a way to combine defstruct, @enforce_keys and the creation of the struct’s type, reducing boilerplate and the possibility of mistakes. (c.f. #118 )

Example:

defmodule User do
  use TypeCheck
  use TypeCheck.Defstruct

  defstruct!(
    name: "Guest" :: String.t(),
    age: _ :: non_neg_integer()
  )
end

is syntactic sugar for:

defmodule User do
  use TypeCheck
  use TypeCheck.Defstruct

  @type! t() :: %User{
    name: String.t(),
    age: non_neg_integer()
  }
  @enforce_keys [:age]
  defstruct [:age, name: "Guest"]
end

Fixes:

  • Long-standing issue where Dialyzer would sometimes complain in apps using TypeCheck is resolved. (c.f. #95)
  • Creation of the new maybe_nonempty_list type will no longer get stuck in an infinite loop on creation. (c.f. #120)

This new release is just in time for ElixirConf.EU where I will be speaking about TypeCheck. I look forward to see a lot of you there (live or virtually)!

There will also be stickers! 😊

As always, you can find TypeCheck on Hex.PM, on GitHub and on the Elixir forum.