I'm onboard with the module attribute approach as it aligns with what we 
already have. The potential existing `@enforce` conflicts would be extremely 
minimal so +1 to eric's proposal. 

> On May 25, 2016, at 11:11 AM, José Valim <[email protected]> 
> wrote:
> 
> Thanks Mike and Parker for the feedback so far.
> 
> Eric has proposed another approach, via module attributes:
> 
> @enforce [:name]
> defstruct [:name, :age]
> 
> One of the benefits of using module attributes is that it matches nicely the 
> already supported @derive attribute:
> 
> @derive Poison.Encoder
> @enforce [:name]
> defstruct [:name, :age]
> 
> Furthermore, the module attribute composes better. For example, if we want to 
> support @enforce in defexception (which is based defstruct), we don't need to 
> change anything, it just works:
> 
> @enforce [:message]
> defexception [:message]
> 
> The same could work with Ecto:
> 
> @enforce [:name]
> schema "users" do
>   ...
> end
> 
> The only downside is that a module attribute can be silently defined. For 
> example, someone may set @enforce [:foo, :bar] in their module for other 
> reasons and now they will conflict. However, in such cases we can easily 
> check and guarantee all fields given to @enforce are also defined in the 
> struct.
> 
> Can anyone think of other pros-and-cons here?
> 
> 
> 
> José Valim
> www.plataformatec.com.br <http://www.plataformatec.com.br/>
> Skype: jv.ptec
> Founder and Director of R&D
> 
> On Wed, May 25, 2016 at 4:33 PM, Parker Selbert <[email protected] 
> <mailto:[email protected]>> wrote:
> The most recent proposal, using `enforce: [:name]` is extremely clear, and 
> nicely backward compatible. Overall I love the recent focus on enforcing the 
> presence of attributes and data integrity.
>  
> — Parker
>  
>  
> On Wed, May 25, 2016, at 02:10 AM, Mike Evans wrote:
>> +1 as it solves the immediate clarity issue nicely with an undeniably strong 
>> word.
>>  
>>  
>>> On May 25, 2016, at 2:07 AM, José Valim <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>>  
>>> Given Peter's feedback, what if we define it as:
>>>  
>>> defstruct [:name, :age], enforce: [:name]
>>>  
>>> The idea of picking :enforce instead of :required is to avoid any possible 
>>> confusion that some of those fields won't be effectively present in the 
>>> struct.
>>>  
>>> Thoughts?
>>>  
>>>  
>>>  
>>>  
>>> José Valim
>>>  
>>> www.plataformatec.com.br <http://www.plataformatec.com.br/>
>>> Skype: jv.ptec
>>> Founder and Director of R&D
>>>  
>>>  
>>>  
>>> On Wed, May 25, 2016 at 3:07 AM, eksperimental <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> José: great new feature. Definitely a needed one!
>>> and +1 on Peter Hamilton's suggestion on how to define required fields.
>>>  
>>> An extra feature that will save us developers a lot of headeaches is
>>> the ability to define a list of accepted values per field. As as the
>>> current state, functions silently fail unexpected values are given
>>> 
>>> On Tue, 24 May 2016 23:35:34 +0000
>>> Peter Hamilton <[email protected] <mailto:[email protected]>> 
>>> wrote:
>>> 
>>> > I am not a fan of the proposed signature. Generally when we have
>>> > multiple clauses of different arity, we try to make them purely
>>> > extensions of the first. In the proposal, we go from (fields) to
>>> > (optional_fields, required_fields). While one could say that it's
>>> > really (optional_fields) to (optional_fields, required_fields), I
>>> > think that's changing the semantics of the current signature, which
>>> > to me is all the fields. I will submit, however, that this is a bit
>>> > subjective and realistically the same in practice.
>>> >
>>> > I would propose instead:
>>> >
>>> > defstruct [age: nil, name: nil], required: [:name]
>>> >
>>> > It not only maintains semantic backwards compatibility, but there
>>> > isn't an implicit meaning behind the two different arguments. It's
>>> > very clear that we have a list of arguments then an explicit list of
>>> > required fields.
>>> >
>>> > On Tue, May 24, 2016 at 4:26 PM José Valim
>>> > <[email protected] 
>>> > <mailto:[email protected]>> wrote:
>>> >
>>> > > To clarify, both :age and :name fields will be present in the
>>> > > underlying User struct/map. The proposal is only about fields which
>>> > > must be enforced when building the structure.
>>> > >
>>> > > We will likely need better names than optional/required.
>>> > >
>>> > > *José Valim*
>>> > > www.plataformatec.com.br <http://www.plataformatec.com.br/>
>>> > > Skype: jv.ptec
>>> > > Founder and Director of R&D
>>> > >
>>> > > On Wed, May 25, 2016 at 1:17 AM, José Valim <
>>> > > [email protected] 
>>> > > <mailto:[email protected]>> wrote:
>>> > >
>>> > >> Hello everyone,
>>> > >>
>>> > >> I would like to propose an extension to defstruct that will require
>>> > >> certain fields to be given when expanding it. Here is an example:
>>> > >>
>>> > >> defmodule User do
>>> > >>
>>> > >>   defstruct [age: nil], # optional
>>> > >>
>>> > >>             [name: nil] # required
>>> > >>
>>> > >> end
>>> > >>
>>> > >>
>>> > >> With this feature, %User{} will fail as the :name field was not
>>> > >> specified. %User{name: "foo"} or %User{name: nil} will both work as
>>> > >> expected. The main use case is to make sure all important fields
>>> > >> are set when building the data. For example, we can use such
>>> > >> fields in the new date time types to enforce proper data
>>> > >> representation.
>>> > >>
>>> > >> *Extra notes*
>>> > >>
>>> > >> 1. The required fields are given as second argument to defstruct
>>> > >> as the API must remain backwards compatibility
>>> > >>
>>> > >> 2. The fields are required only when building structs. Matching
>>> > >> will always work without specifying any field, for example:
>>> > >> %User{} = user
>>> > >>
>>> > >> 3. The Kernel.struct/2 function, used to build structs
>>> > >> dynamically, won't check for required keys. Kernel.struct!/2
>>> > >> should be used if you want to check for required keys (and also
>>> > >> check that no extra keys are given)
>>> > >>
>>> > >> 4. defexception will leverage the same functionality
>>> > >>
>>> > >> *Implementation*
>>> > >>
>>> > >> Implementation-wise, structs will now defined a __struct__/1
>>> > >> function, besides the regular __struct__/0 function. It has not
>>> > >> been decided yet how such function will behave given it must work
>>> > >> both for compile-time (%User{}) and runtime (struct! User, %{})
>>> > >> checks.
>>> > >>
>>> > >> *Feedback*
>>> > >>
>>> > >> Now it is your turn. :)
>>> > >>
>>> > >> *José Valim*
>>> > >> www.plataformatec.com.br <http://www.plataformatec.com.br/>
>>> > >> Skype: jv.ptec
>>> > >> Founder and Director of R&D
>>> > >>
>>> > >
>>> > > --
>>> > > 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] 
>>> > > <mailto:elixir-lang-core%[email protected]>.
>>> > > To view this discussion on the web visit
>>> > > https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2B5b%2BxxcvMOL-n6XyJ4mcQcumTU5B0AhjaTuc7qk-0P1g%40mail.gmail.com
>>> > >  
>>> > > <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2B5b%2BxxcvMOL-n6XyJ4mcQcumTU5B0AhjaTuc7qk-0P1g%40mail.gmail.com>
>>> > > <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2B5b%2BxxcvMOL-n6XyJ4mcQcumTU5B0AhjaTuc7qk-0P1g%40mail.gmail.com?utm_medium=email&utm_source=footer
>>> > >  
>>> > > <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2B5b%2BxxcvMOL-n6XyJ4mcQcumTU5B0AhjaTuc7qk-0P1g%40mail.gmail.com?utm_medium=email&utm_source=footer>>
>>> > > .
>>> > > For more options, visit https://groups.google.com/d/optout 
>>> > > <https://groups.google.com/d/optout>.
>>> > >
>>> >
>>> 
>>> --
>>> 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] 
>>> <mailto:elixir-lang-core%[email protected]>.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/elixir-lang-core/20160525080713.279fe1dd.eksperimental%40autistici.org
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/20160525080713.279fe1dd.eksperimental%40autistici.org>.
>>>  
>>> For more options, visit https://groups.google.com/d/optout 
>>> <https://groups.google.com/d/optout>.
>>>  
>>>  
>>> --
>>> 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] 
>>> <mailto:[email protected]>.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4K5-pCjrDudw1MgXbGcwfhfn%3Da%2BpukmO00cgz1nsYg9Zg%40mail.gmail.com
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4K5-pCjrDudw1MgXbGcwfhfn%3Da%2BpukmO00cgz1nsYg9Zg%40mail.gmail.com?utm_medium=email&utm_source=footer>.
>>> For more options, visit https://groups.google.com/d/optout 
>>> <https://groups.google.com/d/optout>.
>> 
>>  
>> 
>> 
>> --
>> 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] 
>> <mailto:[email protected]>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/6C3AEDA3-34F1-4CED-8B4E-B1769C83D812%40silljays.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/6C3AEDA3-34F1-4CED-8B4E-B1769C83D812%40silljays.com?utm_medium=email&utm_source=footer>.
>> For more options, visit https://groups.google.com/d/optout 
>> <https://groups.google.com/d/optout>.
>  
> 
> -- 
> 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] 
> <mailto:[email protected]>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/1464186821.454905.618394761.3E78A7BC%40webmail.messagingengine.com
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/1464186821.454905.618394761.3E78A7BC%40webmail.messagingengine.com?utm_medium=email&utm_source=footer>.
> 
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.
> 
> 
> -- 
> 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] 
> <mailto:[email protected]>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Ji7JxRFN7fw72VNwqD%2BaqPZ3MQy7EJi-DcUztG-S1KKA%40mail.gmail.com
>  
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Ji7JxRFN7fw72VNwqD%2BaqPZ3MQy7EJi-DcUztG-S1KKA%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

-- 
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/5526D182-2A8E-4276-A2D7-16C6640350B3%40chrismccord.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to