I was expecting that to be a compile time transformation that would
generate the exact same compiled erlang as
```
@type my_struct_with_a() :: %MyStruct{
  a: integer(),
  b: integer() | nil,
  c: integer() | nil
}
```

But that would require `@type` to be able to get the AST for `MyStuct.t()`
during compile time.

On Fri, Feb 5, 2021 at 8:21 PM Louis Pilfold <[email protected]> wrote:

> Hello!
>
> Correct me if I'm wrong but I believe this isn't something that Erlang
> typespecs support, or at least there is no syntax for it.
>
> What do you see this compiling to? Elixir has to work with the capability
> of Erlang here.
>
> Cheers,
> Louis
>
> On Fri, 5 Feb 2021, 22:39 Bernardo Amorim, <[email protected]> wrote:
>
>> Hi folks, I'm not even sure if this is possible nor if it was raised
>> before nor if there is already another way of doing something similar. But
>> this is something that I've been thinking a lot recently and I'd like to
>> know if it is possible and desirable. If it is, I can help with a PR later
>> on.
>>
>> The "problem":
>>
>> It is usual to when we have a Struct (specially Ecto.Schemas) to define a
>> `@type t()` with the fields. Let's say we have a Struct with a few fields
>> like this:
>>
>> ```
>> defmodule MyStruct do
>>   defstruct [:a, :b, :c]
>>   @type t() :: %__MODULE__{
>>     a: integer() | nil,
>>     b: integer() | nil,
>>     c: integer() | nil
>>   }
>> ```
>>
>> Now imagine I want to define a function that receives a struct but
>> requires one of these fields to be non null. What we have to do right now
>> is to:
>>
>> ```
>> @type my_struct_with_a() :: %MyStruct{
>>   a: integer(),
>>   b: integer() | nil,
>>   c: integer() | nil
>> }
>> ```
>>
>> (Ok, maybe in some cases we do not need to redefine all the other fields
>> since they might be irrelevant, but let's assume we actually want to type
>> everything)
>>
>> The proposal:
>>
>> For map values when we just want to change one field we can do something
>> like: ```%MyStruct{my_struct | a: 1}```, but for types this is not possible.
>>
>> My proposal would be to have something like this:
>>
>> ```
>> @type my_struct_with_a() :: %MyStruct{MyStruct.t() | a: integer()}
>> ```
>>
>> That would generate a type with all fields copied from `MyStruct.t()` but
>> with `:a` changed to `integer()` instead of `integer() | nil`.
>>
>> The caveats I see is what to do when the type is not just a map type
>> (maybe it is a sum type, maybe it is not even a map, etc).
>>
>> What do you folks think about this?
>>
>> Thanks,
>> Bernardo Amorim
>>
>> --
>> 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 [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/elixir-lang-core/b152b04f-3c6b-4052-92aa-d23724ed0f92n%40googlegroups.com
>> <https://groups.google.com/d/msgid/elixir-lang-core/b152b04f-3c6b-4052-92aa-d23724ed0f92n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "elixir-lang-core" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/elixir-lang-core/gvLUM0asfmI/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CABu8xFCeqgNAOp1o%3D0JJ%2B9JYwF20H9-%2BnD2DLoY%3DuSisyGB8NA%40mail.gmail.com
> <https://groups.google.com/d/msgid/elixir-lang-core/CABu8xFCeqgNAOp1o%3D0JJ%2B9JYwF20H9-%2BnD2DLoY%3DuSisyGB8NA%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAJVmgvBectadT%3DYaT7tFtyG03APUcsyJWQU8922Y_9zuYb7jxA%40mail.gmail.com.

Reply via email to