Re: Proposal: Syntax extension

From: Wolfgang Lux <>
Date: Fri, 28 Jan 2011 17:00:40 +0100

Sebastian Fischer wrote:

> I wrote:
> Patterns are rigid or flexible and have fall-through or non-
> deterministic semantics in presence of overlapping rules. The
> current situation mixes these aspects.
> I realize that these aspects are not as independent as I thought.
> Fall-through pattern matching called on a free variable would always
> pick the first rule which seems of questionable utility.

Well, it could be considered a poor man's implementation of committed
choice :-)

> I support overlapping case expressions with non-deterministic
> semantics but would like to avoid the name 'fcase' in favor of
> 'cases'. So
> coin = cases () of _ -> 0; _ -> 1
> would be a possible implementation of (0?1).

I disagree. Recall that the f in fcase stands for flexible pattern
matching, but not for flat patterns. Since you can write down
arbitrarily deep patterns, you have to account for overlapping
patterns anyway. E.g., consider a non-deterministic merge written with
an fcase expression:

   merge xs ys =
     fcase (xs,ys) of
       ([],[]) -> []
       (x:xs,_) -> x : merge xs ys
       (_,y:ys) -> y : merge xs ys

It would look strange to me if we would burden the user with
disentangling the overlapping into something like

   merge xs ys =
     fcase (xs,ys) of
       ([],[]) -> []
       (x:xs,[]) -> x : merge xs ys
       ([],y:ys) -> y : merge xs ys
       (x:xs,y:ys) -> cases () of { _ -> x : merge xs (y:ys); _ -> y :
merge (x:xs) ys }

Note that in fact this might yield a rather different behavior than
the above definition for a compiler that uses or-parallel search when
only one of the two arguments is an unbound logical variable.

The example coin = fcase () of { _ -> 0; _ -> 1 } is just a
pathological case having fully overlapping patterns, i.e., the
overlapping patterns occur at root rather than inside some other
pattern. Therefore, I don't think it is worth a separate syntactic form.

> I thought about a generalization of the proposal for undeclared free
> variables. In addition to allowing anonymous free variables written
> as _ one could treat every identifier that starts with an underscore
> and is not in scope as if it was a free variable implicitly declared
> using a where clause. For example
> half n | n =:= add _m _m = _m
> would be a valid definition. However, currently identifiers are not
> allowed to start with an underscore. Why not? I guess the reason
> must be Curry-specific (Haskell allows such identifiers).

No. The reason that Curry does not allow identifiers to start with an
underscore is just a historical one. Haskell did not allow identifiers
to start with underscores before Haskell 98 either, and it is just
that nobody cared about (or asked for) following Haskell in this

Your proposal for making every identifier that starts with an
underscore a logical variable is problematic, however. The problem is
that the scope of such variables is no longer clear with local
definitions. E.g., consider

   f x y = let { g _ = _u; h _ = _u } in (g x, h y)

Do g and h share the same logical variable or has every function its
own variable? (The difference would be easily observable with
disequality constraints: let (a,b) = f _ _ in a =/= b could succeed if
we have two different variables, but not if the functions use the same
variable.) If you propose to use the same variable here, what if g and
h were top level functions? And while the scope for a shared _u in my
above example would be obvious, this might no longer be the case if
the local functions were more deeply nested. Yet, the scope to which a
shared variable is lifted can make a difference to the possible
results of a function.


curry mailing list
Received on Fr Jan 28 2011 - 17:41:47 CET

This archive was generated by hypermail 2.3.0 : Do Jun 13 2024 - 07:15:11 CEST