setsome word without even knowing how it looks like.
setchanges word's value in its context,
word:either creates new entry or changes value in the context where evaluation happens.
x:by yourself if you don't know that it's actually
Thank you very much for discussion and explanations. I'm was experimenting a bit more but I'm still very confused. :worried:
x: 0 set1: func ['word] [set word 1] set2: func ['word] [word: 2] set3: func [word] [word: 3] set1 x set2 x set3 x probe x ; 1 probe word ; *** Script Error: word has no value ; *** Where: probe ; *** Stack: probe
What am I setting in functions
It looks like neither
set2 function, to understand better, lets put some
set2: func ['word] [probe x probe word: 2 probe x] set2 x 0 2 0
your function gets an un-evaluated word (
x and its value is 0 in global context)
then your function sets a value (2) to a locally bound word (
word) (bound to function itself ). So you cannot see its value in outer (global) context:
>> word == ** word has no value ( > in global context < I added this)
'word has nothing related to 'x actually. it is just a local word in your function.
So you are not setting
'x. If you want you should use your
set word valueis same as
word: valueif both are in the same context (for example it is global context if you are on REPL console).
set word valuesets the
words value in global context if you are not explicitly give the context, like
set in obj 'word 2sets the
words value in the context of
wordit is already enough confusing :)
'wis better I think.
word evaluates to
word: do not evaluate to
x:. Each word has a spelling (its
lit-word! are all part of the word syntax, and are constructed by appending/prepending either
' to the
loaded spelling of a word:
>> spelling: "word" == "word" >> load spelling == word >> type? load spelling == word! >> append copy spelling ":" == "word:" >> type? load append copy spelling ":" == set-word! >> type? load head insert copy spelling ":" == get-word! >> type? load head insert copy spelling "'" == lit-word!
So, when you write
set3, you're applying this syntax to the word that has spelling
word, not to the word that has spelling
word appears in function's specification, it is local to function's context, hence you can't see it "from the outside". In
set1, on the other hand,
x comes from the outside world and is bound to some context (
system/words in our case) so what you function does is simply changing its value in its context: since
set is a function, it evaluates its arguments,
word evaluates to
1 evaluates to itself, then
x word in
system/words context is set to an integer
Once again its time to give this nice example I love :)
words carry their contexts
>> a: 0 o: context [a: 1] p: context [a: 2] >> b: reduce ['a in o 'a in p 'a] == [a a a] >> reduce b == [0 1 2] >> set in o 'a 3 == 3 >> reduce b == [0 3 2]
set a-word a-value is always sets the value of a word in global context if you did not explicitly give another context using
in or similar. That's what happen in your set1 function and not in set2 & set3.
>> matrix: collect [loop 4 [keep context [spoon: take [there is no spoon]]]] == [make object! [ spoon: 'there ] make object! [ spoon: 'is ] make object! [ spoon: 'no ... >> cutlery: collect [forall matrix [keep in matrix/1 'spoon]] == [spoon spoon spoon spoon] >> reduce cutlery == [there is no spoon]
riddle: foreach spoon load take/part at read https://gitter.im/red/red/welcome?at=5b0960f6a45f930a65d8489a 498 38 [ append  bind [spoon] context compose [spoon: (to-lit-word spoon) ]] == [spoon spoon spoon spoon spoon spoon spoon]
For those newer to Red, this being the Welcome group, you can see that Red is different and very flexible. For those who know Red, can we distill things to a simple recommendation for beginners? e.g.
If you know the name of the thing you're referring to, use a
set-word!. If you're passing names (words) around, and there's a level of indirection, that's when you use
As an exercise I wrote function that works simillar to pythons
for x in range(1,5):
for-range: func ['var start stop step block] [ set var start while [(reduce var) <= stop] [ do block set var add reduce var step ] ] for-range x 1 5 1 [print x] ; 1 ; 2 ; 3 ; 4 ; 5 counter: 0 for-range x 1 11 2 [print rejoin [multiply x 5 " is the result of loop nr: " set 'counter add counter 1 ]] unset 'counter ; 5 is the result of loop nr: 1 ; 15 is the result of loop nr: 2 ; 25 is the result of loop nr: 3 ; 35 is the result of loop nr: 4 ; 45 is the result of loop nr: 5 ; 55 is the result of loop nr: 6
After few tests it seems to work as long as user will not pass word
var as fist argument to the function. Is there a way to improve it?
counter:and it would have worked as well. I probably was propably afraid that functions have their own context and that to change variable in global scope I have to use
setbut that was clearly wrong assumption.