2013-04-28 5 views
4

В дополнение к == и <, Lua имеет код операции <= и код метаметода (OP_LE, TM_LE).Почему у Lua есть код `<=` opcode и metamethod?

документация говорит, что

в отсутствие "ле" метаметод, Lua пробует "LT", предполагая, что < = Ь эквивалентно не (б < а)

но почему есть '< =' в первую очередь? Почему он не может всегда использовать not (b < a) для a <= b?

Update:

Если это все о DSL, "языковые крючки", и т.д., то почему Lua не имеет ~=, > и >= опкоды и метаметоды?

+0

Если вы определяете 'а <= b' означает, что' a' является подмножеством '' b', не (Ь <а) 'не означает' а <= b'. – Blender

+0

@Blender, если '<=' является "подмножеством", что такое '<'? – Abyx

+0

Это правильное подмножество ('a' не может быть равно' b'). – Blender

ответ

7

Внедрение sets. Было бы очень аккуратно использовать операторы порядка для тестов включения. a < b будет означать, что «a является надлежащим подмножеством b». a = b будет mena "a и b равны". a <= b будет означать, что «a является подмножеством b» (не обязательно правильный, поэтому они могут быть равны).

Теперь рассмотрим

a = Set:new{1, 2, 3} 
b = Set:new{"a", "b", "c"} 

Теперь ни a <= b, ни a < b верно. Почему это? Поскольку отношение подмножества определяет только partial order. Логическое предположение, что a <= b эквивалентно not(a > b), действителен только для полностью отношений, которые определяют total order.

(пример вдохновил "Программирование в Lua, третье издание" стр 131.)

EDIT:

Для решения вашего обновления. Почему у Lua нет меток для ~=, > и >= в отношении внедрения DSL?

Даже на частично упорядоченных множеств, следующие всегда верно:

a > b <==> b < a 
a >= b <==> b <= a 
a ~= b <==> not (b == a) 

Определение различных значений для < и > (для коммутируемой порядка за исключением) сделает ваш код действительно сбивает с толку, не думаете ли вы? То же самое, если два a и b могут быть равными и неравными (или ни один). Полагаю, именно поэтому Lua делает предположение, что он всегда может реализовать эти три оператора в терминах других.

+0

нет, разные значения для '<' and '>' не так запутывают. Например. в C++ '<<' and '>>' поток вывода и ввода потока, двоичные сдвиги и т. д., и никто не жалуется на это. – Abyx

+1

@Abyx, но '<<' and '>>' не должны быть операторами упорядочения/отношения. Я не могу спорить здесь с вами о таких решениях, как это - я не автор Lua. Я могу только сказать вам, в чем ситуация, и приведенный выше ответ - мое лучшее предположение, почему это так (а часть до редактирования даже подтверждается собственной книгой автора о Lua). если это не удовлетворительный ответ на вашу проблему, вы всегда можете попросить список рассылки Lua. возможно, вы даже получите ответ от одного из авторов. –

3

not (b < a) и a <= b не являются эквивалентными.

Для чисел (т.встроенный типа с плавающей точкой), они дают разные результаты в присутствии NaN с:

a = 0/0 
print(a) -- nan 
print(a <= a) -- false 
print(not(a < a)) -- true 

Если вы хотите определить свой собственный тип BCD или комплексное число, чтобы вести себя так же, вам нужно будет использовать оба метаметода. Вы не могли получить тот же эффект, указав только <.

Это не относится к a ~= b, что действительно является эквивалентом not (a == b).

print(not(a == a)) -- true 
print(a ~= a) -- true 
+0

Да, набор, который включает 'NaN', не полностью упорядочен, если' NaN ~ = NaN'. См. Ответ выше. – Abyx