• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp64
r3wp928
total:992

results window for this page: [start: 401 end: 500]

world-name: r3wp

Group: Core ... Discuss core issues [web-public]
Volker:
11-Feb-2007
yes. but keep in mind bind ignores functions and objects, so you 
must  recurse into them too.
Anton:
18-Apr-2007
do bind b 'v  ?
Anton:
23-Apr-2007
set f reduce bind copy next first f2 f2
Rebolek:
11-Jun-2007
some BIND expert, please, help me:

>> act: [add a b]
== [add a b]
>> for a 1 5 1 [for b 1 5 1 [do act]]
** Script Error: a has no value
** Where: do-body
** Near: add a b

There must be something easier than
>> for a 1 5 1 [for b 1 5 1 [do bind bind act 'a 'b]]
btiffin:
11-Jun-2007
May or may not work for your needs

for a 1 5 1 [for b 1 5 1 bind act 'a]
btiffin:
9-Jul-2007
foreach item [1 2 3] [do bind second :report 'item] may work
Pekr:
9-Jul-2007
And I somehow wanted to have 'disk available in my copy-dir :-) Well, 
I can easily solve it via drive: disk and use drive global word in 
my copy-dir func. It is just that I was thinking if I can somehow 
magically bind to it :-)
Pekr:
9-Jul-2007
I need it vice versa - bind item in report to foreach item ....
btiffin:
9-Jul-2007
That will bind report and item to the local foreach item.
btiffin:
9-Jul-2007
Yeah bind is a little ummm, magically delicious.
Gabriele:
9-Jul-2007
inside foreach and accessible somewhere else == global. the proper 
way to do it is a function argument. you can bind, but that does 
not seem clean to me (argument is clean).
Pekr:
4-Aug-2007
Today I was thinking about REBOL paths and namespaces navigation 
"problem". I would like some clever persons 

here, to educate me a bit in that area. So far I think, that REBOL 
breaks on some path rules, of course it 

depends, upon what "philosophy" you provide as an explanation. So, 
I was thinking about 

namespaces/paths/context, as of a tree .... So, all words are defined 
in top (global) context = root, right? 

(excuse simplification). Then comes first question - how can be following 
valid?:

a: 5
b: context [print a]


My objection is, that from the point of  'b "node", there is no 'a. 
So, my explanation is:

1) in the case of directory, we would use ../a
2) or we should go via root reference - b: context [print /a]

3) we create "philosophical" rule, stating that global (top) context 
words are propagated to subsidiary nodes 
(contexts)


I don't mind case 3), if such rules are well defined, and it will 
come, once we switch to modules.


How did I came to think about above? I have somehow aesthetical issue 
with REBOL, when I look at e.g. scheme 

code in R2. It is full of awfull system/words/word references. I 
don't like it. What I would like to see is to 
have some abbreviations. I know that we can do e.g.:

_print: system/words/print


My question is, if we could have some more abstracted solution? Do 
you remember 'with keyword? I don't 

remember how it worked, but I would like to have some ability to 
"bind" particular word from existing context 
to actual context:

bind system/words node here, so that I don't need to use paths
 (kind of like when you create links in unix 
filesystem hierarchy ....


Of course, here we go - we could easily get some colision, e.g. if 
target context contains the same words. But 

maybe that could be somehow taken care for (I thought e.g. about 
automatic adding of underscores, e.g. _print, 
but that is not good solution).


Well, the thing is, that I am not actually even sure, what am I asking 
for :-) So, I would like to ask, if 

some REBOL gurus thought about such topics, or am I completly unrealistic 
here?

Thanks ...
Geomol:
4-Aug-2007
Some thoughts:

Case 3) is like in object-orientated languages. You inherit words 
from parent context (object or class) and can use them right away 
without any further syntax.

You'll probably see system/words/word references in cases, where 
it is words that very like get reused/redefined. So it's typed like 
that to make sure, it's the system definition of the word, that is 
being used.

I'll give you, it's not the most pretty and easy to read. Maybe some 
use of BIND can avoid it.
Graham:
5-Sep-2007
Can someone remind me how bind a bunch of words to a different context? 
 I want to use the named colors in a special context.
Chris:
6-Sep-2007
colors: context [red: 255.0.0 green: 0.255.0 blue: 0.0.255]
reduce bind [red green blue] in colors 'self
btiffin:
7-Sep-2007
Graham;  To quickly get all the colours, try
rebol []


do-thru http://www.rebol.org/library/scripts/capture.rcapture on 
help tuple! capture off
colors: copy []
parse to block! find get-captured newline [
    some [set col word! (append colors col) word! tuple!]
]

;; This will fail, no context
print disarm try [get first colors]
;; Now bind the words to the REBOL context
bind colors 'red  print get first colors
Gregg:
13-Sep-2007
foreach [a b] [1 2 3 4] [print get bind load "a" 'b]
Henrik:
11-Oct-2007
I'm stuck with a BIND problem. What may cause a value that is a string 
to become NONE when it's bound to a block? It's only this one value 
out of several that I have problems with. There are other strings 
bound to the block that work correctly. I have no idea what's going 
on. Suggestions?
Henrik:
11-Oct-2007
the bind is in a foreach loop that very roughly looks like so:

a: [c d e]

f: [stuff (c)  more stuff (d)]

foreach :a b [
...stuff
  compose/deep bind f 'c
...stuff
]


For some reason 'c in the bound block is NONE. I tried binding to 
'd, copy/deep the block, but nothing.
Henrik:
11-Oct-2007
If I probe 'c just before the bind, it has the correct value
Henrik:
11-Oct-2007
I think I'm figuring it out.... nasty bind problem
Chris:
7-Jan-2008
; I'm not sure you can bind whole objects, but you can at least make 
short work of the manual process.  Here's a quickie I've used:

reconstitute: func [object [object!] /local bindings][
	append bindings: [] object
	foreach word next first object [
		switch type?/word word: get in object word [

   function! [foreach context bindings [bind second :word :context]]
			block! [foreach context bindings [bind :word :context]]
			object! [reconstitute :word]
		]
	]
	remove back tail bindings
	object
]
Henrik:
7-Jan-2008
yes, that's why I wanted to make binding cues inside the object, 
so I can load it, and it will automatically bind to wherever is needed.
Chris:
7-Jan-2008
Yep, if you were to do -- context: [a: b: :an-object] -- while you 
could bind a reconstituted 'a and 'b to 'an-object, it would be clones. 
 Possibility: where you are working with faces, you could specifically 
change eg. the feel to lit-word/path before saving, then allow a 
'reconstitute-like function replace that value with the related object. 
 It's a little messy, but still such functions could still be nearly 
as short...
Anton:
25-Jan-2008
>> c1: context [var: "orig" f: func [][print var]]
>> c1/f
orig
>> c2: context [var: "hello"]
>> bind second get in c1 'f c2
== [print var]
>> c1/f
hello
Henrik:
25-Jan-2008
>> a: does [print b] 
>> c: make object! [b: 4]
>> a

** Script Error: b has no value
** Where: a
** Near: print b
>> bind second :a 'c

== [print b]
>> a
** Script Error: b has no value
** Where: a

** Near: print b
Henrik:
25-Jan-2008
solved with:

bind second :a c
[unknown: 5]:
25-Jan-2008
Can someone explain the reason why bind would work but bind/copy 
wouldn't?
BrianH:
25-Jan-2008
You don't rebind the function, you rebind its code block - not quite 
the same thing. Bind/copy wouldn't work because it creates a copy 
rather than rebinding the original block. You can alter the contents 
of the code block of a (R2) function, but you can't change the function's 
reference to that block to point to another block.
BrianH:
25-Jan-2008
If you can create a new function, you can use bind/copy. It is occasionally 
possible to arrange your algorithm so that it is possible to replace 
a function without worrying about aliased references, but usually 
not.
[unknown: 5]:
25-Jan-2008
yeah I understand that but why would bind/copy ever fail where bind 
itself worked?
Anton:
25-Jan-2008
bind/copy goes deep.
Anton:
25-Jan-2008
I think I remember, bind/copy is just a short equivalent to bind 
copy/deep.
[unknown: 5]:
25-Jan-2008
but if bind works and then you try the same code with bind/copy should 
it cause an error?
[unknown: 5]:
25-Jan-2008
yeah that is the way I understand it also which is why it suprised 
me in my code that bind works but when I simply add bind/copy in 
then it breaks the code.
Anton:
1-Apr-2008
The words in block maintain their bindings. This is what you want; 
the words retain the meanings from the context the user wrote them 
in. (ie. your locals do not affect those words because nowhere do 
you bind the words to any of your own contexts.)
Fork:
1-Apr-2008
e.g. will everything else bind the same as you would have otherwise 
expected?
Fork:
1-Apr-2008
It appears that REBOL is just more free about this by default.  You 
make a context for a whole bunch of code, the words bind freely, 
and then you blow it all away on the context level.
Fork:
2-Apr-2008
But if FOO is a function that lives in debug-functions.r then I'd 
need some parameter trick to access the calling context, the way 
bind uses a known-word for example.  Is that the case?
Anton:
4-Apr-2008
Essentially:
	d: does bind [print c] context [c: "Cool"]
Anton:
4-Apr-2008
But, like your version, if we can get the word, we can get its context:
>> probe do bind [self] second second :d
make object! [
    c: "Cool"
]
Anton:
4-Apr-2008
Well... we can unset 'self, so that the above method does not work:
>> do bind [unset 'self] second second :d
>> probe do bind [self] second second :d
** Script Error: self has no value
** Near: self
Henrik:
9-Apr-2008
solved it:

>> a: [(i)]
>> repeat i 5 [print i compose bind a 'i]
1
2
3
4
5
== [5]


I assumed that LOAD MOLD/ALL would kill the existing bindings and 
re-bind it to whatever context it was being run in. I guess it doesn't 
do that.
Anton:
9-Apr-2008
Geomol, why add another refinement when you can just use BIND, which 
allows you to bind it anywhere ?
Geomol:
9-Apr-2008
I was doing this:
a: context [w: load "print"]
get a/w


Same thing. I understand you now, Anton. The words know, what context 
they're bound to. So it should all just be sorted out with BIND. 
And BIND can be confusing (at leat I find it confusing now and then).
Anton:
9-Apr-2008
Yes, the "invisible links" of bind can be confusing.
Geomol:
9-Apr-2008
And we can make our own LOAD to do, what we want: :-)


>> c: context [print: "local" load: func [w] [bind to block! w self 
w] w: load "print"]
>> type? c/w
== string!
>> c/w
== "print"
Geomol:
9-Apr-2008
BIND is hard! Period! ;-)
Geomol:
9-Apr-2008
This does it (I think):

>> c: context [print: "local" load: func [w] [first reduce bind to 
block! w self] w: load "print"]                                  
                           
>> c/w
== "local"
Anton:
10-Apr-2008
Example, given a function:
	f: func [var][
		print var: 10
	]

then you will navigate to the 'var: set-word in the function body 
like so:
	second second :f
because 'var: is in second position, after the 'print word.

(it doesn't matter that it's a set-word and not a word, you can still 
set it and bind to it, etc)

We can test this:
	set second second :f 20
	get second second :f
	; == 20
	?? f
	f: func [var][
		print var: 10
	]

Notice the 10 value is still the same (we didn't touch it.) But we 
know the 'var: set-word is 20 thanks to our setting it above. If 
the function is now evaluated it will not stay that way, obviously.
Dockimbel:
28-Apr-2008
if a & b are locally defined, you should first BIND the block to 
execute like this : do bind code-to-execute 'a
Davide:
15-Oct-2008
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
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:
Anton:
15-Oct-2008
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)]
Anton:
15-Oct-2008
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
double bind ! Thanks Anton, it works
Geomol:
15-Oct-2008
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. :)
Geomol:
16-Oct-2008
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?
Anton:
16-Oct-2008
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.
Anton:
16-Oct-2008
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.
Anton:
16-Oct-2008
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
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
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
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.
Anton:
16-Oct-2008
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.
Chris:
17-Oct-2008
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"]
Chris:
17-Oct-2008
with: func [object [any-word! object! port!] block [any-block!] /only][
	block: bind block object
	either only [block] :block
]
BrianH:
26-Nov-2008
Also, you can't use hash! or list! to store code - BIND won't work 
on them.
Chris:
19-Dec-2008
A 'bind question: how do I construct an object containing blocks 
without changing the blocks' contexts?  This bad:

>> id: #foo
== #foo
>> blk: [id]
== [id]
>> reduce blk
== [#foo]
>> ctx: context append/only [id: #bar bk:] blk
>> reduce ctx/bk
== [#bar]

This good:

>> id: #foo
== #foo
>> blk: [id]
== [id]
>> reduce blk
== [#foo]
>> ctx: magic-context append/only [id: #bar bk:] blk
>> reduce ctx/bk
== [#foo]

How to 'magic-context ?
Geomol:
20-Dec-2008
I found a way to set all locals to none, while just specifying one 
of the locals, and it isn't beautiful, I'm afraid:

f: func [/local a b c][
	a: 1 b: 2 c: 3
	print [a b c]

	; This next line set all locals to none:
	set next bind first :f 'a none
	print [a b c]
]

Running the function in the console:
>> f
1 2 3
none none none
>>
[unknown: 5]:
20-Dec-2008
Yeah John, that is the way I think it has to be done by using 'bind.
Geomol:
20-Dec-2008
My example only works for functions, which doesn't take arguments. 
If a function take argument, you need:

f: func [v /local a b c][
	a: 1 b: 2 c: 3
	print [a b c]

	set next find bind first :f 'a /local none
	print [a b c]
]
Geomol:
20-Dec-2008
:-) It gets worse, if all parameters should be set to none:

f: func [v /local a b c][
	a: 1 b: 2 c: 3
	print [v a b c]

	set bind head remove find first :f /local 'a none
	print [v a b c]
]

Try:
>> f 42
Geomol:
20-Dec-2008
Hm, I don't need the HEAD, so it can be:
set bind remove find first :f /local 'a none
Geomol:
20-Dec-2008
Brian, do you know, if it's possible from outside a function to specity 
its context? (To be used in the second parameter for BIND.)
BrianH:
20-Dec-2008
You don't need the find either. John, your example with ALSO:

f: func [v /local a b c][
	a: 1 b: 2 c: 3
	print [v a b c]

	also
		print [v a b c]
		set bind remove first :f 'a none
]
Steeve:
20-Dec-2008
fun: func [spec body /local me][
	me: construct append copy/deep [
		clear-all: [set bind copy next next first self self none]
	] body	
	me/clear-all: does me/clear-all
	clear find spec /local
	func spec bind body me 
]

f: fun [/local c d ][ c: d: 1 probe self print [c d ] clear-all print 
[c d]]
f
BrianH:
20-Dec-2008
You can't get access to a function's context without having a known 
word that is already bouund to that context. When you do first :f, 
the words retrn are not bound to the function's context. In R2, when 
you do third :f you get words that are bound, but you can only guess 
to what., since words are bound individually. The only safe way to 
do clear-words is to pass both the function and a known word bound 
to the function's context, and even then you have to copy the fuunction's 
argument block and convert any refinements to words before you bind 
the copy.
BrianH:
20-Dec-2008
Getting a the argument list, which you would have to copy, convert 
refinements to words, then bind. The copy and conversion would be 
slower than necessary.
[unknown: 5]:
20-Dec-2008
What is happening with respect to memory and lower level activity 
when using the 'bind function?
[unknown: 5]:
21-Dec-2008
As for the clearing of the locals  from a function - here you go:

clear-locals: func [

        {Used as the ending statement within a function to set the function's 
        locals to none value.}
        fnc [function!]
    ][

        set bind first to-block trim/with mold first :fnc "/" first find 
        second :fnc set-word! none
]
Anton:
21-Dec-2008
These are ok.
>> same? o do bind [self] o
== true
>> same? o do bind [self] in o 'b
== true
Davide:
29-Dec-2008
Now I can ask a more precise question:

here is my problem:
I have an application object app that "serve" two client c1, c2

app: make object! [
	hset: func [c] [k: c/name]
	hget: func [c] [print ["k=" k]]
]

c1: make object! [
	name: "pippo"
]

c2: make object! [
	name: "pluto"
]


The handlers of app, use k as internal container, but of course it's 
shared between clients:

>> app/hset c1
== "pippo"
>> app/hset c2
== "pluto"
>> app/hget c1
k= pluto   


I would bind k (and every set-word in the handler) to the object 
passed as parameter so the last line would produce:

>> app/hget c1
k= pippo

Now I come to this solution, using blocks instead of funcs in app

app: make object! [
	hset: [k: name]
	hget: [print ["k=" k]]
]

c1: make object! [
	name: "pippo"
	vars: make object! [
		k: none
	]
]

c2: make object! [
	name: "pluto"
	vars: make object! [
		k: none
	]
]

This produce:

>>  do bind bind app/hset c1/vars c1
== "pippo"
>> do bind bind app/hset c2/vars c2
== "pluto"
>> do bind bind app/hget c1/vars c1
k= pippo


This works, but I have to collect every set-words used in the handler, 
into the clients (using Ladislav set-words http://www.fm.tul.cz/~ladislav/rebol/set-words.r
)


sw: copy [] repeat h next first app [sw: union sw set-words app/:h]

b: copy [] repeat w sw [insert tail b reduce [to set-word! w none]] 
vars: make object! head b
c1/vars: vars
c2/vars: vars


Now, my questions are:
1) Is this approch "rebolish" ? There's a smarter way to do it ?
2) If I need a function in my app like:

app: make object! [
	hset: [k: avg a b]
	hget: [print ["k=" k]]
	avg: func [x y] [aux: x + y aux: aux / 2]
]


How can I collect the aux: word in avg function, and bind this function 
to c1/vars ?
Davide:
29-Dec-2008
Well I can bind avg to c1 with: 


app/avg: func first get in app 'avg bind bind second get in app 'avg 
c1/vars c1


Still hold the first question: there is a better approach ? If we 
suppose the app object is large, with hundreds of clients, would 
be better, for example, copy the entire app obj in every client, 
so I can execute the code without bind ?
Davide:
30-Dec-2008
If I define aux locally it is shared to every client:

app: make object! [
	aux: none
	hset: [avg a b]
	hget: [print ["avg=" aux]]
	avg: func [x y] [aux: x + y aux: aux / 2]
]

c1: make object! [
	a: 2
	b: 4
]

c2: make object! [
	a: 3
	b: 5
]

>> do bind app/hset c1
== 3
>> do bind app/hget c1
avg= 3
>> do bind app/hset c2
== 4
>> do bind app/hget c1
avg= 4 <<< error this shoud be 3 !
BrianH:
3-Jan-2009
A whitelist is easier to implement in R2. You create an object that 
has all of the legit functions assigned to fields, then load the 
block unbound (to-block of its string representation), then bind 
the block to the legit object. All other function references will 
be unbound in the block. Be really careful when choosing your legit 
functions - you might need to make safe equivalents for some.
BrianH:
21-Jan-2009
BACKPORTS! Hot off the presses! Get your new R3 functions, now here 
for R2! Available now, before the next release!

funct: make function! [
    [catch]
    "Defines a user function assuming all set-words are locals."

    spec [block!] "Help string (opt) followed by arg words (and opt type 
    and string)"
    body [block!] "The body block of the function"
    /local r ws wb a
][
    spec: copy/deep spec
    body: copy/deep body
    ws: make block! length? spec
    parse spec [any [

        set a [word! | refinement!] (insert tail ws to-word a) | skip
    ]]
    wb: copy ws
    parse body r: [any [
        set a set-word! (
            unless find wb a: to-word a [insert tail wb a]
        ) |
        hash! | into r | skip
    ]]
    unless empty? wb: difference ws wb [
        remove find wb 'local
        unless find spec /local [insert tail spec /local]
        insert tail spec wb
    ]
    throw-on-error [make function! spec body]
]

functor: make function! [
    [catch]

    "Defines a user function with all set-words collected into a persistent 
    object (self)."

    spec [block!] "Help string (opt) followed by arg words (and opt type 
    and string)"
    body [block!] "The body block of the function"
    /local r wb a

][ ; Note: Words in the spec override the bindings of the object 
words.
    wb: copy []
    parse body r: [any [
        set a set-word! (unless find wb a [insert tail wb a]) |
        hash! | into r | skip
    ]]
    remove find wb [self:]

    throw-on-error [make function! copy/deep spec  bind/copy body construct 
    wb]
]
Steeve:
9-Mar-2009
tried to made nforeach for R3: 
- missing do/next to evaluate functions in the data block

- probably speed optimizations can be made (not probably, certainly)

nforeach: func [
	data [block!] body [block!]
	/local vars
][
	vars: make block! (length? data) / 2
	data: copy data
	forskip data 2 [
		append vars data/1 			;* extract vars

  change/only data to block! data/1 	;* convert vars to block (if needed)

  if word? data/2 [poke data 2 get data/2];* get serie from word (do/next 
  much relevant if available) 
	]	

 vars: bind? first use vars reduce [vars]	;* create a context with 
 vars
	bind head data vars
	while [
		also not tail? second data: head data 
		forskip data 2 [
			poke data 2 skip set data/1 data/2 length? data/1
		]
	] bind/copy body vars
]
BrianH:
11-Mar-2009
Gabriele, if we had DO in PARSE we would still need DO/next. Just 
not for nforeach - neither DO/next nor DO in PARSE would be appropriate 
there. Nor would REDUCE be needed. All you'd need would be BIND/copy 
and SET, and some loop function.
Steeve:
11-Mar-2009
Was lazzy, so  i made the nforeach brian's version.

nforeach: func [
	vars [block!]  data [block!] body [block!]
	/local ctx n 
][
	data: copy data
	vars: copy vars
	ctx: make object! 5

 forall vars [change/only vars bind/new to block! vars/1 ctx]   ;** 
 convert all vars to blocks of vars (set need it)
	while [
		n: 1
		also not tail? first data
		forall vars [

   poke data n skip set first vars pick data ++ n length? first vars
		]
	] bind/copy body ctx
]
Group: View ... discuss view related issues [web-public]
Anton:
13-Sep-2006
error-window: layout [
	h3 "Program Error!"
	area 300x200
	button "Close" [hide-popup]
]

inform-on-error: func [code [block!]][
	if error? set/any 'error try code [
    	error-obj: disarm error
    	?? error-obj
		error-window/pane/2/text: rejoin [
			mold disarm error 
			now/time/precise
		]
    	either viewed? error-window [
    		; subsequent errors
    		show error-window
		][
			; first error
			
			print "INFORM"		
			;inform error-window
			; Emulate INFORM but without WAIT
			error-window/text: "Dialog"
			error-window/feel: make system/view/window-feel []
			show-popup center-face error-window
		]
	]
]

system/view/wake-event: func [
	port 
	/local event no-btn error ; <-- added 'error
] bind [
    event: pick port 1
    if none? event [

        if debug [print "Event port awoke, but no event was present."]
        return false
    ]
    either pop-face [

        if in pop-face/feel 'pop-detect [event: pop-face/feel/pop-detect 
        pop-face event]
        inform-on-error [do event]
        found? all [
            pop-face <> pick pop-list length? pop-list
            (pop-face: pick pop-list length? pop-list true)
        ]
    ] [
    	inform-on-error [do event]
        empty? screen-face/pane
    ]
] system/view

view/title layout [
	h3 "Avoid the console from popping up"

 box 500x100 "Hold down left mouse button and drag to create errors" 
 feel [
		engage: func [face action event] [
			print ["ENGAGE:" event/time event/type mold event/face/text]
			if find [over away] action [
				2 / 0 ; error!
			]
		]
	]
] "Main Window"
Anton:
27-Sep-2006
Look here:
	print mold svv/vid-styles/text/init

where it says:
	size: (size-text self) ....

We can do the same:
view layout [
	t1: text "AAA"
	btn "Modify" [
		do bind [
			text: "Text changed"
			size: 1000x200
			size: (size-text self) + (edge-size? self) 

     + (to-pair all [para (to-pair para/margin) + to-pair para/origin])
			show self
		] t1
	]
]
Volker:
6-Oct-2006
Theres a trick. 
 feel: make feel bind [..] ctx-edit
