Re: [stack] function/object ambiguity + quotation alternative

William Tanksley <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <1236126154.5247.28336.camel@tanksley>
John Nowak wrote:
> William Tanksley wrote:
> >> The nesting in
> >> Scheme helps visually and things remain mostly understandable even if
> >> you don't know the arities of all the functions involved. That's only

> I really was meaning to compare idiomatic ways of writing code in  
> concatenative languages. Take the following code for example:
>     foo bar [baz] dip quux
> You will, in practice, get concatenative code like this. Now compare  
> to what might be the applicative equivalent:
>     (let ([(x y z) (foo input)]
>           [(b c)   (baz y z)])
>       (quux (bar x) b c))
> Here, it's clear that foo returns three values, bar only cares about  
> one, baz only cares about two, bar uses the first result of foo, baz  
> uses the second two, baz is independent of bar, quuz uses one result  
> from bar and two from baz, etc.

Okay, I agree. But there's another angle to look at this.

In many problem domains, clear and communicative names can be chosen
rather than "foo" and "bar". If that is done (and it normally IS a goal,
even if one sometimes honored in the breach), which code chunk "wins"?

I'd say it's pretty simple -- the code chunk that looks like it's
communicating in the problem domain (with one apparantly random word,
"dip"). The applicative language may use a little of the vocabulary of
the problem domain, but it's obscured in a tangle of parentheses that
may document to the programmer what parameters go where, but don't mean
much to the domain expert who should be able to check at least your
top-level algorithm.

> Getting all of this information out of the concatenative version isn't  
> possible. Does bar use one value? Two? More? What about quux? Does baz  
> depend on the result of bar? All of this is clear in the applicative  
> version but not the stack-based concatenative version.

The naive assumption is that every word depends on its predecessor --
that the order is utterly critical. This assumption won't let you down,
but it won't give you the best performance, either (and it certainly
won't help you analyse the code when there are bugs). To do better, you
need a smart enough development environment to tell you the signature of
each word -- or you flip open a glossary and look at the definitions of
the words. It's an extra step, but it's worth it.

> Again, in practice, I occasionally find this difficult when writing  
> code quickly to prototype something. If you don't, then I certainly  
> won't call you a liar. Perhaps I just have Scheme burned into my head.

I think you meant "when reading code". When writing, you either remember
or you have to look it up; the parens won't help you, because you're the
one who's writing them. With that assumption:

Remembering stack effects without a reference handy is not natural for
humans. No argument. Because of that, names and parens DO give an assist
which _is_ useful. But those are only useful for programmers in that one
context; they're an obstruction in all other contexts, much like stack
shuffle words are. The difference is that stack shuffle words are agreed
to be bad, and are avoided by all; parens and variables are claimed to
be unavoidable or even beneficial.

They're not unavoidable (concatenative languages don't need 'em), and
although they are beneficial in some circumstances, they aren't in all.
Of course, the ideal solution isn't permanent syntax; it's a tool that
underlays the code with syntactic cues.

> - John

-Wm
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.