Skip to content

Instantly share code, notes, and snippets.

@x8x
Created August 4, 2018 18:28
Show Gist options
  • Save x8x/e0af4637838f020e0673f854a9f6e261 to your computer and use it in GitHub Desktop.
Save x8x/e0af4637838f020e0673f854a9f6e261 to your computer and use it in GitHub Desktop.
@toomasv
Copy link

toomasv commented Aug 4, 2018

You should bind a to functions' context, which is provided by :f:

f: func [/local a][a: context [b: context [c: 'ok]] print do bind [a/b/c] :f] f
ok

If you need to load it for some reason:

f: func [/local a][a: context [b: context [c: 'ok]] print do bind reduce [load {a/b/c}] :f] f
ok

@x8x
Copy link
Author

x8x commented Aug 4, 2018

@toomasv Oh well! That works! Thank you! Guess you win the bounty! Please send me your address on Gitter, so I can transfer the REDs!
..btw, always impressed by your Red productivity!! 👍

Now for some details about how/why that works:

  • magic :f, when defining function f, the body block is just that, a block! not executed yet, hence no complain about :f not being defined yet. While when calling f, :f gets its value from the global space, where function f is defined. Correct?
  • Why is that not the same as bind [] 'a ? Binding to a word! should execute the block! in the context where that word! is defined, which in this case would be the f function body.
  • Why do load, inside the function body, execute in the global space and I need to bind it in the first place?

Still curious about Rebol/Red different behaviours, is that wanted, enhancement, regression?

@x8x
Copy link
Author

x8x commented Aug 4, 2018

For reference, this doesn't work in Rebol:

  f: func [/local a][a: context [b: context [c: 'ok]] print do bind reduce [load {a/b/c}] :f] f
** Script Error: bind expected known-word argument of type: any-word object port
** Where: f
** Near: print do bind reduce [load "a/b/c"]

@toomasv
Copy link

toomasv commented Aug 5, 2018

@x8x I can't answer all the questions, as I don't know the implementation internals of Red, but I think you are correct on first point.
About the third point, I think it is because the a resulting from loading the string is bound to default global context. I may hypothesize that a-s in function's body are bound to local context at definition time, but loading happens in runtime, and a resulting from loading in runtime is not bound to functions context.

BTW, in my first snippet bind isn't needed actually, because a is bound in this case:

f: func [/local a][a: context [b: context [c: 'ok]] print do [a/b/c]] f
; or 
f: func [/local a][a: context [b: context [c: 'ok]] print reduce 'a/b/c] f
; or
f: func [/local a][a: context [b: context [c: 'ok]] print a/b/c] f
ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment