Hello there. This is my first message to the elixir group. Thanks for the
great language.
While I'm writing my code, I want to make functions to be safer. It's bad
practice if a function accepts unexpected input and pass it further, and it
blows in a completely different part of a system.
At first glance, I have pattern matching, but it's pretty limited. It
becomes really powerful in conjunction with guards, so I can write a
signature to match literally everything.
But they hard to re-use, If I have multiple functions operating with the
same object. Yes, I can define a custom guard, but can I use pattern
matching there? `Kernel.match?/2` doesn't work, so I'm limited with only
guards in my custom guards.
Another thing that we have typespecs. It seems exactly what I'm looking
for: you have a wide set of built-in types, and I can easily compose and
reuse my own types. The problem with it, that it doesn't affect runtime. I
know about static analyzer `dialyzer`, but I'm not sure it will catch all
cases since it's a static check, not a runtime.
Let's assume a simple function, that wraps a value into a list:
@spec same(number()) :: [number()]
def same(number) do
[number]
end
I'm sure the `dialyzer` won't complain since a signature is valid. But what
if I do: `same("abc")` ? What will prevent Elixir from returning a wrong
type? I guess, nothing.
An example from a real life: I have a function, that accepts a custom
shaped value (using tuples) and feeds it to a queue. Then, in the totally
different part of the system, a consumer gets values from the queue. And
when a wrong value was fed on the producer side, it blows on the consumer
side. So I decided to put some constraints on the producer side to fail
fast.
Yes, I could define a guard, but again, if I have a pretty complex type
instead of the simple `number`, I had to duplicate the type defining: one
for typespec, another is for a custom guard (which is limited, since I
can't use pattern matching there).
Wouldn't it be cool, If we had a mechanism to assert a value to its type,
in runtime? To avoid performance penalty we could enable it only for
runtime. Is there a way right now to check whether a value corresponds to a
type in runtime? Can I implement a custom macro to provide a good DSL for
this? Is it helpful at all?
P.S. You may say, use structs and pattern matching would work in this case.
But what if my type is better represented by a tuple: {atom(),
pos_integer(), string()}. Converting it to a struct might complicate a way
to work with the value.
--
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/4d596f8c-a1f8-4441-927d-91e8748e1e6c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.