I mistook, sorry:  To avoid performance penalty we could enable 
the typespec runtime asserts only for development and testing environments

On Wednesday, November 7, 2018 at 1:00:53 PM UTC+2, Sergiy Kukunin wrote:
>
> 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 elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/cfcb49bc-c245-40ba-9514-d731c028a862%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to