[Proposal] Support transforming lists to type specs

55 views
Skip to first unread message

Kip

unread,
May 16, 2020, 12:25:40 AM5/16/20
to elixir-lang-core
It's not uncommon to have domain overlap between lists of valid tokens (used for validations) and type specs. For example:

  @standard_formats [
    :standard,
    :accounting,
    :currency,
    :percent
  ]

  @currency_formats [
    :currency,
    :accounting,
    :currency_long,
    :currency_short
  ]

  @currency_symbol [
    :standard,
    :iso
  ]

  @type standard_formats :: :standard | :currency | :accounting | :short | :long
  @type currency_formats ::  :currency_short | :currency_long | :decimal_short | :decimal_long
  @type currency_symbol :: :standard | :iso

It would go good to remove one source of error by being able to allow compile time use of a list as the subject of  @typespec. For example:

@type currency_symbol :: @currency_symbol # Any compile-time resolvable list

Of course a macro can be introduced to do this but its quite difficult to achieve since it requires manual manipulation of AST.

Proposal worth considering? Or consign to the history of my less-than-helpful ideas :-)


José Valim

unread,
May 16, 2020, 3:29:27 AM5/16/20
to elixir-l...@googlegroups.com
Today you can do it like this:

var = Enum.reduce(@list, &{:|, _. [&1, &2]}
@type foo :: unquote(var)

But it may be worth introducing something like you describe but it probably makes sense to do it via a construct, such as @type foo :: one_of(@var) that does the conversion for you. I think automatically converting the list can be confusing, because people may think that [:foo, :bar] implies a specific ordering, for example.

I am just not sure of a good name. one_of may conflict with existing code.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/36f821aa-d718-48aa-a9e8-2f6d5e440632%40googlegroups.com.

Kip

unread,
May 16, 2020, 4:21:09 AM5/16/20
to elixir-lang-core
I had the `one_of` approach as my other alternative but figured adding another function to Kernel (or elsewhere) may not be in favour. What do you suggest I do next to progress this `one_of` idea as a poc?

Thanks too for the reduction, my attempts were making that far too complicated!
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-l...@googlegroups.com.

José Valim

unread,
May 16, 2020, 4:40:39 AM5/16/20
to elixir-l...@googlegroups.com
We wouldn't make it a macro per so, but a construct specific to Kernel.Typespec. It should be straight-forward. My biggest concern at this point is the name. :)


To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/3577d145-b325-4c67-806c-d634df15ad5a%40googlegroups.com.

Wiebe-Marten Wijnja

unread,
May 16, 2020, 5:04:18 AM5/16/20
to elixir-l...@googlegroups.com

I like the name `one_of` exactly because it is similar to what is in use by e.g. `StreamData` right now.

If the construct is specific to Kernel.Typespec, then this would also limit conflicts with existing code, right?

signature.asc

José Valim

unread,
May 16, 2020, 5:25:50 AM5/16/20
to elixir-l...@googlegroups.com
Correct. My concern is someone having "@type one_of(X)" as an existing type.

Kip

unread,
May 19, 2020, 4:30:27 PM5/19/20
to elixir-lang-core
If its a construct and not a function does that imply changes to the lexer and parser? If so, then perhaps $one_of or something else that is not a valid identifier in Elixir.
--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-l...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-l...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages