Соглашение об именах Lisp% var - PullRequest
3 голосов
/ 10 июня 2019

На странице https://www.cliki.net/Naming+conventions, которую я прочитал

Низкоуровневая, быстрая, опасная функция или специфичная для системы Lisp реализация foo

Может кто-топеревести это снова, возможно, с примером этих контекстов?

Ответы [ 2 ]

8 голосов
/ 10 июня 2019

Возьмите эту функцию:

(defun add (x y)
  (+ x y))

, которая выполняет общее сложение.Он поддерживает целые числа, числа с плавающей точкой, комплексные числа и отношения в качестве аргументов - все числовые типы, определенные в Лиспе.

Однако, если у вас есть:

(defun add (x y)
  (declare (fixnum x y) (optimize speed (safety 0) (debug 0)))
  (the fixnum (+ x y)))

, это говорит компилятору оптимизировать функцию дляfixnum значений, которые помещаются в регистр сборки.Когда вы используете реализацию, которая компилируется для сборки, это приводит к очень эффективному коду, как вы можете проверить с помощью (disassemble (compile 'add)).Например, в Allegro CL:

cl-user(10): (disassemble 'add)
;; disassembly of #<Function add>                                                                                                                                                                                                                 
;; formals: x y                                                                                                                                                                                                                                   

;; code start: #x10008ae4740:                                                                                                                                                                                                                     
   0: 48 01 f7       addq       rdi,rsi
   3: f8             clc
   4: 4c 8b 74 24 10 movq       r14,[rsp+16]
   9: c3             ret

Однако этот более быстрый код достигается за счет отсутствия любой проверки ошибок: код предполагает , который вы передаете в 2 fixnum аргументов, не более или менее, а также вы обещаете, что результат не будет превышать диапазон fixnum - например, не (add most-positive-fixnum most-positive-fixnum).

Если вы нарушите это обещание, передавая числа с плавающей запятой, такие как (add 3.4 1.2)или только arg (add 3), о котором вы мечтаете - это может привести к повреждению структур данных или даже к выходу из Lisp.

Вторая функция может быть вызвана %add-2-fixnums, чтобы указать, что она особенная, не предназначена для общего использования, новместо этого он специализируется на определенных аргументах, и вызывающие абоненты должны быть очень осторожны.

4 голосов
/ 10 июня 2019

Функция без % является общим интерфейсом для некоторых функций и может даже проверять свои аргументы.Затем он вызывает низкоуровневую реализацию.

Та же функция с префиксом % может эффективно реализовать эту функциональность, даже в зависимости от платформы.

Если эта функция затем используетмакрос для еще более конкретной генерации низкоуровневого кода, можно добавить к макросу префикс %%.

. Могут быть замечены и другие случаи:

  • функции, специфичные для типа
  • встроенные функции
  • специфические для реализации функции
  • очень низкоуровневый код, работающий вблизи уровня реализации Lisp
  • Функции сборки Lisp (функции, написанные на встроенном ассемблере)

Пример. Если проверять, например, исходный код Clozure Common Lisp, очень широко используются % соглашения об именах.

...