Tue, 11 Apr 2000 14:27:26 -0700
From: Jason Marshall [mailto:email@example.com]
>>From: Jason Marshall [mailto:firstname.lastname@example.org]
>>>This is true, but totally irrelevant.
>>>Three arguments of the same data type are still going to compile
>>>and have only a 1 in 6 chance that an arbitrary ordering will be the
>>>Two arguments have a 50/50 chance of being in the right order.
>>Unless you have some unusual insight into programmer's minds, I don't
>>see how you could come up with figures like that. Surely even the
>>stupidest programmer writes better programs than a random text
>>generator, even if the types are truly the same!
>I'll simply cite Finagle's law.
I see your Finagle's law and cite the Peter Principle.
>As an aside, I take it you've never passed arguments in column, row
>order and wondered why your code doesn't work?
As a matter of fact, I haven't done _that_; I have wondered why an obvious
x-y pair was being passed in row-column order, but I've never confused the
two. I can't deny that I've reversed the order of parameters, though;
before I really understood Forth, for example, I used to reverse the order
of arguments to a division or comparison (in the process of translating from
infix to postfix). That wasn't a problem with Forth or infix, though, just
with me, and I've since gotten over it.
I've also never entered a wrong parameter name for an API which required
such (there are some in Python); I always look them up first.
However, this is all clearly and certainly possible. I can't deny it.
>>The purpose here is to develop easily checkable conventions -- or,
>>still, to ratify existing conventions -- which work with the
>>mind to make correct code easy to write. The ultimate in
>>ease of use, IMO,
>>is one parameter per function, with the name of the function entirely
>>determining the nature of the parameter; no need to expose a name for
>>parameter when the function describes its own use. Combinative
>>though, need two parameters, and brevity dictates that we allow more -
>>the limitations of the human mind insist that four is just beyond
>The ultimate ease of use is the minimal set of information
>perform a narrow task. Reducing argument count below that threshold
>introduces all sorts of nasty concurrency issues, which are, in my
>experience, far harder for even senior level programmers to deal with
>than anything I've seen discussed on the list to date.
True enough. This, together with my statements, is a good argument for
designing functions which contain minimal functionality. I believe, and
experience with Forth seems to indicate, that this coincides with passing no
more than three parameters to each function -- if you ever write a function
which needs more than four, rewrite.
>>Oh, BTW, a side note: why not borrow Smalltalk's syntax for
>>such? ST has a good, solid set of conventions for named parameters.
>>course, you would want to remove ST's support for unnamed params (and
>>no doubt make other changes in the syntax and semantics), but that's
>>to be expected.
>I'll have to look at this issue again. Try to hunt up some use cases,
>similar to the ones Bertrand Meyer has done for design contracts. I'm
>sure such must exist.
I'm sorry, I don't understand. What did you want me to do? Find use cases
for Smalltalk? They're all over the place. The original WikiWiki was
written in Smalltalk. Or did you mean find use cases for named
parameterised functions in Smalltalk? Most of the Smalltalk library works
>I mean that named parameters gives compile-time assurance of
>appropriate argument alignment, much as many compilers (C is a notable
>exception) give assurances of argument count and type compatibility at
True. And named dataflow (i.e. stack labels) gives similar assurance, while
keeping the putative advantages of implicit parameter passing when
>>>>A Joy programmer would prefer to wrap stuff, since that reduces the
>>>>number of parameters.
>>>Preference != fix, of course.
>>>But I somehow doubt we'll solve this one in this language iteration.
>>This would be especially difficult since I refuse to acknowledge that
>>anything's broken. Conventions are the only "complete" solution to
>>the difficulty of programming. Machine checkable conventions are
>>the best sort.
>>Human checkable ones are the next best. Everything we've discussed is
>Well, you've just illustrated a human check, and I took exception,
>hoping for a machine check.
We've discussed a lot of things, but I can't think of one which is exclusive
>>>Compact does not equal "concise", nor "readable"
>>Incorrect -- compact code is also concise. It's not always readable,
>>though. It's too easy to make code unreadable in an effort to make it
>Which was the main point I was trying to make.
Okay. It was what my original sentance, which you disagreed with, assumed.
Now that we understand each other a little better, do you agree?
>If you mean 'concise'
>when you say 'compact', then please do say 'concise'.
I'm sorry that my words failed to communicate to you, but I think you're
going a little far in implying that this is my fault, or that I should
change all my future word use to accomodate your linguistic prejudice.
>It's less likely
>to lead someone with only peripheral knowledge of your ideology to
>think you're advocating using 1 letter variable names and 4 letter
>function names in the name of 'compactness', much the way
>sayings like Knuth's "premature optimization is the root of all evil"
>lead to people designing horrible interface contracts because they
>can't be bothered with such trivial "optimizations", which are,
>donchaknow, evil anyway.
Why on earth would choosing a different word change a fool's understanding
of what I have to say? And why should I care? It's one thing to discuss
these issues with people who understand them (often better than I do); it's
another thing to go to lengths to clarify issues which they'll never be able
to use anyhow. And changing a single word won't correct anyone's
Not that misunderstanding a word like "compact" is anything in the class of
misunderstanding Knuth's admonishment. That's STUPID.
>>>>>I don't agree.
>>>>We reach a problem, then; I do agree. Not only do small programs
>>>>(because they can use fewer of the computer's very limited "fast"
>>>>such as registers), but they are also MUCH easier to understand,
>>>>things being equal (that is, "hand optimised" programs are not a
>>>>competitor in this category).
>>>All other things ceased being equal about fifteen years ago.
>>What on earth does this mean? Are you just trying to make fun of
>>I said? If I'm wrong, please rebut me. If I'm confusing and stupid,
>>please rebuke me.
>On the one hand, this goes back to the compactness vs readability
>issue, on the other, it plays into Moore's Law, where the number of
>calculations per second our code is being asked to execute is doubling
>every 18 months. So, really, all things are not equal, because we are
>being asked to write code of such complexity that our forebears would
>have laughed at the notion of ever doing such a thing. Any program
>that is sufficiently simple has insufficient functionality to be
>'interesting' to more that 10% of your userbase.
This is also known as "the software crisis." It keeps looming, always
ominous, always the subject of more books. I'm not saying it doesn't exist;
I'm just a bit tired of hearing it brought up as an unassailable argument
against everything. It's especially wearying to hear it brought up as an
argument against increased modularity.
>Now, I don't want you to get the impression that I'm against elegant,
>I'm playing devil's advocate here as much as anything else.
A vocation which I respect.
>But toy code should never be the measure of a general purpose
>language. It's the big projects that have to be big that will make or
>break you. Sometimes, you just can't get around having a 100,000 line
>program. Usually that means you've already reduced the problem from
>150,000 lines, but you're still stuck with what's left.
Nobody brought up toy code, much less used it as a measure. You're playing
>>>Complexity is not an option.
>>Well, we haven't addressed complexity, but code size is statistically
>>related to complexity. Larger code is more likely to be complex.
>>importantly, large code is capable of hiding more complexity, and when
>>reading large code it's natural to assume complexity.
>Users want complex logic. So there is a fundamental amount of
>complexity to everything we do, and that is irreducible.
No, users want their problems solved. Programmers ideally want to solve
their problems without complex logic, and if the complex logic is needed,
they don't want to think about it outside of where absolutely necessary.
Once you _have_ found the irreducable logic, you want to isolate it, and you
want to be able to ignore it. The smaller it is, the easier it will be to
>>If you don't have access to all of the code which depends on
>>your API, you have no business simply *changing* it.
>>(Making a new version is fine, but you can't force an upgrade.)
>Would that we could always have access to all our dependent code.
Then don't change the APIs.
>Remember, we're trying to design a language here. That means standard
>libraries, that will morph over time.
Of course. You're right. But they'll do so by coming out in new versions,
not by requiring every user to write conversions on the spot. (Ideally, the
system will handle creating conversions automatically, and I think that's
possible -- but I don't think it'll work the first time.)
At any rate, the issues you've been bringing up are trivial compared to the
other problems such an automated library upgrade would have to solve.