Ben Rudiak-Gould wrote:
Brian Hulley wrote:
Here is my proposed layout rule:

1) All layout keywords (where, of, let, do) must either be followed
by a single element of the corresponding block type, and explicit
block introduced by '{', or a layout block whose first line starts
on the *next* line

I wouldn't have much trouble adapting to that.

and whose indentation is accomplished *only* by tabs

You can't be serious. This would cause far more problems than the
current rule.

Why? Surely typing one tab is better than having to hit the spacebar 4 (or 8) times?


I would also make it that explicit braces are not allowed to switch
off the layout rule (ie they can be used within a layout),

I don't understand. What does "used within a layout" mean?

I meant that {;} would be used just like any other construct that has to respect the layout rule so you could write

      let
           a = let { b = 6; z = 77;
               h = 99;
                              p = 100} in b+z+h + p

etc but not:

      let
           a = let { b = 6; z = 77;
h = 99; -- this binding would be part of the outermost 'let'
                              p = 100} in b+z+h + p


multiline strings would not be permitted,

They aren't now, except with \ escapes. A stray " will be caught on
the same line unless the line happens to end with \ and the next line
happens to begin with \, which is exceedingly unusual.

and multiline comments would not be permitted
(pragmas could easily be used just by using --#)

But --# doesn't introduce a comment. And this would make UNPACK
pragmas rather inconvenient to use.

-- # but I hadn't thought about UNPACK...
The motivation in both points is to make it easy for an editor to determine which lines need to be re-parsed based on the number of leading tabs alone.


1) When you see a ';' you could immediately tell which block it
belongs to by looking backwards till the next '{'

I guess that might be helpful, but it doesn't seem easier than
looking left to the beginning of the current line and then up to the first
less-indented line.

There was an example posted on another thread where someone had got into confusion by using ; after a let binding in a do construct with an explicit brace after the 'do' but not after the 'let' (sorry I can't find it again). Also the current layout rule uses the notion of an implicit opening brace which is a to be regarded as a real opening brace as far as ';' in concerned but an unreal non-existent opening brace as far as '}' is concerned. Thus I think it is a real mix-up.


2) Variable width fonts can be used,

They can be used now, if you adhere to a certain style, but not
everyone likes that style. I wrote in C++ with a variable width font and tabs
at one time, but eventually went back to fixed width. One reason was
that I couldn't use comment layout conventions that tend (in my experience)
to improve readability more than monospacing hurts it. Another reason
was that glyph widths appropriate to natural languages didn't work
all that well for source code. Spaces are much more important in
source code than in natural language, for example. A proportional
font designed for source code would be nice, but I haven't found one
yet. Stroustrup used a mixture of proportional and monospaced glyphs
in _The C++ Programming Language_ and it worked well.
or different font faces to
represent different sorts of identifier eg class names, tycons, value
constructors, operators like `seq` as opposed to seq etc

Lots of editors do this with monospaced fonts; I think it's
orthogonal to the layout issue.

For example on Windows Trebuchet MS is a very nice font, also Verdana, both of which are not monospaced. But yes I agree it's not a major issue and I just see the option of being able to use them as a nice side-effect.


3) Using only tabs ensures that vertical alignment goes to the same
position on the screen regardless of the font and tabs could even
have different widths just like in a wordprocessor

Requiring tabs is a really bad idea. Just forget it. Seriously.

I'm really puzled here. I've been using tabs to indent my C++ code for at least 10 years and don't see the problem. The only problem would be if someone mixed tabs with spaces. Since it has to be either tabs only or spaces only I'd choose tabs only to save keystrokes. I suppose though it is always going to be a matter of personal taste...


4) Any keypress has a localised effect on the parse tree of the
buffer as a whole ( { " no longer kill everything which follows and
there would be no {- )

I don't understand why this is an advantage. If you have an editor
that highlights comments in green, then large sections of the program
will flash green while you type a {- -} comment, which might be
annoying, but it also means you'll never forget to close the comment,
so the practical benefit of forbidding {- -}, as opposed to simply
not typing it yourself, seems nil.

But it makes it much easier for the editor to determine where to start re-parsing from (see below). If you allow {- everything becomes a lot more complicated and who needs them anyway? In Visual C++ for example, you just select a block of text and type Control-K Control-C to put single line comments at the beginning of each line in the block. I think (apart from UNPACK) multi-line comments are just a left-over from very old days before single line comments were invented and editors had these simple macros built-in.


5) It paves the way for a much more immersive editing environment,
but I can't say more about this at the moment because I haven't
finished writing it yet and it will be a commercial product :-)))

I guess everything has been leading up to this, but my reaction is
that it renders the whole debate irrelevant. The only reason layout
exists in the first place is to make source code look good in
ordinary text editors. If you have a high-level source code editor that manipulates the AST,
then you don't need layout, or tabs, or any of that silly ASCII
stuff. The only time you need to worry about layout is when
interoperating with implementations that use the concrete syntax, and
then there's nothing to stop you from exporting in any style you
like. And when importing, there's no reason to place restrictions on
Haskell's layout rule, because the visual layout you display in the
editor need have no connection to the layout of the imported file.

Both 4) and 5) are because it is very much faster to type raw ASCII into an editor than to have to click on all kinds of boxes with the mouse. It is also surprisingly difficult to find an intuitive way of navigating a tree of boxes using only an ASCII keyboard, because of the conflict between the logical parent/child or sibling/sibling relationship and the way these could be laid out on the screen in 2d. Eg the right arrow could mean "go to the next sibling" but the next sibling may have to be laid out underneath the current node, so it all becomes very confusing. I don't think it is possible to lay out code in such a way that all parent/child relationships correspond to a vertical relationship on the screen, but possibly my thinking is too influenced by how programs are usually laid out.

Thus I don't think an editor that forced people to work directly with the AST would ever catch on. Years ago I read about a Microsoft Project on "intentional programming" which was about manipulating an arbitrary AST directly but afaik nothing came of it since it was just too painful to use. I also read about some research to do with deriving programs interactively from a proof, where clicking on boxes etc comes into its own, but I don't think there is yet any interactive proof system that comes close to being able to derive "real world" software. Certainly I'd be very interested to know if there is.

Currently all the ASCII editors I know of only do keyword highlighting, or occasional ("wait a second while I'm updating the buffer") identifier highlighting. What I'm trying to get however is complete grammatical highlighting and type checking that is instantaneous as the user types code, so this means that the highlighter/type checker needs a complete AST (with 'gap' nodes to represent spans of incomplete/bad syntax) to work from.

However it is way too expensive to re-parse the whole of a big buffer after every keypress (I tried it with a parser written in C++ to parse a variant of ML and even with the optimized build and as many algorithmic optimizations as I could think of it was just far too slow, and I wasn't even trying to highlight duplicate identifiers or do type inference)

Thus to get a fast responsive editing environment which needs to maintain a parse of the whole buffer to provide effective grammatical highlighting and not just trivial keyword highlighting it seems (to me) to be essential to be able to limit the effect of any keystroke especially when the user is just typing text from left to right but where there may be more stuff after the cursor eg if the user has gone back to editing a function at the top of a file. Things like {- would mean that all the parse trees for everything after it would have to be discarded. Also, flashing of highlighting on this scale could be very annoying for a user, so I'd rather just delete this particular possibility of the user getting annoyed when using my software :-) thus my hopeless attempts to convince everyone that {- is bad news all round :-)))

Of course you're right that for loading and saving files I could do Haskell -> My representation -> Haskell but then someone reading a tutorial on Haskell would find that my editor (or by the above arguments, any similar rich-feedback editor) didn't accept all the examples...


Using my self-imposed layout rule I'm currently editing all my
Haskell code in a standard text editor using tabs set to 4 spaces
and a variable width font and have no problems.

Which is the best argument for keeping the current rule! If it were
changed as you propose, then someday Hugh Briley would come along and
complain that Haskell's layout syntax squandered screen space---but
he *wouldn't* be able to program in his preferred style, because it would no longer be
allowed. Religious freedom is a good thing.

Freedom has many dimensions, some interdependent:

Simplifying the syntax by using a simpler layout rule would make it possible for people to create very efficient incremental parsers and in turn develop more responsive development environments for consensus Haskell, which in turn might lead to more people understanding and therefore using the language, more libraries, more possibilities for individual people to earn a living themselves by programming, more people thinking things out for themselves instead of absorbing corporate propaganda, thus fairer laws, justice, liberty, and *true human freedom* for all!!! :-)

Regards, Brian.

--------------------------------------------------------

"... flee from the Hall of Learning. This Hall is dangerous in its perfidious beauty, is needed but for thy probation. Beware, Lanoo, lest dazzled by illusive radiance thy soul should linger and be caught in its deceptive light." -- Voice of the Silence stanza 33
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to