Skip to content

Commit

Permalink
added docs for call overloading (#9680)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevengj committed Jan 8, 2015
1 parent 2bb647a commit 11ab1b3
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
25 changes: 25 additions & 0 deletions doc/manual/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,31 @@ With the ``do`` block syntax, it helps to check the documentation or
implementation to know how the arguments of the user function are
initialized.

Call overloading and function-like objects
------------------------------------------

For any arbitrary Julia object ``x`` other than ``Function`` objects
(defined via the syntax above), ``x(args...)`` is equivalent to
``call(x, args...)``, where :func:`call` is a generic function in
the Julia ``Base`` module. By adding new methods to ``call``, you
can add a function-call syntax to arbitrary Julia types. (Such
"callable" objects are sometimes called "functors.")

For example, if you want to make ``x(arg)`` equivalent to ``x * arg`` for
``x::Number``, you can define:

This comment has been minimized.

Copy link
@jiahao

jiahao Jan 8, 2015

Member

Needs double colon to be formatted as quoted code block in ReST


Base.call(x::Number, arg) = x * arg

at which point you can do:

x = 7
x(10)

to get ``70``.

``call`` overloading is also used extensively for type constructors in
Julia, discussed later in the manual.

Further Reading
---------------

Expand Down
34 changes: 34 additions & 0 deletions doc/manual/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,40 @@ sufficiently important to be addressed in its own section:

.. _man-immutable-composite-types:

Constructors, Call, and Conversion
----------------------------------

Technically, constructors ``T(args...)`` in Julia are implemented by
defining new methods ``Base.call(::Type{T}, args...)`` for the
:func:`call` function. That is, Julia types are not functions, but
they can be called as if they were functions (functors) via
call-overloading, just like any other Julia object. This also means
that you can declare more flexible constructors, e.g. constructors for
abstract types, by instead explicitly defining ``Base.call`` methods
using ``function`` syntax.

However, in some cases you could consider adding methods to
``Base.convert`` *instead* of defining a constructor, because defining
a :func:`convert` method *automatically* defines a corresponding
constructor, while the reverse is not true. That is, defining
``Base.convert(::Type{T}, args...) = ...`` automatically defines a
constructor ``T(args...) = ...``.

``convert`` is used extensively throughout Julia whenever one type
needs to be converted to another (e.g. in assignment, ``ccall``,
etcetera), and should generally only be defined (or successful) if the
conversion is lossless. For example, ``convert(Int, 3.0)`` produces
``3``, but ``convert(Int, 3.2)`` throws an ``InexactError``. If you
want to define a constructor for a lossless conversion from one type
to another, you should probably define a ``convert`` method instead.

On the other hand, if your constructor does not represent a lossless
conversion, or doesn't represent "conversion" at all, it is better
to leave it as a constructor rather than a ``convert`` method. For
example, the ``Array(Int)`` constructor creates a zero-dimensional
``Array`` of the type ``Int``, but is not really a "conversion" from
``Int`` to an ``Array``.

Immutable Composite Types
-------------------------

Expand Down

0 comments on commit 11ab1b3

Please sign in to comment.