World: r3wp
[Core] Discuss core issues
older newer | first last |
Anton 30-Apr-2006 [4232x2] | >> c1: context [a: b: none] >> c2: context [a: b: none] >> do bind [a: 1 b: 2] c1 == 2 >> probe c1 make object! [ a: 1 b: 2 ] >> do bind [a: 100 b: 200] c2 == 200 >> probe c2 make object! [ a: 100 b: 200 ] |
Oh sorry, you specifically want to bind a function's body to the context. Let's see, I think this will work: bind second get in storage 'list-words A storage/list-words | |
Robert 30-Apr-2006 [4234] | What's this SECOND about? |
Anton 30-Apr-2006 [4235x3] | Just getting the function body. |
>> A: context [a: 1 b: 2 c: 3] >> storage: context [list-words: does [probe first self]] >> storage/list-words [self list-words] == [self list-words] >> bind second get in storage 'list-words A == [probe first self] >> storage/list-words [self a b c] == [self a b c] | |
read as: "bind the body of list-words to A" | |
Robert 30-Apr-2006 [4238] | Ok... now I think I got it. I was always trying to bind the WHOLE function, not only the body... |
Anton 30-Apr-2006 [4239x4] | Yes, bind needs a block! value, not a function! |
A function! is a more complex value, which contains a spec and a body. | |
You wouldn't want to bind the whole function, which would probably imply binding its spec block as well, since that would unlink the argument spec block relative to the body block. | |
Although, now that I think about it, that *could* be useful in some circumstance, maybe.... Many functions with similar argument lists could share a context. | |
Robert 30-Apr-2006 [4243] | ok. Thanks a lot. |
Anton 30-Apr-2006 [4244] | no problem.. |
Robert 30-Apr-2006 [4245x3] | I think I can bind a bunch of functions as well, right? |
I mean in one step. | |
So for example I specify a block of function names, that I want to bind. | |
Anton 30-Apr-2006 [4248] | You could append each function's body block to a single, large block. Then bind that. |
Robert 30-Apr-2006 [4249] | And it will keep it's link to the original function spec? |
Anton 30-Apr-2006 [4250x2] | blk: [] foreach func funcs [append blk second :func] bind blk ctx-A |
Yes, remember it's possible for same-named but differently-bound words to coexist together in a block. | |
Robert 30-Apr-2006 [4252] | Yes, but second FUNC doesn't return the function word. So where is this link kept? Or is the reference to the func body bound? |
Anton 30-Apr-2006 [4253x3] | example: >> blk: reduce [in system 'options in face 'options] == [options options] >> type? get blk/1 == object! >> type? get blk/2 == none! |
Are you talking about the words you have set to function values ? eg: my-word: func [][] | |
Each word has a single value slot (per context). | |
Robert 30-Apr-2006 [4256] | If I'm binding SECOND FUNC the body's reference is used, so this particular block is bound. Not a copy. |
Anton 30-Apr-2006 [4257] | Correct. |
Robert 30-Apr-2006 [4258x2] | Ok. |
The 'blk part doesn't work. I get an error for SECOND | |
Anton 30-Apr-2006 [4260x13] | Did you put function! values into the funcs input block ? |
eg: >> my-func: func [arg][print arg] >> funcs: reduce [:my-func] >> type? first funcs == function! | |
Hmm... it's not working.... | |
It doesn't look as simple operation as I thought... | |
That's weird. When you insert the function body into another block for binding it doesn't work. These two examples are not producing the same result: | |
>> ctx-A: context [a: 60] >> my-func: func [][a: 5] >> bind second :my-func ctx-A == [a: 5] >> ?? ctx-A ctx-A: make object! [ a: 60 ] >> my-func == 5 >> ?? ctx-A ctx-A: make object! [ a: 5 ] | |
>> ctx-A: context [a: 60] >> my-func: func [][a: 5] >> blk: [] append blk second :my-func == [a: 5] >> bind blk ctx-A == [a: 5] >> ?? ctx-A ctx-A: make object! [ a: 60 ] >> my-func == 5 >> ?? ctx-A ctx-A: make object! [ a: 60 ] | |
Insert copies the words into the block unbound from their original context. | |
Ok, so we can do this instead: | |
foreach func funcs [bind second :func ctx-A] | |
No reason for that not to work. | |
Yes, that works: | |
>> ctx-A: context [a: none] >> f1: does [a: 1] >> f2: does [a: 2] >> foreach func reduce [:f1 :f2][bind second :func ctx-A] == [a: 2] >> ?? ctx-A ctx-A: make object! [ a: none ] >> f1 == 1 >> ?? ctx-A ctx-A: make object! [ a: 1 ] >> f2 == 2 >> ?? ctx-A ctx-A: make object! [ a: 2 ] | |
Robert 30-Apr-2006 [4273x3] | This stuff is always really tricky. |
Ok, thanks a lot. That's stuff I'm really going nuts by. I think I will collect all kind of examples and publish them. | |
A BIND how-to, that not only explains what's going on but shows examples, examples, examples is what we need. | |
BrianH 30-Apr-2006 [4276] | Ladislav's Bindology article might help. I think it's on rebol.org... |
Robert 30-Apr-2006 [4277x2] | His article is good, but only for gurus to follow. |
Nothing for people getting into first touch with BIND. | |
BrianH 30-Apr-2006 [4279x3] | I actually think that your best bet here is to pass the context you will be saving to the saving function as a parameter, like your original example storage/save-record context-to-save or if you really want to delegate you can assign the function as a member of context-to-save and call it like context-to-save/save-record context-to-save , but then you are changing the context you are saving wih saving overhead. REBOL does direct delegation by default, rather than mixin delegation like Delphi, because REBOL doesn't pass the object reference as a hidden parameter like object-oriented languages do. Rebinding your function body every time would be time-consuming and either non-recursion-safe (bind) or consume a lot of memory (bind/copy) - just passing the context as a parameter would be quicker. |
Also, you could have some conflict with names in both the storage context and context-to-save that could cause the block you are rebinding to accidently lose its meaning in unexpected ways. | |
Not that learning about bind wouldn't be fun... | |
older newer | first last |