Skip to content

Commit c4719d2

Browse files
author
Tomas Lycken
committed
Change terminology according to JuliaLang#10884 [av skip]
1 parent 45db851 commit c4719d2

File tree

1 file changed

+61
-55
lines changed

1 file changed

+61
-55
lines changed

doc/manual/metaprogramming.rst

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -872,49 +872,52 @@ entirely in Julia. You can read their source and see precisely what they
872872
do — and all they do is construct expression objects to be inserted into
873873
your program's syntax tree.
874874

875-
Staged functions
875+
Generated functions
876876
----------------
877877

878-
*Staged functions* play a similar role as macros, but at a later stage
879-
between parsing and run-time. Staged functions give the capability to
880-
generate specialized code depending on the types of their arguments.
881-
While macros work with expressions at parsing-time and cannot access the
882-
types of their inputs, a staged function gets expanded at a time when
883-
the types of the arguments are known, but the function is not yet compiled.
878+
A very special macro is ``@generated``, which allows you to define so-called
879+
*generated functions*. These have the capability to generate specialized
880+
code depending on the types of their arguments with more flexibility and/or
881+
less code than what can be achieved with multiple dispatch. While macros
882+
work with expressions at parsing-time and cannot access the types of their
883+
inputs, a generated function gets expanded at a time when the types of
884+
the arguments are known, but the function is not yet compiled.
884885

885-
Depending on the types of the arguments, a staged function returns a quoted
886-
expression which then forms the function body of the specialized function.
887-
Thus, staged functions provide a flexible framework to move work from
888-
run-time to compile-time.
886+
Depending on the types of the arguments, a generated function returns a
887+
quoted expression which then forms the method body of the specialized
888+
method. Thus, generated functions provide a flexible framework to move
889+
work from run-time to compile-time.
889890

890-
When defining staged functions, there are three main differences to
891+
When defining generated functions, there are three main differences to
891892
ordinary functions:
892893

893-
1. You use the keyword ``stagedfunction`` instead of ``function``
894+
1. You annotate the function declaration with the ``@generated`` macro.
895+
This adds some information to the AST that lets the compiler know that
896+
this is a generated function.
894897

895-
2. In the body of the ``stagedfunction`` you only have access to the
898+
2. In the body of the generated function you only have access to the
896899
*types* of the arguments, not their values.
897900

898901
3. Instead of calculating something or performing some action, you return
899-
from the staged function a *quoted expression* which, when evaluated,
900-
does what you want.
902+
from a *quoted expression* which, when evaluated, does what you want.
901903

902-
It's easiest to illustrate this with an example. We can declare a staged
904+
It's easiest to illustrate this with an example. We can declare a generated
903905
function ``foo`` as
904906

905907
.. doctest::
906908

907-
julia> stagedfunction foo(x)
909+
julia> @generate foo(x)
908910
println(x)
909911
return :(x*x)
910912
end
911913
foo (generic function with 1 method)
912914

913-
Note that the body returns a quoted expression, namely ``x*x``.
915+
Note that the body returns a quoted expression, namely ``:(x*x)``, rather
916+
than just the value of ``x*x``.
914917

915918
From the callers perspective, they are very similar to regular functions;
916-
in fact, you don't have to know if you're calling a ``function`` or a
917-
``stagedfunction`` - the syntax and result of the call is just the same.
919+
in fact, you don't have to know if you're calling a regular or generated
920+
function or a - the syntax and result of the call is just the same.
918921
Let's see how ``foo`` behaves:
919922

920923
.. doctest::
@@ -929,10 +932,10 @@ Let's see how ``foo`` behaves:
929932
julia> y
930933
"barbar"
931934

932-
So, we see that in the body of the ``stagedfunction``, ``x`` is the
933-
*type* of the passed argument, and the value returned by the ``stagedfunction``,
934-
is the result of evaluating the quoted expression we returned from the
935-
definition, now with the *value* of ``x``.
935+
So, we see that in the body of the generated function, ``x`` is the
936+
*type* of the passed argument, and the value returned by the generated
937+
function, is the result of evaluating the quoted expression we returned
938+
from the definition, now with the *value* of ``x``.
936939

937940
What happens if we evaluate ``foo`` again with a type that we have already
938941
used?
@@ -942,29 +945,29 @@ used?
942945
julia> foo(4)
943946
16
944947

945-
Note that there is no printout of ``Int64``. The body of the ``stagedfunction``
946-
is only executed *once* (not entirely true, see note below) when the method
947-
for that specific set of argument types is compiled. After that, the
948-
expression returned from the ``stagedfunction`` on the first invocation
948+
Note that there is no printout of ``Int64``. The body of the generated
949+
function is only executed *once* (not entirely true, see note below) when
950+
the method for that specific set of argument types is compiled. After that,
951+
the expression returned from the generated function on the first invocation
949952
is re-used as the method body.
950953

951-
The reason for the disclaimer above is that the number of times a staged
952-
function is staged is really an implementation detail; it *might* be only
954+
The reason for the disclaimer above is that the number of times a generated
955+
function is generated is really an implementation detail; it *might* be only
953956
once, but it *might* also be more often. As a consequence, you should
954-
*never* write a staged function with side effects - when, and how often,
957+
*never* write a generated function with side effects - when, and how often,
955958
the side effects occur is undefined. (This is true for macros too - and just
956-
like for macros, the use of `eval` in a staged function is a sign that
959+
like for macros, the use of `eval` in a generated function is a sign that
957960
you're doing something the wrong way.)
958961

959-
The example staged function ``foo`` above did not do anything a normal
962+
The example generated function ``foo`` above did not do anything a normal
960963
function ``foo(x)=x*x`` could not do, except printing the the type on the
961-
first invocation and incurring a higher compile-time cost. However, the
962-
power of a staged function lies in its ability to compute different quoted
964+
first invocation (and incurring a higher compile-time cost). However, the
965+
power of a generated function lies in its ability to compute different quoted
963966
expression depending on the types passed to it:
964967

965968
.. doctest::
966969

967-
julia> stagedfunction bar(x)
970+
julia> @generated function bar(x)
968971
if x <: Integer
969972
return :(x^2)
970973
else
@@ -978,27 +981,30 @@ expression depending on the types passed to it:
978981
julia> bar("baz")
979982
"baz"
980983

984+
(although of course this contrived example is easily implemented using
985+
multiple dispatch...)
986+
981987
We can, of course, abuse this to produce some interesting behavior::
982988

983-
julia> stagedfunction baz(x)
989+
julia> @generated function baz(x)
984990
if rand() < .9
985991
return :(x^2)
986992
else
987993
return :("boo!")
988994
end
989995
end
990996

991-
Since the body of the staged function is non-deterministic, its behavior
997+
Since the body of the generated function is non-deterministic, its behavior
992998
is undefined; the expression returned on the *first* invocation will be
993999
used for *all* subsequent invocations with the same type (again, with the
994-
exception covered by the disclaimer above). When we call the staged
1000+
exception covered by the disclaimer above). When we call the generated
9951001
function with ``x`` of a new type, ``rand()`` will be called again to
9961002
see which method body to use for the new type. In this case, for one
9971003
*type* out of ten, ``baz(x)`` will return the string ``"boo!"``.
9981004

9991005
*Don't copy these examples!*
10001006

1001-
These examples are hopefully helpful to illustrate how staged functions
1007+
These examples are hopefully helpful to illustrate how generated functions
10021008
work, both in the definition end and at the call site; however, *don't
10031009
copy them*, for the following reasons:
10041010

@@ -1009,7 +1015,7 @@ copy them*, for the following reasons:
10091015
the same thing, but it is both simpler and faster.
10101016
* the `baz` function is pathologically insane
10111017

1012-
Instead, now that we have a better understanding for how staged functions
1018+
Instead, now that we have a better understanding for how generated functions
10131019
work, let's use them to build some more advanced functionality...
10141020

10151021
An advanced example
@@ -1043,46 +1049,46 @@ thing: a runtime loop over the dimensions of the array, collecting the
10431049
offset in each dimension into the final index.
10441050

10451051
However, all the information we need for the loop is embedded in the type
1046-
information of the arguments. Thus, we can utilize staged functions to
1047-
move the iteration to compile-time; in compiler parlance, we use staged
1052+
information of the arguments. Thus, we can utilize generated functions to
1053+
move the iteration to compile-time; in compiler parlance, we use generated
10481054
functions to manually unroll the loop. The body becomes almost identical,
10491055
but instead of calculating the linear index, we build up an *expression*
10501056
that calculates the index::
10511057

1052-
stagedfunction sub2ind_staged{N}(dims::NTuple{N}, I::Integer...)
1058+
@generated function sub2ind_gen{N}(dims::NTuple{N}, I::Integer...)
10531059
ex = :(I[$N] - 1)
10541060
for i = N-1:-1:1
10551061
ex = :(I[$i] - 1 + dims[$i]*$ex)
10561062
end
10571063
return :($ex + 1)
10581064
end
10591065

1060-
**What code will this staged function generate?**
1066+
**What code will this generate?**
10611067

10621068
An easy way to find out, is to extract the body into another (regular)
10631069
function::
10641070

1065-
stagedfunction sub2ind_staged{N}(dims::NTuple{N}, I::Integer...)
1066-
sub2ind_staged_impl(dims, I...)
1071+
@generated function sub2ind_gen{N}(dims::NTuple{N}, I::Integer...)
1072+
sub2ind_gen_impl(dims, I...)
10671073
end
10681074

1069-
function sub2ind_staged_impl{N}(dims::NTuple{N}, I...)
1075+
function sub2ind_gen_impl{N}(dims::NTuple{N}, I...)
10701076
ex = :(I[$N] - 1)
10711077
for i = N-1:-1:1
10721078
ex = :(I[$i] - 1 + dims[$i]*$ex)
10731079
end
10741080
return :($ex + 1)
10751081
end
10761082

1077-
We can now execute ``sub2ind_staged_impl`` and examine the expression it
1083+
We can now execute ``sub2ind_gen_impl`` and examine the expression it
10781084
returns::
10791085

1080-
julia> sub2ind_staged_impl((Int,Int), Int, Int)
1086+
julia> sub2ind_gen_impl((Int,Int), Int, Int)
10811087
:(((I[1] - 1) + dims[1] * ex) + 1)
10821088

10831089
So, the method body that will be used here doesn't include a loop at all
10841090
- just indexing into the two tuples, multiplication and addition/subtraction.
1085-
All the looping is performed compile-time, and we avoid looping during execution
1086-
entirely. Thus, we only loop *once per type*, in this case once per ``N``
1087-
(except in edge cases where the function is staged more than once - see
1088-
disclaimer above).
1091+
All the looping is performed compile-time, and we avoid looping during
1092+
execution entirely. Thus, we only loop *once per type*, in this case once
1093+
per ``N`` (except in edge cases where the function is generated more than
1094+
once - see disclaimer above).

0 commit comments

Comments
 (0)