- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]

From: Wolfgang Lux <wlux_at_uni-muenster.de>

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

respect.

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.

Wolfgang

_______________________________________________

curry mailing list

curry_at_lists.RWTH-Aachen.DE

http://MailMan.RWTH-Aachen.DE/mailman/listinfo/curry

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

Date: Fri, 28 Jan 2011 17:00:40 +0100

Sebastian Fischer wrote:

Well, it could be considered a poor man's implementation of committed

choice :-)

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.

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

respect.

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.

Wolfgang

_______________________________________________

curry mailing list

curry_at_lists.RWTH-Aachen.DE

http://MailMan.RWTH-Aachen.DE/mailman/listinfo/curry

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

*
This archive was generated by hypermail 2.3.0
: So Aug 01 2021 - 07:15:04 CEST
*