В компьютерном программировании обобщенная функция — это функция, определенная для полиморфизма .
В статически типизированных языках (таких как C++ и Java ) термин generic functions относится к механизму полиморфизма времени компиляции ( статической диспетчеризации ), в частности параметрического полиморфизма . Это функции, определенные с помощью TypeParameters , предназначенные для разрешения с информацией о типе времени компиляции . Компилятор использует эти типы для создания подходящих версий, разрешая соответствующим образом любую перегрузку функции .
В некоторых системах объектно-ориентированного программирования, таких как Common Lisp Object System (CLOS) [1] и Dylan , обобщенная функция — это сущность, состоящая из всех методов с одинаковым именем. Обычно обобщенная функция — это экземпляр класса, который наследует как от function , так и от standard-object . Таким образом, обобщенные функции — это как функции (которые могут вызываться с аргументами и применяться к ним), так и обычные объекты. В книге « Искусство протокола метаобъектов» подробно описывается реализация и использование обобщенных функций CLOS.
Одним из ранних объектно-ориентированных расширений программирования Lisp является Flavors . Он использовал обычную парадигму отправки сообщений, на которую повлиял Smalltalk . Синтаксис Flavors для отправки сообщения:
( отправить объект : сообщение )
В New Flavors было решено, что сообщение должно быть настоящей функцией, и следует использовать обычный синтаксис вызова функции:
( объект сообщения )
message теперь является обобщенной функцией , объектом и функцией в своем собственном праве. Отдельные реализации message называются методами .
Та же идея была реализована в CommonLoops . [2] Новые разновидности и CommonLoops оказали основное влияние на Common Lisp Object System.
Определите универсальную функцию с двумя параметрами object-1 и object-2. Имя универсальной функции — collide .
( defgeneric collide ( object-1 object-2 ))
Методы, принадлежащие к общей функции, определены вне классов. Здесь мы определяем метод для общей функции collide , который специализирован для классов asteroid (первый параметр object-1) и spaceship (второй параметр object-2). Параметры используются как обычные переменные внутри тела метода. Не существует специального пространства имен, имеющего доступ к слотам классов.
( defmethod collide (( object-1 asteroid ) ( object-2 spaceship )) ( format t "asteroid ~a collision with spaceship ~a" object-1 object-2 ))
Вызов универсальной функции:
? ( collide ( make-instance 'asteroid ) ( make-instance 'spaceship )) астероид № <ASTEROID 4020003FD3> сталкивается с космическим кораблем № <SPACESHIP 40200048CB>
Common Lisp также может извлекать отдельные методы из универсальной функции. FIND-METHOD находит метод из универсальной функции collide, специализированной для классов asteroid и spaceship .
? ( метод поиска #' столкновение nil ( список ( класс поиска 'астероид ) ( класс поиска 'космический корабль ))) # <СТАНДАРТНЫЙ МЕТОД СТОЛКНОВЕНИЕ NIL ( АСТЕРОИД КОСМИЧЕСКИЙ КОРАБЛЬ ) 4150015E43>
Универсальные функции примерно соответствуют тому, что Smalltalk называет методами , с заметным исключением, что в Smalltalk класс получателя является единственным фактором, определяющим, какой код вызывается: типы или значения аргументов не имеют значения ( единичная диспетчеризация ). В языке программирования с множественной диспетчеризацией при вызове универсальной функции диспетчеризация метода происходит на основе всех аргументов, а не только одного, который является привилегированным. Новые разновидности также предоставляют универсальные функции, но только одиночную диспетчеризацию.
В JavaScript универсальная функция — это функция, которая может работать со значениями разных типов, а не с конкретным типом. Это достигается за счет использования параметров типа или динамической проверки типа значения, с которым выполняется операция. Одним из распространенных вариантов использования универсальных функций в JavaScript является создание повторно используемых функций, которые могут работать с разными типами данных, такими как массивы, строки или объекты. Динамическая система типизации JavaScript делает его особенно подходящим для создания универсальных функций, поскольку значения можно легко приводить или преобразовывать в разные типы по мере необходимости.