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.

Reply via email to