Skip to content

create generic functions with no methods #8283

Closed
@mauro3

Description

Currently, a generic function can only be created by making a method. However, it may be useful to declare generic functions without having to provide an implementation. For instance Common Lisp provides this functionality with its defgeneric macro. Examples where this could be useful:

This issue touches on: documentation (e.g. #3988), function types (e.g. #1090), interface-oriented programming (e.g. #6975), and method ambiguity warnings (#6190 (comment)). In particular, @StefanKarpinski's comment on how to potentially specify (interfaces)[https://github.com//issues/6975#issuecomment-44502467] also has syntax to define generic functions within an interface specification.

Declaring a generic function should:

  • not break any existing code
  • make a generic function if none exists already
  • associate the given documentation with the generic function
  • generate an appropriate error message if there is no matching method when calling the generic function
  • maybe impose restrictions on the associated methods signatures, or if methods are already defined, check that they all comply.

Implementations:

The most straight forward implementation would just create the generic function and allow documentation to be associated with it:

doc"""
Returns the size of a container.
"""
generic size

More complicated would be to allow to constrain the call signature. Inspired by Common Lisp, the syntax could look like:

doc"""
A function taking arguments:
- a: one input of type T
- b: another input
...
"""
generic afun{T<:Integer, S<:String}(a::T, [b::S]; y::Int=7, ...)-->T

The names of the arguments would be dummy-names useful for documentation and consistency in method implementations. a would be a required argument, b would be optional, likewise for keyword arguments, and ... would allow any number of other optional arguments (the [] and ... couldn't be allowed at the same time).

Example size:

doc"""
Returns a tuple containing the dimensions of A.  If specified, along a particular
dimension of a multidimensional collection.
"""
generic size(obj::Any, [dim::Integer])

size(a::Array) = arraysize(a)
size(a::Array, d) = arraysize(a, d)

Thus, the generic declarations could follow largely what is defined in the standard library documentation https://github.com/JuliaLang/julia/tree/master/doc/stdlib in a more formal way.

To think about:

  • should/could restrictions on method-signature be part of the generic definition?
    • should method-signature be a recommendation or be enforced?
  • what to do when there are several definitions of a generic function?
    • within the same module it should be an error.
    • otherwise warn: this would probably mean that two packages export the same generic function.
  • how would this fit with a future interface specification Interfaces for Abstract Types #6975? Is it needed as well, is it redundant or even inconsistent? If all generic functions are only part of a single interface, then this feature is probably not needed. But I suspect that some functions will not belong to any interface, whereas others may belong to several interfaces.

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions