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]> 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 > Skype: jv.ptec > Founder and Director of R&D > > On Wed, May 25, 2016 at 1:17 AM, José Valim < > [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 >> 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]. > 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?utm_medium=email&utm_source=footer> > . > For more options, visit 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/CAOMhEnwWiQKO08LXMo%3D2v-ojC1vF6V0PMacEVC%2BG1PDH2izuTw%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
