Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[refactoring s-c?]

 [1/12] from: rebol665:ifrance at: 13-Mar-2002 22:43


Hi rebollers Again exploring Ladislav's contexts.html, I have difficulty understanding the s-c? function. The goal of the s-c? function is to test if two words are in the same context. Two Words WORD1 and WORD2 are bound to the same context, if the expression (s-c? word1 word2) yields TRUE. Here (1) is the original version of s-c? and (2) my simplified version. Both return the same result (3). Something is certainly missing in the simplified version, but what ? what are the purposes of the 'use and 'reduce in the original version ? (1) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; s-c? function undefined?: func [ {determines, if a word is undefined} word [any-word!] ] [ error? try [error? get/any :word] ] s-c?: func [ {Are word1 and word2 bound to the same context?} word1 [word!] word2 [word!] ] [ found? any [ all [ undefined? word1 undefined? word2 ] all [ not undefined? word2 same? word1 bind use reduce [word1] reduce [ 'first reduce [word1] ] word2 ] ] ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; the (over?) simplified version (2) sc: func [ {Are word1 and word2 bound to the same context?} word1 [word!] word2 [word!] ] [ print mold use reduce [word1] reduce ['first reduce [word1]] found? any [ all [ undefined? word1 undefined? word2 ] all [ not undefined? word2 same? word1 first bind [word1] word2 ] ] ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; tests (3)
>> o: make object! [a: 1 b: 2] >> a: 100
== 100
>> >> word1: 'a
== a
>> word2: second first o
== a
>> word3: third first o
== b The original s-c? gives :
>>s-c? word1 word2
== false
>>s-c? word1 word3
== false
>>s-c? word2 word3
== true The simplified version gives
>>sc word1 word2
a == false
>>sc word1 word3
a == false
>>sc word2 word3
a == true As for the subject of this post, I was just kidding. I'am pretty sure that Ladislav's code do not need any refactoring. Patrick

 [2/12] from: rotenca::telvia::it at: 14-Mar-2002 14:23


Hi Pat,
> all [ > not undefined? word2 > same? word1 first bind [word1] word2 > ] > ] > ]
1) If you do not get 'word1 o reduce [word1], 'word1 is 'word1, not its value (the real word to test) 2) if 'word1 is not in the context of 'word2, bind does not change it and same? return true.
>> o: context [b: 2] >> same? 'a first bind [a] in o 'b
== true --- Ciao Romano

 [3/12] from: rebol665:ifrance at: 15-Mar-2002 15:24


Thank you romano I think I have a long way in front of me before I fully understand the s-c? code. Sometimes it seems the more I go the less I know. I would be glad if someone (Ladislav ?) could explain it to me. Patrick No news of rebol/core 2.6 ? it was supposed to be available this week, isn't it ?

 [4/12] from: lmecir:mbox:vol:cz at: 15-Mar-2002 19:15


Hi Pat, thanks for looking into that. The goal of the USE and REDUCE usage is to create a word equal to a given word but not the same as the given word. I could have defined a function NONSAME as follows: nonsame1: func [ { create a word equal to the given word but not the same as the given word } word [word!] {the given word} ] [ use reduce [word] reduce [ 'first reduce [word] ] ] My implementation was incorrect (as I have found out when I looked into it). A correct implementation should have been as follows: nonsame: func [ { create a word equal to the given word but not the same as the given word } word [word!] {the given word} ] [ first use reduce [word] reduce [ reduce [word] ] ] Can you find my error? The implementation of the S-C? function could then have been as follows: s-c?: func [ {Are word1 and word2 bound to the same context?} word1 [word!] word2 [word!] ] [ found? any [ all [ undefined? word1 undefined? word2 ] all [ not undefined? word2 same? word1 bind nonsame word1 word2 ] ] ] Cheers (and thanks for your question) Ladislav ----- Original Message ----- From: "pat665" <[rebol665--ifrance--com]> To: <[rebol-list--rebol--com]> Sent: Wednesday, March 13, 2002 10:43 PM Subject: [REBOL] [refactoring s-c?] Hi rebollers Again exploring Ladislav's contexts.html, I have difficulty understanding the s-c? function. The goal of the s-c? function is to test if two words are in the same context. Two Words WORD1 and WORD2 are bound to the same context, if the expression (s-c? word1 word2) yields TRUE. Here (1) is the original version of s-c? and (2) my simplified version. Both return the same result (3). Something is certainly missing in the simplified version, but what ? what are the purposes of the 'use and 'reduce in the original version ? (1) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; s-c? function undefined?: func [ {determines, if a word is undefined} word [any-word!] ] [ error? try [error? get/any :word] ] s-c?: func [ {Are word1 and word2 bound to the same context?} word1 [word!] word2 [word!] ] [ found? any [ all [ undefined? word1 undefined? word2 ] all [ not undefined? word2 same? word1 bind use reduce [word1] reduce [ 'first reduce [word1] ] word2 ] ] ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; the (over?) simplified version (2) sc: func [ {Are word1 and word2 bound to the same context?} word1 [word!] word2 [word!] ] [ print mold use reduce [word1] reduce ['first reduce [word1]] found? any [ all [ undefined? word1 undefined? word2 ] all [ not undefined? word2 same? word1 first bind [word1] word2 ] ] ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; tests (3)
>> o: make object! [a: 1 b: 2] >> a: 100
== 100
>> >> word1: 'a
== a
>> word2: second first o
== a
>> word3: third first o
== b The original s-c? gives :
>>s-c? word1 word2
== false
>>s-c? word1 word3
== false
>>s-c? word2 word3
== true The simplified version gives
>>sc word1 word2
a == false
>>sc word1 word3
a == false
>>sc word2 word3
a == true As for the subject of this post, I was just kidding. I'am pretty sure that Ladislav's code do not need any refactoring. Patrick

 [5/12] from: rebol665:ifrance at: 16-Mar-2002 18:24


Hi Ladislav, I am even more confused, but I like that! I can play the luke-who-wants-to-be-a-jedi part, master Yoda. 1. Assuming that nonsame is correct, I have tested that : a: 100 word1: nonsame 'a
>> s-c? 'a 'word1
== true I was puzzled because I thought that use will create a new context and return something bound to this context. I had found an interesting example of that in the escribe archives : a: 1 block: [a] use [a] [a: 2 append tail block [a]]
>> block
== [a a]
>> s-c? first block second block
== false Fortunately I realized my mistake and that the correct testing was :
>> s-c? 'a word1
== false That was confirmed by
>> s-c? 'a nonsame 'a
== false Assertion 1 : nonsame returns a word bound to another context. Assertion 2 : this context is created by use. Assertion 3 : nonsame returns a word with the same spelling.
>> mold word1
== "a"
>> mold 'a
== "a" I am aware that assertion 1 and assertion 3 are certainly bound because it is not possible to have two words with the same spelling in the same context. 2. From (1) I have learned that use was required to create a new word with the same spelling but different. As for comparing nonsame1 and nonsame, I have learned nothing. As far as I can tell they are equivalent :
>> word2: nonsame1 'a
== a
>> s-c? 'a word2
== false 3. Why reduce ? I have still no idea, but I can try removing it and see what happens. ns: func [ word [word!] {the given word} ][ use [word][word] ]
>> ns 'a
** Script Error: word has no value ** Where: ns ** Near: word Definitively wrong ns: func [ word [word!] {the given word} ][ use [word] reduce [word] ]
>> ns 'a
== 100 Returns a value. It is not good. ns: func [ word [word!] {the given word} ][ use [word] reduce ['first reduce [word]] ]
>> ns 'a
== a Looks better. first is used to extract a word rather than a value. An extra block is needed to be the body that use requires. However this is not good because :
>> same? 'a ns 'a
== true Assertion 4 : I am exhausted ! 4. As far as I can tell now, I am not able to explain why nonsame is better than nonsame1. All my experiments have fail to prove any of : - nonsame1 and nonsame do not return always the same result - nonsame1 has an undesired side-effect - nonsame1 rises an error 5. Epilogue Learning that I know nothing is indeed a valuable lesson. Knowing that is certainly better than pretending to know something that I don't. I don't know if I am ready for understanding the truth. It is not for the apprentice to decide. I have spent half my day with all these trials and must return now to a normal life ! Hoping for the best Patrick

 [6/12] from: rotenca:telvia:it at: 17-Mar-2002 1:33


Hi, Pat
> Assertion 4 : I am exhausted ! > > 4. As far as I can tell now, I am not able to explain why nonsame is better > than nonsame1. All my experiments have fail to prove any of : > > - nonsame1 and nonsame do not return always the same result > - nonsame1 has an undesired side-effect > - nonsame1 rises an error >
Try with the word 'first --- Ciao Romano

 [7/12] from: lmecir:mbox:vol:cz at: 17-Mar-2002 8:44


Hi Pat, you are doing well, don't give up (use the source, Luke...), your mail is nice. <<Pat>> ...snip... Assertion 1 : nonsame returns a word bound to another context. Assertion 2 : this context is created by use. Assertion 3 : nonsame returns a word with the same spelling. ...snip... 2. From (1) I have learned that use was required to create a new word with the same spelling but different. As for comparing nonsame1 and nonsame, I have learned nothing. As far as I can tell they are equivalent : <</Pat>> NONSAME1 and NONSAME look so much equivalent, that it confused even me. The only difference is the usage of 'first. That is the source of the trouble in NONSAME1: same? 'first nonsame1 'first ** Script Error: first has no value ** Where: nonsame1 ** Near: first [first] If we try this for NONSAME, we will get: same? 'first nonsame 'first == false <<Pat>> ...snip... 3. Why reduce ? I have still no idea, ...snip... <</Pat>> Just in case you need it, here is the reason for REDUCE: word: 'a block1: [word] block2: reduce [word] block3: reduce [[word]] block4: reduce [reduce [word]] <<Pat>> ...snip... 5. Epilogue Learning that I know nothing is indeed a valuable lesson. Knowing that is certainly better than pretending to know something that I don't. I don't know if I am ready for understanding the truth. It is not for the apprentice to decide. I have spent half my day with all these trials and must return now to a normal life ! Hoping for the best Patrick <</Pat>> Nice epilogue :-) My feelings are similar, because my implementation of S-C?, although pretending to be correct, was in fact incorrect. Hope the trial and error didn't exhaust you too much. Now it should be clearer, but feel free to ask, if anything remains unclear. Best regards L P.S. The newest version of [Contexts] is at: http://www.rebolforces.com/~ladislav/contexts.html P.P.S. How do you like the change in the UNBOUND? function?

 [8/12] from: rebol665:ifrance at: 17-Mar-2002 22:16


Hi Ladislav, 1. first 'first If I understand nonsame1 is equivalent to nonsame except if called with the word 'first. <<yoda>> same? 'first nonsame1 'first ** Script Error: first has no value <<L>> So I have tried to find out the part of nonsame1 that breaks ... In the following line from nonsame1, I see two parts : use reduce [word] reduce ['first reduce [word]] or use <part 1> <part 2> <part 1> being a block of words, here a block with only one word. <part 2> being a block to evaluate. Evaluation returning the given word. A little test shows that <part 1> is correct.
>> myword: 'first
== first
>> reduce [myword]
== [first] Therefore I concentrate myself on <part 2>. To emulate <part 2> I create this little function test: func [x [word!]][do reduce ['first reduce [x]]] However I was desappointed with the result.
>> test myword
== first No error, so neither <part 1> or <part 2> is responsible for the error. It is only when they are bind together by use, that an error rises. I think also there is nothing wrong with 'first by itself. To clear that, I have made the following test where 'first is replaced by 'second.
>> test2: func [word [word!]][use reduce [word] reduce ['second reduce
[word]]]
>> test2 'second
** Script Error: second has no value Bingo ! let's try to remove first ...
>> test2: func [word [word!]][use reduce [word] reduce [reduce [word]]] >> test2 'first
== [first] It is almost ok, except that a block is returned instead of a word. And it was indeed the purpose of using 'first to give us a word. A part that it returns a block, test2 give us the right thing : a word with the same spelling but not the same word.
>> first test2 'first
== first Here we can get the "new" first with the same spelling.
>> same? 'first first test2 'first
== false And it is not the same as the global first. From that it is easy to build test3 which is indeed nonsame :
>> test3: func [word [word!]][first use reduce [word] reduce [reduce
[word]]]
>> test3 'first
== first
>> same? 'first test3 'first
== false 2. second reduce Let's play again with my simplification of use : use <part 1> <part 2> where <part 1> is a block including one word <part 2> is a block returning that word Why can't we simply write : test4: func [x [word!]][use [x][x]] This is an answer
>> use [x][x]
** Script Error: x has no value ** Where: do-boot ** Near: x The x in part 2 exists but have never been set. It has no value to return. In fact, we don't want the value of x but the word associated. May be this could work. test4: func [x [word!]][use [x]['x]]
>> test4 'first
== x Nope, 'x is taken litteraly here. test4: func [x [word!]][use [x][compose [('x)]]]
>> test4 'first
== [x] test4: func [x [word!]][use reduce [x][compose [('x)]]]
>> test 'first
== [first [first]] Yeah, another puzzle: one in -> two out. However it is first that comes out. So I think I understand the first reduce. Let's replace compose by reduce too. test4: func [x [word!]][use reduce [x][reduce [x]]]
>> test4 'first
== [first] Not bad ! but is it the real one ?
>> same? 'first first test4 'first
== true No luck again. Indeed it says something. Since we get the global 'first, it means that the use did not work at all. This one is a bit tricky test5: func [x [word!]][use [first][reduce [x]]]
>> test5 'first
== [first]
>> same? 'first test5 'first
== false It works, however it works only with 'first. It shows anyway that only <part 2> needs to be taken care of. Let's try to see what is wrong in that <part 2>. test6: func [x [word!]][use reduce [x][print reduce [x]]]
>> test6 'first
** Script Error: first expected series argument of type: series pair event money date object port time tuple any-function library struct event ** Where: test6 ** Near: first It seems that x is evaluated again. To prevent evaluation, it can be put in an extra block. test6: func [x [word!]][use reduce [x][print [reduce [x]]]]
>> test6 'first
first As we know that print reduces its argument, all we have to do is to replace print by reduce. test7: func [x [word!]][use reduce [x][reduce [reduce [x]]]]
>> test7 'first
== [[first]] And yet there is an external block to get rid of. test8: func [x [word!]][use reduce [x] reduce [reduce [x]]]
>> test8 'first
== [first]
>> same? 'first test8 'first
== false And finally from what we learned from (1.). test9: func [x [word!]][first use reduce [x] reduce [reduce [x]]]
>> test9 'first
== first
>> same? 'first test9 'first
== false Which is not a surprise because test9 is nonsame. 3. third contexts.html I was very proud to see my name in the acknowledgements part. I show it to everybody in the house except my cat. 4. fourth unbound I noticed the replacement of error? by any-type? I will look into later, because I have very few little grey cells available at the moment. Patrick

 [9/12] from: g:santilli:tiscalinet:it at: 17-Mar-2002 15:38


Hi Ladislav, On Friday, March 15, 2002, 7:15:31 PM, you wrote: Reading your later posts, and thinking about it... LM> nonsame: func [ LM> { LM> create a word equal to the given word LM> but not the same as the given word LM> } LM> word [word!] {the given word} LM> ] [ LM> first use reduce [word] reduce [ LM> reduce [word] LM> ] LM> ] what about: nonsame: func [ { create a word equal to the given word but not the same as the given word } word [word!] {the given word} ] [ use reduce [word] reduce [ to-lit-word word ] ] It seems to work correctly for me. (Not that is much clearer, or better in any way --- just a different approach.) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [10/12] from: rotenca:telvia:it at: 18-Mar-2002 2:57


It has the side effect of creating a new global word if the word had been created with to-block. Perhaps a more readable version of s-c? could be created with compose. I use it in my own. --- Ciao Romano

 [11/12] from: rotenca:telvia:it at: 18-Mar-2002 3:12


> 4. fourth unbound > > I noticed the replacement of error? by any-type? I will look into later, > because I have very few little grey cells available at the moment.
Could be any of none? tuple? error? datatype? and so on. It must accept an any-type! arg and have no side effect. --- Ciao Romano

 [12/12] from: lmecir:mbox:vol:cz at: 18-Mar-2002 9:02


Hi Gabriele, exactly as Romano said, your version enlarges (sometimes) the global context (and it is not as generalizable to any-word types). We can use a variable to shorten the source: nonsame: function [ { create a word with equal spelling as the given word has but not the same as the given word } word [word!] {the given word} ] [block] [ first use block: reduce [word] reduce [block] ] ----- Original Message ----- From: "Romano Paolo Tenca" Sent: Monday, March 18, 2002 2:57 AM Subject: [REBOL] Re: [refactoring s-c?] It has the side effect of creating a new global word if the word had been created with to-block. Perhaps a more readable version of s-c? could be created with compose. I use it in my own. --- Ciao Romano