Re: Library conventions

2000-06-29 Thread Hannah Schroeter

Hello!

On Fri, Jun 23, 2000 at 09:52:53AM -0700, Mark P Jones wrote:
 [...]

 Hugs is also quite old; it's core goes back nearly ten years!
 With a more "modern" interface, we might solve the interface
 dilemma by arranging for fully qualified names, types, etc. to
 pop up in a "tooltip" when the user mouses over an identifier
 in an error message.  Perhaps other people can suggest more
 modest proposals for making intelligent choice of qualifying
 prefixes that would fit in more directly with the existing
 framework.

Please don't make hugs into a Windows only thingy (or X only,
for that respect). While I don't do real projects with Haskell,
I still like using hugs from the OpenBSD text console (or screen
or a remote login). So also please don't make reasonable usage
dependant on graphics.

 [...]
 developers to get the job done on their own.  I'm convinced
 that the only way we will ever have truly excellent tools is
 by working on them together as a community.

That's true in principle, however not everyone doing things
with Haskell are able to grok something like the ghc source
code; when I tried reading some of it, I didn't understand
very much, even though I've read some papers about ghc's
translation techniques, just for an example. Yes, I might
find the hugs source easier to understand, however there's
a significant threshold even there, I think.

 All the best,
 Mark

The same for you and all other implementors and Haskellers.

Kind regards,

Hannah.




Re: Library conventions

2000-06-27 Thread Lennart Augustsson

 Using `Left' and
 `Right' for such cases is fundamentally confusing since it is not
 clear what the meaning of `Left' and `Right' is.
Well, I don't totally agree.  Anyone using Right for Wrong deserves to
have his/her head examined. :)

-- Lennart




Re: Library conventions

2000-06-27 Thread D. Tweed

On Tue, 27 Jun 2000, Lennart Augustsson wrote:

  Using `Left' and
  `Right' for such cases is fundamentally confusing since it is not
  clear what the meaning of `Left' and `Right' is.
 Well, I don't totally agree.  Anyone using Right for Wrong deserves to
 have his/her head examined. :)

I probably deserve to have my head examined for different reasons :), but
lots of my code uses Left - ok result, Right - error indication and I'm
a native english speaker. I think the reason is the same reason non-native
english speakers don't complain about how the keywords/ubiquitous `words'
in virtually every programming language are all english terms: very
quickly they just become abstract symbols based on how they look/are typed
without any connection to the natural language they were drawn from. (I've
always been puzzled by the choice of Left and Right, which imply symmetry,
when at least in the programs I write, Primary  Secondary would fit the
usage better since if there is general symmetry rather than a
`desirability ordering' that's almost always done in a new datatype.)

___cheers,_dave
www.cs.bris.ac.uk/~tweed/pi.htm|I shoulda realised building the 
email: [EMAIL PROTECTED] |memory allocation subsytem with 
work tel: (0117) 954-5253  |--with-malicious-ai was a bad idea.






Re: Library conventions

2000-06-27 Thread johnsson


Lennart Augustsson writes:
   Using `Left' and
   `Right' for such cases is fundamentally confusing since it is not
   clear what the meaning of `Left' and `Right' is.
  Well, I don't totally agree.  Anyone using Right for Wrong deserves to
  have his/her head examined. :)
Unless you're left-handed of course (:-)
--Thomas (sometimes left-handed)





Re: Library conventions

2000-06-26 Thread George Russell

Jon Fairbairn wrote:
 Am I alone in thinking that the prelude is desperately in
 need of restructuring? 
No.  Personally I think it should be got rid of entirely, or rather
trimmed down to the absolute bare minimum required for the syntax.

By the way I think Sven's proposals are thoroughly excellent.  I don't
agree with those who say that empty sets, empty maps and so on should all
have the same name, distinguished only by module.  This is just too
inconvenient.  Lennart Augustsson writes:
   If I want to switch from FooTree to BarTree
   I have to change all over the code
