Мужики, поясните за eval-when. В целом, эмпирически, я представляю как работает eval-when в разрезе compile-file, (load .lisp) и (load .fasl), но таблички в HyperSpec-е и CLtL2 вообще никак соотнести со своими представлениями не могу. В частности, не могу понять что из-себя compile-time-too и non-compile-time режимы представляют и когда они наступают. В описании какие-то мутные, если можно так сказать, определения.
Для удобства, приведу таблички здесь: http://www.lispworks.com/documentation/HyperSpec/Body/03_bca.htm
| CT | LT | E | Mode | Action | New Mode | |-----+-----+-----+------+----------+------------------| | Yes | Yes | - | - | Process | compile-time-too | | No | Yes | Yes | CTT | Process | compile-time-too | | No | Yes | Yes | NCT | Process | non-compile-time | | No | Yes | No | - | Process | non-compile-time | | Yes | No | - | - | Evaluate | - | | No | No | Yes | CTT | Evaluate | - | | No | No | Yes | NCT | Discard | - | | No | No | No | - | Discard | - |
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node68.html#SECTION00933000000...
| LT | CT | EX | CTTM | Action | |-----+-----+-----+------+---------------------------------------| | yes | yes | - | - | process body in compile-time-too mode | | yes | no | yes | yes | process body in compile-time-too mode | | yes | no | - | no | process body in non-compile-time mode | | yes | no | no | - | process body in non-compile-time mode | | no | yes | - | - | evaluate body | | no | no | yes | yes | evaluate body | | no | no | - | no | do nothing | | no | no | no | - | do nothing |
Статью (на русском) Fare про eval-when знаю, но считаю её ещё более запутанной, чем описания в первоисточниках.
P.S. У меня вот такие таблички получились:
| :compile-toplevel | :load-toplevel | compile-file | load .fasl | |-------------------+----------------+----------------+------------| | - | - | - | - | | + | - | eval | - | | - | + | compile | eval | | + | + | eval & compile | eval | | :execute | load .lisp | |----------+----------------| | - | - | | + | eval |Это всё для случая, когда eval-when на верхнем уровне. В подформах для eval-when имеет смысл только :execute. Если стоит — обрабатываем, если нет — nil.