Re: Beautifying Haskell programs (was: Re: pretty newby )

2003-09-24 Thread Wolfgang Jeltsch
Am Mittwoch, 24. September 2003, 18:01 schrieb Keith Wansbrough:
> [...]

> And your other point, Luc, about generating type signatures automatically,
> shows up something about your approach to debugging code.  You should always
> put the type signatures in as you go - preferably, before you write the
> function!  This is not just good design practice and good documentation, it
> helps you debug the function.  With type signatures, the compiler can see
> what you intended to write, and verify that what you did write matches it.
> Without type signatures, all it can see is that two things don't match - it
> has no idea what you meant to type.  Try it: try putting in type signatures,
> and see how much better the compiler's error messages become.

Let me add that there are situations where you don't want the most general 
type (which is yielded by type inference) as the type of a specific variable 
(which can be a function, of course).

One reason might be that the most general type doesn't fit your idea about 
what the variable (function) shall describe. You could, for example, describe 
mappings from keys to values as lists of key value pairs. An empty mapping 
would be implemented as []. The type of this would be infered as [a] but what 
you want is [(a,b)].

Another reason for giving a type signature with a restricted type is that you 
want to enforce certain constraints by the type system. A good example is 
Peter Thiemanns handling of HTML documents in his WASH/CGI software.

Note also that the asTypeOf function from the prelude is essentially the const 
function; the only difference is the type. It's the restricted type of 
asTypeOf that lets this function fulfill its purpose.

> Hope this helps..
>
> --KW 8-)

Wolfgang

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pretty newby

2003-09-24 Thread Malcolm Wallace
John Hughes <[EMAIL PROTECTED]> writes:

> The problem is that parsers in compilers don't keep track of comments.
> Instead they discard them at the first opportunity (during lexing).
>   ...  What's needed is a parser that can parse
> comments, and tie them to the *right place* in the abstract syntax tree.

Fortunately, there *is* one Haskell parser already which preserves
comments in the source code and links them properly to the surrounding
program structure, namely Haddock, the automatic-documentation
generator.  I expect Haddock would be a good place to start if one
wanted to develop a program re-formatter.

(Furthermore, if one were to add a type inference engine that
could fill-in missing type signatures in a program, that would be
highly useful for both Haddock and the hypothetical re-formatter.)

Regards,
Malcolm
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Beautifying Haskell programs (was: Re: pretty newby )

2003-09-24 Thread Keith Wansbrough
John Huges wrote:

> On Wed, 24 Sep 2003, Luc Taesch wrote:
> 
> > alos, Im surprised that this bland issue has not already been solved (PP
> > lib paper looks dated 96). no offence intended, but aas im newbie, i
[..]
> 
> As the author of the 96 paper (wasn't it 95?), let me defend it a bit, or
> at least explain what it offers, and what it does not.

I think the reason it "looks dated" is that it pretty much solved the
problem it was addressing.  For pretty-printing data structures, the
solution given in that paper does a rather good job, is configurable
in the ways you might want to configure it, and is fairly easy to use
and understand.  No one has needed to invent a new way of doing it
since.


Regarding beautifying Haskell programs: as John says, it's not
straightforward.  But I think the reason that there isn't such a thing
is that most people don't need it.  We mostly use editors that allow
us to get the indentation right, automatically, as we type the source
in, and we take care to preserve it as we edit, because it makes the
code easier to understand.

(note that there *are* tools for producing beautified documentation:
Haddock lists exports, type definitions, type signatures, and argument
and function documentation in HTML format, but it doesn't deal with
actual code).

And your other point, Luc, about generating type signatures
automatically, shows up something about your approach to debugging
code.  You should always put the type signatures in as you go -
preferably, before you write the function!  This is not just good
design practice and good documentation, it helps you debug the
function.  With type signatures, the compiler can see what you
intended to write, and verify that what you did write matches it.
Without type signatures, all it can see is that two things don't match
- it has no idea what you meant to type.  Try it: try putting in type
signatures, and see how much better the compiler's error messages
become.

Hope this helps..

--KW 8-)

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pretty newby

2003-09-24 Thread Frank Atanassow
On woensdag, sep 24, 2003, at 17:46 Europe/Amsterdam, John Hughes wrote:
What's needed is a parser that can parse
comments, and tie them to the *right place* in the abstract syntax 
tree.
Figuring out what a comment is really commenting is probably extremely
hard...
The commenting conventions of Haddock serve this purpose pretty well. 
And Haddock's parser must hold onto the comments to do its job. Maybe 
that's a good place to start on a Haskell pretty-printer.

Regards,
Frank
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pretty newby

2003-09-24 Thread John Hughes
On Wed, 24 Sep 2003, Luc Taesch wrote:

> alos, Im surprised that this bland issue has not already been solved (PP
> lib paper looks dated 96). no offence intended, but aas im newbie, i
> wonder what am i missing ? what is different in the process of creation
> so that this need did not arised already? i should admint i'm puzzled,
> given the facilities at hand...

As the author of the 96 paper (wasn't it 95?), let me defend it a bit, or
at least explain what it offers, and what it does not.

The problem I was solving in that was paper was how to pretty-print
*data-structures* from inside a program. That includes abstract syntax
trees in compilers -- in fact, that's maybe the most important
application. The library is used in GHC, for example, to pretty-print
programs at various stages, after varying degrees of transformation. You
the user can see what the compiler has produced after each phase, and you
see it laid out in a readable format.

Pretty-printing data-structures is quite different from pretty-printing
*programs* -- we should have two different words for it, really! When you
pretty-print a program, you just want to change the layout in an existing
text, and comments etc. ought to be preserved and appear in sensible
places afterwards. When we pretty-print programs, there is an input (the
program as you wrote it) to take into account. When you pretty-print a
data-structure, you're just trying to output something produced by a
program... there is no "input" it was produced from which the
pretty-printed output ought to resemble.

So, if you want to see what GHC has produced after phase X, then the
pretty-printing library is appropriate. Of course, if there were comments
in the program you wrote, then you ought to realise the compiler discarded
them early, and you should not expect them to appear in the result of
various transformations/optimisations.

But if you want to standardise the layout of a program you wrote, then
this is no good. The pretty-printing library is not sufficient to do this
by itself... it solves a different problem. It is possible to BUILD a
program pretty-printer using the library (although this is not the only
possible approach), but it requires combining the library with a parser
which loses no information, in particular including comments at the
appropriate places in abstract syntax trees, so that they are a part of
the data structure being pretty-printed.

The problem is that parsers in compilers don't keep track of comments...
instead they discard them at the first opportunity (during lexing). Thus
such a parser, combined with a pretty-printer, cannot solve the *program
pretty-printing* problem.  What's needed is a parser that can parse
comments, and tie them to the *right place* in the abstract syntax tree.
Figuring out what a comment is really commenting is probably extremely
hard... But without an AST with attached comments in the right places, my
pretty-printing library, and Simon PJ's extension, are useless.

That said, maybe it is surprising that no good Haskell pretty-printer has
appeared yet, especially given the importance of layout in the language.
Why not write one? I dare say there would be many users, and no doubt you
could publish a paper at the Haskell Workshop...

John Hughes

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pretty newby

2003-09-24 Thread Luc Taesch
Thanks. i understand that a2ps is rather for printing.
What I had in mind what to pp my own programs, to clean the source layout, rather.

The process i used in other context is  to hack , without really taking care of the 
layout ( say getting distracted by) , and once i got a resonalble level of stability, 
i cleaned the program, using a pp;

ideally in haskell, this would add the typing for me, also. ( still havent made my 
religion if that's cool to have the typing on top of the definition, or not, but at 
least for doc generation purpose, that's good.) 
feedback on that ?

so the two gain i was expecting were : 
- cleaning the layout, after i removed all the debugging code
- generating the type 

but i understood from Per from that the parser would not take care of the comments. ( 
not take care, or remove , btw ?).

alos, Im surprised that this bland issue has not already been solved (PP lib paper 
looks dated 96). no  offence intended, but aas im newbie, i wonder what am i missing ? 
what is different in the process of creation so that this need did not arised already? 
i should admint i'm puzzled, given the facilities at hand...


> Alle 16:05, martedì 23 settembre 2003, Luc Taesch ha scritto:
> > are there any facility to pretty print an haskell program ?
> 
> If what you need is an external program and not a library, have a look 
> at GNU a2ps.
> 
> Vincenzo
> 
> ___
> Haskell mailing list
> [EMAIL PROTECTED]
> http://www.haskell.org/mailman/listinfo/haskell

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pretty newby

2003-09-23 Thread Nick Name
Alle 16:05, martedì 23 settembre 2003, Luc Taesch ha scritto:
> are there any facility to pretty print an haskell program ?

If what you need is an external program and not a library, have a look 
at GNU a2ps.

Vincenzo

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pretty newby

2003-09-23 Thread Per Larsson
On Tuesday 23 September 2003 16.05, Luc Taesch wrote:
> are there any facility to pretty print an haskell program ?
> im aware of HPJ combinators library, but i was looking for a command line
> utility, rather.. am i missing an entry in HPJ ?
>
> thanks
> Luc
> ___
> Haskell mailing list
> [EMAIL PROTECTED]
> http://www.haskell.org/mailman/listinfo/haskell

Hi,
In GHC (and HUGS?) you can use the 'haskell-src' package which contains
functions for parsing and pretty-printing haskell code. Using these, it only 
takes a couple of lines to make your own command line, pretty-printer for 
haskell code. If you want to, you can use my implementation which I attach to 
this mail. The problem with the parser, however, is that it doesn't handle 
comments at all.

Regards
Per-- FILE: HsIndent.hs
-- AUTH: Per Larsson
-- DATE: 03/10/2003
-- CODE: Haskell Code

module Main where

import System.Environment
import System.Exit
import System.IO
import Control.Monad
import Language.Haskell.Parser
import Language.Haskell.Pretty
import System.Console.GetOpt

header  = "hsindent [OPTION ...] FILE"
version = "hsindent 1.0"
usage   = usageInfo header options

data Config = Config {showHelp, showVersion :: Bool, pmode :: PPHsMode}
 
defaultConfig = Config False False defaultStyle

defaultStyle :: PPHsMode
defaultStyle = PPHsMode { 
classIndent = 8,
doIndent = 3,
caseIndent = 5,
letIndent = 4,
whereIndent = 6,
onsideIndent = 2,
spacing = True,
layout = PPOffsideRule,
linePragmas = False,
comments = True
  }

options :: [OptDescr (Config -> Config)]
options = 
[ opt 'h' "help" "print this help information and exit" 
  (\c -> c {showHelp = True}) 
, opt 'v' "version" "print version information and exit"
  (\c -> c {showVersion = True})
, opt 'u' "nospacing" "don't insert blank lines"
  (\c -> c {pmode = (pmode c) {spacing = False}})
, opt 'p' "pragmas"  "insert source pragmas" 
  (\c -> c {pmode = (pmode c) {linePragmas = True}})
, opt 'e' "comments"  "keep comments" 
  (\c -> c {pmode = (pmode c) {comments = True}}) 
, arg 's' "class" "N" "indent class declarations N columns" 
  (\s c -> c {pmode = (pmode c) {classIndent = read s}})
, arg 'd' "do" "N" "indent do expressions N columns"
  (\s c -> c {pmode = (pmode c) {doIndent = read s}}) 
, arg 'w' "where" "N" "indent where expressions N columns" 
  (\s c -> c {pmode = (pmode c) {whereIndent = read s}})
, arg 'l' "let" "N" "indent let expressions N columns"
  (\s c -> c {pmode = (pmode c) {letIndent = read s}})
, arg 'c' "case" "N" "indent case expressions N columns" 
  (\s c -> c {pmode = (pmode c) {caseIndent = read s}})
, arg 'o' "onside" "N" "indent at line continuations N columns" 
  (\s c -> c {pmode = (pmode c) {onsideIndent = read s}})
, arg 'y' "layout"  "ARG" "set layout style to ARG, one of\n\
  \ 'OffsideRule', 'SemiColon', 'Inline' or 'NoLayout'"
  (\s c -> c {pmode = (pmode c) {layout = toLayout s}})  
] 
   where
   opt short long msg update = 
   Option [short] [long] (NoArg update) msg
   arg short long argdescr msg update = 
   Option [short] [long] (ReqArg update argdescr) msg
  
toLayout :: String -> PPLayout
toLayout "OffsideRule" = PPOffsideRule
toLayout "SemiColon"   = PPSemiColon
toLayout "InLine"  = PPInLine
toLayout "NoLayout"= PPNoLayout
toLayout _ = error "toLayout"

--   

main = do 
args <- getArgs
(conf,files) <- case getOpt Permute options args of
(o,n,[])   -> return (foldr ($) defaultConfig o, n)
(_,_,errs) -> error (concat errs ++ usageInfo header options) 
when (showHelp conf) (exitSuccess usage)
when (showVersion conf) (exitSuccess version)
unless (length files == 1) (exitFail usage)
file <- return (head files)
h <- openFile file ReadMode
s <- hGetContents h
result <- return (parseModuleWithMode (ParseMode file) s)
case result of
ParseOk hsModule -> 
exitSuccess (prettyPrintWithMode (pmode conf) hsModule)
ParseFailed pos msg -> 
exitFail ("Parse Error at: " ++ show pos ++ "\n " ++ show msg)
where 
exitSuccess msg = (putStrLn msg >> exitWith ExitSuccess)
exitFail msg = (putStrLn msg >> exitFailure)
 


___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: pretty newby

2003-09-23 Thread Malcolm Wallace
Luc Taesch <[EMAIL PROTECTED]> writes:

> are there any facility to pretty print an haskell program ?
> im aware of HPJ combinators library, but i was looking for a command line
> utility, rather.. am i missing an entry in HPJ ?

To some extent, you can use an ordinary Haskell compiler to
pretty-print your Haskell code.  For instance, among the various
debugging options in nhc98, the compiler has the option
+CTS -parse -CTS
to show the abstract syntax tree of a module immediately after parsing it.
(Other options show the syntax tree at other stages of the compilation,
such as after desugaring of field-syntax, type-checking, etc.)
I'm sure that ghc must have something similar.

In nhc98 there are also various options to control the 'look' of the
output of the pretty-printer, e.g.
-showqualified
-noshowqualified
-showwidth=80
-showident=4

Regards,
Malcolm
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell