World: r3wp
[Core] Discuss core issues
older newer | first last |
Gabriele 13-Oct-2008 [11089] | Anton, yes, as Brian says, that looks like a bug. |
Anton 13-Oct-2008 [11090] | Well, I guess a bug report is due then. Who's responsibility is it ? Graham - I think you :) |
BrianH 13-Oct-2008 [11091] | Terry, you should consider structuring your parse rules so that you can do more processing of the data you recognize on the fly in parens. When you are using a hundred local words and doing your processing afterwards, you are repeating yourself. |
Gregg 13-Oct-2008 [11092] | Will, I got away from lit-word! params because they're a pain when you're doing more dynamic things in code. As soon as you want to compute the arg, they get in the way. My classic example is an INCR function. For control funcs, I think they make the calling code read more naturally, and the cases where they cause problems there are much less frequent. |
Davide 15-Oct-2008 [11093] | hi, I need your help with bind: - I have an object h h: make object! [ q: [] ] append h/q make object! [ f1: func [a][print ["f1" a]] f2: func [b][f1 join "f2 " b] ] if I call f1 and f2 the results are correct: >> h/q/1/f1 "hi" f1 hi >> h/q/1/f2 "hi" f1 f2 hi --------------------- Now, I want to make the code of f2 dynamic, so I add a second param "code" to f2: h/q/1/f2: func [b code][do code] of course this doesn't work, f1 and b aren't bound: >> h/q/1/f2 "hi" [f1 join "f2 " b] ** Script Error: f1 has no value ** Where: f2 ** Near: f1 join "f2 " b I've tried with no luck the followings: h/q/1/f2: func [b code][do bind code 'f2] h/q/1/f2: func [b code][do bind code in h/q/1 'f2] What is the magic word: "do bind code ******* " ? |
Anton 15-Oct-2008 [11094x3] | The 'f2 word which you are trying to use as an example word is not bound to the object you want, because you create the function after making the object. If you had defined the function which does the bind directly in the object spec to start with you wouldn't have this problem. But if you need to define the function after creating the object, then you could do any of these: |
h/q/1/f2: func [b code][do bind bind code 'b h/q/1] h/q/1/f2: func [b code][do bind bind code 'b in h/q/1 'self] h/q/1/f2: func [b code] compose [do bind bind code 'b (h/q/1)] h/q/1/f2: func [b code] compose [do bind bind code 'b (to-lit-word in h/q/1 'self)] h/q/1/f2: func [b code] compose [do bind bind code 'b (to-lit-word in h/q/1 'f1)] | |
The first alternative looks the simplest to me. :) The extra BIND to one of F2's locals ('b) is necessary if CODE ever refers to any of F2's locals (B or CODE). (This avoids the next error message you were going to get. :) | |
Davide 15-Oct-2008 [11097] | double bind ! Thanks Anton, it works |
Geomol 15-Oct-2008 [11098] | Learn to bind knots with REBOL lecture one. ;) I always have trouble with BIND. Maybe I didn't ever take the time to really get it. So much to investigate with this language. :) |
amacleod 16-Oct-2008 [11099x2] | How do I convert: [{some sentence with some carriage returns and tabs}] to: [{some sentence with^/^-some carriage returns^/^-^-and tabs}] |
Is there a simple method or do I need to parse through and append each line while inserting the ^/ | |
Sunanda 16-Oct-2008 [11101] | This may have side effects, removing extra spaces: x: [{some sentence with { some carriage returns { and tabs}] >> trim first x == "some sentence with^/some carriage returns^/and tabs" |
Anton 16-Oct-2008 [11102] | Geomol, I was like that too, for quite some time, at the beginning. But... we can teach it to you !! It's really a simple concept. |
Geomol 16-Oct-2008 [11103x2] | I know the concept of a context. I actually use the word CONTEXT in most of my scripts. And reading the BIND help (with ? bind), I see, it binds words to a known word. So I guess, the known word is defining the context, the new words (1. argument of BIND) should bind to. But why, Anton, do you use two binds in your example? I would guess, something like: do bind [code b] h/q/1 should work? |
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 [11137x2] | 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} | |
older newer | first last |