Re: [stack] stOck

spir <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <20090311205342.51cc2391@o>
Le Wed, 11 Mar 2009 11:22:55 -0700,
William Tanksley <[email protected]> s'exprima ainsi:

> spir wrote:
> > John Nowak <[email protected]> s'exprima ainsi:
> > > His proposal is equivalent to dynamic scoping. Locals in Factor
> > are  
> > > lexically scoped.
> 
> > Excuse me to ask something that seems obvious to you: I simply don't
> > understand. My proposal is about a kind of "namable" stack (stock).
> > There are no additional variables, no variables outside the
> > 'stock' (read: data flow from func to func). No locals in the usual
> > sense neither, except if one calls 'locals', simply because they can
> > be named, the data items that will be deleted when used in a func.
> 
> If I read this correctly, you're suggesting that in addition to the
> "standard" stack, we add a dictionary into which name/data bindings can
> be inserted at runtime. This dictionary is (like the stack) passed from
> function to function and is always available.

Exactly. Except I proposed instead a kind of mixed stack-dict. But the principle is well what you express -- and implementing with a stack and a dict is easier. 

> Bindings in that dictionary are created by some means (you don't give an
> example), and are destroyed after their first use (I'm assuming that's
> what you mean when you say "the data items that will be deleted when
> used in a func").

I proposed in fact to reuse the existing syntax for naming functions/words. For instance

	:word 1 + :name 2 * :result 

(For this to be parsable there should be a distinct token to end func defs, like ';'.)
A name is bound to the current result, meaning what's on top of the stack.

> Am I even close here?

Yes.

> > In a stack-based language (without world/env data outside the stack),
> > there cannot be any lexical scoping, or do I miss a point?
> 
> Certainly you can -- for example, you can define a scope as the space
> inside some arbitrary syntactic form. Implementing that can be complex,
> depending on how powerful your language is, but it can be done.

All right. 

> > Adding the possibility to bind names to some of these data items does
> > not change anything about the data flow: the data are the same, they
> > follow the same path and 'die' when and where used as well: simply
> > some are named in the aim of making the programmer's life nicer; by
> > letting him give sensible names,
> 
> Okay, I think I can offer some critiques.
> 
> First, your proposal is concatenative (as you intended): the associative
> law still holds, and factoring is still possible. Good.
> 
> Second, by making the bindings delete themselves at first use, you solve
> the problem of knowing when a data item goes away. Good.
> 
> Third, you don't seem to propose a notation for any of this. How does
> the reader know when bindings are created or destroyed? Perhaps some
> conventional syntax would help: a! would create a binding named "a" and
> pop the top stack item as its bound value; using the name later will
> push the value back on the stack and remove the binding.

Exactly. And the process is similar to what Raven does; except that it creates local variables, while my proposal is about the "stock of data" that flows from func to func.
Actually, there was a notation proposed in the message that started this thread -- see above. Not so important as long as it's not misleading.

> Fourth, the fundamental problem with dynamic binding is that it's hard
> to tell where a name's coming from. It might help to provide a notation,
> to be used like a stack effect comment (and possibly type-inferenced in
> some languages). I'll use #( -- ) to indicate which bindings the
> function takes as input, and which it leaves in the dictionary.
> 
> So a function might start like this:
> 
> : quadratic ( a b c -- )#( -- root root2 discriminant )
>   ...
> ;

Nice ;-)

> ...so that function returns nothing on the stack, and instead lets you
> pull from the dict if you need it.
> 
> Dunno how excited I am about that, but there you have it -- the
> possibility of arbitrarily strong typechecking on names.
> 
> > avoiding stack juggling and dup-licating .
> 
> If the data "dies" when it's first used, then you will have to "dup" if
> you use the same data twice -- or you'd have to provide a syntax to get
> the value of a binding without destroying it. Example: a@.

What I proposed about that is: when entering a function, the names used twice in the body of this function are copied into a distinct "transient" dict. When leaving the func this one dict is blanked. Names used from the main data dict are erased like the one from a normal stack. So, while the function is executed, names not found in the main stack+dict will be looked up inside the transient dict.

> > If I remember well, you stated that a concatenative language needs not
> > beeing stack-based. I understood that you meant the pack of data
> > passed from func to func can be stored in another kind of data
> > structure. Maybe I miss a trivial issue here; anyway, I guess this is
> > precisely what my proposal is about.
> 
> I'm certain that structures other than a stack can be added to the
> standard stack. This (and Forth's dictionary) is just another example.

Forth dictionaries, as I understand them, are kinds of modules like in eg Ruby: distinct namespaces.

> I'm not certain that this idea is useful. Perhaps it needs to be seen in
> a real-world example. Feel free to proceed... :-)

Well, I already found a flaw myself: that naming in a function definition is different from naming at func call. Maybe Raven's way is better.

> > Denis
> 
> -Wm
> 
> 


------
la vita e estrany
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.