Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.compilers > #999 > unrolled thread

Programming language and IDE design

Started byMartin Ward <martin@gkc.org.uk>
First post2013-10-17 11:06 +0100
Last post2013-10-24 19:57 -0400
Articles 17 — 9 participants

Back to article view | Back to comp.compilers


Contents

  Programming language and IDE design Martin Ward <martin@gkc.org.uk> - 2013-10-17 11:06 +0100
    Re: Programming language and IDE design "BartC" <bc@freeuk.com> - 2013-10-19 22:05 +0100
      Re: Programming language and IDE design Martin Ward <martin@gkc.org.uk> - 2013-11-07 19:40 +0000
        Re: Programming language and IDE design glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-11-08 05:21 +0000
        Re: Programming language and IDE design Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2013-11-08 06:45 +0100
        Re: Programming language and IDE design George Neuner <gneuner2@comcast.net> - 2013-11-08 16:04 -0500
        Re: Programming language and IDE design "Jonathan Thornburg" <jthorn@astro.indiana.edu> - 2013-11-10 04:41 +0000
    Re: Programming language and IDE design Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2013-10-20 03:22 +0200
    Re: Programming language and IDE design Gene Wirchenko <genew@telus.net> - 2013-10-20 14:03 -0700
      Re: Programming language and IDE design Gene Wirchenko <genew@telus.net> - 2013-10-21 14:44 -0700
    Re: Programming language and IDE design George Neuner <gneuner2@comcast.net> - 2013-10-22 16:17 -0400
      Re: Programming language and IDE design Hans-Peter Diettrich <DrDiettrich1@aol.com> - 2013-10-23 03:40 +0200
      Re: Programming language and IDE design wclodius@earthlink.net (William Clodius) - 2013-10-22 19:56 -0600
      Re: Programming language and IDE design "BartC" <bc@freeuk.com> - 2013-10-23 19:09 +0100
        Re: Comments, was Programming language and IDE design "BartC" <bc@freeuk.com> - 2014-08-01 13:15 -0400
      Re: Programming language and IDE design Stefan Monnier <monnier@iro.umontreal.ca> - 2013-10-24 10:55 -0400
        Re: Programming language and IDE design George Neuner <gneuner2@comcast.net> - 2013-10-24 19:57 -0400

#999 — Programming language and IDE design

FromMartin Ward <martin@gkc.org.uk>
Date2013-10-17 11:06 +0100
SubjectProgramming language and IDE design
Message-ID<13-10-016@comp.compilers>
At the 2013 IEEE Workshop on Source Code Analysis and Manipulation
http://www.ieee-scam.org/2013/ each presenter was asked to come up
with a controversial statement. Mine was:

"Source code should be hard to write [and easy to read]".

The first comment from the audience was that this was not controversial!
Programmers in general spend more time reading code than writing code:
so anything which makes code easier to read, even at the expense of
harder to write, should be a gain overall.

The really controversial statement is to drop the phrase in brackets:

"Source code should be hard to write".

The justification for this statement is that one metric which correlates
very strongly with maintenance effort is lines of code.
If code is hard to write, then programmers will be motivated
to spend fewer lines of code to implement a particular functionality.
As Dijkstra wrote in "On the cruelty of really teaching computer science":

"if we wish to count lines of code, we should not regard them as
'lines produced' but as 'lines spent': the current conventional wisdom
is so foolish as to book that count on the wrong side of the ledger."

Similarly foolish wisdom is seen in IDEs (Integrated Development Environments)
which allow the programmer to create hundreds of lines of code
with just a few clicks of the mouse. Thus instantly creating a significant
maintenance effort. Another example of this "wisdom" (which in my
experience is very common among commercial IBM assembler
programmers) is when a programmer needs to implement a new function
which is fairly similar to an existing function: he or she just grabs a copy
of the existing module, changes a few lines of code and slaps it
into production. Over time, the two copies drift further apart,
bugs are fixed in one copy but remain lurking in the other copy,
new programmers have two lots of code to read, which are
confusingly similar, and so on.

So my assertion is "Source code should be hard to write": *even if*
the writing difficulty does not result in any improvement in ease of
reading! For example: before any programmer checks in a new module or
program change, they should be forced to write out all the code
longhand with a quill pen.  This apparently pointless extra work
should give programmer's the opportunity to think about whether there
might be a shorter way to solve the problem (which might even be
easier to read and understand).

This also affects programming language design:

(1) Rather than use "{" and "}" for every type of grouping, each
different type of group such as an if statement or while loop, should
have its own opening and closing keywords.  This is something that
modern COBOL gets right (along with the many things it gets wrong!)

(2) A commonly accepted rule for designing databases and software
systems is that each piece of information should be stored in only one
location.  With a programming language, it is better for the reader if
information is duplicated to all the places where it might be needed,
with the compiler enforcing consistency. For example, data types and
formal parameter names should be recorded everywhere they are needed.
This helps the reader because the data type of a variable, for
instance, is right there in the function where the variable is
referenced, and the reader does not have to look it up in a different
file.

(3) Indentation helps the reader if it is consistent: so should also
be enforced by the compiler. In line with point (2), nesting should
be defined by *both* indentation *and* grouping keywords:
with the compiler enforcing consistency between the representations.
This means that the reader can rely on either indication of nesting,
since both are reliable.

Comments, anyone?

--
			Martin

STRL Reader in Software Engineering and Royal Society Industry Fellow
martin@gkc.org.uk  http://www.cse.dmu.ac.uk/~mward/  Erdos number: 4
G.K.Chesterton web site: http://www.cse.dmu.ac.uk/~mward/gkc/
Mirrors:  http://www.gkc.org.uk  and  http://www.gkc.org.uk/gkc

[It's always seemed to me that the blats of code from IDEs that you
then might twiddle are an admission that the underlying design is bad,
and they don't understand OOP.  Shouldn't those twiddles be
subclasses, with no code at all for the stuff that doesn't change?

On the other hand, having recently written a lot of python code, I've
come around to the opinion that enforced indentation is all the grouping
you need. -John]

[toc] | [next] | [standalone]


#1000

From"BartC" <bc@freeuk.com>
Date2013-10-19 22:05 +0100
Message-ID<13-10-017@comp.compilers>
In reply to#999
"Martin Ward" <martin@gkc.org.uk> wrote in message

> (3) Indentation helps the reader if it is consistent: so should also
> be enforced by the compiler. In line with point (2), nesting should
> be defined by *both* indentation *and* grouping keywords:
> with the compiler enforcing consistency between the representations.
> This means that the reader can rely on either indication of nesting,
> since both are reliable.

> [On the other hand, having recently written a lot of python code, I've
> come around to the opinion that enforced indentation is all the grouping
> you need. -John]

Grouping provides useful extra redundancy and inspires more confidence in
the reader of the code. Example:

s1           # statement 1
if cond:
   s2
   s3
   s4
s5
s6

An accidental press of Delete before s4 removes the tab (although I've used
spaces for usenet purposes. And if usenet has also eaten those spaces, then
s2, s3 and s4 should be indented). Now the code still compiles, but doesn't
do the same thing:

s1
if cond:
   s2
   s3
s4
s5
s6

Compare with a version using begin-end grouping:

s1
if cond then
   s2
   s3
   s4
end if
s5
s6

It still works correctly whether there's a tab in front of s4 or not. The
presence of the 'end if' reinforces that belief that s4 is part of the
conditional block.

Transmission often removes tabs, or mixes up tabs and spaces, or removes
what it thinks is superfluous white space altogether.

--
Bartc
[Chacun
   a
  son
     gout
 -John]

[toc] | [prev] | [next] | [standalone]


#1027

FromMartin Ward <martin@gkc.org.uk>
Date2013-11-07 19:40 +0000
Message-ID<13-11-003@comp.compilers>
In reply to#1000
BartC <bc@freeuk.com> makes the point that the redundancy
provided by enforced consistency between grouping and indentation
will catch typos which would otherwise cause bugs in the code.

Hans-Peter Diettrich <DrDiettrich1@aol.com> claimed that batch
processing "leads to *better* code, by thinking *before* writing
instead of while debugging and bug fixing."  Our esteemed moderator
also noted that "Keypunching often had this salutary effect."

Regarding automatic generation of code, two cases need to
be distinguished:  A domain specific language which is automatically
translated into executable code is fine:  so long as it is the DSL code
which is maintained.  This is a way to reduce the total amount of code
for the reader to have to read, while also making it more readable:
a good DSL should lead to code which is closer to the problem
domain and is understandable by an expert in the domain.
On the other hand, if the DSL is used to generate huge wads of code
which then form part of the system to be maintained:  well, that is
the same as using a compiler to generate an assembler program,
then throwing away the source code and maintaining the assembler.

How many languages should be used in one program?  As many as necessary:
if they are "little languages".  If they are huge, baroque monstrosities
like PL/I or C++, then one of these language is already too many :-)

"Using PL/1 must be like flying a plane with 7000 buttons,
switches and handles to manipulate in the cockpit."
--E.W.Dijstra "The Humble Programmer".

"If you think C++ is not overly complicated, just what is a protected
abstract virtual base pure virtual private destructor, and when was
the last time you needed one?"--Tom Cargill, C++ Journal, Fall 1990.

Hans-Peter describes the idea of recording variable types
everywhere as "another maintenance nightmare":  but with proper
tool support it does not have to be.  Even without tool support:
forcing the programmer who wants to change the type of a data
item to at least glance at all the modules which use that data
could be beneficial.

Regarding enforced indentation:  with continuation lines it could
be possible to slightly relax the restrictions and allow two or more
indentation points to be valid.

George Neuner <gneuner2@comcast.net> says "My preference is simply
for a common END keyword used by all constructs."
This is just as bad as using "}" to close all nesting:
        END
      END
    END
  END
END
I want to insert a line of code at the end of the loop body which
is nested in some IF statements, and contains some nested statements.
Where do I put it? (The top of the loop is a few pages earlier.)

Of course, you could still end up with:
        FI
      FI
    FI
  FI
FI
... which is an argument for repeating the test at the closing keyword.

> How exactly should a compiler "enforce consistency" of corresponding
> declarations in separate compilation units?  How is the compiler even
> to know that they should be corresponding?

This point raises some important issues about languages and compilers:

(1) The language should be easy to parse: both for humans and computers.
Just because it is *possible* to invent a new parsing technique
which can unscramble almost impenetrable complexity and ambiguity,
does not mean it is a good idea to define such a language.

(2) Absolutely no behaviour should be "implementation dependent"
or "undefined". Every syntactically valid program should have
a single semantically valid meaning (even if that meaning
is "halt with an error message").

(3) The language should be easy to analyse.  Current program
analysis sometimes feels like a race between researchers developing
ever more sophisticated analysis techniques, and language
designers adding ever more impenetrable features to the language.
Currently, the language designers are winning:  for example,
in C++ it is a non-computable problem just to determine which piece
of code will be executed at runtime for a given function call.

(4) The language should not impose arbitrary limitations on the programmer.
An integer data type should be available and efficiently implemented
which can hold any size of integers. Similarly, a string data type
which can hold any size of string. Hash tables should allow
any type of key and value, and so on.

One aim is to catch errors as early as possible:  syntactic errors
can be caught at editing time (with a syntax-aware editor),
semantic errors can be caught at compile time, and as a last resort,
runtime errors are caught at runtime (and do not result in potentially
exploitable undefined behaviour!).

This means:  redundancy (to catch errors at edit time), strong typing
(catch errors at compile time), no aliasing (so the behaviour
of a piece of code can be determined from the code alone),
no unrestricted pointers, no undefined behaviour (so runtime errors
can be caught at runtime).

As well as the security benefits, there are also significant
performance benefits from the above approach:  if the language
is easy to parse, then the whole program can be parsed quickly:
which solves the problem of ensuring consistency between modules.
If the language is also easy to analyse, then the whole program
can be analysed and compiled as a unit:  leading to many more
optimisation possibilities.  Strong typing, together with the
elimination of aliasing and pointers also allows much deeper analysis
and optimisation.  Memory is cheap and CPUs are powerful,
so whole-program analysis and optimisation should become the norm:
but this provides the greatest benefit when the language is
easy to analyse.

Hans-Peter Diettrich <DrDiettrich1@aol.com> wrote:
> It turned out soon that C is the most ugly and pretentious language WRT
> to automatic analysis, that's why I continued research and
> implementation on just that language. Newer languages should be much
> easier to master automatically...

Newer languages like C++, for example? :-)

William Clodius <wclodius@earthlink.net> wrote:
> Among workers whose primary task is not
> programing it can be very difficult to get a mutually consistent
> programming style unless their mutual inconsistencies, where it affects
> legibility, have significant consequences.

Indeed: a consistent coding style is much more important than anyone's
personal preference: in the sense that readability is improved when everyone
is forced to use the same style (even if some think that it is sub-optimal)
compared to the mix of styles that results when everyone is allowed
to write in their own way. Not to mention the wasted effort when
people keep on restructuring each other's code into their preferred style!

--
			Martin

Dr Martin Ward STRL Principal Lecturer and Reader in Software Engineering
martin@gkc.org.uk  http://www.cse.dmu.ac.uk/~mward/  Erdos number: 4
G.K.Chesterton web site: http://www.cse.dmu.ac.uk/~mward/gkc/
Mirrors:  http://www.gkc.org.uk  and  http://www.gkc.org.uk/gkc

[toc] | [prev] | [next] | [standalone]


#1029

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2013-11-08 05:21 +0000
Message-ID<13-11-005@comp.compilers>
In reply to#1027
Martin Ward <martin@gkc.org.uk> wrote:
> BartC <bc@freeuk.com> makes the point that the redundancy
> provided by enforced consistency between grouping and indentation
> will catch typos which would otherwise cause bugs in the code.

(big snip)
> This point raises some important issues about languages and compilers:

(snip)
> (2) Absolutely no behaviour should be "implementation dependent"
> or "undefined". Every syntactically valid program should have
> a single semantically valid meaning (even if that meaning
> is "halt with an error message").

Much "implementation dependence" comes from dependence on the host
processor.  Maybe sometimes too much, but it is nice to be able to use
the new features of newer processors.

Many early machines were sign magnitude, but most now use twos
complement, which mostly is an advantage.

Different word sizes are also a common dependence, with 36 bit words
and 6-bit characters common on the early scientific machines.

-- glen

[toc] | [prev] | [next] | [standalone]


#1031

FromHans-Peter Diettrich <DrDiettrich1@aol.com>
Date2013-11-08 06:45 +0100
Message-ID<13-11-007@comp.compilers>
In reply to#1027
Martin Ward schrieb:

> Hans-Peter describes the idea of recording variable types
> everywhere as "another maintenance nightmare":  but with proper
> tool support it does not have to be.  Even without tool support:
> forcing the programmer who wants to change the type of a data
> item to at least glance at all the modules which use that data
> could be beneficial.

Just to clarify my understanding and use of an IDE:

I use an IDE as a tool that tells me *more* about the source code than
it contains literally. Other people prefer to work offline, where a
small window on screen or a printed page should contain all essential
information - but do these people really need or even use an IDE?

I also don't like the way how many IDEs limit their single source code
pane to postcard size, surrounded by many toolbars and views of other
items. Often I need three or more parallel views on different parts of
a project, related to some item. Just like many printouts can be
arranged on an physical desktop, an IDE should allow for the same on
(multiple) monitors.


> (3) The language should be easy to analyse.  Current program
> analysis sometimes feels like a race between researchers developing
> ever more sophisticated analysis techniques, and language
> designers adding ever more impenetrable features to the language.
> Currently, the language designers are winning:  for example,
> in C++ it is a non-computable problem just to determine which piece
> of code will be executed at runtime for a given function call.

That's the advantage and price of OOP!

To me it's essential that I can split a problem into dedicated objects
(classes), of significantly lower complexity and limited dependencies.
Every object has a slim interface (public methods), nothing more is
required to understand the role and use of that object in the rest of
the code.

Of course virtual methods and heritage make it impossible to know which
exact incarnation of an object is used in a specific place of the entire
program. That's where a tool (IDE) is required to shed some light on the
internals, but not normally to understand what's going on at this place
behind the scene, moreoften instead for understanding special situations
where a specific object is used and must react in the right way.


> (4) The language should not impose arbitrary limitations on the programmer.
> An integer data type should be available and efficiently implemented
> which can hold any size of integers.

ACK

> Similarly, a string data type
> which can hold any size of string.

While I strongly agree that a string type is an absolute must, string
handling and text processing can be considered subject to a domain
specific language. At least it turned out that string operators look
nice in code, but tend to result in poor runtime behaviour (.NET) or
obscure runtime errors (Java), or both.

String handling also should be separated in multiple levels of
abstraction. The lowest level covers the allocation and operations on
physical storage elements (bytes/codepoints), and precautions against
out-of-bounds references. The next higher level deals with characters
and allows to work easily with MBCS. In fact no character type should be
used herefore, even UCS-4 does not allow to deal with fixed-size
characters (ligatures...)!

The next higher level(s) cover language/culture specific aspects of
textual information. The right name herefore would be *text* processing,
as opposed to more physical string handling (concatenation...). Casing
and sorting (comparison...) are commonly used operations at this level,
even if ASCII users often don't understand that these are not trivial
operations in foreign countries. The same for parsing and decomposition
of non-ASCII texts, such operations should be reserved for the
implementation of text processing programs (document editors...). IMO.


> Hash tables should allow
> any type of key and value, and so on.

I'd consider hash tables as domain specific, together with databases and
other containers. As opposed to strings, such items should be part of
libraries, be language specific or third-party.


> One aim is to catch errors as early as possible:  syntactic errors
> can be caught at editing time (with a syntax-aware editor),
> semantic errors can be caught at compile time, and as a last resort,
> runtime errors are caught at runtime (and do not result in potentially
> exploitable undefined behaviour!).

Means for Structured Exception Handling should be part of every
language, easily usable so that nobody would ever revert to using less
safe means for error handling.


> Hans-Peter Diettrich <DrDiettrich1@aol.com> wrote:
>> It turned out soon that C is the most ugly and pretentious language WRT
>> to automatic analysis, that's why I continued research and
>> implementation on just that language. Newer languages should be much
>> easier to master automatically...
>
> Newer languages like C++, for example? :-)

C++ suffers from two diseases: compatibility and competition ;-)

The first means syntactic and semantic compatibility to C, so that the
newly introduced good language features can be (and often are)
circumvented in real world code. Next comes execution speed, which
should not be lower than equivalent C code, what typically means that
additional safety checks are omitted from the standard libraries. And
finally C++ comes in so many incompatible flavours, that it is not
usable for platform independent projects. IMO Java is the only usable C
spring off, which is said to only look like C, but is something very
different underneath.  .NET instead is still under construction, and
only works on MS supported platforms; this certainly is a design goal,
so that no cure should be expected. Some people say the same about C++,
which had to be as complicated as possible, to ensure Bjarne's long term
living :-]



> Indeed: a consistent coding style is much more important than anyone's
> personal preference: in the sense that readability is improved when everyone
> is forced to use the same style (even if some think that it is sub-optimal)
> compared to the mix of styles that results when everyone is allowed
> to write in their own way. Not to mention the wasted effort when
> people keep on restructuring each other's code into their preferred style!

Style and fashion is a matter of taste, subject to frequent change and
personal preferences. IMO we simply should accept this human component
as given, and leave it to an IDE to bridge the gap between formal syntax
and human diversity. HTML (XML...) is an example of a language that can
be used either at low level, or in a WYSIWIG presentation. The only
requirement is a standardized low level representation of a language,
which can be presented and edited in a variety of textual or more
graphical formats.

What's so bad with different representations of a program/project, with
e.g. a graphical (dependency...) view for easy overview and navigation,
and more or less abstract levels on the road down to concrete source code?

Every (event driven) GUI program requires dedicated (domain specific)
presentations of its visual components. It doesn't make sense to me when
such presentation and editing capabilities are prevented by a formal
programming language. The same for databases or other non-visual
components, which have their own interface, relationship and use in a
program. An IDE *Integrates* such views end editors, for aspect/domain
specific *Development* of parts of a project.

DoDi

[toc] | [prev] | [next] | [standalone]


#1032

FromGeorge Neuner <gneuner2@comcast.net>
Date2013-11-08 16:04 -0500
Message-ID<13-11-008@comp.compilers>
In reply to#1027
On Thu, 7 Nov 2013 19:40:43 +0000, Martin Ward <martin@gkc.org.uk>
wrote:

>George Neuner <gneuner2@comcast.net> says
>
>> How exactly should a compiler "enforce consistency" of corresponding
>> declarations in separate compilation units?  How is the compiler even
>> to know that they should be corresponding?
>
>This point raises some important issues about languages and compilers:
>
>(1) The language should be easy to parse: both for humans and computers.
>Just because it is *possible* to invent a new parsing technique
>which can unscramble almost impenetrable complexity and ambiguity,
>does not mean it is a good idea to define such a language.

The majority of successful languages are LL(k) for small k.  It's hard
to get much simpler than that for parsing.


>(2) Absolutely no behaviour should be "implementation dependent"
>or "undefined". Every syntactically valid program should have
>a single semantically valid meaning (even if that meaning
>is "halt with an error message").

It's impossible not to have implementation dependent behavior: e.g.,
program execution time is a behavior that can't be specified.

Limitations of hardware must be addressed when implementing high level
features - the runtime must compensate for hardware features that are
unavailable on some platforms or have differing semantics across
platforms: e.g., signed vs unsigned arithmetic, flag vs branch
compare, floating point support, etc.

Witness that there is not a single CPU that *fully* implements
IEEE-754 arithmetic (old or new spec), and every implementation
differs in what is lacking and in what needs to be corrected by
software to yield compliant results.


>(3) The language should be easy to analyse.  Current program
>analysis sometimes feels like a race between researchers developing
>ever more sophisticated analysis techniques, and language
>designers adding ever more impenetrable features to the language.

Agreed - they *should* be easy to analyze.  The problem is that in
theory, theory and practice are the same - in practice they aren't.

Programs which do no I/O, use no (psuedo)random operations and are
completely constrained to their virtually constructed bubbles are
relatively easy to analyze.  It is also the case that nearly all such
programs are completely useless.

Programs which interface with the messy, error-ridden, analog real
world, and which operate on dynamic data, are not easy to analyze
regardless of language.


>Currently, the language designers are winning:  for example,
>in C++ it is a non-computable problem just to determine which piece
>of code will be executed at runtime for a given function call.

That's a straw man: it's a variant of the halting problem which is
undecidable.


>(4) The language should not impose arbitrary limitations on the programmer.
>An integer data type should be available and efficiently implemented
>which can hold any size of integers. Similarly, a string data type
>which can hold any size of string. Hash tables should allow
>any type of key and value, and so on.

