Ooo, fantastic questions, I am curious, let's test.  :-)

On Thursday, August 25, 2016 at 10:22:08 AM UTC-6, José Valim wrote:
>
>  
>
>> # -- or happy's way --
>> {:ok, str} when is_binary(str) = get_a_string_or_whatever() # Enforce 
>> entire matching semantics, inline!
>>
>
> Unfortunately this requires mangling of the AST because "=" has higher 
> precedence than "when". I wonder if happy path behaves correctly in cases 
> such as:
>
> IO.inspect({:ok, str} when is_binary(str) = get_a_string_or_whatever())
>
>
Testing, indeed it is not valid there.  :-)

I wonder if it would be worth supporting such a case, I could report it in 
any case, done.  :-)


On Thursday, August 25, 2016 at 10:22:08 AM UTC-6, José Valim wrote: 

> Or in cases such as:
>
> {:ok, str} when is_binary(str) = tuple when is_tuple(tuple) = 
> get_a_string_or_whatever()
>
>
Testing, and cool an unhandled case, reported that too.  :-)


On Thursday, August 25, 2016 at 10:22:08 AM UTC-6, José Valim wrote: 

> And we cannot change the precedence as it would break cases such as:
>
> {:ok, str} = tuple when is_binary(str) ->
>
>
Not unless `->` was removed from such a section and it became a call set 
like my case example, then the precedence could be fixed.  :-)


On Thursday, August 25, 2016 at 10:22:08 AM UTC-6, José Valim wrote:

> I do like `<-` and `->` but when I see them I think of list stuff (I'm an 
>> old erlang programmer) and certainly not inline matching enforcement. 
>>
>
> None of them are related to looping. -> is only used inside do blocks to 
> specify clauses, such as case and receive (exactly the same as in Erlang). 
> <- would be more correctly described as a "soft-matching" operator. In both 
> for and with, they specify that the construct should not continue if there 
> is not a match. The looping is not a property of <-, but a property of the 
> enclosing construct (i.e. for/with). This is also inline with the usage of 
> <- in monads (which could describe both for and with).
>

Hmm, soft-matching operator, makes sense.  Any chance on updating the docs 
at http://elixir-lang.org/docs/stable/elixir/Kernel.SpecialForms.html#for/1 
where it states "Enumerable generators are defined using <-:" to something 
of that form, maybe like "`<-` matches on each given element and skips 
non-matches", although that still does not match how `with` does it.  Hmm, 
it seems that `for` and `with` are using an identical operator in 
incompatible ways.  Unsure how to resolve that without changing the form of 
one or the other...  (/me really dislikes operators that do different 
things in different areas)


On Thursday, August 25, 2016 at 10:22:08 AM UTC-6, José Valim wrote:

> Personally, I'd change Elixir so that `=` supports `when`, just naturally 
>> and everywhere
>>
>
> I would love this too, it is one the things I attempted early on but the 
> operator precedence would never work out. Which is what makes me wary of 
> overloading =, specially if it requires mangling the AST.
>

Hmm, having `when` be directly adjacent to `=` in precedence, what side 
effects would that have?  I do not think that `=` is allowed adjacent to a 
`when` that I can think of in function heads (which are the only other case 
where `when` is used that comes to immediate mind) so no issue there.


This all gets me back to thinking maybe there is a way to pre-set forced 
matches.  Just playing with ideas, this is not a proposed syntax or 
anything:
```elixir
{:ok, str} = get_a_string_or_something() when is_binary(str)  # Hmm, nope, 
the `when` is too far away from the thing it is testing...

when is_binary(str) in {:ok, str} = get_a_string_or_something() # Hmm, 
requires an extra thing here designated by 'in' although I doubt you could 
use the actual 'in' here as it has uses in matching, but what word would be 
appropriate...

when is_binary(str) {:ok, str} = get_a_string_or_something() # Maybe a way 
to do it without the inner part, it is a single expression after all, but 
becomes noisy...

when is_binary(str)
{:ok, str} = get_a_string_or_something() # A more functionally way, put the 
'spec' on the prior line, hmm...

@spec {:ok, String.t}
{:ok, str} = get_a_string_or_something() # I would so *love* if 
@spec/@type/etc... could be made first-class citizens of Elixir, 
# where the compiler could enforce certain things, like this thing would 
fail at compile-time unless get_a_string_or_something()
# will always return {:ok, String.t} or more refined in its function spec 
(where that spec is also verified via the call-path in the
# function, thus function-scoped type checking, fairly easy to do unless 
more detailed ones)
# However this method does not resolve the prior issue where those fail at 
run-time, not compile-time.

@spec {:ok, String.t} | MatchFailure.t
{:ok, str} = get_a_string_or_something() # Maybe this could allow both 
compile-time checks and runtime failure (via MatchFailure.t)
# if it fails to match, maybe the `|` could be `else` or something, could 
be as detailed or specific as wanting to allow, more specific
# like the `MatchFailure.t` would only allow a MatchFailure.t through, so 
if the `get_a_string_or_something()` function spec possibly
# had more then it would fail at compile-time unless handled via more or 
less specific matching.
```

I think what I really want is a(n even optionally) typed elixir.  I'd love 
to put `@spec`s on my variables, functions, everything, and have the 
compiler fail to even compile if they do not match.  That would catch the 
number one source of bugs that I experience by a significant margin.

-- 
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/17192c62-241a-4eff-891f-60d8852960f3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to