[erlang-questions] Guards syntax for multiple values
Richard O'Keefe
raoknz@REDACTED
Thu Mar 28 12:36:42 CET 2019
I believe I already said that an OR-pattern is allowed anywhere a pattern
is allowed.
Further, an alternative of an OR-pattern may bind variables if and only if
every alternative of the OR-pattern binds the same variables (ignoring wild
cards).
(Not entirely unlike Erlang 'case'.)
It's the same in F#. Here's an example from the manual.
let detectZeroOR point = match point with | (0, 0) | (0, _) | (_, 0) ->
printfn "Zero found." | _ -> printfn "Both nonzero."
So that is at least three functional languages that currently support
OR-patterns: Caml, F#, and SML (both SML/NJ and MLton).
However, it seems likely that this fills a much-needed gap.
Complex patterns are probably wrong.
On Thu, 28 Mar 2019 at 01:29, Jesper Louis Andersen <
jesper.louis.andersen@REDACTED> wrote:
> On Wed, Mar 27, 2019 at 2:17 AM José Valim <
> jose.valim@REDACTED> wrote:
>
>> > Everybody seems to be chasing after how to express "X in [...]" as a
>> guard
>> without responding to the suggestion of copying SML/NJ's "or patterns"
>>
>> What are the restrictions for OR patterns?
>> Can OR patterns be allowed anywhere in a pattern (i.e. arbitrarily
>> nested) or are they allowed only at the root?
>> Can we bind variables inside OR patterns?
>>
>>
> I'll use Ocaml as the language for this, since it has the same pattern as
> SML/NJ, and I happen to have Ocaml installed, but not SML/NJ.
>
> In erlang we write:
>
> case Exp of
> P1 -> E1;
> P2 -> E2;
> P3 -> E3
> end
>
> In Ocaml, we would write
>
> match Exp With
> | P1 -> E1
> | P2 -> E2
> | P3 -> E3
>
> Note that we prefix each pattern by '|' rather than separate them with ';'
> as in Erlang. The semantics are otherwise the same at least up to a very
> high level of equivalence. Now suppose, we have a case where we want to
> write
>
> match Exp with
> | P1 -> E
> | P2 -> E
> | P3 -> E3
>
> That is, both patterns P1 and P2 runs the same function body E. In this
> case, Ocaml allows us to avoid the repetition, the so-called OR-pattern:
>
> match Exp with
> | P1 | P2 -> E
> | P3 -> E3
>
> What are the rules? Any use of a variable 'x' in E must be bound in the
> scope and must have the same type. That is, if P1 binds 'x : t' i.e., with
> type t, then P2 must also bind 'x : t'. In principle, we could allow it if
> the scope/context has 'x : t' and it isn't bound in P2, but this is
> currently rejected by the language, probably on the grounds of being prone
> to error.
>
> The compiler has a relatively easy rewrite to make:
>
> let body_E x = E in
> match Exp with
> | P1 x -> body_E x
> | P2 x -> body_E x
> ...
>
> more or less (caveat: capture! body_E must be be passed parameters
> appropriately if it uses them from the context. Further optimizations might
> then lift them). Extract the common body into a local function and apply
> that function. Further optimizations are often able to remove 'body_E' from
> the generated code. Since we are in ML-land with Standard ML and Ocaml, the
> Mlton compiler has a contification optimization which will fuse the body_E
> continutation appropriately. This can then uncover further optimizations
> down the road.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20190329/1b4db3d1/attachment.htm>
More information about the erlang-questions
mailing list