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

Bug! path! in objects don't behave the same as path! outside object

 [1/5] from: al::bri::xtra::co::nz at: 25-Sep-2000 12:29


Bug! path! in objects don't behave the same as path! outside object. REBOL/View 0.10.34.3.1 23-Sep-2000 Copyright 2000 REBOL Technologies. All rights reserved.
>> base: make object! [
[ p: does [print "function 'p in 'base"] [ ]
>> derived: make object! [
[ p: first [base/p] [ ]
>> p: first [base/p]
== base/p
>> p
function 'p in 'base
>> :p
== base/p
>> base/p
function 'p in 'base
>> derived/p
== base/p The above is incorrect, I believe. The result of the above should be the result of base/p: function 'p in 'base _not_ the path: base/p Andrew Martin ICQ: 26227169 http://members.nbci.com/AndrewMartin/ http://members.xoom.com/AndrewMartin/

 [2/5] from: rebol:techscribe at: 24-Sep-2000 21:48


Hi Andrew, you wrote:
>Bug! path! in objects don't behave the same as path! outside object.
Which parallel case involving paths are you thinking of? Here is an example case that does not involve objects at all and behaves exactly the case you attribute to objects:
>> base: func [/p] [ either p [print "'p in 'base."] [print "'base"] ] >> base/p
'p in 'base.
>> derived: make function! [/p] [ either p [p: first [base/p]] [first
[base] ] ]
>> derived
== base
>> derived/p
== base/p When you create the object (or in my example the function) the expression first [base/p] is evaluated. It evaluates to the path base/p
>> type? first [base/p]
== path! base/p is a value of type path! This value, base/p, is referenced by p in your make object! example. If you want REBOL to instead assign p as a reference to the value that the path evaluates to, you must tell REBOL that:
>> first reduce [base/p]
'p in 'base. i.e. derived: make object! [ p: first reduce [base/p] ]
>REBOL/View 0.10.34.3.1 23-Sep-2000 >Copyright 2000 REBOL Technologies. All rights reserved.
<<quoted lines omitted: 24>>
>http://members.xoom.com/AndrewMartin/ >-><-
;- Elan [ : - ) ] author of REBOL: THE OFFICIAL GUIDE REBOL Press: The Official Source for REBOL Books http://www.REBOLpress.com visit me at http://www.TechScribe.com

 [3/5] from: al:bri:xtra at: 25-Sep-2000 19:50


> Hi Andrew,
Hi, Elan. I agree with everything up to here:
> If you want REBOL to instead assign p as a reference to the value that the
path evaluates to, you must tell REBOL that:
> >> first reduce [base/p] > 'p in 'base. > i.e. > derived: make object! [ > p: first reduce [base/p] > ]
Unfortunately, that doesn't work:
>> base: make object! [p: does [print "function 'p in 'base"]] >> derived: make object! [p: first reduce [base/p]]
function 'p in 'base ** Script Error: p needs a value. ** Where: p: first reduce [base/p] I'd like 'p in 'derived to be a path!, which refers to 'p in 'base. Like I can do with 'p outside of derived. Watch closely:
>> p: first [base/p]
== base/p
>> type? p
function 'p in 'base == unset!
>> type? :p
== path!
>> probe p
function 'p in 'base ** Script Error: probe is missing its value argument. ** Where: probe p
>> probe :p
base/p == base/p Now if this behaviour outside an object were implemented inside an object, then it would be very easy to write objects that inherit behaviour, and the storage cost wouldn't involve copying functions into every object. I think that would be very nice behaviour. I can also show that it's fault in objects because:
>> derived: make object! [p: first [base/p]] >> derived/p: :p
== base/p
>> probe derived
make object! [ p: base/p ]
>> derived/p
== base/p
>> p
function 'p in 'base Andrew Martin Breaking new paths... ICQ: 26227169 http://members.nbci.com/AndrewMartin/ http://members.xoom.com/AndrewMartin/

 [4/5] from: rebol:techscribe at: 25-Sep-2000 12:10


Hi Andrew, Aha. Got it. What you are observing is not specific to objects. It is the result of how REBOL evaluates words and paths. Let me simplify your example so that we can more easily focus on the essential difference.
>> base: make object! [ p: "'p in 'base." ] >> derived: make object! [ p: 'base/p ]
1. Word evaluation: a) word references a path that evaluates to a string.
>> p: 'base/p
== base/p
>> :p
== base/p
>> p
== "'p in 'base." b) word references a path that evaluates to a path:
>> r: 'derived/p
== derived/p
>> :r
== derived/p
>> r
== base/p In both cases when REBOL evaluates a word and the word evaluates to a path, then REBOL returns the value that is referenced by the path. It stops dereferencing values at the second level as demonstrate by r. The evaluator return base/p and did not continue to dereference the path base/p. Compare to: 2. Path evaluation:
>> derived/p
== base/p Re: 1. (a and b) When REBOL evaluates a word, and the returned value is a path, then REBOL returns the value referred to by that path. Re: 2. When REBOL evaluates a path, then it returns the value that path is associated with. Unlike case 1., the path returned by evaluating the top-level path is not dereferenced. 3. In both cases 1. and 2. if the returned value is a function, then that function is evaluated and the value resulting from evaluating the function is returned. So what you are dealing with here is an exception that REBOL evaluator makes for words, when those words evaluate to paths. You can say that with respect to this behavior the REBOL evaluator works something like this: evaluate: func [something [any-type!]] [ if value? 'something [ either all [ word? get 'something path? get get 'something ] [ return get get 'something ][ return get 'something ] ] return print "unset" ]
>> evaluate p
== "'p in 'base."
>> evaluate derived/p
== base/p Note that this really has nothing to do with objects. You can do the same thing with blocks:
>> block: [ p "'p in 'block" ]
== [p "'p in 'block"]
>> block/p
== "'p in 'block" Word is assigned a path:
>> p: 'block/p
== block/p When the REBOL evaluator discovers that the word p is referencing a path, then the path is dereferenced as well:
>> p
== "'p in 'block" But when REBOL is evaluating a path (this time associated with a block) then unlike when evaluating a word, the evaluation is not repeated for the referenced path:
>> derived: [ p block/p ]
== [p block/p]
>> derived/p
== block/p In short, REBOL is consistent with respect to the distinction it makes between evaluating words and evaluating paths. The way REBOL treats path is not specific to objects. Hope this helps, ;- Elan [ : - ) ] author of REBOL: THE OFFICIAL GUIDE REBOL Press: The Official Source for REBOL Books http://www.REBOLpress.com visit me at http://www.TechScribe.com

 [5/5] from: al:bri:xtra at: 26-Sep-2000 19:55


Hi, Elan. You wrote:
> When the REBOL evaluator discovers that the word p is referencing a path,
then the path is dereferenced as well:
> >> p > == "'p in 'block" > > But when REBOL is evaluating a path (this time associated with a block)
then unlike when evaluating a word, the evaluation is not repeated for the referenced path:
> >> derived: [ p block/p ] > == [p block/p] > >> derived/p > == block/p > > In short, REBOL is consistent with respect to the distinction it makes
between evaluating words and evaluating paths. The way REBOL treats path is not specific to objects. I agree. But it would be very, very nice if the natural value of a path! is the dereferenced value. So that a path! value operates like a function! value does. Andrew Martin ICQ: 26227169 http://members.nbci.com/AndrewMartin/ http://members.xoom.com/AndrewMartin/

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted