[REBOL] Re: Sameness - a pragmatic approach.
From: lmecir:mbox:vol:cz at: 12-Feb-2003 18:10
Hi Joel,
> 2) My original question was in reference to the example of
>
> foo: make object! [a: 1 b: "Hi!"]
> baz: make object! [a: 1 b: "Hi!"]
> equal? foo baz
>
> where functions were not involved. It seems to me that this
> is not significantly harder to solve than
>
> fooblk: ["a" 1 "b" "Hi!"]
> bazblk: ["a" 1 "b" "Hi!"]
>
> without functions in the picture.
Just to show it is possible:
do http://www.rebolforces.com/~ladislav/evaluation.r
equal-state? foo baz ; == true
> With "elementary" types, EQUAL? is strictly two-valued: we can
> state with total confidence that two values are or are not
> equal. Aristotle would have been proud.
:-)
> There are really three possible answers for EQUAL? over function
> values: we know they are equal (probably SAME?), we know they
> are not equal (e.g. different argument signatures), or we simply
> can't tell (given a specific set of criteria). Of course EQUAL?
> must return a boolean value by definition, so we fold the "can't
> tell" case into FALSE (properly IMHO).
>
> Let me interrupt myself to assert the view that enhanced
> equality testing for objects should be concerned with
> correspondance of the attributes and content, without regard
> for ordering, so that
>
> altfoo: make object! [a: 1 b: "Hi!" c: false d: 3.14]
>
> would be considered equal to
>
> altbaz: make object! [d: 3.14 a: 1 c: false b: "Hi!"]
>
> because the *sets* of local words can be placed into 1-to-1
> correspondance with equal names and values. Now back to our
> regularly scheduled program...
Let me just have a look, what the EQUAL-STATE? thinks about it:
equal-state? altfoo altbaz ; == false
Bad luck. Nevertheless, this seems to be in contradiction with your rule stating that
(mold altfoo) should equal to (mold altbaz), which isn't the case.
> So this leaves open a number of possibilities for object equality
> testing:
>
> 0) Give up unless the two objects are SAME? This is the present
> behavior AFAIK.
>
> 1) Define equality of objects without trying to analyze inner
> functions. This would allow equality testing over objects
> that are used as structured data containers, as in the
> common REBOL idiom:
>
> make object! decode-cgi system/options/cgi/query-string
>
> or the FOO and BAZ pairs above. Synonymous object attributes
> that are set to FUNCTION! values would be compared with EQUAL?
> which would still "do the right thing" for such cases as
>
> newfoo: make object! [a: 1 b: "Hi!" say: :print]
> newbaz: make object! [a: 1 b: "Hi!" say: :print]
>
> where the words referred to the same external/nonmethod func.
> This case would treat normal methods as "don't know" = FALSE .
Let me check EQUAL-STATE? again:
equal-state? newfoo newbaz ; == true
> 2) Use a smarter "method-aware" equality test for the specific
> case of functions being compared as values of object-local
> words: two methods would be considered equal if corresponding
> arguments and refinements had the same names and types, their
> locals had the same names, and their bodies were the same
> except for the appearance of corresponding argument, local,
> refinment, and parent-object words, which would have to match
> in the obvious way. Thus we would get TRUE for EQUAL? over
>
> foofun: make object! [
> a: 1
> b: "Hi!"
> say: func [n [number!]] [
> loop n [
> print ["a" a tab "b" b]
> ]
> ]
> ]
>
> and
>
> bazfun: make foo [] ;; OK, I'm lazy... ;-)
>
> because of the following analysis:
>
> foofun type bazfun
> ---------------------- ----------------------
> a: corr. a:
> 1 equal 1
> b: corr. b:
> "Hi!" equal "Hi!"
> say: corr. say:
> func [ equal func [
> n corr. n
> [number!]] [ loop equal [number!]] [ loop
> n corr. n
> [ print [ "a" equal [ print [ "a"
> a corr. a
> tab "b" equal tab "b"
> b corr. b
> ] ] ] ] equal ] ] ] ]
>
> (where I'm crowding as much "equality" as possible into one
> line for the sake of brevity).
>
> In all of these alternatives, there will still be "don't know"
> cases that become FALSE (i.e. our heuristics can't prove they
> are equal) but I see some virtue in pushing the envelope. My
> (uninformed) guess is that option (1) wouldn't be very costly
> to add, as we already have an equality test for functions:
>
> >> stampa: :print
> >> equal? :print :stampa
> == true
>
> We certainly don't want to wait for the interpreter to solve
> the Halting Problem, however! ;-)
>
> -jn-
I just wanted to start with a simpler, yet, as it seems, unsolvable problem. How it should
be with the equality of:
a: func [a] [a]
b: func [a] [a]
although this seems to be almost trivial, it isn't, see below:
c: func [a] [a]
change second :c use [a] [a: 0 'a]
probe :c ; func [a][a]
Now I don't know about any better method to compare A and C, than the classical
sameness. Moreover, this shows, that Rebol is less transparent, then it seems at a first
glance.
Regards
-L