Re: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Erik Meijer

> Personally I find the convention of using `a', `b', and `c' for type
> variables to be a poor one.  I much prefer using `t' (if there's
> only one) or `t1', `t2', ... (if there's more than one).
> I find that for me this makes it much easier to read type declarations,
> because names like `a', `b', and `c' sound like values, whereas names
> like `t1', `t2', and `t3' suggest types.

I *love* to use the same name for type variables and term variables, as in 

f :: a -> a
f = \a -> a

I also love to use the same name for type constructors and value constructors, as in

data Foo a = Foo a

Erik






Re: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Christian Sievers

> So, the name of a type is always at least a full word, as are the names of
> specific functions.  But type variables are almost always single
> characters, and distinct from the names of any type.  Conventionally, they
> are also usually "a", "b", and "c", although "m" is for monad.
> Conventionally also, generic function arguments are "f" and "g", the
> conventional predicate is "p". Generic arguments are "x" and "y" (or "xs"
> and "ys" if they are lists); arguments with specified types are usually
> the first letter of their type name (e.g., "c" for Char, "i" for an Int;
> "n" and "m" are indices)... that covers most of it, I think.

I've never thought about a difference between i (and j) on the one
hand and n and m on the other, besides I would use i, j more locally,
if there were such a difference. So I might use i<-[1..n], but would
nearly never use  n<-[1..i].
If I don't do pattern matching on a list, I sometimes use l.
Otherwise, I use (a:as) as well as (x:xs) for lists.
I'm in trouble when it comes to @-patterns: is xs@(x:_) acceptable?
For non-integral numbers, I often use x, y.

> I think most of the Haskell code I've ever seen that *wasn't* written by
> me follow these conventions pretty closely.  But the strange thing is...I
> haven't found a prominent place on, e.g., the Haskell home page where this
> is spelled out. (Please tell me if I'm missing anything obvious.) In a
> way, I guess this is trivial, but I know from hard experience it can often
> take a long time to become completely aware of trivial things.

I've seen the (x:xs) (or whatever letter you want, BTW I'd use (f:fs)
for a list of functions) convention written somewhere. Most of the
rest is what is usually used in mathematics or is done in any computer 
language (such as c for Char).
Yes, a list of these things might be helpful.


Christian Sievers





Re: make-like facilities (Was: Re: How to murder a cat)

1999-06-11 Thread D. Tweed

On Fri, 11 Jun 1999, Malcolm Wallace wrote:

> Well, compiler-independent is possible (e.g. hmake extracts
> dependencies from any Haskell sources, regardless of compiler.)
> However, language-independent is much more difficult.  How could one
> tool deal with all of C, C++, Haskell, and LaTeX?  Since each language
> has different lexical/parsing rules, not to mention different semantic
> notions of imports or inclusions, it seems to me that the only
> component of such a tool that would be common to all languages is the
> core dependency-graph analyser.

I wasn't thinking of something that would do all of the above at once but
rather a `library-like' base that people could slot into their own code
for determining from a given file what inferences & further checks should
be done from it. Presumably there'd be some common categories, eg,

* included file where changes don't force recompile

* included file where changes do force recompile
 
* file => dependency on (included file basename).(particular extension) if
it exists (eg .h generally implies depends on .o if it exists)

* check file at compile time for regexp (eg `Rerun to get references
correct')

etc,etc.

Being honest though I haven't given it any serious thought (and don't
propose to any time this side of submitting :-) ) 

___cheers,_dave__
email: [EMAIL PROTECTED]   "`What sort of people would we be if
www.cs.bris.ac.uk/~tweed/pi.htmwe didn't go into the Library?'
work tel: (0117) 954-5253 `Students.' -- Terry Pratchett







Re: how to write a simple cat

1999-06-11 Thread Friedrich Dominicus

> >I disagree, small scripts spend most of the time doing I/O if I don't
> >understand how to do that I'm not able to even write the most simple
> >things. This is eg. true for my cat ...
> 
> I disagree. You need to know more about Functional Programming
> (and also the Haskell type system and its IO system) before
> you should try to solve your problems. It's like you want
> to drive without knowing anything about the engine, brakes, ...

What a comparison. I've nearly learned the languages I know of while
trying to solve  problems which come it's way. And this was just one
problem I were not able to figure out. It is trivial and don't expect
too much, so it was a good think trying out.

> 
> There are many great introductory books which would
> give you an idea about some of the basic building blocks
> of "functional" software development.

I have tow of them: "Structure and interpretation of Computer Programs"
and "The Craft of FP programming using Haskell" The example I choose can
be found in Chapter 17 and it did not work this way, and what was is a
simple cat. So I asked why that example didn't work. I got very good and
interesting answers and have said thanks.



> 
> I think both versions are really simple to write.

The may be of somone who knows FH, they are damn hard for someone
lacking that knowledge. If you are planning to write an Eiffel program
you and you have such a trouble with that problem in Eiffel you are very
welcome to send a note to the Eiffel- mailing lists. I don't think that
you will get an answer, first learn OOP than  ask

Regards
Friedrich





make-like facilities (Was: Re: How to murder a cat)

1999-06-11 Thread Malcolm Wallace

David Tweed writes:

> > $ gcc -M main.c   >>Makefile
> > $ ghc -M Main.hs  >>Makefile
> > $ hmake -M MyProg >>Makefile
>  
> Since several people have pointed out the -M option for gcc I'd better
> explain that, for reasons of no interest to Haskell users, when tackling
> _C++_ it produces dependencies which are much, much worse than they could
> be (at least for me). 
>  
> Purely personally, I'd find it easier to have a tool that was independent
> of the compiler to customise, which could also be extended to other
> things, eg, latex, that don't have a -M option. 

Well, compiler-independent is possible (e.g. hmake extracts
dependencies from any Haskell sources, regardless of compiler.)
However, language-independent is much more difficult.  How could one
tool deal with all of C, C++, Haskell, and LaTeX?  Since each language
has different lexical/parsing rules, not to mention different semantic
notions of imports or inclusions, it seems to me that the only
component of such a tool that would be common to all languages is the
core dependency-graph analyser.

Regards,
Malcolm






Re: How to murder a cat

1999-06-11 Thread D. Tweed

[drifting off-topic]
On Fri, 11 Jun 1999, Malcolm Wallace wrote:

> David Tweed writes:
> 
> > I think it'd probably better software engineering to split the two tasks. 
> > Other than a rather nasty syntax, make does what it sets out to do quite
> > well:  using specified dependencies and time-stamps on files to run
> > `compilation-type' processes in an appropriate way. What would, as you
> > say, be very nice is a tool which can be run periodically to auto-generate
> > these dependencies.
> 
> $ gcc -M main.c   >>Makefile
> $ ghc -M Main.hs  >>Makefile
> $ hmake -M MyProg >>Makefile

Since several people have pointed out the -M option for gcc I'd better
explain that, for reasons of no interest to Haskell users, when tackling
_C++_ it produces dependencies which are much, much worse than they could
be (at least for me). 

Purely personally, I'd find it easier to have a tool that was independent
of the compiler to customise, which could also be extended to other
things, eg, latex, that don't have a -M option. 

___cheers,_dave__
email: [EMAIL PROTECTED]   "`What sort of people would we be if
www.cs.bris.ac.uk/~tweed/pi.htmwe didn't go into the Library?'
work tel: (0117) 954-5253 `Students.' -- Terry Pratchett






Re: How to murder a cat

1999-06-11 Thread Malcolm Wallace

On Thu, 10 Jun 1999, Craig Dickson wrote:
 
> programming, especially lazy functional programming. If it seems desireable
> to re-implement a standard Unix utility in Haskell, I suggest 'make'. One
> could even design and implement a 'make' that would know all about Haskell
> modules, and parse them to generate dependencies automatically.

$ hmake MyProg

[ Announcement: `hmake' release 1.0, sources now available: ]
[http://www.cs.york.ac.uk/fp/hmake/ ]
 
David Tweed writes:

> I think it'd probably better software engineering to split the two tasks. 
> Other than a rather nasty syntax, make does what it sets out to do quite
> well:  using specified dependencies and time-stamps on files to run
> `compilation-type' processes in an appropriate way. What would, as you
> say, be very nice is a tool which can be run periodically to auto-generate
> these dependencies.

$ gcc -M main.c   >>Makefile
$ ghc -M Main.hs  >>Makefile
$ hmake -M MyProg >>Makefile

Regards,
Malcolm






Re: Projects using HUGS or Haskell

1999-06-11 Thread Wolfram Kahl

Simon Peyton-Jones <[EMAIL PROTECTED]> writes:
 > What I have not done (any volunteers) is to export these rules, or
 > the function definitions to a thm prover.  

I am in the course of exporting function definitions
(and later probably also rules)
to the term graph transformation system HOPS
(
  URL: http://www2.informatik.unibw-muenchen.de/kahl/HOPS/
)
which can also be considered as a fledgling theorem prover ---
anyway I expect the problems to be essentially the same.

I am trying to finish a short summary next week...

Wolfram






Re: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Keith Wansbrough

Jonathan King writes:

> So, the name of a type is always at least a full word, as are the names of
> specific functions.  But type variables are almost always single
> characters, and distinct from the names of any type.  Conventionally, they
> are also usually "a", "b", and "c", although "m" is for monad.
> Conventionally also, generic function arguments are "f" and "g", the
> conventional predicate is "p". Generic arguments are "x" and "y" (or "xs"
> and "ys" if they are lists); arguments with specified types are usually
> the first letter of their type name (e.g., "c" for Char, "i" for an Int;
> "n" and "m" are indices)... that covers most of it, I think.
> 
> I think most of the Haskell code I've ever seen that *wasn't* written by
> me follow these conventions pretty closely.  But the strange thing is...I
> haven't found a prominent place on, e.g., the Haskell home page where this
> is spelled out. (Please tell me if I'm missing anything obvious.) In a
> way, I guess this is trivial, but I know from hard experience it can often
> take a long time to become completely aware of trivial things.

I think this kind of thing is valuable... Hungarian notation [1] serves the same 
purpose in Windows C / C++ programming.  It *is* valuable having canonical variable 
names for most situations; it reduces the intellectual load on the (human) reader of 
the code... you don't have to check back to the type signature and argument list to 
figure out what a particular variable denotes; it's just obvious from the name.

--KW 8-)


[1] @Article{
   Simonyi*91:Hungarian,
   author="Charles Simonyi and Martin Heller",
   title="The {H}ungarian Revolution",
   journal="{BYTE}",
   year="1991",
   volume="16",
   number="8",
   pages="{131--138}",
   month=aug,
   abstract="For all the attention given to names in the literature and
  magic (for to name a thing is to control it), names in programming
  languages have received curiously little attention.  Although
  today's computer programming languages force a rigid syntax on
  the programmer, they permit the use of more or less arbitrary
  names for variables, functions, and macros.  A reasonable standard
  for variable naming helps the development and maintenance of
  software.",
}


-- 
: Keith Wansbrough, MSc, BSc(Hons) (Auckland) :
: PhD Student, Computer Laboratory, University of Cambridge, England. :
:  (and recently of the University of Glasgow, Scotland. [><] )   :
: Native of Antipodean Auckland, New Zealand: 174d47' E, 36d55' S.:
: http://www.cl.cam.ac.uk/users/kw217/  mailto:[EMAIL PROTECTED] :
:-:







RE: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Frank A. Christoph

Jonathan King wrote:
> >   transformListElems :: (elem -> elem') -> List elem -> List elem'
> >   transformListElems transform Nil = Nil
> >   transformListElems transform (Cons elem elemRest) =
> > Cons (transform elem) (transformListElems transform elemRest)
>
> Well, the second version does more than just use descriptive variable
> names (and some not very descriptive, for that matter).  It also spells
> out constructors, has an especially long-winded function name, and uses
> one name for both a type variable and an argument (and a "primed" version
> for a second type variable).

Heh. :) I agree that using different constructor names is probably going
overboard, but when I look at industrial-strength C++ code it is not at all
uncommon to see such long-winded, redundant definitions, although they
usually aren't so polymorphic.

> You point out that short variable names keep code segments short, but my
> take on the why Haskell seems to "prefer" short names in many situations
> is that they are easier to think of as being *generic*.  (Intuitively,
> when you make a concept something more specific, it tends to get a longer
> name.)

That thought occurred to me too, but I had to reject it. Variable names can
be chosen in at least two ways: according to their domain (e.g., "File," or
less concretely, "f"), or according to the role they play in the definition
in question (e.g., "elem" or "kont"). If the variable is completely
polymorphic (or generalized), then its domain is essentially unrestricted,
but it still has a particular role to play.

Maybe a better motivation/explanation is simply that the descriptiveness of
a variable name is typically inversely proportional to the size of its
scope, where, realistically, the measure of scope size should involve both
textual length and expression size.

> > Of course, for more involved definitions, it is better to use
> > descriptive names.
>
> Well, for more specific definitions, anyway.  If I've got the style right.

For more specific definitions too. But if, say, you reimplemented a function
with a more efficient algorithm, you might be persuaded to use more
descriptive names, at least internally. But maybe you're right and
"specific" is more specific than "involved." :)

--FC






Re: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Jan Skibinski



On Fri, 11 Jun 1999, Craig Dickson wrote:

> I don't see that underscores serve readability in the same way as Hungarian
> notation purports to (unless the Eiffel people claim that underscores
> somehow convey type information?), so I don't see a conflict here. One could
> easily use both, e.g. n_widget_count for an integer value.

The only readability advantage of underscores is when
someone starts including abbreviations within the names.
PAToVA?
PAtoVA?
PA_to_VA? [Whatever PA and VA means]

Often such abbreviations are not justifyable, but
some might be well known and accepted
within a given project.

What is important is a consistency - as you pointed it out
when speaking about "my", "own", "a" (
Smalltalk uses it too for local variables)
"the", etc.

But what really counts and is well stressed in Eiffel
are two things:
- avoid duality caused by side effects; that is: "set"
  type procedures never-never return anything but void.
 
  In low-level C programming practises people
  often oversuse the mixed "get-set" approach.
  Sometimes one does not have a choice (efficiency reasons)
  but often it is just a matter of bad habits. 
  Fortunatelly, Haskell does not have this sort of problems.
  
- document your routines according to return types:
void - verbs to indicate actions [perhaps monads in
   Haskell?]
bool - "True if .." or "Is ... ?"
other objects - nouns (possibly with adjectives) 

Looking back on what Prelude does - I do not think
there is any consistent naming rule with respect
to a noun-verb question. 

Jan







Re: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Craig Dickson

Christian Sievers <[EMAIL PROTECTED]> wrote:

> I'm in trouble when it comes to @-patterns: is xs@(x:_) acceptable?

I'm sure I've used that, or something quite like it. xs is the whole list,
and x is its head.

> I've seen the (x:xs) (or whatever letter you want, BTW I'd use (f:fs)
> for a list of functions) convention written somewhere.

Its use is recommended in the Gentle Introduction to Haskell.

Craig







Re: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Jonathan King


On Fri, 11 Jun 1999, Jan Skibinski wrote:
>
>Keith Wansbrough <[EMAIL PROTECTED]>, 
> >
> > [[EMAIL PROTECTED] wrote stuff but got snipped]
> > >
> > > [stuff about whether there was a Haskell coding convention snipped]
> > 
> > I think this kind of thing is valuable... Hungarian notation [1] 
> >
> > [virtues of Hungarian notation extolled]
> >
>   But there are some stylistic camps, such as Eiffel's, that
>   prefer names with underscores rather than Hungarian notation
>   - claiming exactly the same reason: better readability. :-)

Yes, I guess what I posted did invite this kind of religious outpouring.
:-)  

But I really *did* want to know whether there were in fact a set of
Haskell coding conventions or a set of style suggestions published
somewhere on the net or elsewhere.  Is there?  I've looked in the FAQ, on
the Hugs and GHC sites, and other places.  What the Prelude style is does
seem pretty clear, and people are always pointed to it as an example of
good Haskell code, but there are dense people out there (e.g., me) who
might benefit from also seeing that style documented somewhere, as I'm
guessing it surely is.

jking






Re: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Jan Skibinski



> I think this kind of thing is valuable... Hungarian notation [1] 
> serves the same purpose in Windows C / C++ programming.  It *is* 
> valuable having canonical variable names for most situations; it reduces
the
> intellectual load on the (human) reader of the code... you don't have to
> check back to the type signature and argument list to figure out what a
> particular variable denotes; it's just obvious from the name.

But there are some stylistic camps, such as Eiffel's, that
prefer names with underscores rather than Hungarian notation
- claiming exactly the same reason: better readability. :-)

Jan







Re: Haskell conventions (was: RE: how to write a simple cat)

1999-06-11 Thread Craig Dickson

Jan Skibinski <[EMAIL PROTECTED]> wrote:

> But there are some stylistic camps, such as Eiffel's, that
> prefer names with underscores rather than Hungarian notation
> - claiming exactly the same reason: better readability. :-)

I don't see that underscores serve readability in the same way as Hungarian
notation purports to (unless the Eiffel people claim that underscores
somehow convey type information?), so I don't see a conflict here. One could
easily use both, e.g. n_widget_count for an integer value.

Whether underscores are better than mixed case, or whether Hungarian
notation is useful, seem to be matters of personal taste, not of fact. I
personally don't see much advantage to either underscores or mixed case
(except in C++, where many programmers tend towards such lengthy names that
the use of mixed case instead of underscores is actually helpful in keeping
identifier lengths under control). I use Hungarian notation only in C/C++,
and only when writing specifically for MS Windows, simply because that's the
convention on that platform (all of MS's documentation and samples use it).
I tend to think (getting off topic here) that Hungarian notation is fairly
useless; I'd rather know something about the scope of a variable (e.g. is it
a global? file-static? class member? static class member? local? static
local? In C++ there are so many possibilities! And that's not even
considering "const", "mutable", "volatile"...) so that I can see what the
variable relates to and how widely-felt the effects of changing it might be.
One company I worked at a few years back had a cute prefix scheme for this:
non-static member variables were prefixed "my" (i.e. owned by a single
object), static members "our" (i.e. shared by a class of objects), globals
and file-statics "the" (i.e. there can only be one), and locals "a" or "an"
(depending, of course, on whether the variable name began with a consonant
or a vowel). In practice, this seemed to my then-co-workers and me to be far
more helpful than Hungarian notation.

Craig







Re: How to murder a cat

1999-06-11 Thread Fergus Henderson

On 10-Jun-1999, D. Tweed <[EMAIL PROTECTED]> wrote:
> On Thu, 10 Jun 1999, Craig Dickson wrote:
> 
> > If it seems desireable
> > to re-implement a standard Unix utility in Haskell, I suggest 'make'. One
> > could even design and implement a 'make' that would know all about Haskell
> > modules, and parse them to generate dependencies automatically.
> 
> I think it'd probably better software engineering to split the two tasks. 
> Other than a rather nasty syntax, make does what it sets out to do quite
> well:  using specified dependencies and time-stamps on files to run
> `compilation-type' processes in an appropriate way.

I agree the tasks should be split, but I have to object to any claim that
standard Unix make does its job well.  Standard make has a number of
severe flaws over and above its nasty syntax -- lack of programmability,
no support for dynamic dependencies, no support for conditional inclusion,
lack of support for transitive dependencies, lack of support for makefile
code reuse, very limited support for polymorphism or abstraction,
lack of static checking (e.g. mispelt variable names are silently ignored),
and so on.  All of these are very important for "compilation-type processes".

More modern make programs, in particular GNU Make, certainly do a better job.
But even GNU Make still suffers from nasty syntax, lack of programmability,
limited support for dynamic dependencies, and inefficient and cumbersome
support for datestamp files to avoid unnecessary rebuilding, and a few bugs.

(GNU Make does however support parallel make, and this feature is sufficiently
important, and sufficiently difficult to program, that writing a improved
replacement for GNU Make would be a fairly significant amount of work.)

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
WWW:   |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.





RE: Projects using HUGS or Haskell

1999-06-11 Thread Simon Peyton-Jones


> Idea 1:
> Export Haskell declarations to a theorem prover, such as HOL 
> or PVS. Then
> permit the user of the theorem prover to state and prove 
> properties of the
> Haskell program, using the exported definitions.
> 
> Ideas 2:
> 
> There was recently a discussion about adding "rules" to 
> Haskell, that document
> the properties that are desired from a class. How about adding such
> annotations (perhaps as some kind of special comment syntax). These
> additions would be without any semantic content *to Haskell*. However,
> the rules could also be exported to HOL, PVS, ..., so that a theorem
> prover could be used to discharge these proof obligations.

Good ideas.

Indeed the RULES that I've added to GHC (in the CVS tree but not
in a 4.xx release yet) take exactly this form:

{-# RULES
"app1"  forall xs . xs ++ [] = xs
 #-}


What I have not done (any volunteers) is to export these rules, or
the function definitions to a thm prover.  

Simon





RE: strict data field

1999-06-11 Thread Simon Peyton-Jones

> Here is my situation:  I have a state monad.  It seems to me that
> if states are built out of lazy types, then there may be many
> states all live at the same time, thus blowing up the space.
> But deep in my state data types, I have strings.  Also some
> monad operations return strings.  So I need strict strings.
> 
> In case I haven't made this clear, here is an example:
> 
> example = 
>   do some_string <- a_function_of_state
>modify_the_state
>modify_the_state_some_more
>do_something_with_a_string some_string
> 
> Now if I run example on a state s0, then s0 will be live throughout
> the execution of example, whereas, if "a_function_of_state" returned
> a completely evaluated data structure and a completely updated the
> state, then the parts of s0 that are not shared should be collectable.

It depends on the particular state monad.  In the GHC/Hugs libraries,

IO and ST are strict
LazyST is lazy

A strict state monad means is that there is only one state.
So in your program, modify_the_state won't happen until a_function_of_state
has exectued at least all stuff which affects the state. The
"strict" part is that all computations are strict in the state.
So modify_the_state evaluates its input state, forcing all the earlier
statful
operations to take place.

Of course, some_string might still have unevaluated thunks that
don't involve the state.

Simon