Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jul 01 2018 17:34
    @greggirwin banned @BIjeuca_twitter
  • Dec 03 2017 05:53
    @PeterWAWood banned @matrixbot
  • Sep 28 2016 12:20
    @PeterWAWood banned @TimeSeriesLord
Boleslav Březovský
@rebolek
Anyway, to me they are directly equivalent. Even in @greggirwin's example, he's changing set-word! to word!.
Vladimir Vasilyev
@9214
@rebolek you can't use set-word! syntax if you don't know word's spelling in advance.
While you can set some word without even knowing how it looks like.
Boleslav Březovský
@rebolek
>> x: 'a do reduce [to set-word! x 5]
== 5
>> a
== 5
Vladimir Vasilyev
@9214
@rebolek that's no the point.
set changes word's value in its context, word: either creates new entry or changes value in the context where evaluation happens.
Vladimir Vasilyev
@9214
not* the point
You can't write x: by yourself if you don't know that it's actually x.
Boleslav Březovský
@rebolek
If that's point, it's not communicated in Gregg's post very clearly.
Vladimir Vasilyev
@9214
@rebolek maybe he skipped his coffee?
Boleslav Březovský
@rebolek
@9214 Ouch. I hope he's fine.
Vladimir Vasilyev
@9214
He didn't post his :^) in a while... :worried:
Boleslav Březovský
@rebolek
suspicious...
Greg T
@gltewalt

word gets evaluated immediately, so you get the value. Equivalent to set 1 1.

This works and will not throw an error, but you are setting x, not word:

word: 'x
== x
set word 1
== 1
word
== x
x
== 1
```

I think that's all he was trying to point out.

Vladimir Vasilyev
@9214
You are not binding x, you are setting it to some value.
Binding is changing word's context, setting is changing its value in its context.
Greg T
@gltewalt
Edited
Greg T
@gltewalt
first cola
Gregg Irwin
@greggirwin
You're all correct. :^) @9214 and @GregT got my intent, but my example should have been reversed, as @rebolek noted:
>> set word 1
*** Script Error: word has no value
*** Where: set
*** Stack:  

>> word: 1
== 1
Gregg Irwin
@greggirwin
The important point is that, while similar, or even the same in some cases, set-word! and set syntax are not equivalent.
Semseddin Moldibi
@endo64

@gltewalt > word gets evaluated immediately
Correct, blocks are not evaluated immediately, hence:

word: 'x
set [word] 1
word ; == 1
x ; *** Script Error: x has no value

We are setting word to 1 not its evaluated value (x) to 1.

Gregg Irwin
@greggirwin
Wow. This could turn into an entire topic.
ne1uno
@ne1uno
can we find something other than word here? it's already overloaded enough
Gregg Irwin
@greggirwin
<he he> Good point @ne1uno.
Remigiusz Kozdra
@vejitatoja

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 set2 and set3?
It looks like neither x nor word

Semseddin Moldibi
@endo64

@vejitatoja for set2 function, to understand better, lets put some probes

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)
And 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 set1

set word value is same as word: value if both are in the same context (for example it is global context if you are on REPL console).
otherwise set word value sets the words value in global context if you are not explicitly give the context, like set in obj 'word 2 sets the words value in the context of obj
And @ne1uno is right, lets use another word for word it is already enough confusing :) 'w is better I think.
Vladimir Vasilyev
@9214

@vejitatoja word evaluates to x, but 'word and word: do not evaluate to 'x and x:. Each word has a spelling (its formed representation). set-word!, get-word! and lit-word! are all part of the word syntax, and are constructed by appending/prepending either : or ' 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 word: in set2 and set3, you're applying this syntax to the word that has spelling word, not to the word that has spelling x. Since 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 x, 1 evaluates to itself, then x word in system/words context is set to an integer 1.

Phew! :smile:

Semseddin Moldibi
@endo64

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.

Vladimir Vasilyev
@9214
>> 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]
Toomas Vooglaid
@toomasv
"No spoon" festival!!
Vladimir Vasilyev
@9214
A common rite of passage in Redboland.
Toomas Vooglaid
@toomasv
Be brave and allow web-content, then reduce riddle:
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]
Toomas Vooglaid
@toomasv
Or better yet:
i: 0 riddle: foreach spoon load take/part at read https://gitter.im/red/red/welcome?at=5b0960f6a45f930a65d8489a 498 38 [append [] bind pick [no spoon] odd? i: i + 1 context reduce [pick [no: spoon:] odd? i to-lit-word spoon]]
== [no spoon no spoon no spoon no]
Toomas Vooglaid
@toomasv
Had to squeeze it on one line to work by copying.
Gregg Irwin
@greggirwin

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 set and get.

Remigiusz Kozdra
@vejitatoja
Thank you @endo64 @9214 @greggirwin your explanations were very helpful! I think i get it now. :fire:
Remigiusz Kozdra
@vejitatoja

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?

hiiamboris
@hiiamboris
@vejitatoja and what happens if user does pass var as 1st argument?
Remigiusz Kozdra
@vejitatoja
@hiiamboris I'm sorry for confusion I must have made error and forgot to change all of the instances of x to var when testing it.
Now I see that when passed var stop or start as the first argument it still works as intended.
hiiamboris
@hiiamboris
:+1:
BeardPower
@BeardPower
@vejitatoja Just out of curiosity: are you really comfortable with the set style?
hiiamboris
@hiiamboris
@vejitatoja you can replace set 'counter add counter 1 with counter: counter + 1 and reduce var with get var
Gregg Irwin
@greggirwin
@vejitatoja nice! Already creating your own control structures.
Remigiusz Kozdra
@vejitatoja
@BeardPower It's not a problem now that I understand it a little better. From what I learned I have to use set this way inside the function if i don't know the name of the word being passed by the user.
BeardPower
@BeardPower
@vejitatoja Yes, but the word counter is known.
Remigiusz Kozdra
@vejitatoja
@BeardPower Yes that's true. As @hiiamboris suggested I could have used 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 set but that was clearly wrong assumption.
BeardPower
@BeardPower
@9214 Maybe the chief of context can explain that ;-)
Vladimir Vasilyev
@9214
@BeardPower what was the question?