Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiple match + guards #2856

Closed
vicuna opened this issue Jul 25, 2001 · 3 comments
Closed

multiple match + guards #2856

vicuna opened this issue Jul 25, 2001 · 3 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Jul 25, 2001

Original bug ID: 453
Reporter: administrator
Status: closed
Resolution: not a bug
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Hello,

the following is not accepted by the compiler though it makes perfect
sense:

let f p = function
| None | Some x when p x -> ()
| Some x -> ()

The compiler complains that:

File "bla.ml", line 2, characters 4-17:
Variable x must occur on both sides of this | pattern

It might be better to check whether variables contained in the patterns
are actually used on the right hand side of the match. Otherwise it is
impossible to use guards as presented above.

Best regards,
Markus Mottl

--
Markus Mottl markus@oefai.at
Austrian Research Institute
for Artificial Intelligence http://www.oefai.at/~markus

@vicuna
Copy link
Author

vicuna commented Jul 25, 2001

Comment author: administrator

Hello,
Hello,

the following is not accepted by the compiler though it makes perfect
sense:

let f p = function
| None | Some x when p x -> ()
| Some x -> ()

The compiler complains that:

File "bla.ml", line 2, characters 4-17:
Variable x must occur on both sides of this | pattern
This is more a limitation than a plain bug.

Basically, the guard is not a part of the pattern, but a part of the matching
clause
(whose syntax is | pattern [when expression] -> expression''). Hence, your example means | None | Some x'' when p x'' -> ()''
^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^^^
pattern guard result
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
clause

Hence, the error is correct (!), since x is not a variable bound
by the or-pattern ``None | Some x''

It might be better to check whether variables contained in the patterns
are actually used on the right hand side of the match.
No, in such a case, programmers are invited to put ``_'' themselves.
Having the compiler to produce warnings would indeed clobber its
output with no clear benefit.

But, anyway, in your exemple, variable ``x'' is used (in the guard).
Since the scope of x is guard and result.

Otherwise it is
impossible to use guards as presented above.
Indeed.

The general solution (consider guards as patterns up to the point of
allowing things ``(x when p x, y when p y) when p (x+y)'') is not
very difficult to design neither to implement in the pattern matching
compiler. It has already been discussed in the mailing list.
But this would imply inserting expressions inside patterns.
This would thus probably imply important changes in the compiler and we are a
bit reluctant to do that.

Note that this issue was not relevant in the good old days when
varibles in a pattern meant no or-pattern.
Then, one could ignore that guards belong to clauses.

Best regards,
Markus Mottl

Best regards,

--Luc Maranget

@vicuna
Copy link
Author

vicuna commented Jul 25, 2001

Comment author: administrator

On Wed, 25 Jul 2001, Luc Maranget wrote:

Basically, the guard is not a part of the pattern, but a part of the matching
clause
(whose syntax is | pattern [when expression] -> expression''). Hence, your example means | None | Some x'' when p x'' -> ()''
^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^^^
pattern guard result
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
clause

Hence, the error is correct (!), since x is not a variable bound
by the or-pattern ``None | Some x''

Ok, I see, I thought that guards work on a per pattern basis, which may
allow more fine-grained matching.

It might be better to check whether variables contained in the patterns
are actually used on the right hand side of the match.
No, in such a case, programmers are invited to put ``_'' themselves.
Having the compiler to produce warnings would indeed clobber its
output with no clear benefit.

That's not quite what I meant: I thought that the scope could be limited
to the guard if the variable isn't used on the right hand side. But I
agree that this would be somewhat messier from a compiler implementor's
or language designer's point of view: the scope of a variable should
be clearly defined and not "adjustable" as required, even if this were
"convenient".

Unfortunately, the present rules require copying of right hand sides or
lifting out the expression in a unit-function if this involved too much
code, which can be a bit tedious.

The general solution (consider guards as patterns up to the point of
allowing things ``(x when p x, y when p y) when p (x+y)'') is not
very difficult to design neither to implement in the pattern matching
compiler. It has already been discussed in the mailing list.
But this would imply inserting expressions inside patterns.
This would thus probably imply important changes in the compiler and we are a
bit reluctant to do that.

I have never needed this generality anyway. In fact, I'd even find such
nesting confusing to follow.

Thanks for the explanations!

Best regards,
Markus Mottl

--
Markus Mottl markus@oefai.at
Austrian Research Institute
for Artificial Intelligence http://www.oefai.at/~markus

@vicuna
Copy link
Author

vicuna commented Jul 26, 2001

Comment author: administrator

User accepted our explanation of why things are the way they are :-)

@vicuna vicuna closed this as completed Jul 26, 2001
@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant