What's your favorite year end method?

hendrik at topoi.pooq.com hendrik at topoi.pooq.com
Wed Dec 26 11:54:30 EST 2007


On Tue, Dec 25, 2007 at 10:13:07AM -0500, Mike or Penny Novack wrote:
> 
> >So language design doesn't matter -- it's all up to the programmer? I
> >disagree completely with that. I think it's a combination of the two,
> >and some languages are so bad, it's almost impossible to write
> >well-structured programs in them. That's why we aren't writing
> >programs in Fortran II any more. Of course bad programmers will write
> >bad programs in any language. But good programmers will write bad
> >programs in bad languages.
> >  
> >
> I will challenge that statement. Give me just about ANY language and I 
> can write well structured, well self documented code in it. THAT isn't 
> the problem. The problem is whether the average programmer given that 
> program to maintain will make shambles of it. You can write well 
> structured code even for an assembler.
> 
> >I think Scheme (and Lisp generally) is a special case in the
> >programming language space, because the prefix syntax departs from our
> >usual notation, particularly for arithmetic expressions.
> >
> There are just two "natural" placements, before (like LISP) or after 
> (like FORTH). The usual "infix" notation for arithmetic expression means 
> dependence on just how many operands the operation expects. That is 
> useless for GENERAL operations. If you think the "prefix" position is 
> unfamiliar, trust me, the "after position" (reverse Polish) notation 
> would be even more so. FORMAL arithmetic tends to use either prefix or 
> postfix. For implementers, postfix is actually easier (all evaluated 
> operands are already on the stack when the function is evaluated).

Traditional mathematical notation evolved/was designed for manual 
manipulation of algebraic expressions on paper.  For that, it'ws very 
good.  And I do mean traditional mathematical notation, with 
single-letter variables, juxtaposition for multiplication, exponents as 
superscripts, use of the second dimension for for division, and so 
forth.  It uses the natural visual grouping performed by the human 
visual system.  It's really good as a notation for polynomials.  Just 
try manipulation them with, say, just a change of operator priorities 
(additions before multiplaication, for example), or exlicit 
multip[licatino operators (which are normally omitted) and you will see 
what I mean.  it is a data structure on paper, optimised for the 
operations normally performed on it.

None of that is available in prefix or postfix notation.  Some of 
it survives with the linearized form of algebraic expression 
introduced by FORTRAN and preserved in programming languages ever since.

When mathematicians want n-ary operations, they use brackets and commas 
around the arguments with prefix operators.  Occasionally they use 
operatod syntax in which the operator typographically contains one of 
the operands (such as a box with the operand in it) so as to pack more 
oomph iton infix notation.  Or a notation with operands all around 
spatially, such as the definite integral (that one has a bound variable, 
too).

Attempts to do that kind of thing in programming languages has largely 
failed, possibly because of typographical complexity, possibly because 
the use of ad-hoc multidimensional notation is too difficult to parse.  
Algol 60 intended programs to be formatted specially for print 
publication, using normal mathematical notation wherever that made 
things clear, despite the unavailability of the same notation when 
entering the program into a computer.

Lisp has taken the opposite extreme -- everything prefix with lots of 
explicit parentheses.  It uses the explicit parentheses for variadic 
operations.  The big advantage here is complete uniformity.

My research group has experimented with notational variations.  We've 
tried postfix, since that is natural execution order, but found it 
inhumain.  We've since reversed postfix to make it prefix, and 
that was somewhat workable  (actually, we use semicolins.  Text between 
semicolons is left-right reversed, the semicolons are deleted, and then 
everything is executed left to right.  The language esds up 
consisteing of statements executed left-to-right, but the words within 
the statements are executed right-to-left).  Humans seem to need a 
notation where they see the operator first.  By the way, given our 
prefix or postfix notation, it's natural to have an operator accept 
several operands and return several results.  The challenge is to allow 
that and retain readability.)  We're still trying to figure out usable 
rules for the insertion of parentheses in this notation.  The only rule 
I've found so far is the constraint that in an expression line (a b c d 
e f g h), where operands and operators are executed in the order h, g, 
f, e, d, c, b, a, the entre expression removes nothing from the stack 
that was there before executing h (so the expression is in some sense 
self-containted) and the net result of executing the entire expression 
is to push on the stack all and only the value(s) returned ba a.

So the parentheses are entirely optional, and all operations have 
statically known numbers of operands (this is a form of static typing, 
by the way).  But the optional parentheses have semantics, and this is 
checked by the compiler.  This check is one of the things that makes them 
useful.

I'm not at all sure whether the a in (a b c d e f g) should be allowed 
to return anything but a single value, though.  Opinions and experience 
would be welcome.

(We also use square brackets around function bodies, and have toyed 
with curly brackets around type information.)

We have some of the advantages of Lisp notation -- uniformity, 
without some of its drawbacks -- difficulty of parenthesis matching.

 > 
> >
> >So if you write reports in Scheme, you restrict future development of
> >them to Scheme devotees, a very small percentage of people who know
> >how to write code, even the really bright ones.
> >
> The REAL issue of suitability if language to task is what are the 
> fundamental data objects of the language compared to the natural data 
> objects of the problem. Thus the LISP family is ideal if you are 
> processing lists, SNOBOL (today say bash + the standard 'nix shell 
> utilities) if you are processing strings, APL if your natural data 
> elements are vectors, etc. If you don't know in advance what sort of 
> data you will need to be processing most of the time, the great 
> generality of things like LISP family languages quite useful.
> 
> Ask rather why we see errors in coding, commonly made errors (thus 
> "buffer overflow vulnerabilities" in C applications because processing 
> strings of undefined length is not "natural" for C)

The real advantage of Lisp over C here is the universality of reliable 
storage management.

-- hendrik

> 
> Michael
> _______________________________________________
> gnucash-user mailing list
> gnucash-user at gnucash.org
> https://lists.gnucash.org/mailman/listinfo/gnucash-user
> -----
> Please remember to CC this list on all your replies.
> You can do this by using Reply-To-List or Reply-All.


More information about the gnucash-user mailing list