В Common Lisp, вы можете прочитать следующие из спецификации:
7.6.1 Introduction to Generic Functions
Когда defgeneric
форма оценивается, один из трех действий принимается (из-за ensure-generic-function
):
- Если общая функция данного имени уже существует, изменяется существующий универсальный функциональный объект. Добавляются методы, заданные текущей формой
defgeneric
, и любые методы в существующей общей функции, которые были определены предыдущей формой defgeneric
, удаляются. Методы, добавленные текущей формой defgeneric
, могут заменить методы, определенные defmethod
, defclass
, define-condition
или defstruct
. Никакие другие методы в общей функции не затрагиваются или не заменяются.
- Если заданное имя называет обычную функцию, то сигнализируется макрос или специальный оператор.
- В противном случае создается общая функция с методами, определенными определениями метода в форме
defgeneric
.
7.6.2 Introduction to Methods
Когда метод-определение формы оцениваются, объект метода создан и одно из четырех действий берутся:
- Если родовая функция данного имя уже существует, и если объект метода уже существует, что согласуется с новым в параметризаторах и определителях, новый объект метода заменяет старый. Для определения одного метода, согласующегося с другим по параметрическим специалистам и квалификаторам, см. Раздел 7.6.3 (Соглашение о специалистах и квалификаторах параметров).
- Если общая функция данного имени уже существует и если нет объекта метода, который согласуется с новым в параметризаторах и классификаторах, существующий универсальный функциональный объект модифицируется, чтобы содержать новый объект метода.
- Если заданное имя называет обычную функцию, то сигнализируется макрос или специальный оператор.
- В противном случае создается универсальная функция с помощью метода, определяемого формой, определяющей метод.
Определение ensure-generic-function
:
Если имя-функции определяет обобщенную функцию, которая имеет другое значение для :lambda-list
аргумента, и новое значение сравнимо с лямбда-списки всех существующих методов или нет методов, значение изменяется; в противном случае сигнализируется ошибка.
Если имя функции задает общую функцию, которая имеет другое значение для аргумента :generic-function-class
, и если новый универсальный класс функций совместим со старым, то для изменения класса универсальной функции вызывается change-class
; в противном случае сигнализируется ошибка.
Если имя функции задает общую функцию, которая имеет другое значение для аргумента :method-class
, значение изменяется, но любые существующие методы не изменяются.
У вас также есть add-method
и remove-method
.
Как вы можете видеть, общие функции сохраняют свою идентификацию между определениями defmethod
и даже между определениями defgeneric
. Общие функции изменяются в Common Lisp.
В Джулии, вы можете прочитать следующие из документации:
Defining Methods
Чтобы определить функцию с несколькими способами, один просто определяет функцию несколько раз, с разными номерами и типы аргументов. Первое определение метода для функции создает объект функции, а последующие определения метода добавляют новые методы к существующему объекту функции.
Как вы можете видеть, объекты функций изменяются в Юлии.
Это ничего не говорит обо всех других языках рассылки. Вы можете придумать несколько языков отправки прямо сейчас, чтобы показать, что вы можете сделать это с неизменностью, например. методы добавления возвращают новую функцию, аналогичную предыдущей функции, но с добавленным методом. Или язык, на котором функции генерируются статически во время компиляции, так что вы не можете каким-либо образом изменить его во время выполнения, даже не добавлять или удалять методы.
Возможно, короткий ответ заключается в том, что в Юлии каждая * общая функция * представляет собой набор функций для разных подписей, каждый из которых не является изменяемым. Большинство вызовов функции Julia * * выбирают специальную сигнатуру функции для вызова во время компиляции с использованием системы вывода типов. Если вы будете подробно описывать функции * безстоящего программирования *, которые вас беспокоят, это поможет их решить. –
@DanGetz, я на самом деле не был обеспокоен * о изменчивости - я просто хотел лучше понять мультиметоды. Теперь я отредактировал свой вопрос. – Aivar