Я просто хочу немного расширить ответ @Sorawee Porncharoenwase. Они упомянули два вида равенства: ссылочное равенство с eq?
и структурное равенство с equal?
.
Все эти различные понятия равенства должны соответствовать основным c требованиям рефлексивности, симметрии и транзитивности. Но то, что отличает их друг от друга, - это гарантии, которые они дают, когда возвращают истину или ложь.
Некоторые полезные классы равенства, о которых следует помнить, - это эталонное равенство, структурное равенство для всех времен, структурное равенство для текущего времени и доменные спецификации c эквивалентности.
ссылочное равенство
Функция eq?
реализует ссылочное равенство и имеет самые сильные гарантии, когда он возвращает истину, но когда он возвращает ложь, вы многому не научились.
(eq? x y)
подразумевает, что x
и y
являются буквально одним и тем же объектом и что любая операция на x
может быть заменено тем же на y
, включая мутацию. Одна вещь, которая помогла мне объяснить это, была в книге «Царство ракеток», в которой говорилось, что если вы бреете x
, то y
также будет побриться, потому что это тот же объект.
Однако, когда (eq? x y)
возвращает ложь, это довольно слабый соус. На многих структурах данных, которые включают выделение памяти, eq?
может возвращать false просто потому, что указатели разные, даже если они неизменны, а все остальное одинаково.
Это может быть обеспечено автоматически при программировании язык, потому что это на самом деле не намного больше, чем равенство указателей, и ему не нужно генерировать новое поведение для новых структур данных.
Структурное равенство за все время
Это понятие равенства в настоящее время не поддерживается базовым Racket или стандартной схемой, хотя библиотеки, такие как Rackjure, могут предоставлять ограниченные версии этого с функциями, такими как egal?
. Он реализует ссылочное равенство в изменяемых структурах данных, но структурное равенство в неизменяемых структурах данных.
Это должно обеспечить гарантию того, что если (egal? x y)
вернет true сейчас, то это было верно в прошлом и будет продолжаться быть верным в будущем, пока существуют x
и y
.
Это может быть обеспечено автоматически языком программирования, если язык позволяет вам указать, какие структуры данных являются неизменяемыми по сравнению с изменяемыми и обеспечивает неизменность.
Если вы хотите прочитать больше, см. Типы равенства в Pyret или Равные права для функциональных объектов .
Структурное равенство для текущего времени
Функция equal?
реализует структурное равенство для текущего времени. Это означает, что две изменяемые структуры данных теперь могут быть равны, если они в настоящее время имеют все равные компоненты, даже если они не были равны в прошлом или не будут в будущем из-за мутации.
Это может быть обеспечено автоматически языком программирования, если он всегда знает все части данных, содержащиеся в структурах данных.
Спецификация домена c Эквивалентность
Например, для области числа и математика, вы можете захотеть, чтобы точное число 2.0
было равно точному целому числу 2
. Для области поиска строк может потребоваться эквивалентность без учета регистра для строк и символов, чтобы A
и a
были эквивалентными. Для области наборов может потребоваться, чтобы порядок был неактуальным, чтобы (a b)
и (b a)
были эквивалентны.
Каждый домен отличается, поэтому для каждого домена требуется больше усилий. Язык программирования не может читать ваши мысли.