World: r3wp
[Core] Discuss core issues
older newer | first last |
Geomol 16-Oct-2008 [11104] | amacleod, you might get confused by some small inconsistent in REBOL? >> {a { ^-b} == "a^/^-b" >> {a { ^-b { ^-c} == {a ^-b ^-c} |
Sunanda 16-Oct-2008 [11105] | Amacleod -- please ignore my effort -- it fails to retain the tabs. Sorry! |
Geomol 16-Oct-2008 [11106] | (My last example was from the console, in case it isn't obvious.) |
Anton 16-Oct-2008 [11107x4] | Geomol, yes the known word just defines the context. I use two binds because there are two contexts involved - the h/q/1 context, and the function's context. (Each time you create a function, a context is created for its locals.) |
do bind [code b] ctx would not do what we want, because it would only bind the two words in the block ('code and 'b) to the context. | |
What we want is to bind the words *inside* the block that 'code refers to. Bind considers each word inside the block, checking to see if they are in the target context. If so, they are rebound to the target context. This step essentially gives the words a useful meaning, the meaning that's intended, and the meaning that's defined in the target context, not in some other context like the global context. | |
So BIND selectively "paints" a context over words in a block. BIND recurses into sub-blocks to do this, but does not get the value of words and recurse into them too, if they are blocks. This is why bind [code] ctx does not affect the CODE block; it only affects the 'code word (and only that instance of the 'code word, not any other instances floating around elsewhere in the system, in their own blocks.) | |
Geomol 16-Oct-2008 [11111] | What we want is to bind the words *inside* the block that 'code refers to. Ah yes. I get it now. |
Davide 16-Oct-2008 [11112] | Would be easier (for me) to have something like "do/bind-here code", where all words in the code are bound in the context where there is the "do". |
Anton 16-Oct-2008 [11113] | Davide, that is not possible in rebol, because there is no concept of "here". That is, there is no "current" context. That's just an illusion created by groups of words travelling together in blocks. Every word has its own binding. Just because several words in a block often have the same binding does not mean that the block knows anything of the context. This word-binding is a unique feature of rebol, and people used to other languages confuse it for scope, which is less flexible. |
Geomol 16-Oct-2008 [11114] | Why is it, that b is not auto-bound to the function in this example? >> f: func [b code] [do code] >> f "hi" [print b] ** Script Error: b has no value I mean, passing [print b] as an argument to the function, it's just a block of words without meaning initially. When handed to f, f takes over and will now do it. So f has to find out, what's the meaning of the inside of the block. First it finds the word "print", which makes sense. Then it find the word "b", and this doesn't makes sense to f. Why not? |
amacleod 16-Oct-2008 [11115x3] | Why: >> {a { b { c} == "a^/b^/c" but: {a { ^-b { ^-^-c} == {a ^-b ^-^-c} |
I need the entire text sting on one line... | |
{a^/^-b^/^-^-c} | |
Geomol 16-Oct-2008 [11118] | Yes, it's one of the 'funny' corners of REBOL. Are you sure, you really need it on one line? What are you doing with the string? |
Anton 16-Oct-2008 [11119] | Geomol, when FUNC is evaluated, a new function is created, along with a new "function context", as we say. The words in the function body block are then bound to the new function context. There are only two words in the block, 'do and 'code. So those are the only words affected. This binding only happens *once*, at function creation time. It does not happen again automatically when the function is evaluated for the first time, or any time afterwards. Even if it did, it would not affect the block of words referred to by 'code, because, as I've said above, BIND does not evaluate words to check if they are a block so it can recurse into them. (If it did, that would have far reaching consequences.) Not having to rebind words each time the function is evaluated keeps it efficient. If we want 'foreign' code to be bound to a function's context so it can interact with the function's locals, then we have to do it ourselves; functions created by FUNC won't do it for us. |
Geomol 16-Oct-2008 [11120] | I see. If it's more efficient (faster) this way, then it's a good thing! :-) I (and others) just have to remember it and act accordingly. |
Anton 16-Oct-2008 [11121] | Actually, it would be quite annoying for functions to automatically bind code like that. Suppose we had a code block and we wanted to send it somewhere, and to get there it must pass through a few functions not authored by us. Will the code make it, retaining its meaning ? That depends on whether we accidentally used any words that happen to be the same name as locals of the functions involved. If we did use such a word, then it would be rebound to a function's context and change its meaning. That's not typically how functions are supposed to be used. Functions are supposed to hide their implementation details from the outside world, and have no side-effects. |
Geomol 16-Oct-2008 [11122x3] | I used to think, blocks of words didn't have any meaning, until they were e.g. evaluated. In one context, the words mean one thing, in another something else. When I program, I don't think alot about this, I just work with REBOL. Now I some cases, where I might not expect the output, I'm getting. Example: >> a: 1 == 1 >> f: func [a code] [do code] >> f 2 [print a] 1 Before doing this, I would have guessed, 2 was printed. Funny I haven't had such a problem, that I can remember. |
Now I *see* cases ... | |
Remembering some discussion about block pre-evaluation or something. So the interior of blocks are being giving meaning, when they are born. And you can't put anything in a block: >> blk: [a 7-] ** Syntax Error: Invalid date -- 7- | |
amacleod 16-Oct-2008 [11125] | I'm using tretbase to store formatted text but tretbase strips carriage returns. I've removed the trim/lines function from tretbase but teh retrieve functions and search functions etc. expect the data to be on one line. Carriage returns can be in the data file as long as they are on one line. |
Geomol 16-Oct-2008 [11126] | Maybe newlines are not stored as one character, but two? Like: >> str: {^^/} == "^^/" >> length? str == 2 |
Anton 16-Oct-2008 [11127] | Geomol, you're right, actually, the real meaning of a word is only ever actualised when it is evaluated. But you can think of a word's binding as its potential meaning. (Above, I wrote as if binding and meaning are the same, whereas they are not quite; they are close, but binding is one step back from meaning.) |
Gregg 16-Oct-2008 [11128] | Alan, have you tried this ('s being your string): replace/all s "^/" "^^/" |
amacleod 16-Oct-2008 [11129] | s: {a { ^-b { ^-^-c} == {a ^-b ^-^-c} replace/all s "^/" "^^/" == {a^^/^-b^^/^-^-c} >> print s a^/ b^/ c Not what I want. |
Anton 16-Oct-2008 [11130] | s2: copy s parse/all s2 [some [p: "^/" (change/part p "^^/" 1) skip | "^-" (change/part p "^^-" 1) skip | skip]] |
Gregg 16-Oct-2008 [11131] | Because of tabs? Just do the same replace for them. |
amacleod 16-Oct-2008 [11132] | THat was my next strp. I thought I was missing some simple conversion. |
Anton 16-Oct-2008 [11133] | That's simpler to write, but two passes. The parse I show above is more complex to write, but one pass. |
amacleod 16-Oct-2008 [11134x2] | s2: copy a parse/all s2 [some [p: "^/" (change/part p "^^/" 1) skip | "^-" (chang e/part p "^^-" 1) skip | skip]] == true >> s2 == {a^^/^^-b^^/^^-c} >> print s2 a^/^-b^/^-c Anton, It looks like what I want but if aI print it the newlines are not reconized??? |
But if I do it manually: >> z: {a^/^-b^/^-^-c} == {a ^-b ^-^-c} >> probe z {a ^-b ^-^-c} == {a ^-b ^-^-c} I do not get it. Are there hidden characters? | |
Gregg 16-Oct-2008 [11136] | By adding the secon ^, it escapes the ^ that marks the newline, so it is no longer a newline. When you write the string out, then it will write out as "a^/^-b^/^-c" which will convert to newlines again when loaded. If you're writing out and loading strings, you may have to convert the data back yourself when you load it, because REBOL won't parse into it to do so. e.g., if you mold an object spec to be on a single line like that, REBOL will convert them on load, but if you just read a file as a string, it won't. |
Anton 16-Oct-2008 [11137x4] | The confusing thing is, rebol molds short strings and longer strings differently. In short strings, the newlines are molded as ^^/ , but in longer strings (like yours above) the newlines are "evaluated" (moving the cursor to next line). |
Check it out: >> "a^/b" == "a^/b" >> "a^/^-b" == "a^/^-b" >> "a^/^-b^/" == "a^/^-b^/" >> "a^/^-b^/^-^-c" == {a ^-b ^-^-c} | |
boom! That last line is long enough that the newlines are "evaluated". | |
(It's more complicated than just string length, actually. Exact algorithm unknown.) | |
amacleod 16-Oct-2008 [11141] | Greg, I tried wrote it out ot a file and loaded it but it still does not print properly Is there a work around? |
Anton 16-Oct-2008 [11142x3] | amacleod, I think Greg and mine solution both work. They produce a string molded so that the two control characters (newline and tab) are escaped. You just need to ... ahh... here's where I was going to say "just LOAD it." but I get an error message. >> load "^^/" ** Syntax Error: Invalid path -- ^/ ** Near: (line 1) ^/ So maybe do this instead: s: "^/" ; <-- input string s: "^^/" ; <--- specially "molded" string as produced by PARSE or REPLACE above. load rejoin ["{" s "}"] ; <-- specially "loaded" string the result of which should be the same as the input. |
The longer example: | |
>> s: "a^/^-b^/^-^-c" == {a ^-b ^-^-c} >> s2: copy s parse/all s2 [some [p: "^/" (change/part p "^^/" 1) skip | "^-" (change/part p "^^-" 1) skip | skip]] == true >> s3: load rejoin ["{" s "}"] == {a ^-b ^-^-c} >> s = s3 == true | |
amacleod 16-Oct-2008 [11145] | Did you mean: s3: load rejoin ["{" s2"}"] ? with s2 in the rejoin and not s ? That seems to work and produce what I'm tring to get... A little awkward but only two lines for what I want... Thanks again, Anton. I can use this in the short time but I may need to just use SQLite or my own solution for storage as Paul is no longer developing Tretbase... |
Geomol 16-Oct-2008 [11146] | amacleod, can you use NicomDB? http://www.fys.ku.dk/~niclasen/nicomdb/index.html NicomDB is the result of an education, I took some years ago. More info: http://www.fys.ku.dk/~niclasen/nicomdb/thesis.pdf There's also a group about it here in the REBOL3 world. See group !NicomDB |
Anton 17-Oct-2008 [11147] | amacleod, ah yes, small typo there. |
Chris 17-Oct-2008 [11148x2] | On 'bind, I use 'with to make some bind situations more readable: other-context: context [ print: [statement][probe head reverse copy statement] ] with other-context [print "Text"] |
with: func [object [any-word! object! port!] block [any-block!] /only][ block: bind block object either only [block] :block ] | |
amacleod 17-Oct-2008 [11150x3] | I was looking into sqlite but reluctantly... |
Idid a quick glance through your paper and it had a lot of good iseas that might fit my needs. I'm going to play around with it. Are you still developing it? | |
iseas = ideas | |
Geomol 18-Oct-2008 [11153] | amacleod, I use NicomDB myself in different projects and is developing it further, when needs arise. |
older newer | first last |