[Proposal] Allow String Literal in the TypeSpec

91 views
Skip to first unread message

Yordis Prieto

unread,
Feb 13, 2022, 5:55:50 PM2/13/22
to elixir-lang-core
I would like to be able to do the following in my typespec:

```
@spec to_struct("account_created") :: %AccountCreated{}
@spec to_struct("account_closed") :: %AccountClosed{}
@spec to_struct(String.t()) :: no_return()

@spec to_string(%AccountCreated{}) :: "account_created"
@spec to_string(%AccountClosed{}) :: "account_closed"
@spec to_string(struct()) :: no_return()
```

This will help the documentation much better, while also keeping the typespec closer to what the intention was.

José Valim

unread,
Feb 13, 2022, 6:15:45 PM2/13/22
to elixir-l...@googlegroups.com
Type specs are restricted to what Erlang allows. So unless this is added to Erlang, which I hardly see happening, it can’t be added to Elixir. It also feel like atoms could be a better fit here. Convert the strings to atoms at the edge of the system.

--
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/147aa05a-be3d-4f32-aab8-13a1938341b0n%40googlegroups.com.

Yordis Prieto

unread,
Feb 14, 2022, 4:04:21 AM2/14/22
to elixir-lang-core
Trying to avoid more layers since the string thing is being imposed by a behavior.

Where would be the place to discuss bringing this to Erlang?

Michał Muskała

unread,
Feb 16, 2022, 6:28:16 AM2/16/22
to elixir-l...@googlegroups.com

Even if string literals were allowed, the proposed spec wouldn’t be accepted by dialyzer. Dialyzer does not support overloaded specs with overlapping arguments. In this case “account_created” is a subtype of String.t(), so the spec would be rejected.

 

You can see by having a similar spec using atoms:

 

-spec to_struct

    (account_created) -> {account_created};

    (account_cloded) -> {account_closed};

    (atom()) -> no_return().

 

Produces the following diagnostic from dialyzer:

 

test.erl:5:2: Overloaded contract for test:to_struct/1 has overlapping domains; such contracts are currently unsupported and are simply ignored

 

Michał.

--

Yordis Prieto

unread,
Feb 16, 2022, 12:46:31 PM2/16/22
to elixir-lang-core
I am aware of the overloading issue, my apologies for confusing you a bit more.
Reply all
Reply to author
Forward
0 new messages