Well I think the solution to this is to make the name for the
empty object "emptyXXX" (and the type name itself)
only encode the functionality provided.  Thus all balanced trees (or anything
which provides a reasonable mapping function on an Ordered type) should have
the same type name and "emptyXXX" name.  If you want to change from one sort
of balanced tree to another you only have to change the import declaration.
If you want a more fundamental change, say between hash tables and balanced
trees, then you WILL have to go through changing emptyXXX to emptyYYY
(if you don't want the quick hack of saying "import YYY;emptyXXX=emptyYYY")
but since the functionality has changed I think you should have to anyway.




Re: Library conventions

2000-06-24 Thread Manuel M. T. Chakravarty

Frank Atanassow [EMAIL PROTECTED] wrote,

 Chris Okasaki writes:
   If anybody has a good argument against using the module system in
   this context, I would very much like to hear it, because I use the
   module-based convention almost exclusively in Edison.
 
 To be fair, I can give 4 arguments against it.
[..]
   3) Nobody else uses it either, except me (and Chris, apparently :).
[..]

HOpenGL uses it and Gtk+HS is moving the same way.  (And
this although the C libraries on which these Haskell
libraries are based use prefixes as poor man's name spaces.)

Manuel




Re: Library conventions

2000-06-24 Thread Manuel M. T. Chakravarty

Jon Fairbairn [EMAIL PROTECTED] wrote,

 4) Qualified infix operators are ugly.
  
  Yes, I can't deny that. :)
 
 That seems like a presentation problem.  One day an editor 
 might be persuaded to display Prelude.+ as (till ex.) + in 
 proper size and 'Prelude' in smaller type beneath it or as 
 a subscript.

You can't base the design of a general purpose programming
language on the capabilities of one (or even some)
editor(s).  Sometimes I am editing Haskell over a remote
login connection, which leaves me more or less with plain
ascii.

Manuel





RE: Library conventions

2000-06-24 Thread Manuel M. T. Chakravarty

"Mark P Jones" [EMAIL PROTECTED] wrote,

 I'm convinced that the only way we will ever have truly
 excellent tools is by working on them together as a
 community.

Very true!

Manuel




Re: Library conventions

2000-06-24 Thread Marcin 'Qrczak' Kowalczyk

Fri, 23 Jun 2000 23:58:36 +0200, Sven Panne [EMAIL PROTECTED] 
pisze:

 stToIO is a misnomer (should be sTToIO),

stToIO looks better for me. What about declaring that lowercasing the
first letter of an abbreviation consisting of only capital letters is
realized by lowercasing the whole word? Including ioRefToFoo.

 e.g. proposals for the names of non-monadic versions of updateBlah,

Edison uses
  update :: Seq s = Int - a - s a - s a
  adjust :: Seq s = (a - a) - Int - s a - s a
for what my guidelines could give
  setElem:: Seq s = s a - Int - a - s a
  updateElem :: Seq s = s a - Int - (a - a) - s a

Not that I don't like partial application, but Edison's order is
usually not used elsewhere, e.g. in PosixTTY (using "with" prefix
instead of my "set"), Bits (using separate setBit and clearBit instead
of setBit with Bool parameter, and complementBit instead of updateBit -
but the latter is OK), FiniteMap.

Maybe we should promote Edison's order, which is consistent with
module List, but what about above libraries?

-- 
 __("  Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/GCS/M d- s+:-- a23 C+++$ UL++$ P+++ L++$ E-
  ^^W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-





Re: Library conventions

2000-06-24 Thread Sven Panne

Marcin 'Qrczak' Kowalczyk wrote:
 stToIO looks better for me. What about declaring that lowercasing
 the first letter of an abbreviation consisting of only capital
 letters is realized by lowercasing the whole word? [...]

OK, this makes sense and the rule is not much more complicated.

  e.g. proposals for the names of non-monadic versions of updateBlah,
 
 Edison uses
   update :: Seq s = Int - a - s a - s a
   adjust :: Seq s = (a - a) - Int - s a - s a
 for what my guidelines could give
   setElem:: Seq s = s a - Int - a - s a
   updateElem :: Seq s = s a - Int - (a - a) - s a
 
 Not that I don't like partial application, but Edison's order is
 usually not used elsewhere, [...]

Please note that at least since the hslibs shipped with GHC 4.06,
the `update' prefix has been taken by actions (namely updateIORef,
which has accompanied by an updateSTRef lately). I'm a little bit
reluctant to propose it for a different usage now. Edison uses it
in neither way.   :-(   But we could use Edison's `adjust' for the
non-monadic case.

 Bits (using separate setBit and clearBit instead of setBit with
 Bool parameter, and complementBit instead of updateBit - but the
 latter is OK) [...]

Well, Bits is IMHO an example for a module which is completely
messed up: Totally inconsistent naming, too many methods, etc.
Perhaps I'm grumbling about this in a different mail.  :-)

 Maybe we should promote Edison's order, which is consistent with
 module List, but what about above libraries?

Aaaah, finally something which has nothing to do with names. :-)
I don't have a clear picture about common practice regarding argument
order. Any ideas for simple rules which cover most cases? Remember:
This is not a futile attempt to prescribe everyone how to do things.
But remembering the argument order for the tons of functions within
hslibs without peeking into the respective docs is currently not easy,
so an easy convention would be nice here.

