Comments on: A change to paths for blocks
I must bring this up again... because I find it one of the annoying things about using blocks as data structures. You might think I've gone crazy to mention it. (Perhaps it's true.)
Yes, at times I want to use a block like a "structure" (a non-contextual storage object.) It's usually for simple little scripts where I don't want to build an object, etc. For example, right now I'm working on a small script to help construct the C part of plugin interfaces.
For example, if I have a block:
user: [name: "Steve" age: 38 country: France]
there are times when I want to use the words for selecting their related values, like:
Of course, this does not currently work, because the selector must be of identical type (it is age: not age.) Therefore, I must write:
print select user to-set-word 'age
To modify the value, it's even less friendly looking:
change next find user to-set-word 'age 40
and, of course, it's not really that simple if we're not sure that the word age is within the block. We would need to check the result of FIND before doing the CHANGE.
But, what if we could write:
It's not a new idea, but it seems useful -- simple, friendly.
However, it's not free. There are issues and consequences.
For instance, if I have a block:
blk: [a: b b: 10]
This happens because the path selection action will match any word. This is necessary for backward compatibility.
I'm sure that some of you will have strong opinions one way or the other. It took only a few lines of code to modify R3 A77 to try it out. Only the path behavior has changed; SELECT has not changed and can be used for the compatible behavior.
We will see where this takes us.
I've been missing this for a long time as a way to avoid using objects for small databases. However the issue at the bottom might be a bit of a killer for user defined words.|
Yes. It's quite nice. I just used it to set the exports on a code that helps build plugin modules. It made the code clean and simple:
title: "Plugin test"
f1: command ...
f2: command ...
code/rebol/exports: collect-words/set code
The code is also more readable.
Hmm, shouldn't these cases be handled by map! ?
I mean, shouldn't we rather optimize map! than try to make block! "too smart"?
I often use blocks instead of objects for speed and mem use reasons...
its nice that we can now have a spec and an object of that spec be used without differences in the path notation.
Objects and maps require their selectors to be unique (for maps, upto lit-get-set equivalence). Blocks allow their selectors to be duplicated. If you combine that feature with lit-get-set equivalence you may create too much confusion.|
I'm with meijeru, that mixing blocks with object addressing makes it quite complicated.
Another idea (just thinking loud) _if_ a block contains only set-word / value pairs, then use only the set-words as selectors.
a: [a: b b: c]
b: [a: b b c]
c: [a b b: c]
Though I think that this creates too many surprises.
a/b == 'c
b/b == 'b
c/b == 'b:
This is a tough one. It sounds very appealing on the surface. I often want to use a spec-block as a block, but it's a pain, or you use wrappers. On the other hand, could it make it harder to write generic routines that work correctly, because of assumptions we make about these "structured" blocks?|
still thinking ...
how about a special path notation?
a: [a b c d c: e]
a/c == d
a//c == e
So, "//" would only look for set-words.
This is one of the first things I tried on blocks.|
blk: ['a 1 a 2]
REBOL 3 return 1, REBOL 2 return 2 (, which I think is more correct). The problem is how to specify a set-word! in a path without actually setting anything. What about:
Is that possible?
Since the notations 'word, word, word:, :word and :word: are all already used somewhere, we could use another prefix symbol used exclusively for the get case. It could the be followed by the conventional : for set use.
The &, ! are good candidates since they are shortly typed and not yet associated with other REBOL uses as a prefix. Some languages use the & as an indirect content accessor.
The (at), |, #, *, +, ^, - and the DOT (.) are already used but some are more easily accessed than others when typed at the keyboard (single key - no key combination). For my french keyboard these are : #, *, +, - and the DOT(.).
Look at them when used :
/&word /&word: /!word /!word:
/(at)word /(at)word: /|word /|word:
/#word /#word: /*word /*word:
/+word: /+word: /-word /-word:
/^word /^word: /.word /.word:
I think the $ % " / or (at) could do the job but may become confusing since they are already in use.
But may be I am on the wrong direction.
Then I would use the above suggestion from John Niclasen.
This is the one that most resembles what is already in use but it's longer to type and this conflicts a bit with the targeted speed objective. Clarity would be safe for me in this last case however.
Post a Comment:
You can post a comment here. Keep it on-topic.