Generic function

Last updated

In computer programming, a generic function is a function defined for polymorphism.

Contents

In statically typed languages

In statically typed languages (such as C++ and Java), the term generic functions refers to a mechanism for compile-time polymorphism (static dispatch), specifically parametric polymorphism. These are functions defined with TypeParameters, intended to be resolved with compile time type information. The compiler uses these types to instantiate suitable versions, resolving any function overloading appropriately.

In Common Lisp Object System

In some systems for object-oriented programming such as the Common Lisp Object System (CLOS) [1] and Dylan, a generic function is an entity made up of all methods having the same name. Typically a generic function is an instance of a class that inherits both from function and standard-object. Thus generic functions are both functions (that can be called with and applied to arguments) and ordinary objects. The book The Art of the Metaobject Protocol explains the implementation and use of CLOS generic functions in detail.

One of the early object-oriented programming extensions to Lisp is Flavors. It used the usual message sending paradigm influenced by Smalltalk. The Flavors syntax to send a message is:

(sendobject:message)

With New Flavors, it was decided the message should be a real function and the usual function calling syntax should be used:

(messageobject)

message now is a generic function, an object and function in its own right. Individual implementations of the message are called methods.

The same idea was implemented in CommonLoops. [2] New Flavors and CommonLoops were the main influence for the Common Lisp Object System.

Example

Common Lisp

Define a generic function with two parameters object-1 and object-2. The name of the generic function is collide.

(defgenericcollide(object-1object-2))

Methods belonging to the generic function are defined outside of classes. Here we define a method for the generic function collide which is specialized for the classes asteroid (first parameter object-1) and spaceship (second parameter object-2). The parameters are used as normal variables inside the method body. There is no special namespace that has access to class slots.

(defmethodcollide((object-1asteroid)(object-2spaceship))(formatt"asteroid ~a collides with spaceship ~a"object-1object-2))

Calling the generic function:

?(collide(make-instance'asteroid)(make-instance'spaceship))asteroid#<ASTEROID4020003FD3>collideswithspaceship#<SPACESHIP40200048CB>

Common Lisp can also retrieve individual methods from the generic function. FIND-METHOD finds the method from the generic function collide specialized for the classes asteroid and spaceship.

?(find-method#'collidenil(list(find-class'asteroid)(find-class'spaceship)))#<STANDARD-METHODCOLLIDENIL(ASTEROIDSPACESHIP)4150015E43>

Comparison to other languages

Generic functions correspond roughly to what Smalltalk terms methods, with the notable exception that, in Smalltalk, the receiver's class is the sole determinant of which body of code is called: the types or values of the arguments are irrelevant (single dispatch). In a programming language with multiple dispatch when a generic function is called, method dispatch occurs on the basis of all arguments, not just one which is privileged. New Flavors also provided generic functions, but only single dispatch.

In JavaScript, a generic function is a function that can work with values of different types, rather than a specific type. This is achieved through the use of type parameters or by dynamically checking the type of the value being operated on. One common use case for generic functions in JavaScript is to create reusable functions that can work with different data types, such as arrays, strings, or objects. JavaScript's dynamic typing system makes it particularly suited for the creation of generic functions, as values can be easily coerced or converted to different types as needed.


Related Research Articles

<span class="mw-page-title-main">Common Lisp</span> Programming language standard

Common Lisp (CL) is a dialect of the Lisp programming language, published in American National Standards Institute (ANSI) standard document ANSI INCITS 226-1994 (S20018). The Common Lisp HyperSpec, a hyperlinked HTML version, has been derived from the ANSI Common Lisp standard.

<span class="mw-page-title-main">Dylan (programming language)</span>

Dylan is a multi-paradigm programming language that includes support for functional and object-oriented programming (OOP), and is dynamic and reflective while providing a programming model designed to support generating efficient machine code, including fine-grained control over dynamic and static behaviors. It was created in the early 1990s by a group led by Apple Computer.

<span class="mw-page-title-main">Lisp (programming language)</span> Programming language family

Lisp is a family of programming languages with a long history and a distinctive, fully parenthesized prefix notation. Originally specified in 1960, Lisp is the second-oldest high-level programming language still in common use, after Fortran. Lisp has changed since its early days, and many dialects have existed over its history. Today, the best-known general-purpose Lisp dialects are Common Lisp, Scheme, Racket and Clojure.

<span class="mw-page-title-main">Smalltalk</span> Object-oriented programming language first released in 1972

Smalltalk is a purely object oriented programming language (OOP), created in the 1970s for educational use, specifically for constructionist learning, at Xerox PARC by Learning Research Group (LRG) scientists, including Alan Kay, Dan Ingalls, Adele Goldberg, Ted Kaehler, Diana Merry, and Scott Wallace.

In computing, serialization is the process of translating a data structure or object state into a format that can be stored or transmitted and reconstructed later. When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object. For many complex objects, such as those that make extensive use of references, this process is not straightforward. Serialization of object-oriented objects does not include any of their associated methods with which they were previously linked.

In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function with the value or reference to which the name was bound when the closure was created. Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

Multiple dispatch or multimethods is a feature of some programming languages in which a function or method can be dynamically dispatched based on the run-time (dynamic) type or, in the more general case, some other attribute of more than one of its arguments. This is a generalization of single-dispatch polymorphism where a function or method call is dynamically dispatched based on the derived type of the object on which the method has been called. Multiple dispatch routes the dynamic dispatch to the implementing function or method using the combined characteristics of one or more arguments.

<span class="mw-page-title-main">Common Lisp Object System</span>

The Common Lisp Object System (CLOS) is the facility for object-oriented programming which is part of ANSI Common Lisp. CLOS is a powerful dynamic object system which differs radically from the OOP facilities found in more static languages such as C++ or Java. CLOS was inspired by earlier Lisp object systems such as MIT Flavors and CommonLoops, although it is more general than either. Originally proposed as an add-on, CLOS was adopted as part of the ANSI standard for Common Lisp and has been adapted into other Lisp dialects such as EuLisp or Emacs Lisp.

A method in object-oriented programming (OOP) is a procedure associated with an object, and generally also a message. An object consists of state data and behavior; these compose an interface, which specifies how the object may be used. A method is a behavior of an object parametrized by a user.

In programming language theory and type theory, polymorphism is the provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types. The concept is borrowed from a principle in biology where an organism or species can have many different forms or stages.

In object-oriented programming languages, a mixin is a class that contains methods for use by other classes without having to be the parent class of those other classes. How those other classes gain access to the mixin's methods depends on the language. Mixins are sometimes described as being "included" rather than "inherited".

In programming languages, ad hoc polymorphism is a kind of polymorphism in which polymorphic functions can be applied to arguments of different types, because a polymorphic function can denote a number of distinct and potentially heterogeneous implementations depending on the type of argument(s) to which it is applied. When applied to object-oriented or procedural concepts, it is also known as function overloading or operator overloading. The term ad hoc in this context is not intended to be pejorative; it refers simply to the fact that this type of polymorphism is not a fundamental feature of the type system. This is in contrast to parametric polymorphism, in which polymorphic functions are written without mention of any specific type, and can thus apply a single abstract implementation to any number of types in a transparent way. This classification was introduced by Christopher Strachey in 1967.

In computer science, a metaobject is an object that manipulates, creates, describes, or implements objects. The object that the metaobject pertains to is called the base object. Some information that a metaobject might define includes the base object's type, interface, class, methods, attributes, parse tree, etc. Metaobjects are examples of the computer science concept of reflection, where a system has access to its own internal structure. Reflection enables a system to essentially rewrite itself on the fly, to alter its own implementation as it executes.

In computer science, dynamic dispatch is the process of selecting which implementation of a polymorphic operation to call at run time. It is commonly employed in, and considered a prime characteristic of, object-oriented programming (OOP) languages and systems.

In software engineering, double dispatch is a special form of multiple dispatch, and a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call. In most object-oriented systems, the concrete function that is called from a function call in the code depends on the dynamic type of a single object and therefore they are known as single dispatch calls, or simply virtual function calls.

Many programming language type systems support subtyping. For instance, if the type Cat is a subtype of Animal, then an expression of type Cat should be substitutable wherever an expression of type Animal is used.

Flavors, an early object-oriented extension to Lisp developed by Howard Cannon at the MIT Artificial Intelligence Laboratory for the Lisp machine and its programming language Lisp Machine Lisp, was the first programming language to include mixins. Symbolics used it for its Lisp machines, and eventually developed it into New Flavors; both the original and new Flavors were message passing OO models. It was hugely influential in the development of the Common Lisp Object System (CLOS).

CommonLoops is an early programming language which extended Common Lisp to include Object-oriented programming functionality and is a dynamic object system which differs from the OOP facilities found in static languages such as C++ or Java. Like New Flavors, CommonLoops supported multiple inheritance, generic functions and method combination. CommonLoops also supported multi-methods and made use of metaobjects. CommonLoops and New Flavors were the primary ancestors of CLOS. CommonLoops was supported by a portable implementation known as Portable CommonLoops (PCL) which ran on all Common Lisp implementations of the day.

Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code. The data is in the form of fields, and the code is in the form of procedures.

References

  1. The Common Lisp Object System: An Overview
  2. "CommonLoops, Merging Lisp and Object-Oriented Programming" (PDF). Archived from the original (PDF) on 2011-06-04. Retrieved 2009-12-10.