Re: Proposal: Relaxing restrictions in Curry

From: Wolfgang Lux <>
Date: Tue, 02 Nov 2004 18:28:10 +0100

Michael Hanus wrote:

> The first one is related to the introduction of free variables.
> The current language definition (Curry Report, C.3) requires
> that in an expression of the form
> let x free in e
> e must be of type "Success" (1).
> [...]
> Thus, I propose to drop the restriction (2).
> This would also make the application of let and where
> "more equivalent".

I wholeheartedly agree to this proposal. (I did object against breaking
the symmetry between let and where right from the start, so this
comes at no surprise to you.)

> The second restriction concerns the sequential conjunction
> of constraints, which is currently defined as
> (&>) :: Success -> Success -> Success
> c &> x | c = x
> in the prelude.
> [...]
> Since such a guard function is quite useful, I propose
> to generalize the type of (&>) to
> (&>) :: Success -> a -> a
> so that it is a general function to establish new constraints
> during arbitrary computations.

In MCC's Success library module, I have introduced two operators
   (==>) :: Success -> a -> a
   (<==) :: a -> Success -> a
for exactly the same reason quite a while ago. (I have chosen (<==)
as it resembles Toy's guard notation.) However, it turns out that I
use these functions vary sparingly. For one, MCC supports guards in
case expressions, which covers most of the cases where I was using
these operators. And second, it turns out that the prelude already
contains an even more general operator, which does achieve exactly the
same effect. Instead of guard (x=:=1) (2+x), you could as well write
   x=:=1 `seq` 2+x


P.S.: I have another proposal for a minor change in the report
regarding evaluation annotations. At present, the report says
(p. 14 in Sect. 3)

   A function can be explicitly annotated as rigid. If an
   explicit annotation is not provided by the user, a default
   strategy is used: functions with the result type ``IO ...''
   are rigid and all other defined functions are flexible.
   Functions with a polymorphic result type (like the identity)
   are considered as flexible, although they can be applied like
   a function with result type ``IO ...'' in a particular context.

I have been a proponent of the IO exception because flexible
evaluation in an IO context does not make sense. However, with
hindsight, I concede that this was ill-advised because we have
no concurrency at the level of the IO monad and therefore the
choice is simply between failing either due to a suspending
computation or a non-deterministic computation.

Moreover, the quote from the report is utterly misleading.
For instance, mapIO has result type IO [b], but its prelude
implementation is nevertheless flexible. And to add to the
confusion, sequenceIO is rigid whereas sequenceIO_ is not!
Therefore, I propose to simplify the default strategy so as
to make all functions flexible by default and replace the
quoted sentences by:

   A function can be explicitly annotated as rigid. If an
   explicit annotation is not provided by the user, it is

curry mailing list
Received on Mi Nov 03 2004 - 08:47:41 CET

This archive was generated by hypermail 2.3.0 : Sa Dez 07 2019 - 07:15:06 CET