# Programming language malleability, etc.

## cpcogan — 2004-12-30 21:48:11

    I found X's idea of having function results go to the queue or to the

    stack depending on their data-or-function type interesting. What I

    liked about it was the idea of the underlying system doing something

    automatically that I would have to do "manually" otherwise.

    This is in fact a major design goal of mine: Making the way things

    happen be what we want to happen without having to explicitly specify

    it, and yet doing so without a table of rules and such. That is, the

    idea is to make the system "just happen" to work in such a way that

    it frequently does what we want it to just because that's the way the

    pieced of the "mechanism" happen to work together.

    Achieving this requires carefully choosing our primaries. It's like a

    mathematical system where we have so carefully chosen the postulates

    that the resulting system of theorems just happens to be one that is

    useful to us. Some games are this way, too (Go and Chess come to

    mind, especially Go, though there are places in both games where the

    underlying simplicity has been corrupted to make them more playable).

    One of the things about a good concatenative language that I like is

    that we may *never* need to "corrupt" the underlying mathematical

    structure to make them workable. By finding suitable alternatives to

    loops and variables and such, we may finally have languages in which

    we can have *BOTH* genuinely practical and mathematically pure.

    This is the sort of thing that can happen when the foundational

    issues of a discipline are adequately dealt with. Spending our days

    constructing loops and If-then-elseif-then-elseIf-etc constructs is

    silly, when you think about it (and annoying as well). That's exactly

    the sort of things *computers* are supposed to be doing. And yet,

    here I sit, day in an day out, writing loops and If-then-elses and

    such in VB .NET.

    This brings me to: Malleability. Prototyping has been around for a

    long time, even in the software development business, but most

    programming languages do not lend themselves well to a prototyping

    approach, largely because of the requirements of all the language

    constructs that make modifying a program in useful ways much more

    difficult than it really should be, most of the time.

    Spoken and written language have the malleability that programming

    languages should strive for (or at least toward). Our own programming

    languages have a lot of this malleability that's missing from most

    conventional languages.

    Why prototype? Because, if you can work out the entire design before

    coding and testing anything, then you are doing something that's too

    routine to be interesting, and possibly too routine even to be useful.

    We need to design software by thinking and programming and testing,

    if we are doing something at all novel, because that's how we find

    out what a near-best or at least good-enough way to do it is. The

    structures we build in software are too rich in their working-out to

    be handled well by the static-engineering approach.

    And, as soon as we *do* work something out so well that we can handle

    it statically, it becomes just another component in some much larger

    structure that still needs experimenting to work out fully.

    Developing new software is a little like scientific theory building;

    we formulate a hypothesis, work out a prediction (a software

    implementation to test) and then we test the hypothesis (run the

    software) and consider whether the results falsify the hypothesis

    (show that the software is workable).

    Of course, paradoxically, languages like Joy give us the *best*

    chance of doing things by static-engineering methods, because getting

    rid of loops and variables is a major step towards making them have a

    static structure that reflects the process we are trying to

    implement. That is, instead of thinking of something as a loop (for

    example), we can think of it as a black box that requires certain

    inputs and provides certain outputs, but we don't have to know what

    it really does inside.

    In a sense, the problem with loops is that they are black boxes that

    have been open up and their guts strewn over many lines of code, with

    all the gory details taking up mental and source-code space. I want

    to say, "That's really ugly. Put that into a black box where it

    belongs."

    Ordinary languages allow use to make a black box for *specific* loops

    (etc.) of course, but they don't allow us to make a *single* black

    box for all loops that have certain abstract characteristics (such as

    performing an arbitrary piece of code N times). For each arbitrary

    piece of code, I'm very likely going to have to make another such

    black box. This is because we can't pass code as parameters in

    ordinary languages; the code has to be hard-coded into each loop or

    other such construct. Ugh.

    The greater hiding of "guts" allowed by combinators actually

    *reduces* the need for the malleability I spoke of earlier, because

    it makes these things into discrete "building-block" units (along

    with ordinary functions like calculating sqaure roots and such). As

    discrete building blocks, they are much easier to manage

    conceptually, so we are able to mentally grasp "larger" problems with

    the same work, thus enabling us to do more of the "hypothesis-

    testing" in our minds, thereby reducing the need for malleability. Of

    course, in practice, we want both, so we can tackle ever more-

    interesting problems successfully at less cost in drudgery and time.

    Conclusion: Languages like Joy give us two major benefits not found

    in the mainstream languages: Great malleability so we can easily try

    programming hypotheses out *AND* much greater manageability by static-

    engineering analysis methods, so that the malleability may in some

    cases be much less *needed.*

    --Chris