@@ -6,21 +6,17 @@ This document will explain how functions, method definitions, and method tables
66## Method Tables
77
88Every function in Julia is a generic function. A generic function is conceptually a single function,
9- but consists of many definitions, or methods. The methods of a generic function are stored in
10- a method table. Method tables (type ` MethodTable ` ) are associated with ` TypeName ` s. A ` TypeName `
11- describes a family of parameterized types. For example ` Complex{Float32} ` and ` Complex{Float64} `
12- share the same ` Complex ` type name object.
13-
14- All objects in Julia are potentially callable, because every object has a type, which in turn
15- has a ` TypeName ` .
9+ but consists of many definitions, or methods. The methods of a generic function are stored in a
10+ method table. There is one global method table (type ` MethodTable ` ) named ` Core.GlobalMethods ` . Any
11+ default operation on methods (such as calls) uses that table.
1612
1713## [ Function calls] (@id Function-calls)
1814
19- Given the call ` f(x, y) ` , the following steps are performed: first, the method cache to use is
20- accessed as ` typeof(f).name.mt ` . Second, an argument tuple type is formed, ` Tuple{typeof(f), typeof(x), typeof(y)} ` .
21- Note that the type of the function itself is the first element. This is because the type might
22- have parameters, and so needs to take part in dispatch . This tuple type is looked up in the method
23- table .
15+ Given the call ` f(x, y) ` , the following steps are performed: First, a tuple type is formed,
16+ ` Tuple{typeof(f), typeof(x), typeof(y)} ` . Note that the type of the function itself is the first
17+ element. This is because the function itself participates symmetrically in method lookup with the
18+ other arguments . This tuple type is looked up in the global method table. However, the system can
19+ then cache the results, so these steps can be skipped later for similar lookups .
2420
2521This dispatch process is performed by ` jl_apply_generic ` , which takes two arguments: a pointer
2622to an array of the values ` f ` , ` x ` , and ` y ` , and the number of values (in this case 3).
@@ -49,15 +45,6 @@ jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs);
4945
5046Given the above dispatch process, conceptually all that is needed to add a new method is (1) a
5147tuple type, and (2) code for the body of the method. ` jl_method_def ` implements this operation.
52- ` jl_method_table_for ` is called to extract the relevant method table from what would be
53- the type of the first argument. This is much more complicated than the corresponding procedure
54- during dispatch, since the argument tuple type might be abstract. For example, we can define:
55-
56- ``` julia
57- (:: Union{Foo{Int},Foo{Int8}} )(x) = 0
58- ```
59-
60- which works since all possible matching methods would belong to the same method table.
6148
6249## Creating generic functions
6350
9481
9582## Constructors
9683
97- A constructor call is just a call to a type. The method table for `Type` contains all
98- constructor definitions. All subtypes of `Type` (`Type`, `UnionAll`, `Union`, and `DataType`)
99- currently share a method table via special arrangement.
84+ A constructor call is just a call to a type, to a method defined on `Type{T}`.
10085
10186## Builtins
10287
@@ -128,18 +113,14 @@ import Markdown
128113 Markdown. parse
129114```
130115
131- These are all singleton objects whose types are subtypes of `Builtin`, which is a subtype of
132- `Function`. Their purpose is to expose entry points in the run time that use the "jlcall" calling
133- convention:
116+ These are mostly singleton objects all of whose types are subtypes of `Builtin`, which is a
117+ subtype of `Function`. Their purpose is to expose entry points in the run time that use the
118+ "jlcall" calling convention:
134119
135120``` c
136121jl_value_t * (jl_value_t* , jl_value_t** , uint32_t)
137122```
138123
139- The method tables of builtins are empty. Instead, they have a single catch-all method cache entry
140- (`Tuple{Vararg{Any}}`) whose jlcall fptr points to the correct function. This is kind of a hack
141- but works reasonably well.
142-
143124## Keyword arguments
144125
145126Keyword arguments work by adding methods to the kwcall function. This function
@@ -228,18 +209,13 @@ sees an argument in the `Function` type hierarchy passed to a slot declared as `
228209it behaves as if the `@nospecialize` annotation were applied. This heuristic seems to be extremely
229210effective in practice.
230211
231- The next issue concerns the structure of method cache hash tables. Empirical studies show that
232- the vast majority of dynamically-dispatched calls involve one or two arguments. In turn, many
233- of these cases can be resolved by considering only the first argument. (Aside: proponents of single
234- dispatch would not be surprised by this at all. However, this argument means "multiple dispatch
235- is easy to optimize in practice", and that we should therefore use it, *not* "we should use single
236- dispatch"!) So the method cache uses the type of the first argument as its primary key. Note,
237- however, that this corresponds to the *second* element of the tuple type for a function call (the
238- first element being the type of the function itself). Typically, type variation in head position
239- is extremely low -- indeed, the majority of functions belong to singleton types with no parameters.
240- However, this is not the case for constructors, where a single method table holds constructors
241- for every type. Therefore the `Type` method table is special-cased to use the *first* tuple type
242- element instead of the second.
212+ The next issue concerns the structure of method tables. Empirical studies show that the vast
213+ majority of dynamically-dispatched calls involve one or two arguments. In turn, many of these cases
214+ can be resolved by considering only the first argument. (Aside: proponents of single dispatch would
215+ not be surprised by this at all. However, this argument means "multiple dispatch is easy to optimize
216+ in practice", and that we should therefore use it, *not* "we should use single dispatch"!). So the
217+ method table and cache splits up on the structure based on a left-to-right decision tree so allow
218+ efficient nearest-neighbor searches.
243219
244220The front end generates type declarations for all closures. Initially, this was implemented by
245221generating normal type declarations. However, this produced an extremely large number of constructors,
0 commit comments