Cheers,
   Sven




Re: Library conventions

2000-06-24 Thread Marcin 'Qrczak' Kowalczyk

Sat, 24 Jun 2000 14:34:37 +0200, Sven Panne [EMAIL PROTECTED] 
pisze:

 Please note that at least since the hslibs shipped with GHC 4.06,
 the `update' prefix has been taken by actions (namely updateIORef,
 which has accompanied by an updateSTRef lately). I'm a little bit
 reluctant to propose it for a different usage now.

I too prefer distinguishing similar operations that differ in
monadness, to avoid silly mistakes that may make some people feel
"stupid Haskell forces me to remember what is monadic and what is not,
what a silly distinction". But it's hard to do all the time anyway
(e.g. isX, setX), so some exceptions should not hurt much.

For updating we have: update, modify, adjust. I proposed modify for
the monadic case, because IMHO it sounds most imperatively and better
than update suggests that the old value is used. You changed it to
update. OK, I have not strong feelings for modify.

Monadic modify is used in MonadState. Monadic update is used in
{IO,ST}Ref. Pure adjust is used in Edison. Something like pure update
is produced by DrIFT. I have not found more in lib/std or hslibs.

 I don't have a clear picture about common practice regarding argument
 order. Any ideas for simple rules which cover most cases?

For functions that take an old version of something plus some modifiers
and return a new version, current practice is inconsistent.

Old version is the first argument:
  (Array.//)
  FiniteMap
  Bits
  PosixTTY
  plusAddr

Old version is a middle argument:
  Array.accum

Old version is the last argument:
  Prelude.fmap
  List
  Array.ixmap
  MonadState
  Edison
  PackedString

Maybe we should promote the last argument, while stating that for
historical reasons it is not always used...

Rationale for the last argument: partial application of course,
using layout where the old value is complex and modifiers are simple,
and applying many modifications at once (the last case works for the
first argument variant only when there is exactly one other argument,
so the function name can be put in backquotes).



Some other rules.

When a function takes a state and returns a pair consisting of some
result and an updated state, the result should be first and the state
should be second. Seems to be consistently used (Random, MonadState).

When an Either result encodes a good result or an error, the error
should be Left and the good result should be Right. Rationale:
partially applied type is a good Functor and Monad. Seems to be
consistently used (MonadEither, Parsec).



Edison's documentation contains various argument order rules.



I am trying to make an unified system of classes that would catch
three Edison's families: sequences, collections and associations.
And maybe the fourth that does not fit into these and is missing:
arrays. It's hard and complex :-(  Results are less ugly when
functional dependencies are used, but I still cannot keep the whole
functionality of current Edison.

The problem is that if element type is going to the context, then
it's impossible to have methods like current
  intersectWith :: FiniteMapX m k = (a-b-c) - m k a - m k b - m k c

-- 
 __("  Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/GCS/M d- s+:-- a23 C+++$ UL++$ P+++ L++$ E-
  ^^W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-





Re: Library conventions

2000-06-24 Thread Chris Okasaki

 Edison uses
   update :: Seq s = Int - a - s a - s a
   adjust :: Seq s = (a - a) - Int - s a - s a
 for what my guidelines could give
   setElem:: Seq s = s a - Int - a - s a
   updateElem :: Seq s = s a - Int - (a - a) - s a
 
 Not that I don't like partial application, but Edison's order is
 usually not used elsewhere, e.g. in PosixTTY (using "with" prefix
 instead of my "set"), Bits (using separate setBit and clearBit instead
 of setBit with Bool parameter, and complementBit instead of updateBit -
 but the latter is OK), FiniteMap.
 
 Maybe we should promote Edison's order, which is consistent with
 module List, but what about above libraries?

Simon PJ sold me on this order, which supports multiple updates like

  update 1 'a' $ update 2 'b' $ update 3 'c' s

instead of

  update (update (update 3 'c' s) 2 'b) 1 'a'

Chris





Re: Library conventions

2000-06-24 Thread Marcin 'Qrczak' Kowalczyk

24 Jun 2000 13:54:49 GMT, Marcin 'Qrczak' Kowalczyk [EMAIL PROTECTED] pisze:

 I am trying to make an unified system of classes that would catch
 three Edison's families: sequences, collections and associations.
 And maybe the fourth that does not fit into these and is missing:
 arrays. It's hard and complex :-(  Results are less ugly when
 functional dependencies are used, but I still cannot keep the whole
 functionality of current Edison.

Seems that it would get simpler if association maps were expressed as
collections of key:=value pairs (with Eq,Ord instances ignoring the
value component). Association maps would have extra functions, but
they could be always treated as appropriate collections of such pairs.

Is this idea fundamentally broken for some reason?

Advantages: simpler interface, and that concrete collections can easily
provide association maps (those extra functions would be methods with
default implementations).

Names for association maps would get rotated. E.g. instead of separate
Collection.minElem   :: OrdColl   c a = c a   - a
Assoc.minElem:: OrdAssocX m k = m k a - a
Assoc.minElemWithKey :: OrdAssoc  m k = m k a - (k,a)
there would be single Collection's minElem with a special case being
equivalent to current Assoc.minElemWithKey, and a separate minValue
for association maps that returns only the value.



Seems that an extended form of context could be useful. E.g.
(forall a. Coll c a) = ...
means that c is constrained to types for which there exists an
appropriate instance that works for all types a.

Is this a good idea? Is it possible/easy to implement?

-- 
 __("  Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/GCS/M d- s+:-- a23 C+++$ UL++$ P+++ L++$ E-
  ^^W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-





Re: Library conventions

2000-06-24 Thread Chris Okasaki

 Seems that it would get simpler if association maps were expressed as
 collections of key:=value pairs (with Eq,Ord instances ignoring the
 value component). Association maps would have extra functions, but
 they could be always treated as appropriate collections of such pairs.
 
 Is this idea fundamentally broken for some reason?

I considered this for Edison but rejected in for two reasons.
First, it constrains the implementation, adding an extra level
of indirection to every access.  Second, and more seriously, it moves 
the unconstrained type variable into the class, which leads to several 
potential problems such as more ambiguity messages.  Your idea below 
would take care of at least some of these problems.

 Seems that an extended form of context could be useful. E.g.
 (forall a. Coll c a) = ...
 means that c is constrained to types for which there exists an
 appropriate instance that works for all types a.

Chris





Re: Library conventions

2000-06-24 Thread Marcin 'Qrczak' Kowalczyk

Sat, 24 Jun 2000 13:10:24 -0400 (EDT), Chris Okasaki [EMAIL PROTECTED] pisze:

 I considered this for Edison but rejected in for two reasons.
 First, it constrains the implementation, adding an extra level
 of indirection to every access.

It does not, if extra functions for association maps are methods
themselves, instead of always going through generic functions on
(:=) pairs.

This means that collections would still need to get some trivial
instances to be used as maps.

 Second, and more seriously, it moves the unconstrained type variable
 into the class, which leads to several potential problems such as
 more ambiguity messages.

Indeed. I'm not sure know how big the problem is...

OTOH I can imagine types that need these constraints: sequences of
bits, packed strings of characters, containers shared with foreign
languages. IArray does constrain elements and has unboxed arrays
as instances.

It seems impossible to unify things that currently share names, without
either constraints on elements or contexts with local foralls :-(

-- 
 __("  Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/GCS/M d- s+:-- a23 C+++$ UL++$ P+++ L++$ E-
  ^^W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-





Re: Library conventions

2000-06-24 Thread Manuel M. T. Chakravarty

Sven Panne [EMAIL PROTECTED] wrote,

 Marcin 'Qrczak' Kowalczyk wrote:
  stToIO looks better for me. What about declaring that lowercasing
  the first letter of an abbreviation consisting of only capital
  letters is realized by lowercasing the whole word? [...]
 
 OK, this makes sense and the rule is not much more complicated.

That's indeed also what I usually do.

Manuel




Re: Library conventions

2000-06-24 Thread Manuel M. T. Chakravarty

[EMAIL PROTECTED] (Marcin 'Qrczak' Kowalczyk) wrote,

 Sat, 24 Jun 2000 14:34:37 +0200, Sven Panne [EMAIL PROTECTED] 
pisze:
 
  I don't have a clear picture about common practice regarding argument
  order. Any ideas for simple rules which cover most cases?
 
 For functions that take an old version of something plus some modifiers
 and return a new version, current practice is inconsistent.
 
 Old version is the first argument:
   (Array.//)
   FiniteMap
   Bits
   PosixTTY
   plusAddr
 
 Old version is a middle argument:
   Array.accum
 
 Old version is the last argument:
   Prelude.fmap
   List
   Array.ixmap
   MonadState
   Edison
   PackedString
 
 Maybe we should promote the last argument, while stating that for
 historical reasons it is not always used...
 
 Rationale for the last argument: partial application of course,
 using layout where the old value is complex and modifiers are simple,
 and applying many modifications at once (the last case works for the
 first argument variant only when there is exactly one other argument,
 so the function name can be put in backquotes).

I just scanned through some of my code and it seems that I
relatively consistently place the old version as the first
argument in my libraries.  Indeed one of the few places
where I used the last argument is my finite map
implementation and I am always messing up the arguments of
these functions when I use them.

In fact, I think, one reason that makes it difficult to find
a single rule here is because we essentially two different
classes of functions:

(1) Functions describing a generic traversal of a data
structure (like the well know list functions map, foldr,
etc).

(2) Functions modelling state updates (eg, entering elements
into a finite map etc).

In the first case, partial applications are often very
useful, which promotes the use of the last argument for the
traversed data structure.  In contrast, state updates (ie,
functional state transformers) feel more natural when the
modified structure is the first argument.  Reasons for this
are probably that this is the convention that we are used to
from imperative and oo languages, and furthermore, when
reading a program containing such functions, the most
important question is `which structure is modified', and then,
we check how the structure is modified exactly.

