Common Lisp THE не дает предупреждений компилятору - PullRequest
0 голосов
/ 19 апреля 2020

Из примеров, приведенных для функции THE (http://clhs.lisp.se/Body/s_the.htm), когда я меняю следующую форму

(the (values integer float) (truncate 3.2 2))

на

(the (values integer integer) (truncate 3.2 2))

I все еще не получают никаких предупреждений компилятора, тогда как (the integer 1.2) выдает

; предупреждения компилятора:; В анонимной лямбда-форме в позиции 0: объявления типов, нарушенные в (INTEGER 1.2)

Может ли кто-нибудь объяснить, почему приведенное выше не вызывает предупреждений? Я проверяю их на CCL.

1 Ответ

2 голосов
/ 20 апреля 2020

Вы неправильно поняли, что делает the. Спецификация говорит вам так много слов:

the указывает, что значения, возвращаемые формой, относятся к типам, указанным в value-type. Последствия не определены, если какой-либо результат не относится к объявленному типу.

(Мой акцент.)

Другими словами, то, что the делает, чтобы позволить вам сказать компилятору: «Я обязуюсь, чтобы эти вещи имели эти типы, и вы можете скомпилировать соответствующий код для этого без проверок; если это не так, то я полностью согласен с тем, что вам, возможно, придется поджечь мои волосы и выколоть мой единственный оставшийся глаз ».

Теперь, как известно, CMUCL и его производные, такие как SBCL, придерживаются довольно другого подхода к проверка типа. Из руководства SBCL :

Компилятор SBCL обрабатывает объявления типов иначе, чем большинство других компиляторов Lisp. В соответствии с политикой компиляции по умолчанию компилятор не верит слепо в объявления объявлений типов, а рассматривает их как утверждения о программе, которые должны быть проверены: все объявления типов, которые не всегда поддерживаются, создаются во время выполнения.

Таким образом, система обрабатывает the как утверждение о типах, которое, если оно еще не известно, должно быть проверено. Это, я думаю, согласуется, так как «неопределенные последствия», очевидно, могут включать в себя «создание исключения хорошим способом» (лично я предпочитаю сногсшибательные компиляторы, но это только я).

Но если вы хотите писать переносимый код, вы не должны предполагать, что the делает это. Скорее вам нужно либо принять на себя риски, которых он не делает, либо использовать какую-то форму, например check-type или assert, с проверкой типа в качестве того, что вы утверждаете.

...