Re: Curry module system

From: Wolfgang Lux <wlux_at_uni-muenster.de>
Date: Mon, 30 Jan 2006 17:22:40 +0100

Michael Hanus wrote:

> working on an update of the Curry report, I think it is necessary
> to clarify or slightly change a few aspects related to the module
> system which I'd like to propose in the following.
>
> 1. Currently, it is not specified where modules are stored but this
> is relevant to find import modules. Therefore, I propose to state
> that a module named "M" should be stored in a file named "M.curry".
> I think this is already required in all current implementations
> of Curry.

Only if you ignore literate source files (which means that the source of
module M should be stored in M.lcurry, see Sect. 10) and hierarchical
module
names. An implementation could assume thae module A.B.C is stored in
file
A.B.C.curry, but also in A/B/C.curry. Unless the report is going to make
one of the two schemes mandatory, you should refine the proposal to say

   a module named M, where M contains no dots, should be stored in a
file
   M.curry.

> 2. As a consequence of 1., it seems reasonable that in a Curry program
> stored in file "Prog.curry" with a missing module head, the default
> module head "module Prog where" is inserted (currently, the report
> states that in this case the standard module head "module main
> where"
> is inserted).

As Wolfgang Jeltsch has already pointed out, this introduces an
incompatibility with Haskell, but I also see no problem with this.
After all, the current report is already incompatible with Haskell
for using the module name main instead of Main.

> 3. The current report states that the prelude is always implicitly
> imported into all modules. However, there are situations where
> it is reasonable to hide some prelude entities which is impossible
> if the prelude is always imported. Thus, I propose to state that
> the prelude is always implicitly imported if it is not explicitly
> imported. For instance, this allows the hiding of the prelude
> operations "map" and "filter" in the current module by writing
> the import declaration "import prelude hiding (map,filter)".

Seconded. Being unable to hide prelude entities would be a serious
shortcoming in Curry. Furthermore, this proposal removes an
incompatibility with Haskell. IMHO, this is also an opportunity to
fix a few other incompatibilities with Haskell's module system:
- Inside module M, it is always possible to refer to an entity x defined
   at the top-level of the module with the qualified name M.x.
- This allows making the description more concise of what is exported
   when module M occurs in the export list of a module: Module M in this
   context is simply an abbreviation for the list of all entities whose
   unqualified name x is in scope and whose qualified name M.x is in
scope.
   Note that the unqualified name x could be ambiguous.
- Definitions at the top-level do not shadow definitions imported from
   another module, instead the defined entity's name is ambiguous and
one
   must use a qualified name in order to disambiguate it in the right
hand
   side of a declaration.
- A hiding clause acts on both the unqualified and the qualified name.

> Please let me know if you have any objections or further improvements.

I'd like to propose a few more extensions to Curry.

- As-patterns. They are far too convenient when you have to spell out a
   pattern in order to avoid overlapping left hand sides in a
declaration,
   but you are not really interested in the pattern's components
(because
   they are handled elsewhere). The prototypical example is in the
   definition of a simple depth first search strategy:

     dfs g = all (try g)
       where all [] = []
             all [g] = [g]
             all gs_at_(_:_:_) = concatMap dfs gs

   According to the current version of the Curry report, one would have
   to write all (g1:g2:gs) = concatMap dfs (g1:g2:gs) for the last
equation.

- Guards and local declarations in the alternatives of case expressions
   with a fall-through semantics as in Haskell, e.g.

     case x of
       Left y | y >= 0 -> -1
       Right y | y >= 0 -> 1
       _ -> 0

   This expression would reduce to the number 0 if x is bound to Left
(-1).
   Rewriting a case expression using boolean guards into one without can
   lead to a lot of code duplication or the introduction of a lot of
   auxiliary functions -- in particular for more complex matches as the
   example above -- which may obscure the intended meaning of a program.

- The ability to define and use new data constructor symbols, e.g.

     infix 4 :=
     data Assoc a b = a := b
     flipAssoc (x := y) = y := x

   is also convenient, but I do not consider it as important as
   the preceding two items.

- Finally, one big plea: Can we please rename the prelude into
   Prelude. I find it really annoying that I have to change
     import Prelude hiding(...)
   into
     import prelude hiding(...)
   when switching from Haskell to Curry and vice versa. Besides,
   PAKCS and MCC already use capitalized names for the modules in
   their standard libraries, so why should there be an exception
   for the prelude? In fact, I'd really like to see Curry adopt
   Haskell's capitalization conventions, but I guess Michael is
   opposed to this ...

Regards
Wolfgang


_______________________________________________
curry mailing list
curry_at_lists.RWTH-Aachen.DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/curry
Received on Mo Jan 30 2006 - 19:05:18 CET

This archive was generated by hypermail 2.3.0 : Di Apr 23 2024 - 07:15:07 CEST