Я смущен о том, где и как часто я должен объявлять типы возвращаемых функций в общем lisp. Если я правильно понимаю, для использования информации, предоставляемой декларациями, не требуется никакой реализации, и когда эта информация используется, эффекты не являются четко определенными и, вероятно, не согласованными в разных реализациях, поэтому это скорее вопрос лучших практик чем официальные определения. Пожалуйста, имейте это в виду, если вы попытаетесь ответить на них. В принципе, это то, что я хочу знать: Предполагая, что я нацелен на максимальную эффективность ((optimize (debug 0) (safety 0) speed)
), когда функция декларации типа возвращаемого типа предоставляет в принципе, полезную информацию, которую компилятор может использовать для оптимизации? Это широкий вопрос, и я возьму широкие ответы; но чтобы лучше понять, что мне нужно, позвольте мне разбить его на несколько конкретных вопросов. С учетом следующих определений:Когда я должен объявлять типы возвращаемых функций?
(defun foo (a)
(the <type> <form>))
(defun bar (a)
(foo a))
(defun baz (a)
(bar a))
a. Может ли компилятор оптимизировать вызовы на BAZ
, или должны ли формы возврата в BAR
и BAZ
быть обернуты в (как представляется, избыточным) форму THE
, как в FOO
? Другими словами, сможет ли компилятор обработать (bar <form>)
как (the <type> (bar <form>))
, если бы я не сказал это явно?
b. Относительный порядок трех определений влияет на ответ на (a)?
c. Если вышеупомянутые определения произошли в трех отдельных исходных файлах, которые были скомпилированы в три отдельных файла fasl, как это изменит ответ на (a)?
d. Учитывая следующее:
(let ((var1 (foo <form1>))
(var2 (bar <form2>))
(var3 (baz <form3>)))
<form>*)
Может/будет компилятор правильно выводить типы (объекты, связанные с) VAR1
, VAR2
и VAR3
внутри тела LET
без деклараций явного типа, или я должен добавить еще DECLARE
форму сразу после привязки?
e. Если предположить, что LET
от вопроса (г) имеет место в файле, отличном от файла (ов), в котором определены три функции, какой эффект будет следующие объявления:
(declaim (ftype (function (t) <type>) foo bar baz))
в верхней части файла имеют на ответ на (d)?
Common Lisp - это спецификация языка. Как компилятор оптимизирует сгенерированный код, во многом зависит от компилятора. В реализациях существует такое широкое разнообразие, что невозможно дать общий ответ. Вам нужно задать конкретные вопросы для конкретных реализаций. Одна реализация не очень-то и использует виртуальную машину, другая - компилирует целые программы на C, третий запускается на JVM, четвертый - делает какой-то вывод типа и генерирует машинный код напрямую ... Все очень разные. –
Я понимаю, что информация используется по-разному в разных реализациях. Мой вопрос - это больше о том, как предоставить большую часть информации, не будучи избыточным. – nbtrap
Это очень отличается для каждой реализации. –