Hi,
since I see a lot of potential in the feature I'd like to provide a couple
of arguments in favour of it. I will use points for ease of discussion.
1. I am not going to talk about specific implementation (through @guard
property) as proposed, but generally about giving possibility to create
invariants in structs, i.e. possibility to raise on instantiating struct
with invalid data.
2. No solution will be perfect (i.e. mentioned possibility of using
Map.put/3 or manually creating struct as map through %{__struct__:
MyStruct}, using those features is somehow similar to addressing raw memory
in C - if you're doing it, you should expect problems), a lot can be
achieved by modifying just struct/2, %MyStruct{} and %MyStruct{my_struct |
key: val}, as those are prevalent in the codebase.
3. Though there is possibility to define function performing those
validations (i.e. it is quite common to see new/1 in a lot of libraries),
there is no way to restrict creation of struct to that functions. I believe
it to be a good decision, since data is just data, but it makes it quite
easy to make a mistake that is hard to pin down, since no warnings or any
other suggestions are issued.
4. While it is correct that in general forcing users to use API is the way
to go, literal struct creation is very common and in most cases correct,
which can lead to confusion. It can also encourage extensive boilerplating
of functions like 'new', just in case, which can be detrimental to language
clarity.
5. Adding invariants does not breaks the premise of validating data on
boundries, it supports it. Ability to restrict field values leads to
cleaner code, since it is not necessary to check input validity in every
function. Raising error on invalid instantiation actually forces to perform
validation on the boundry - in the place where struct is instantiated. It
allows for less defensive coding, since programmer can actually assume that
struct is correct.
6. Matching on %Foo{} in this scenario doesn't actually cause problems,
since the structure won't be even instantiated if it is wrong, unless it's
manually put together from map.
In general I believe that adding more possibilities to express ideas
through types could really help the language.
Cheers,
Rafal
--
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/109cedb8-b2f2-42be-adbc-27c3a8a64a84%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.