You're ignoring that user-friendly features such as arbitrary
precision arithmetic impose other limits such as unpredictable
execution timing and memory use.

Perhaps we should do away with "general purpose" languages altogether
and separate languages into "system" or "application" uses.

"Application" languages should be safe by default.  However, even safe
languages probably shouldn't be fully insulated from hardware, else
people will simply abandon them for system languages.  There should
have expert modes that allow safely getting closer to the hardware
when necessary.  E.g., if the developer *knows* that the dynamic data
range makes it safe to use hardware integer types, she should not be
prevented from doing so.


>One aim is to catch errors as early as possible:  syntactic errors
>can be caught at editing time (with a syntax-aware editor),
>semantic errors can be caught at compile time, and as a last resort,
>runtime errors are caught at runtime (and do not result in potentially
>exploitable undefined behaviour!).
>
>This means:  redundancy (to catch errors at edit time), strong typing
>(catch errors at compile time), no aliasing (so the behaviour
>of a piece of code can be determined from the code alone),
>no unrestricted pointers, no undefined behaviour (so runtime errors
>can be caught at runtime).

Lotsa luck!  Have you tried to write a non-trivial program that has
absolutely no (source level) aliasing?


>As well as the security benefits, there are also significant
>performance benefits from the above approach:  if the language
>is easy to parse, then the whole program can be parsed quickly:
>which solves the problem of ensuring consistency between modules.
>If the language is also easy to analyse, then the whole program
>can be analysed and compiled as a unit:  leading to many more
>optimisation possibilities.

"Simple to analyze" does not necessarily equate to "simple to
optimize".  Nor is "safe" synonymous with "simple".

It is true that whole program analysis can find more optimization
opportunities, but the possibilities ultimately are constrained by the
operational semantics of the language.

In general, "safe" languages require more complex implementations
which present fewer optimization possibilities than do "simple"
languages.

YMMV,
George

[toc] | [prev] | [next] | [standalone]


#1035

From"Jonathan Thornburg" <jthorn@astro.indiana.edu>
Date2013-11-10 04:41 +0000
Message-ID<13-11-011@comp.compilers>
In reply to#1027
Martin Ward <martin@gkc.org.uk> wrote:
> (2) Absolutely no behaviour should be "implementation dependent"
> or "undefined". Every syntactically valid program should have
> a single semantically valid meaning (even if that meaning
> is "halt with an error message").

This is really problematic in the area of floating-point arithmatic.
For example, at what point should floating-point arithmetic overflow
or underflow, and what should be the consequences of this happening?
To be very precise, what "single semantically valid meaning" should we
perscribe for trying to compute the square of 1.0e300?

If we say "the answer should be 1.0e600" then we're forbidding the
efficient use of hardware floating-point on machines that provide
IEEE-double (for which the multiplication of 1.0e300 by itself will
overflow).

If we say "the answer should be a floating-point overflow" then we're
forbidding the efficient use of hardware "double extended" floating-point
on machines that provide extended-precision floating-point registers
with a wider exponent range (so that the multiplication of 1.0e300 by
itself will not overflow).

And if we don't use hardware floating-point, on some codes we lose
a lot of performance.


Underflow presents even worse problems: Apart from the question of
just where the underflow threshold should be, what happens after an
underflow?  Should our "single semantically valid meaning" specify
gradual underflow or flush-to-zero or underflow-is-an-error?


And dwarfing all of these problems are the question of what to do about
trancendental (math) functions?  Just what should we specify the result
of  cos(x)  to be?  Some possibilities include
* specify one particular approximation (this is what Java did at first)
  --> blocks the use of better approximations if/when they're developed
      in the future
* specify "the floating-point number closest to the exact result"
  --> is rather hard to implement; it's doable for cos(x) but pow(x,y)
      is still an active (not-yet-solved) research problem


Java encountered all of these problems, and eventually chose to back
off its "precise specification" to allow implementation-defined
semantics for floating-point arithmetic.

Most other languages which have or want to have substantial use for
scientific computation left floating-point arithmetic machine-dependent
from the start.

--
-- "Jonathan Thornburg [remove -animal to reply]" <jthorn@astro.indiana-zebra.edu>
   Dept of Astronomy & IUCSS, Indiana University, Bloomington, Indiana, USA
   "There was of course no way of knowing whether you were being watched
    at any given moment.  How often, or on what system, the Thought Police
    plugged in on any individual wire was guesswork.  It was even conceivable
    that they watched everybody all the time."  -- George Orwell, "1984"

[toc] | [prev] | [next] | [standalone]


#1001

FromHans-Peter Diettrich <DrDiettrich1@aol.com>
Date2013-10-20 03:22 +0200
Message-ID<13-10-018@comp.compilers>
In reply to#999
Martin Ward schrieb:

> If code is hard to write, then programmers will be motivated
> to spend fewer lines of code to implement a particular functionality.

A similar (or better) effect can be achieved by old batch processing,
with one compilation per day, feedback next day. This procedure leads
to *better* code, by thinking *before* writing instead of while
debugging and bug fixing.


> Similarly foolish wisdom is seen in IDEs (Integrated Development Environments)
> which allow the programmer to create hundreds of lines of code
> with just a few clicks of the mouse. Thus instantly creating a significant
> maintenance effort.

See your statement (2) below.

IMO the use of domain specific languages is good practice, and when an
IDE performs the translation of such a language into the
implementation language, I see no reason why an IDE should be able to
create much code when required. A preprocessor could do the same job,
leading to the same problem: how many languages or macros should be
used in one program? Is such domain-specific code really easy to read,
for somebody not familiar with all those languages?

In practice I can't see anything bad in automatic generation of e.g.
event handlers (Delphi forms), or replication of declarations for
implementation (2).

> Another example of this "wisdom" (which in my
> experience is very common among commercial IBM assembler
> programmers) is when a programmer needs to implement a new function
> which is fairly similar to an existing function: he or she just grabs a copy
> of the existing module, changes a few lines of code and slaps it
> into production. Over time, the two copies drift further apart,
> bugs are fixed in one copy but remain lurking in the other copy,
> new programmers have two lots of code to read, which are
> confusingly similar, and so on.

This is what I observe in one of my current projects. An attempt to
merge 4 spring-offs back into one program is a nightmare, for which I
couldn't find a solution yet. First it's hard to figure out all the tiny
differences in the copies (maybe tiny but important), and then to add
virtual methods to cover all the differences. In the end nobody will
understand the purpose of those added methods, how to prove their
correctness, and where to place further adaptations.


> So my assertion is "Source code should be hard to write": *even if*
> the writing difficulty does not result in any improvement in ease of
> reading! For example: before any programmer checks in a new module or
> program change, they should be forced to write out all the code
> longhand with a quill pen.  This apparently pointless extra work
> should give programmer's the opportunity to think about whether there
> might be a shorter way to solve the problem (which might even be
> easier to read and understand).

See "batch processing" above.


> This also affects programming language design:
>
> (1) Rather than use "{" and "}" for every type of grouping, each
> different type of group such as an if statement or while loop, should
> have its own opening and closing keywords.  This is something that
> modern COBOL gets right (along with the many things it gets wrong!)

True in general, but assistance of an IDE (for proper closing brackets)
would increase productivity. I'm not sure what "modern COBOL" means, but
the idea of IF...FI, DO...OD and similar bracketing is nothing new.

More verbose or less systematic brackets (IF...THEN...ELSE...ENDIF,
DO...LOOP, BEGIN...END) could be substituted by an IDE. The same for
nationalization (WENN...DANN...ANDERNFALLS...FERTIG) <shudder>


> (2) A commonly accepted rule for designing databases and software
> systems is that each piece of information should be stored in only one
> location.  With a programming language, it is better for the reader if
> information is duplicated to all the places where it might be needed,
> with the compiler enforcing consistency. For example, data types and
> formal parameter names should be recorded everywhere they are needed.
> This helps the reader because the data type of a variable, for
> instance, is right there in the function where the variable is
> referenced, and the reader does not have to look it up in a different
> file.

I really don't like that, as it results in another maintenance nightmare
- unless properly supported by an IDE. Hyper links, hint popups and
multiple synchronized views (for declaration, definition, documentation
etc.) are my favorite assistants. A reader should trust the compiler,
which assures that the code is consistent, even if the source does not
have all declarations or qualifiers inlined.


> (3) Indentation helps the reader if it is consistent: so should also
> be enforced by the compiler. In line with point (2), nesting should
> be defined by *both* indentation *and* grouping keywords:
> with the compiler enforcing consistency between the representations.
> This means that the reader can rely on either indication of nesting,
> since both are reliable.

ACK

Indentation should be enforced, so that a user can e.g. view the code
expanded to his preferred tab width, without any consequential and
persistent changes to the source code.

Problematic are continuation lines, where some people prefer to continue
parameter lists on the first parameter level. This style will quickly
result in unreadable code, when nested function calls are involved.


> Comments, anyone?

IMO a language, compiler and IDE have different purposes, which you
mixed up a bit in your text. A language should allow for a compressed
and clear writeup of declarations and implementations, with a choice of
general purpose and domain specific languages. A compiler should be able
to check as much as possible, not only syntax. An IDE should assist in
both writing *and* understanding source code.


> [It's always seemed to me that the blats of code from IDEs that you
> then might twiddle are an admission that the underlying design is bad,
> and they don't understand OOP.  Shouldn't those twiddles be
> subclasses, with no code at all for the stuff that doesn't change?

I'm not sure which language or IDE you have in mind. I'm quite happy
with Delphi form design and coding, where the IDE creates the skeleton
which the coder then only has to complete.

> On the other hand, having recently written a lot of python code, I've
> come around to the opinion that enforced indentation is all the grouping
> you need. -John]

+1

DoDi

[toc] | [prev] | [next] | [standalone]


#1003

FromGene Wirchenko <genew@telus.net>
Date2013-10-20 14:03 -0700
Message-ID<13-10-020@comp.compilers>
In reply to#999
On Thu, 17 Oct 2013 11:06:26 +0100, Martin Ward <martin@gkc.org.uk>
wrote:

[snip]

>So my assertion is "Source code should be hard to write": *even if*
>the writing difficulty does not result in any improvement in ease of
>reading! For example: before any programmer checks in a new module or
>program change, they should be forced to write out all the code
>longhand with a quill pen.  This apparently pointless extra work
>should give programmer's the opportunity to think about whether there
>might be a shorter way to solve the problem (which might even be
>easier to read and understand).

     It is pointless.  I would be too concerned with the writing to
look much at the code.

     Someone who is not inclined to think more about the problem is
not going to start doing so because you make him write it longhand.

[snip]

Sincerely,

Gene Wirchenko
[He's being ironic, dude.  Keypunching often had this salutary
effect. -John]

[toc] | [prev] | [next] | [standalone]


#1004

FromGene Wirchenko <genew@telus.net>
Date2013-10-21 14:44 -0700
Message-ID<13-10-021@comp.compilers>
In reply to#1003
On Sun, 20 Oct 2013 14:03:18 -0700, Gene Wirchenko <genew@telus.net>
wrote:

>On Thu, 17 Oct 2013 11:06:26 +0100, Martin Ward <martin@gkc.org.uk>
>wrote:
>
>[snip]
>
>>So my assertion is "Source code should be hard to write": *even if*
>>the writing difficulty does not result in any improvement in ease of
>>reading! For example: before any programmer checks in a new module or
>>program change, they should be forced to write out all the code
>>longhand with a quill pen.  This apparently pointless extra work
>>should give programmer's the opportunity to think about whether there
>>might be a shorter way to solve the problem (which might even be
>>easier to read and understand).
>
>     It is pointless.  I would be too concerned with the writing to
>look much at the code.
>
>     Someone who is not inclined to think more about the problem is
>not going to start doing so because you make him write it longhand.
>
>[snip]
>
>Sincerely,
>
>Gene Wirchenko
>[He's being ironic, dude.  Keypunching often had this salutary
>effect. -John]

      Is he?  I once read a similar opinion where the writer was
apparently quite serious.  In that case, it was a student learning
programming should be required to rewrite down the entire program when
he made errors.

Sincerely,

Gene Wirchenko
[I hope we'll find out. -John]

[toc] | [prev] | [next] | [standalone]


#1005

FromGeorge Neuner <gneuner2@comcast.net>
Date2013-10-22 16:17 -0400
Message-ID<13-10-022@comp.compilers>
In reply to#999
On Thu, 17 Oct 2013 11:06:26 +0100, Martin Ward <martin@gkc.org.uk>
wrote:


>"Source code should be hard to write".

I disagree. Code should be easy to write ...

and easy to read ...

and, in almost all cases, easy to understand!

There are times when [well documented!!!] clever tricks are called
for, but in general, developers should be striving to write code that
is as boring and straightforward as possible.

I don't necessarily agree with the idea of limiting general purpose
languages, but I do think that sharp tools, by default, should be
reserved to "expert" modes.

Rather I agree with Hans-Peter that when suitable domain languages
exist, they ought to be used.  My definition of "suitable", however,
presumes that the DSL is *practical* to use in real world situations.

Mathematica makes testing algorithms simple.  Its apparent simplicity,
however, is a trap because Mathematica is, on average, 30x slower than
an equivalent C program.  Even experienced users can too easily write
"programs" for which the running time against a realistically large
data set which will enable the user to take a foreign holiday.
Processing really _big_ data using Mathematica is just infeasible.

As a point of comparison, Lisp also makes testing algorithms pretty
simple. However, the combination of an experienced Lisp programmer and
a good Lisp compiler can closely rival a C program for speed.



>The justification for this statement is that one metric which correlates
>very strongly with maintenance effort is lines of code.
>If code is hard to write, then programmers will be motivated
>to spend fewer lines of code to implement a particular functionality.
>As Dijkstra wrote in "On the cruelty of really teaching computer science":
>
>"if we wish to count lines of code, we should not regard them as
>'lines produced' but as 'lines spent': the current conventional wisdom
>is so foolish as to book that count on the wrong side of the ledger."
>
>Similarly foolish wisdom is seen in IDEs (Integrated Development
Environments)
>which allow the programmer to create hundreds of lines of code
>with just a few clicks of the mouse. Thus instantly creating a significant
>maintenance effort.

99% (or more) of generated code will never be touched by a human.
Probably 80% of it even will never be looked at.

I have never read anything which suggests to me that Dijkstra was - or
would have been - against source code generators.  He had a well known
preference for typed, high level, structured languages rather than
assembly, but AIUI his main concern was with the control of stupid
programmer errors.  He also was quite concerned with programmer
efficiency and coding effectiveness, noting in "The Humble Programmer"
that software systems were rapidly becoming too complex for a single
programmer to fully understand.

Given the second point, I believe he would have been in favor of
(carefully applied) source code generation.  In particular, I think he
would have eagerly supported the idea of domain languages designed to
reduce the semantic gap between programmer and problem. I don't think
he would have been bothered much by the idea of DSL compilers
generating (good quality) programs in source form for an existing GPL
compiler.  He would have preached discipline (another of his favorite
themes) in resolving problems within the domain language rather than
resorting to tweaking the generated GPL code.



>Another example of this "wisdom" (which in my
>experience is very common among commercial IBM assembler
>programmers) is when a programmer needs to implement a new function
>which is fairly similar to an existing function: he or she just grabs a copy
>of the existing module, changes a few lines of code and slaps it
>into production. Over time, the two copies drift further apart,
>bugs are fixed in one copy but remain lurking in the other copy,
>new programmers have two lots of code to read, which are
>confusingly similar, and so on.

Cut-n-paste happens with every programmer and in every language.  I
have done it and I'll wager that you have done it and so too has
everyone you can find to ask.

The concern about unknown bugs being duplicated is valid, but consider
that:

1) generally you start by copying code that is already known to work.
It may contain latent bugs, but if the code was thoroughly tested for
its original purpose, bugs that remain should pertain only to
conditions that could not arise in that use.

2) once the code is modified for a new use, it is new code.  Latent
bugs present in the original may no longer be there or (as in 1) may
pertain to conditions that will not arise in the new use.

3) you *ARE* going to thoroughly test the new code for its intended
purpose.


Cut-n-paste doesn't worry me so much as the decline of design and
development skills.  The average software developer today has little
or no CS or CE education, and often little experience in the domain of
the application.  Combined with easy access to great volumes of open
source code that they understand poorly or not at all, I consider the
majority of these people to be highly dangerous.  IMNSHO, a lot of
"professional" software developers would be doing a world a favor by
finding another profession.



>So my assertion is "Source code should be hard to write": *even if*
>the writing difficulty does not result in any improvement in ease of
>reading! For example: before any programmer checks in a new module or
>program change, they should be forced to write out all the code
>longhand with a quill pen.  This apparently pointless extra work
>should give programmer's the opportunity to think about whether there
>might be a shorter way to solve the problem (which might even be
>easier to read and understand).

Why stop at quills?  Make them write the program in Sanskrit and carve
it into stone tablets ... *after* first fashioning their own copper
chisels and cutting stone for the tablets.



>This also affects programming language design:
>
>(1) Rather than use "{" and "}" for every type of grouping, each
>different type of group such as an if statement or while loop, should
>have its own opening and closing keywords.  This is something that
>modern COBOL gets right (along with the many things it gets wrong!)

C's mistake was not in using (or over using or abusing) curly braces.
Rather, C's mistake was in defining the scope of its control
constructs to be a single statement rather than a demarcated list of
statements.  Had C control constructs always expected a list of
statements - thus *requiring* the scoping braces - many stupid
programmer errors might have been avoided.  [Lisp proponents would say
the error was defining the language in terms of "statements" vs
"expressions" ... but I don't go that far.]


I don't object to closing keywords [in fact I prefer Pascal-like
syntax, though Modula3 and Oberon are better examples than Pascal
itself] but I don't agree that they necessarily make errors easier to
spot for human readers.  Closing keywords are nothing more than
syntactic punctuation, and punctuation in human language normally is
absorbed by readers at a subconscious level.

I despise stupid keyword reversal closings such as IF..FI - loop can
go jump in the pool and tceles sounds to me like a high speed train
(and probably is a homophone for a swear word in some language).

Things like <keyword>..END<keyword> get unwieldy when keyword phrases
may contain optional attributes, such as in generalized loop
constructs where the demarcation keywords may have to include labels
and/or conditions.

My preference is simply for a common END keyword used by all
constructs. I think keyword case consistency is important, but I think
the choice to use all upper or all lower should be left to the
programmer.


What actually *is* important is not the choice of keywords, scope
markers or other punctuation, but rather that the scope of control
constructs is defined to be a list of statements.  Given this,
indentation by a structural editor will immediately show structural
mistakes as misaligned statements.
[For an example, look at Lisp code using Emacs "lisp mode".  Try
adding or removing a parenthesis somewhere and see what happens.]



>(2) A commonly accepted rule for designing databases and software
>systems is that each piece of information should be stored in only one
>location.

Singleton data doesn't prevent name aliasing, in databases or in
programs.  It is the aliasing which is a major source of programming
errors.

Moreover, there is data for which multiple instances are
indistinguishable in use, e.g., the integer value 42.  Non-shared uses
of such data can use copies interchangeably.



>With a programming language, it is better for the reader if
>information is duplicated to all the places where it might be needed,
>with the compiler enforcing consistency.

Yes and no.

Redundancy is good to a point beyond which it becomes noise.

I prefer to define things in one place and to have the compiler
propagate the information to wherever it is needed.  Excepting
interfaces to "foreign" objects which otherwise would be unknown to
the compiler, I consider the redundant declarations required by many
languages to be error-prone unnecessary crap.

How exactly should a compiler "enforce consistency" of corresponding
declarations in separate compilation units?  How is the compiler even
to know that they should be corresponding?



>(3) Indentation helps the reader if it is consistent: so should also
>be enforced by the compiler. In line with point (2), nesting should
>be defined by *both* indentation *and* grouping keywords:
>with the compiler enforcing consistency between the representations.
>This means that the reader can rely on either indication of nesting,
>since both are reliable.

Under NO circumstances should a compiler be enforcing coding styles.


Significant indentation is the dumbest idea since paper tape.

Ergonomics dictates that the screen dimensions, fonts and indentation
units that I choose for my viewing comfort should have absolutely no
effect on your choices.

Indentation does aid human readers and should be applied consistently
... by means of a structural editor.  Given a properly designed
language in which control constructs expect a demarcated list of
statements, then matching scopes will have matching indentation and
structural mistakes in the code will be apparent due to statement
misalignments

Python got many things right, but the whole idea of significant
indentation in a modern language is a non-starter.  I understand why
Guido thought it might be a good idea, but he really should have left
it alone.

YMMV,
George

[toc] | [prev] | [next] | [standalone]


#1006

FromHans-Peter Diettrich <DrDiettrich1@aol.com>
Date2013-10-23 03:40 +0200
Message-ID<13-10-023@comp.compilers>
In reply to#1005
George Neuner schrieb:

> Cut-n-paste doesn't worry me so much as the decline of design and
> development skills.  The average software developer today has little
> or no CS or CE education, and often little experience in the domain of
> the application.

Did you ever find a person mastering both areas?

> Combined with easy access to great volumes of open
> source code that they understand poorly or not at all, I consider the
> majority of these people to be highly dangerous.  IMNSHO, a lot of
> "professional" software developers would be doing a world a favor by
> finding another profession.

ROTFL - well spoken :-]


> I despise stupid keyword reversal closings such as IF..FI - loop can
> go jump in the pool and tceles sounds to me like a high speed train
> (and probably is a homophone for a swear word in some language).

It's CASE..ESAC :-)


> Things like <keyword>..END<keyword> get unwieldy when keyword phrases
> may contain optional attributes, such as in generalized loop
> constructs where the demarcation keywords may have to include labels
> and/or conditions.

Such verbosity can help the reader in untying long and deeply nested
constructs. But in most such cases a repetition of the starting
condition or loop variable is a must.

In such situations a folding editor is extremely helpful, which can hide
all the code of an block, or the optional attributes of a loop. It also
could display the documentation of an code block, instead of the code
itself - kind of assisted Literate Programming.

> My preference is simply for a common END keyword used by all
> constructs. I think keyword case consistency is important, but I think
> the choice to use all upper or all lower should be left to the
> programmer.

I'm still waiting for the first Chinese programming language, case
insensitive, unambiguous and easy to parse due to the use of keyword
symbols (tokens), kind of AcPL. Translations into the preferred
representation of every reader would not be hard to add, even for RTL or
TTB reading. Remains the problem of identifiers, how could these be made
language neutral?



> What actually *is* important is not the choice of keywords, scope
> markers or other punctuation, but rather that the scope of control
> constructs is defined to be a list of statements.  Given this,
> indentation by a structural editor will immediately show structural
> mistakes as misaligned statements.
> [For an example, look at Lisp code using Emacs "lisp mode".  Try
> adding or removing a parenthesis somewhere and see what happens.]

Right, see above.

>> (2) A commonly accepted rule for designing databases and software
>> systems is that each piece of information should be stored in only one
>> location.
>
> Singleton data doesn't prevent name aliasing, in databases or in
> programs.  It is the aliasing which is a major source of programming
> errors.
>
> Moreover, there is data for which multiple instances are
> indistinguishable in use, e.g., the integer value 42.  Non-shared uses
> of such data can use copies interchangeably.

I like OPL enums and sets for a disambiguation, by named and typed
constants.


>> With a programming language, it is better for the reader if
>> information is duplicated to all the places where it might be needed,
>> with the compiler enforcing consistency.
>
> Yes and no.
>
> Redundancy is good to a point beyond which it becomes noise.
>
> I prefer to define things in one place and to have the compiler
> propagate the information to wherever it is needed.  Excepting
> interfaces to "foreign" objects which otherwise would be unknown to
> the compiler, I consider the redundant declarations required by many
> languages to be error-prone unnecessary crap.

+1

> How exactly should a compiler "enforce consistency" of corresponding
> declarations in separate compilation units?  How is the compiler even
> to know that they should be corresponding?

Plus: how should a compiler know that some declaration or code is an
*intentional* modification? An IDE should allow to e.g. list all
implementations of a virtual method.


> Under NO circumstances should a compiler be enforcing coding styles.

This is what I'd assign to the tasks of an IDE. Not by reformatting the
source code, but by a consistent and user defined representation and
according editing features.

*Uncontrolled*
> Significant indentation is the dumbest idea since paper tape.


> Ergonomics dictates that the screen dimensions, fonts and indentation
> units that I choose for my viewing comfort should have absolutely no
> effect on your choices.

I'd extend that to the vertical axis (folding), maybe in more dimensions
  for touch screeens and other newer technologies.


> Indentation does aid human readers and should be applied consistently
> .... by means of a structural editor.  Given a properly designed
> language in which control constructs expect a demarcated list of
> statements, then matching scopes will have matching indentation and
> structural mistakes in the code will be apparent due to statement
> misalignments

I'd go one or more steps further. My experience with decompilers and
translators revealed that most code can be represented in various
programming languages, not only the original one. E.g. assembly code,
from the time where restricted languages or compilers suggested to write
library code in assembly, could be translated frequently into well
structured high-level code. Maybe a result of manually tweaked compiler
output, but I doubt that.

I also could find tons of errors in prominent C code (official
examples...), by using an better compiler or by translating the code
into C++ or OPL. IMO it were really helpful to have a chance to add
semantic attributes (strong types...) to some source code, checkable by
a compiler or dedicated tool - remember lint? This would not necessarily
prevent reading and compiling a lean and mean auto-generated C version
of that code. The only practical problem is the continued development of
the uncheckable C code, whereby all added safety attributes will get
lost soon.

This might become the domain of another class of tools, which decompile
applications or libraries into structured (meta?) code, which can be
matched better with older revisions of the attributed code, so that the
modifications can be incorporated automatically into that code. In an
first step a unified representation of the compiler's parse tree could
be used for the meta language, as it reduces considerably the analysis
of final compiled binary or ASM code. This would be not so hard with
open source compilers (gcc), but the language deviations of some
(Microsoft in detail, or ObjectiveC...) compilers suggest to implement
an highly configurable parser. At least my first C decompiler could
handle compiler and linker specifics of a considerable number of C (and
BASIC) compilers and platforms (Atari, Amiga, HP-UX...), and my ToPas
translator handles source code written for GNU, Microsoft and Borland C
compilers.

It turned out soon that C is the most ugly and pretentious language WRT
to automatic analysis, that's why I continued research and
implementation on just that language. Newer languages should be much
easier to master automatically, provided that a common meta language can
be defined for the different declarations and control structures. So I
hope to end up now with something more on-topic than C bashing ;-)

DoDi

[toc] | [prev] | [next] | [standalone]


#1007

Fromwclodius@earthlink.net (William Clodius)
Date2013-10-22 19:56 -0600
Message-ID<13-10-024@comp.compilers>
In reply to#1005
George Neuner <gneuner2@comcast.net> wrote:

> On Thu, 17 Oct 2013 11:06:26 +0100, Martin Ward <martin@gkc.org.uk>
> wrote:
> <snip>
> >(3) Indentation helps the reader if it is consistent: so should also
> >be enforced by the compiler. In line with point (2), nesting should
> >be defined by *both* indentation *and* grouping keywords:
> >with the compiler enforcing consistency between the representations.
> >This means that the reader can rely on either indication of nesting,
> >since both are reliable.
>

I have strong disagreements about what followed. I strongly suspect that
it is based on no significant experience with significant indentation.

> Under NO circumstances should a compiler be enforcing coding styles.

There are good reasons whay Python has become popular in education and
the sciences. In practice novices have problems developing a consistent
coding style unless there are significant consequences from not having a
consistent coding style. Among workers whose primary task is not
programing it can be very difficult to get a mutually consistent
programming style unless their mutual inconsistencies, where it affects
legibility, have significant consequences. In principle these
consedquences can flow from the boss/teacher or from their
collaborators, but doing so uses up a lot of time and energy that are
far better used elsewhere. Putting this enforcement in the
compiler/interpretter/editor gets a ton of stylisstic decisions out of
the way so that far more important issues can have priority.

> Significant indentation is the dumbest idea since paper tape.
>
> Ergonomics dictates that the screen dimensions, fonts and indentation
> units that I choose for my viewing comfort should have absolutely no
> effect on your choices.

Strictly speaking Python restricts none of your choices the screen
dimensions, fonts or indentation units. Normally indentation
significant languages such as Python, Occam, and Haskell in the
appropriate mode, do not have specific indentation units, they only
enforce an increase of indentation for each level of nesting per
sytactic construct, and indentation consistency for the current
syntactic level. However Python's community has developed a style
guide of recommended practices, that is very pragmatic in its
recommendations, readilly enforced by tools such as editors or IDEs,
widely followed in the community, and enforced for the main public
distributions as the leadership of the individual development efforts
have come to believe that a consistency of style is a good idea.

The limited ergonomic studies that have been done suggest that humans
are both flexible and consistent in their ergonomic preferences. They
have trouble consistently recognizing indentation if it is only one
character and can miss the start of lines if it is over eight
characters, but can handle indentation of two to six characters with
with only minor differences in performance. In latin alphabets, as the
line length beyond the indentation starts exceeding fifty to sixty
characters reading performance degrades. As the number of nesting
levels gets above four the ability to keep track of detailed logic
degrades (I suspect related to the nominal limit of seven items a
human can keep track of.) The ideal Python style: four spaces of
indentation per syntactic level, a strong preference for no more than
eighty characters per line but exceptions allowed to keep statements
or strings to a single line, etc are consistent with what is by and
large universally applicable style guidelines.

Your choice of scrren dimensions, fonts, indentation units etc will
interact with other aspects of ergonomics that you do not list: line
length, identtifier size, nesting level, comment structure etc. It is
common, for example, for programmers that indulge in large numbers of
nesting levels to want to compensate by making the indentation units
small. Similarly long line lengths make it easier to write long
statements without factoring out and naming the components in a way
that clarifies the logic.

> Indentation does aid human readers and should be applied consistently
> ... by means of a structural editor.  Given a properly designed
> language in which control constructs expect a demarcated list of
> statements, then matching scopes will have matching indentation and
> structural mistakes in the code will be apparent due to statement
> misalignments

While this addresses some sources of errors, I tend to believe it is the
more superficial one.

> Python got many things right, but the whole idea of significant
> indentation in a modern language is a non-starter.  I understand why
> Guido thought it might be a good idea, but he really should have left
> it alone.

