简体   繁体   中英

Does an expression exist such that <<expression>> == <<expression>> is always false?

I'm not an expert on Haskell. And this question is not exactly a Haskell question, but I know Haskell people would have a better understanding of what I'm trying to achieve.

So I'm building a dynamic language and I want it to be pure... Totally pure. (With support for IO effects, and I already know why, but that's not part of this question)

Also, I would like it to have some form of polymorphism, so I'm toying with the idea of adding class support.

(Also, everything in the language is supposed to be an expression, so yep, no statements)

While exploring the idea I ended up realizing that in order for it to be referentially transparent, class expressions should be able to be substituted too.

The thing with class expressions is that one of its main functionalities is to check whether some value is instance of it.

So

val Person =class {...}
val person1 =Person(blabla)

Person.instantiated(person1) // returns true

// Equivalent to

class {...}. 
instantiated(class{...}(blabla))

Yet. That last part makes no sense.., It feels wrong, like I created two different classes

So!

Is there an expression such that

val expr = <<expression>>
expr == expr // true

But <<expression>> == <<expression>> is false?

In a pure language?

I think that what I'm asking is equivalent to asking if the newtype Haskell statement could become an expression

The way you've worded your question, you're likely to get at least a few answers that talk about peculiarities of the == operator (and, as I write this, you've already gotten one comment to that effect). But, that's not what you're asking, so forget about == . Go back to your class example.

Referential transparency implies that after:

val Person = class {<PERSONCLASSDEFN>}
val person1 = Person(<PERSONARGS>)

the two expressions:

Person.instantiated(person1)

and:

(class {<PERSONCLASSDEFN>}).instantiated((class {<PERSONCLASSDEFN>})(<PERSONARGS>))

should be indistinguishable. That is, a program's meaning should not change if one is substituted for the other and vice versa.

Therefore, the identity of classes must depend only on their definition (the part in the curly braces), not where or how many times they are (re)defined or the names they are given.

As a simpler example, you should also consider the implications of:

val Person = class {<CLASSDEFN>}
val Automobile = class {<CLASSDEFN>}

val person = Person(<ARGS>)
val automobile = Automobile(<ARGS>)

after which, the two objects person and automobile should be indistinguishable.

I find it difficult to see what this question actually is about, but maybe the problem is that you're talking about equalities when you actually mean equivalence relations ?

Two objects that are an instance of the same class are typically not equal, and correspondingly == will yield False . Yet they are equivalent in the sense of being instances of the same class. They're members of the same equivalence class (mathematical term; the usage of the word “class” in both OO and Haskell descends from this).

You can just have that equivalence class as a different operator. Like, in Python

def sameclassinstances(a, b):
    return (type(a) is type(b))

Depending on your language's syntax that could of course also be a custom infix operator like

infix 4 ~=.

A separate issue is that equality itself can be interpreted as either value equality (always in Haskell), or some form of implementation equality or reference equality, which is fairly common in other languages. But if you want your language to be pure, you should probably stay away from the latter, or give it a telling name like Haskell's reallyUnsafePtrEquality .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM