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