Re: [stack] things

spir <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <20090305110157.36fe3074@o>
Le Wed, 04 Mar 2009 11:47:22 -0800,
William Tanksley <[email protected]> s'exprima ainsi:

> spir wrote:
> > All those talks about concatenativity let me "dream" about a tiny
> > language designed only to exhibit some properties -- or the lack of
> > them. An attempt to have a base of concrete ;-) facts to reason.
> > Here a kind of informal description I wish you experimented language
> > designers will comment & criticize; before I really start a foolish
> > implementation. It may be written in Io (using a modified version of
> > IoPEG, see http://code.google.com/p/iopeg/), for I'm learning this
> > language.
> 
> Sounds like fun; I hope you enjoy it.
> 
> > Then I intend to explore how modifications will let the language get
> > or lose this one or that one property.
> 
> I agree that you'll learn something from this. Nowak is right that
> you'll also learn something valuable from using a good concatenative
> language, so you may want to start by coding something in a known-good
> concatenative language -- perhaps it might be worthwhile to code your
> new language in Factor or Joy. I'd say that Factor is the more practical
> choice, given the amount of documentation and libraries.

Yes, I think John Nowak is right, too -- thanks for his sensible advice -- and I'm considering using either Joy or Factor. The point is making something practicle (such as a parser) requires a minimum knowledge: I spent some weeks reaching that point with Io. My choice will probably depend on how fast I may feel "gemütlich" (comfortable, easy, at home) with one or the other language.

> > -4- plain text data
> > Basically, things are internally stored as plain text the same way
> > they are literally expressed in source code (thinking at TCL). Wich
> > should be the Lisp-like (...) expression above.
> 
> I hate this. It's your choice, but I don't think this is one of the
> pleasant features of TCL.

I understand this point of view and even agree it's stupid (I'll have to parse them to construct their structure anyway before doing anything). The purpose here is only to have data and code _really_ be the same thing. Then I may get rid of that: parse textual representations (of code or real data) as soon as encountered in source to store them into tree data structures.

> > -5- one unique "operational" primitive word: "write"
> > Write will take the topmost item on the stack and write it out into a
> > tree view like shown above.
> 
> Not unique. Most interactive languages have a "show top stack item"
> function. Traditionally it's named "." (Forth, I believe, started that
> tradition).

Sorry, I meant "single". I may use '.' for 'write' -- but it will actually show a tree view.

By the way, I have another issue with "code is data". Code is always valid data -- but is the converse statement true?

> > -6- every action is explicitely word call
> > There are some "meta-primitives", first of all push and pop that must
> > be expressed. Things read (or produced by possible future words) go
> > into an accumulator. Push moves them from the accumulator to the top
> > of the stack. Pop removes the topmost item. Do "does" code that should
> > be on the stack (if the code is a defined word, it may be referenced
> > instead).
> 
> Why do you have an accumulator? Why not just use the stack directly?

> Many Forth processors DO have accumulator registers, but they
> automatically merge them with the stack. I don't see why you'd use one.

Again the purpose is primarily self-pedagogical: to make it explicit that everything is an action/word/function:
	(1)
literal alone does nothing: (1) (the value) will briefly live inside the accumulator
	(1) push
is an action that lets 1 available on the stack for further process. I think at John insisting that everything is a function -- a feature I find closely related to concatenativity. May be wrong, but I feel the need to feel it with my guts ;-)

Then again I will get rid of this requirement in favor of a Forth-like behaviour were literals (including code expressions) are implicitely pushed.
One may also read that () means push -- but in fact parens are rather useful for "things" are inherently composite (and nestable): it make clear the difference between eg "(1 2)" and "(1) (2)" while without parens both would read "1 2".

> > An intriguing idea is to change Thing's structure into a kind of
> > nested record (or dict), or named tree, where nodes have
> > keys/names/indexes. Like for instance:
> > (point:(kind:center position:(33 99) color(127 0 255)))
> 
> I heard of one language that does this (I lack the time to search, but
> it's a derivative of LISP that processed dictionaries instead of lists).
> It's interesting to try to imagine what would happen if you attempted to
> execute a dictionary -- what would named elements of the dictionary do?
> 
> > [I do not know how to call such a mix of record and list.]
> 
> It looks like a record that maps from symbol/string to "item"s. By the
> way, I would recommend you name "item" something more standard and
> descriptive -- if it's always a list, you might as well call it a list.

Actually, I could name it node instead. When it happens to be a branch then it is indeed analog to a list -- and may be implemented as a list. Only the outermost thing must be a branch/list, even if it happens to contain only a single leaf node, or even none.
I read something about a data type that gets rid of the distinction between a "1-uple" (how do you call tuples of length 1 in english?) and the single item it holds but I can imagine it practically. Also, a 0-uple should be (equal/identical to) 'nothing'?
 
> > Then a word definition written as
> > 	name:(block)
> > directly maps to a thing literal without any word-name data item: the
> > word's name is the top-level key of the thing.
>
> That's one thing you could do, but it doesn't tell you what happens if
> someone types:
> 
> name:(some thing with:(something else))

[Assuming I get rid of explicite push]
It stores the right hand literal in a dict under the name 'name'. Then what would do "name do"?
some & thing are pushed on the stack. with:(something else) too. If ever it happens to be valid code code, then a combinator (in the sense of joy) could use it as argument. Now, the name "with" is useless, indeed.
After
	name:(some thing with:(something else) do)
then "name do" would push some & thing and should run with:(something else). But it's obviously inconsistent as a code expression because of the name. It seems to me that plain code (the right-hand side of a def) can be only flatly linear, unstructured, except for real data expressions -- I mean intended as data by the programmer.

> I don't know if you care. I don't, except for idle curiosity.

I just realize it builds a syntax for variables ;-)
As code and data have the same form, then 
	x : whatever
will store it under the name 'x' even if "whatever" is not *intended* to be the definition of a function/word. The interpreter cannot make the difference at this stage. Only when x is recalled for execution using 'do'.

This is also related to the question I asked above: is data always valid code? Is there any semantic distinction to do? It seems to me that in the worst case it will simply push the whole thing on the stack. It will actually do something when the thing itself contains 'do'. And as I have only one operational primitive (write), then
	x do
will perform something only if x contains tself the expression
	write do
Otherwise there will only be stack changing games.

> > 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.