Volker:
6-Oct-2006
so it can shortcut system/view/focal-face too. bind to both.
Pekr:
6-Oct-2006
hmm, that is guru stuff ... although I do seem to understnad the 
bind, I think I also understand, while less experienced user is in 
hell ... then stylize/master is insufficient imo
Volker:
6-Oct-2006
No, for system/view %source/view-edit.r there is some bind-magic 
at the end.
Anton:
6-Oct-2006
Here's the "copy, paste and bind" way:
Anton:
6-Oct-2006
view layout [
	field feel [
		engage: func [face act event] bind bind [
			switch act [
				down [

     either equal? face focal-face [unlight-text] [focus/no-show face]
					caret: offset-to-caret face event/offset
					show face
				]
				over [
					if not-equal? caret offset-to-caret face event/offset [
						if not highlight-start [highlight-start: caret]
						highlight-end: caret: offset-to-caret face event/offset
						show face
					]
				]

    key [if event/key <> #"^M" [edit-text face event get in face 'action]]
			]		
		] system/view ctx-text
	]
]
Pekr:
6-Oct-2006
to your double bind example - what does it do internally? you first 
bind the block to system/View - what happens in that context, and 
what happens in next context - ctx-text?
Anton:
6-Oct-2006
When you bind a block, eg:
	bind [all my words] some-context

an attempt is made to bind each of the words in the block to the 
specified context.

If the context contains the word in question, then the word is bound, 
otherwise the word is left with the same binding as it had before.
401 / 9921234[5] 678910