Manuel




Re: Library conventions

2000-06-23 Thread Lennart Augustsson

Chris Okasaki wrote:

 I've taken a look at these.  I'll limit myself to just one comment:

 1.1.1. Constructor names
 
 Empty values of type X have the name emptyX, e.g. emptySet.

 You've struck a pet peeve of mine.  These suffixes are doing namespace
 management, avoiding name clashes between different things that you
 want to call empty.  But Haskell already has a perfectly good language
 mechanism for doing this -- the module system!  Why is emptyX preferable
 to X.empty?  The latter convention is much more flexible.

I agree 100% with Chris.  Having the type as a suffix just gives you poor
maintainability of the code.  If I want to switch from FooTree to BarTree
I have to change all over the code, whereas with an `import .. as X' and
X.empty I only have to change in one place.

--

-- Lennart







Re: Library conventions

2000-06-23 Thread Lennart Augustsson

Frank Atanassow wrote:

 To be fair, I can give 4 arguments against it.

   1) Hugs's error messages don't qualify names, so they become very difficult
  to read when you use this convention.

That's a totally bogus reason.  Tell the implementors to fix Hugs.


   2) The Prelude doesn't use it.

Well, it doesn't for historical reasons.


   3) Nobody else uses it either, except me (and Chris, apparently :).

I do.  I think many people do.  The libraries that come with HBC uses it.



   4) Qualified infix operators are ugly.

Yes, I can't deny that. :)



--

-- Lennart







Re: Library conventions

2000-06-23 Thread Juan J. Quintela

 "chris" == Chris Okasaki [EMAIL PROTECTED] writes:

chris You've struck a pet peeve of mine.  These suffixes are doing namespace
chris management, avoiding name clashes between different things that you
chris want to call empty.  But Haskell already has a perfectly good language
chris mechanism for doing this -- the module system!  Why is emptyX preferable 
chris to X.empty?  The latter convention is much more flexible.  It allows the
chris user to 

I completely agree with chris in this point.

Later, Juan.

-- 
In theory, practice and theory are the same, but in practice they 
are different -- Larry McVoy




Re: Library conventions

2000-06-23 Thread Jon Fairbairn

Lennart Augustsson wrote:
 Frank Atanassow wrote:
2) The Prelude doesn't use it.
 
 Well, it doesn't for historical reasons.

Am I alone in thinking that the prelude is desperately in 
need of restructuring?  Has anyone got any proposals for 
nested modules (so we could have Prelude.List.head)?

3) Nobody else uses it either, except me (and Chris, apparently :).
 
 I do.  I think many people do. 

I would if I needed it.

4) Qualified infix operators are ugly.
 
 Yes, I can't deny that. :)

That seems like a presentation problem.  One day an editor 
might be persuaded to display Prelude.+ as (till ex.) + in 
proper size and 'Prelude' in smaller type beneath it or as 
a subscript.

 Jón

-- 
Jón Fairbairn [EMAIL PROTECTED]
18 Kimberley Road[EMAIL PROTECTED]
Cambridge CB4 1HH+44 1223 570179 (after 14:00 only, please!)






RE: Library conventions

2000-06-23 Thread Mark P Jones

|   1) Hugs's error messages don't qualify names, so they become 
|  very difficult to read when you use this convention.
| ...
| ... #1 is the least important in theory, since it's fixable and
| implementation-dependent, but turned out for me to be the most
| important in practice; Hugs' atrocious behavior on this score has 
| caused me to disregard my own better judgement here for serious
| projects.

Despite the way that many people use it, and even with all the
changes that have been made to it, Hugs simply wasn't designed
for "serious projects".  It was intended for small projects,
and as a tool for education and research.  Using qualified names
in error messages can make things unnecessarily harder to read
in such contexts like that.  As an expert user working on large
projects, your perspective is different.  But I don't think the
design choices are as clear cut as you suggest.

Hugs is also quite old; it's core goes back nearly ten years!
With a more "modern" interface, we might solve the interface
dilemma by arranging for fully qualified names, types, etc. to
pop up in a "tooltip" when the user mouses over an identifier
in an error message.  Perhaps other people can suggest more
modest proposals for making intelligent choice of qualifying
prefixes that would fit in more directly with the existing
framework.

A final comment: don't forget that you have full access to the
source code for Hugs, and hence the opportunity not just to
identify weaknesses, but also to fix them, and to share the
results so that everyone benefits!  The same goes for all of
our Haskell systems, not just Hugs.  There just aren't enough
developers to get the job done on their own.  I'm convinced
that the only way we will ever have truly excellent tools is
by working on them together as a community.

All the best,
Mark





Re: Library conventions

2000-06-23 Thread Marcin 'Qrczak' Kowalczyk

Fri, 23 Jun 2000 09:05:54 -0400 (EDT), Chris Okasaki [EMAIL PROTECTED] pisze:

 These suffixes are doing namespace management, avoiding name clashes
 between different things that you want to call empty.  But Haskell
 already has a perfectly good language mechanism for doing this --
 the module system!  Why is emptyX preferable to X.empty?  The latter
 convention is much more flexible.

I prefer recognizing common interfaces and making appropriate classes.
It is more convenient and more flexible than qualified imports:

* More than one type can be used unqualified at the same time.

* The same function will work for different types.

* Adding a new implementation will get some derived functions and
  default methods for free.

* Different types need not be exported by separate modules.

* Interfaces of derived modules will be overloaded instead of
  being tied to particular implementation. Imagine what happens
  when one module produces a set implemented as SetX and another
  expects a set implemented as SetY. We don't have parametrized
  modules.

I don't like modules that have to be imported qualified.

-- 
 __("  Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/GCS/M d- s+:-- a23 C+++$ UL++$ P+++ L++$ E-
  ^^W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-





RE: Library conventions

2000-06-23 Thread Robert Ennals

On Fri, 23 Jun 2000, Mark P Jones wrote:

[snip] 

 Hugs is also quite old; it's core goes back nearly ten years!
 With a more "modern" interface, we might solve the interface
 dilemma by arranging for fully qualified names, types, etc. to
 pop up in a "tooltip" when the user mouses over an identifier
 in an error message.  Perhaps other people can suggest more
 modest proposals for making intelligent choice of qualifying
 prefixes that would fit in more directly with the existing
 framework.

One approach that seems to work quite well (and which I have used), is to 
keep note of all the names that are currently in use, and whenever a name 
is displayed, qualify it enough to distinguish it from all other names that 
could occur.

[snip]


-- 
Robert Ennals - 0798-904-3486 - http://thor.cam.ac.uk/~rje33/




Re: Library conventions

2000-06-23 Thread Marcin 'Qrczak' Kowalczyk

23 Jun 2000 16:57:48 GMT, Marcin 'Qrczak' Kowalczyk [EMAIL PROTECTED] pisze:

 * [...]

* Overloading by the monad (like MArray) allows adding instances for
  derived monads, without explicit lifting on each use.

-- 
 __("  Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/GCS/M d- s+:-- a23 C+++$ UL++$ P+++ L++$ E-
  ^^W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-





Re: Library conventions

2000-06-23 Thread Chris Okasaki

  These suffixes are doing namespace management, avoiding name clashes
  between different things that you want to call empty.  But Haskell
  already has a perfectly good language mechanism for doing this --
  the module system!  Why is emptyX preferable to X.empty?  The latter
  convention is much more flexible.
 
 I prefer recognizing common interfaces and making appropriate classes.
 It is more convenient and more flexible than qualified imports:
 
 [...reasons deleted...]

But classes and qualified imports are not in competition!  Suppose you
have two *classes* that both need/want the same name.  For example,
you may have a class of sequences and a class of finite maps that
both want to use an empty method.  Do you call one emptyS and the
other emptyFM?  Or do you disambiguate using qualified names?

You might say, "Neither!  Make a common superclass containing empty
and anything else common to both sequences and finite maps."  Unfortunately,
this doesn't work because type constructors for sequences and finite maps
both have different kinds and different constraints on their elements.


 I don't like modules that have to be imported qualified.

Can you be more specific?  I understand that you don't want to use
qualified names in those situations where a class would be a better
solution, but what about when classes alone don't solve the problem?

Chris





Re: Library conventions

2000-06-23 Thread Marcin 'Qrczak' Kowalczyk

Fri, 23 Jun 2000 14:11:04 -0400 (EDT), Chris Okasaki [EMAIL PROTECTED] pisze:

 Suppose you have two *classes* that both need/want the same name.
 For example, you may have a class of sequences and a class of finite
 maps that both want to use an empty method.  Do you call one emptyS
 and the other emptyFM?  Or do you disambiguate using qualified names?
 
 You might say, "Neither!  Make a common superclass containing empty
 and anything else common to both sequences and finite maps."

Depends on if there is a chance that the same piece of code would
be used for any of these types, disambiguated by a decision taken
elsewhere.

If yes, I would try to put them in a single class. If not, and if
making a class just for overloading looks silly, unfortunately people
have different opinions whether to add suffixes or use qualified names.

 Unfortunately, this doesn't work because type constructors for
 sequences and finite maps both have different kinds and different
 constraints on their elements.

It does work in this case:

classHasEmpty c   where empty :: c
instance HasEmpty [a] where empty = []
instance HasEmpty (FiniteMap k v) where empty = emptyFM

If constraints were needed here, they could be easily added to
instance contexts.

  I don't like modules that have to be imported qualified.
 
 Can you be more specific?

If some names clash with other modules, there is a tendence to
import the whole module qualified instead of deciding individually,
remembering which names can be used unqualified. Then some names are
unnecessarily long.

Not all modules provide only a type with operations on it.

The module Concurrent provides several kinds of references and streams.
Some of them are reexported from other modules, but QSem and QSemN
both originate from module Semaphore. If
waitQSem  :: QSem - IO ()
waitQSemN :: QSem - Int - IO ()
were to share a single name, they would have to be split to two modules
and imported separately instead of by just "import Concurrent".

Maybe even the interface of semaphores could be overloaded, although
it does not give much.
wait  :: Semaphore  s = s - IO ()
would be defined as waitQSem or \s - waitQSemN s 1, and
waitN :: SemaphoreN s = s - Int - IO ()
would have only one instance among types provided: waitQSemN. If
somebody wanted to share a semaphore with another language (provided
that concurrency eventually works for foreign calls), a foreign
binding to a foreign semaphore would make another instance.

I don't mind using short names and accidental clash for the name "wait"
between independent modules rarely used together, but I think that
Haskell modules are not good in parametrizing by large pieces of code.
I treat the import list as the function of entities used in the module,
not the opposite.

-- 
 __("  Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/GCS/M d- s+:-- a23 C+++$ UL++$ P+++ L++$ E-
  ^^W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK5? X- R tv-- b+++ DI D- G+ e h! r--%++ y-





Re: Library conventions

2000-06-23 Thread Sven Panne

I *knew* people couldn't resist talking about names! :-) OK, I've
invited you to do this, but more than a dozen mails solely about the
first item of section 1.1.1 were a little bit surprising...

To be more serious: Perhaps I wasn't clear enough about the purpose of
these conventions. What they're trying to describe is current practice
in hslibs, not what would be the best thing if they were rewritten
from scratch. Note that hslibs currently contains about 100 modules,
and there are probably lots of programs out there using this library
collection. Making fundamental changes like the replacement of
suffixes by qualification would break almost every single program
using hslibs. I doubt that a lot of people would cheerfully change
most of their programs they've written, not to mention the heart
attack SPJ would probably suffer... ;-) I remember the tons of mails
on the developer lists about an extremely simple change (to the
inaugurated: makeForeignObj).

Personally, I'm not a true believer in this whole prefixing/suffixing
business either. I've silently dropped the rl_ prefix from the names
in the Readline lib, nuked the gl/glu/glut prefix in my HOpenGL
binding, etc. But these were either seldom used or completely new
libs, you can't do this for hslibs in general. If we were living in a
better world, Haskell would have a more expressive module system
(i.e. parameterized, first class modules in non-flat name-space, etc.)
and people would have used it correctly from the start. But alas, we
have to live with the current state of things, at least for H98. For
Haskell 2 there should probably be a hslibs 2, too, incorporating what
we've learned from the design of the H98 libs.

To be more concrete: Although Set.empty vs. emptySet or IORef.update
vs. updateIORef seem to have some advantages, but things are not always
that simple: What about e.g. the xToY convention?  Or getEnv? (The
environment is not a separate type, much less an own module.) And what
about Integer.to? (Even if there was a module Integer, I'd prefer
toInteger.) It seems that we have to live with prefixes/suffixes in
one way or the other.

And note that even in their current (probably non-perfect) form the
conventions are of some use: They state clearly that e.g. readIORef is
the correct name (not getIORef), updateIORef returns (), stToIO is a
misnomer (should be sTToIO), makeStablePtr should better be named
newStablePtr, etc. Making a careful transition to a consistent scheme
within hslibs is likely to be non-trivial amount of work.

What I was hoping to get were some less drastic improvements of the
conventions, e.g. proposals for the names of non-monadic versions of
updateBlah, some guidelines when a type should live in its own module,
etc.

Cheers,
   Sven




Re: Library conventions

2000-06-23 Thread Michal Gajda

On Fri, 23 Jun 2000, Chris Okasaki wrote:
(...)
 Also, I've noticed a tendency to shorten the suffixes as much as
 possible (eg, emptyS or emptyFM), in which case you again quickly
 run into name clashes.
(...)
I agree, that is undesirable. Such names get cryptic and are usually
overlooked when searching for "stuff like this" in the library.

Michal Gajda
[EMAIL PROTECTED]





Library conventions

2000-06-22 Thread Sven Panne

After some discussions in the GHC developer mailing lists a small
bunch of conventions around library design emerged. Currently things
mainly concentrate on naming issues (everybody's delight :-), but it
is only meant as a starting point:

   http://www.informatik.uni-muenchen.de/~Sven.Panne/hslibs-intro.html

Please feel free to discuss, improve, and extend this proposal. If
the feedback is quick enough, the conventions could already make their
way into the upcoming final GHC 4.07 distribution, which would be a
good thing. Although some parts might sound a little bit narrow-minded,
keep in mind that we're not prescribing how to do things, but are
collecting folklore and good habits. A sound collection of conventions
improves readability of code, ease of use of a library, and last but
not least makes the life of a library writer easier.

Cheers,
   Sven