UPDATE Mar-2019: This proposal has been shifted to a more benign variation, where IS and ISN'T replace == and !==.
Rebol has historically had a lot of trouble with questions of equality, and various hierarchies of it. The idea of EQUIV? even came up, which was to check to see if two blocks of code weren't just STRICT-EQUAL? but if the words in them had the same bindings. :-/ (I killed off EQUIV? in Ren-C pretty early because I couldn't think of any reasonable application of the knowledge you'd be getting out of it.)
The fact that Rebol equality is lax by default has bothered a lot of people. One of the worst and most memorable cases I've run into wound up leading to a day (or more) of debugging some code while trying to port Red to R3-Alpha. A tag and a string were considered equal. It's still the case today...Ren-C hasn't yet changed R3-Alpha's behavior on this, nor has Red:
>> <fOo> = "FoO"
== true
But none of it really makes sense, check out this situation also the case in R3-Alpha and Red:
>> <abc> = %ABC
== true
>> (quote def:) = 'def
== true
>> "ghi" = <GhI>
== true
>> [<abc> def: "ghi"] = [%ABC 'def <GhI>]
== false
Bleah. This is all pretty clearly bad mojo, and needs to get sorted out.
My opinion is that it doesn't seem you should have to say == to get a level of rigor that makes sense to a programmer. I don't think different datatypes should be candidates for equality of any kind, you should have to ask something like same-spelling? if this is your intent. Also, historically there has been a push and pull over whether Rebol should be case-sensitive or case-insensitive by default. I think @earl advocated (or at least considered advocating) for case-sensitivity in equal? and =, with some other operation like approximately-equal? being ~= or similar.
My "radical proposal" was to say that when you're using constructs like CASE or SWITCH that indeed, by default, they would operate case-insensitively... but that the symbolic nature of the = sign would be equal? and really mean equal. Then, rather than go with something "ugly" like ~=, we would pick another English word for an approximate equality. I proposed the infix word is, with a prefix form of is? Then negate this with isn't... apostrophe and all.
The idea is about a year or so old now, and I've become more convinced with time. The more I think of the aesthetic properties of code, the more I do not like ==. It looks like a header or barrier more than an operator, and even with C experience I kind of cringe at seeing it used for equality in Rebol code. There are better applications:
==: function [:label [string!] :terminal [word!]] [
unless '== is terminal [
fail ["== expects string followed by ==, not" terminal]
]
if verbosity = 2 [
print ["==" label "=="]
]
]
== {Section Two} ==
Besides "Rebol shouldn't look like C", there's another reason to hate it. In the C language == and != are complements, but given Rebol having distinct equality meanings for = and == it means that the real complement to == is !==. That's just going to confuse people.
My suggestion for IS was to have it be "friendly". So "a" is first "ABC" would be true, allowing an equivalence between single character strings and characters. Approximations would be in effect for 1.0 is 1. It seemed to me that this non-rigorous behavior would gel well with touchy-feely people who liked the English expression, while the more rigorous behavior would be favored by those who liked the mathematical notion--who believed = should mean equal? should mean equality.
(Note: Red currently uses IS in its reactive programming model for field is reaction, "Defines a reactive relation whose result is assigned to a word." It is the infix form of IS~. I have proposed BE as a possible substitute for that meaning, should the reactive model be carried over.)
It may sound like a difficult change to make, but it's more an inconvenience than it is truly difficult. As with most Ren-C conversions, the way to go about this would be to have a period of deprecation of = and !=, where you use is and isn't and continue using ==. Then when enough time has passed and all the old = and != are believed to be gone, you bring them back under the "strict equality" meaning, replacing the lingering ==s.
The bigger details are just kind of wondering about "the meanings of things". For instance, today you can have a block like block: [foo 10 bar 20 baz 30] and say block/bar and get 20 back. One wonders how much that hinges on the equality of words and SET-WORD!. Since Ren-C has evolved such that "PICKing" and "POKEing" are driven by the same code that does paths (hence "path picking" and not "path selection"), we might say that only SET-WORD!s are considered candidates for picked words. So block: [foo: bar bar: 20 baz: 30] would pick foo/bar as 20 and not bar:. If you wanted bar: you'd have to use SELECT, and select would honor the datatype given.
What are people's thoughts?