Mailing List Archive: 49091 messages

## [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:

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

(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
```