If it were a non-starter Python wouldn't be one of the most popular
languages in use today. Guido got the idea from years of experience with
ABC, a teaching language he had years of experience with as one of its
developers.

[toc] | [prev] | [next] | [standalone]


#1008

From"BartC" <bc@freeuk.com>
Date2013-10-23 19:09 +0100
Message-ID<13-10-025@comp.compilers>
In reply to#1005
"George Neuner" <gneuner2@comcast.net> wrote in message
> On Thu, 17 Oct 2013 11:06:26 +0100, Martin Ward <martin@gkc.org.uk>
> wrote:

>>This also affects programming language design:
>>
>>(1) Rather than use "{" and "}" for every type of grouping, each
>>different type of group such as an if statement or while loop, should
>>have its own opening and closing keywords.  This is something that
>>modern COBOL gets right (along with the many things it gets wrong!)
>
> C's mistake was not in using (or over using or abusing) curly braces.
> Rather, C's mistake was in defining the scope of its control
> constructs to be a single statement rather than a demarcated list of
> statements.  Had C control constructs always expected a list of
> statements - thus *requiring* the scoping braces - many stupid
> programmer errors might have been avoided.

C source code is quite resilient (when it comes to adding/removing
newlines, copy&pasting etc). But I have a problem with braces, because
there are so many combinations of ways to place them (especially, as
you say, when they are also optional), and they tend to get in the way
too.

> I don't object to closing keywords [in fact I prefer Pascal-like
> syntax, though Modula3 and Oberon are better examples than Pascal
> itself] but I don't agree that they necessarily make errors easier to
> spot for human readers.  Closing keywords are nothing more than
> syntactic punctuation, and punctuation in human language normally is
> absorbed by readers at a subconscious level.
>
> I despise stupid keyword reversal closings such as IF..FI - loop can
> go jump in the pool and tceles sounds to me like a high speed train
> (and probably is a homophone for a swear word in some language).
>
> Things like <keyword>..END<keyword> get unwieldy when keyword phrases
> may contain optional attributes, such as in generalized loop
> constructs where the demarcation keywords may have to include labels
> and/or conditions.
>
> My preference is simply for a common END keyword used by all
> constructs. I think keyword case consistency is important, but I think
> the choice to use all upper or all lower should be left to the
> programmer.

My own syntax uses 'end' for all block endings. But it also allows an
optional keyword to follow, such as 'end if', in which case it must
match the one that opens the statement containing the block.

There are also (built-in) macros that allow forms such as 'endif' to
be used (so making the space optional), as well as the obligatory
'fi', 'esac' and 'od', which map to 'end if', 'end case' and 'end do'.
(I've used 'fi', 'esac' and 'od' for 30 years, they seem completely
natural to me. However, 'hctiws', 'pool', 'nigeb', 'noitcnuf' and such
look seriously weird...)

[ COMMENT looks fine to me TNEMMOC -John]

Anyway, I provide a choice, and the extra forms allow the compiler to
pick up mismatched 'end's too.

> Python got many things right, but the whole idea of significant
> indentation in a modern language is a non-starter.  I understand why
> Guido thought it might be a good idea, but he really should have left
> it alone.

(As it happens, my current project is to translate code written in the
syntax of my choice, into Python (as well as a one or two more
mainstream languages). The indented format is trivial to generate, but
since I will rarely need to look at it, I don't care what it looks
like! I just prefer that in the source syntax, a block of statements
needs to be terminated, which at least tells you when you've reached
the end (and don't have more lines off the screen, or accidently
deleted!)

--
Bartc

[toc] | [prev] | [next] | [standalone]


#1357 — Re: Comments, was Programming language and IDE design

From"BartC" <bc@freeuk.com>
Date2014-08-01 13:15 -0400
SubjectRe: Comments, was Programming language and IDE design
Message-ID<14-08-001@comp.compilers>
In reply to#1008
"BartC" <bc@freeuk.com> wrote in message news:13-10-025@comp.compilers...

> (I've used 'fi', 'esac' and 'od' for 30 years, they seem completely
> natural to me. However, 'hctiws', 'pool', 'nigeb', 'noitcnuf' and such
> look seriously weird...)
>
> [ COMMENT looks fine to me TNEMMOC -John]

That would be preferable to actual Algol-68 syntax which seems to use
COMMENT ... COMMENT bracketing. If used to comment out blocks of code, you
can't tell, at a glance, whether any particular COMMENT is an opening or
closing one! It makes nested comments awkward too; a bit like using {,{
braces instead of {,}.

--
Bartc
[Algol68 used comment, co, #, or � (a cent sign) in matching pairs
to delimit comments, sort of like recent languages use '' and "" for
strings.  No doubt it seemed like a good idea at the time. -John]

[toc] | [prev] | [next] | [standalone]


#1014

FromStefan Monnier <monnier@iro.umontreal.ca>
Date2013-10-24 10:55 -0400
Message-ID<13-10-031@comp.compilers>
In reply to#1005
>> Similarly foolish wisdom is seen in IDEs (Integrated Development
>> Environments) which allow the programmer to create hundreds of lines
>> of code with just a few clicks of the mouse.  Thus instantly creating
>> a significant maintenance effort.
> 99% (or more) of generated code will never be touched by a human.
> Probably 80% of it even will never be looked at.
> I have never read anything which suggests to me that Dijkstra was - or
> would have been - against source code generators.

IIUC, the OP was referring to the use of things like templates.
I.e. case where the generated source code is then edited by the user.
DSLs, macros, compiler compilers, and other code generators are
completely different, since the generated code is constantly
re-generated: it's not "source" code.


        Stefan

[toc] | [prev] | [next] | [standalone]


#1018

FromGeorge Neuner <gneuner2@comcast.net>
Date2013-10-24 19:57 -0400
Message-ID<13-10-035@comp.compilers>
In reply to#1014
On Thu, 24 Oct 2013 10:55:09 -0400, Stefan Monnier
<monnier@iro.umontreal.ca> wrote:

>>> Similarly foolish wisdom is seen in IDEs (Integrated Development
>>> Environments) which allow the programmer to create hundreds of lines
>>> of code with just a few clicks of the mouse.  Thus instantly creating
>>> a significant maintenance effort.
>
>> 99% (or more) of generated code will never be touched by a human.
>> Probably 80% of it even will never be looked at.
>> I have never read anything which suggests to me that Dijkstra was - or
>> would have been - against source code generators.
>
>IIUC, the OP was referring to the use of things like templates.
>I.e. case where the generated source code is then edited by the user.
>DSLs, macros, compiler compilers, and other code generators are
>completely different, since the generated code is constantly
>re-generated: it's not "source" code.

My sense was that OP was referring to application wizards more so than
templates or macros.  In any event, I disagree with the notion that
where the fix is applied makes a fundamental difference.  To me the
difference is the probability of a programmer having to look at the
output of the generator.

To reveal potential bias: I have developed GUI applications on Mac and
Windows since early on (MacOS 2 and Windows 3) - I've written
applications for them from scratch, using skeletons and using wizard
generators.  I also have done a fair bit of bare metal embedded work,
and have created several DSL tools myself for various purposes -
including one commercial product.  Consequently I have spent quite a
lot of time over the years poring over code generated by various tools
... assembly listings, parser code, templates and, of course, the
output of my own DSL tools.

IME wizard framework code is simultaneously the least likely to be
looked at, but the most likely to require direct modification when
developing a non-trivial application.

DSL, template and macro generated code is more likely to have to be
traced through - because, charitably speaking, the errors and warnings
from compiling them, and the problems from using them quite often are
difficult to understand without doing so.  However, as you say, it is
the usual case that the problem will be solved in the DSL or template
source.

YMMV,
George

[toc] | [prev] | [standalone]


Back to top | Article view | comp.compilers


csiph-web