r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Chris
12-Oct-2008
[11082]
Could be tidied up a little with an exceptions option...
Terry
12-Oct-2008
[11083]
can't seem to get it to fire.. do you have a working example by chance?
Chris
12-Oct-2008
[11084x5]
>> parse "str" localize [a: "str" (probe b: a)]

"str"
== true

>> a

** Script Error: a has no value

** Near: a

>> b

== "str"
I guess 'into doesn't go into paren! in 2.7.6?
; perhaps I forgot something:

	localize: func [block /local word words rule][
		words: copy []

  rule: [set word any-word! (append words word) | into [any rule] | 
  skip]
		parse block [any rule]
		forall words [words/1: to-word words/1]
		use words compose/only [(block)]
	]
Anyhow, could use some work, just throwing out the idea...
localize: func [block /with except /local word words rule][
	words: copy []

 rule: [set word any-word! (append words word) | into [any rule] | 
 skip]
	parse block [any rule]
	forall words [words/1: to-word words/1]
	words: difference unique union words except except
	use words compose/only [(block)]
]


parse "string" localize/with [a: "str" (probe a) copy b "ing" (probe 
b)][probe]
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.