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.