Intent
Jason Marshall
jmarsh@serv.net
Sat, 01 Apr 2000 09:15:01 PST
>
>From: Jason Marshall [mailto:jmarsh@serv.net]
>
>> Recently, btanksley@hifn.com wrote:
>>Talk of
>>whiz-bang ways of implementing yet-another-language-with-some-
>>induction-logic is, while interesting, old hat, and does nothing for
>>readability before I've had my morning coffee, which is exactly when
>>I'm going to botch the code.
>
>Grin. I certainly understand that.
Here's where things get trickier. There's a severe shortage of
programmers
in the good-great category. We're short on architects (me), and we're
way
short on artists (also probably me), and so far, software engineering
has been
an artform, no matter what people try to tell you. It's really no
different than
architectural engineering. You want something to stand up, sure, but
you
want it to be functionally elegant, and to not fight you all the time.
I can't
honestly say I'd like that state of affairs to change, but then, the
'system'
works well for me already.
Anyway, that wasn't where I was heading with that. Where was I? Ah,
yes.
So since it's hard to find good help, this means I am always going to
have
at least one coworker who is, essentially, me without my morning
coffee,
but all day long. Even barring this, there's always going to be The
New
Guy, fumbling around as s/he figures out how our codebase functions (or
doesn't, as the case may be). I would love to be able to stack the
deck
in favor of the adequate programmer being capable of a significant
fraction of the tasks that a good/great programmer can accomplish.
I want an executive summary of my code. I further want to be able to
indicate that certain salient features of a module of code are
non-negotiable. They are what makes the module functional. I should
be able to watch that no one comes along and breaks this behavior,
in the name of new functionality, on accident. DBC and inheritance
try to accomplish this, but I don't think they cover enough aspects of
the code.
This essentially means that I want a delinter as standard equipment for
developers. I want to be warned when a feature of my code is lost or
gained. This should help track down unintended side effects, which
means fewer bugs. I have more interesting things to do with my time,
frankly.
>>No one talks of formalized metadata, which is what I am after, and
what
>>I thought/think Fare is after. Why?
>
>Because you don't talk about it? I mean, if it's interesting, talk
about
>it! Don't dis my language because I don't talk about what you're
interested
>in.
Fair enough.
>Okay, the topic is a lot clearer to me. You want metadata, and you
want it
>embedded in the language. IMO, it would be best as an optional thing,
but I
>don't mind it being required. You don't actually object to
concatenative
>languages; you simply want a language with metadata provided. (You
should
>have _said_ that, instead of just stating that concatenative languages
were
>inferior.)
I want explicit metadata as a standard, yes. If it's not part of the
design
process, and doesn't improve static checking of the code, then I don't
know
how Useful it is. While it's true that a lot of metadata can be
assigned at the
function/method level, I am still not entirely grasping how you prevent
loss of information in the translation from brain-to-silicon within the
body
and signature of the method in a terse form that relies on deductive
logic.
>Okay, try this on for size: a concatenative language with two types of
>annotation. The first, in the form ( x -- y ), appears at the
beginning of
>the word definition and is a type description (x and y may be any
number of
>type names, seperated by spaces). The last item in x is the type of
the top
>of the stack (as with traditional Forth stack comments). Types are
handled
>entirely statically, and are fully polymorphic (including return
values).
>The second annotation, in the form ( x ), appears anytime within the
>definition of a word, and is a stack naming (x may be any number of
one-word
>names). Names for stack elements may be traced at compile time, and
must be
>consistent within a given definition.
>
>example:
> 3 2 ( adder addend ) swap ( addend adder ) + ( sum )
>or
> ( number[myType] number[myType] -- number[myType] )
> ( adder addend ) swap ( addend adder ) + ( sum )
>or
> 3 2 ( adder addend ) swap ( adder ) + ( sum )
>
>The last one of these demonstrates that the stack names don't have to
name
>everything on the stack.
I'm mostly worried about names between code modules, where most of the
trouble will crop up.
But if you name the variables, the system can labor to sort out which
variable
order makes most sense, based on data alignment issues, frequency of
argument use, difficulty of reordering at the caller, etc. Your
function
implementation from four months ago will likely no longer maintain your
optimal ordering as you determined when you first wrote it, and woe be
unto s/he who changes the order of his arguments after everyone else
is already using his/her code.
>>> Of the two of us, who's more likely to reveal the most intent?
>
>>By sheer volume of citations of intent? Your users. You wrote the
code
>>once, and now everyone else is having to live with your mistakes (and
>>you are human, so don't imagine you haven't made any, because you
have).
>
>You missed my point. Take two people, you and me, writing code in our
>seperate languages: yours with named parameters and mine being
>concatenative. Which OF THOSE TWO PEOPLE will reveal more intent by
means
>of their language's mechanisms which are designed for that purpose?
>
> - The concatenative language is designed for quick, easy factoring
and
>refactoring, allowing the author to create many functions which work
>together to solve his problem, and leave many component functions
which may
>be reused.
> - The parameterized language is designed to allow the programmer to
name
>his parameters, and communicate those names to later reusers.
>
>Both languages have ways of communicating internal intent to the
external
>world, as well as structuring to preserve internal intent. Do you
really
>think that one of these MUST be more revealing than the other?
>>I am familliar with the classes of mistakes programmers in team an
API
>>settings make, in real development environments.
>>I understand that Kyle has grasped this, and that you see it as a
>>non-issue.
>
>No, I don't see it as a non-issue -- I simply see many other issues to
deal
>with, which add up to readability.
>
>Note that Forth traditionally has no type checking at all (although my
>suggestion for type checking, above, is based on a Forth type
checker), and
>even large projects in Forth don't run into that particular problem
very
>much -- almost certainly because it's so painful to use large numbers
of
>parameters in Forth.
I keep bumping into situations where static type checking seriously
erodes
the advantages gained by reflective code. Sometimes pushing error
discovery off until runtime comes back to bite you in the butt.
>>Not in the least. People want flexibility in a language in case
>>the environment isn't subtle enough for their tastes. Then they turn
>>around and complain because everyone comes up with a 'clever' synonym
>>for the code they would have written, sometimes correctly, sometimes
>>totally wrong, but either way, totally greek to their peers.
Formalism
>>takes the edge off such concerns over abuse of power. Here is your
>>rope sir, but you have to justify any requests to tie it into a knot.
>
>The odd thing is that I think I understand what you're saying (both
times
>you've said it), and I'm just about certain I agree entirely with it,
but I
>_still_ don't see what on earth it has to do with our discussion.
What does
>this have to do with named parameters versus implicit parameter
passing?
Because formal logical naming of parameters is a type of formalism.
>>> -- except that you have a huge translation layer, and I have a tiny
>>> one.
>
>>I have a segmented translation layer, which is an important
>>distinction.
>
>I have three low-level segments:
> - the quotation system (which defines a 'function structure' and
provides
>ways of accessing its fields and compiling natively the function it
>indicates; the function structures contain properties such as
profiling
>data, frequency of calls, and so on; this layer is also written in
processor
>dependant code).
The segments to which I refer fall within the spirit of your quotation
segment.
>>You have a tiny translation layer, or you're falling victim to the
>>incomplete implementation fallacy?
>
>Well, there are two systems like this that I know of which have been
in
>commercial use for five to ten years now. Add a third, if you count
Elate
>(which uses a similar design but with a slightly different emphasis on
the
>underpinnings).
>
>>How big is your standard library going to be?
>
>If it includes everything TUNES wants, infinitely large. However, I
expect
>it to fit on a floppy.
Okay, so in order to compete on the merit of size alone, my interpreter
has to provide enough extra value to reduce the verbosity of the core
libraries. I am hopeful that such will be the case. That was the
message
I was trying to get across.
>>Concerns over how big an 'unabridged' edition of the machine would be
>>have some merit, but not as much as you're attributing to the issue.
>
>Okay, here's the concern I'm expressing: contrary to your statement, I
>believe that my optimiser, with or without metainformation, will
produce
>compact, efficient code. I base this opinion on systems similar to
mine,
>such as Quartus Forth and 4THCOMP.
How do these systems benchmark compared to C or C++ equivalent
code? I've been curious about how these other styles compare to
the rest of the industry.
>>There is no requirement that a compiler issue, or the
>>interpreter honor,
>>any optional data. If the optional data represents 80% of the
>>dictionary,
>>and 90% of the implementation complexity, who really cares? All I've
>>done
>>is provide a formal vessel into which optional tools can place their
>>data, in an attempt to avoid ad hoc formats. What does that hurt?
>>Nothing, according to the industry examples I can find.
>
>Our discussion used to be about a language which _required_ parameter
names
>to be included in every call. I don't know what you're discussing
now, but
>it's definitely not the same thing. Could you provide an URL, or give
a
>description of what you're talking about?
I'm discussing things you snipped from my previous letter. Your
comment on
size issues I assumed was directed at my general desire to have a
generic
markup system for the code, of which parameter names were but one
markup. Apparently I misinterpreted where you were going with that.
>>Different environments will contain a different subset of the content
>>handlers for the language. My deployment environments won't care
about
>>debug data. My dev environment will. My palm pilot doesn't care
about
>>MPP or high precision math or vector math, or advanced speed-for-
space
>>tradeoffs. My workstation doesn't care about space-for-speed
>>tradeoffs,
>>but when I'm downloading a new multiplayer game off the net, I'd much
>>appreciate if it was usable the first time I ran it. No VM I know of
>>is giving me that.
>
>Check out Elate, formerly known as Tao OS, at
>http://www.tao.co.uk/2/tao/index.html. Very cool. Very similar to
what Sam
>and I are building, and does exactly what you say.
And commercial, yes? If I've learned anything, it's that you always
give the razor
away for free, and then you talk about selling the blades. Every
language
someone has forced developers to buy has been marginalized. You want
to make
money off a language? Fine. You wrote the thing, don't you think that
qualifies
you to make a killing on consulting contracts? Books? Just please
stop this silly
nonsense of trying to sell the basic runtime.
Regards,
Jason Marshall