Commit d335458
authored
Remove all uses of the term
There is some persistent confusion around the term functor. There is of
course a well established mathematical definition, but some programming
languages have taken to reuse the term for various sorts of callable
objects. Julia should not be one of them, and we did (as mentioned
below) actually reach this conclusion ten years ago. Yet the terminology
has somewhat stubbornly persisted. This commit removes it. However, it
is only fair that when one makes sweeping categorical proclamations on
terminology, there should be some history and justification that can be
linked to in the future, so I will attempt to do so in this commit
message.
## History
(Claude helped with the research in this section, if I missed something,
please let me know, so I can go yell at Claude)
The first use of the term functors in Julia was in 2014 5c91960,
introducing special function objects for common generic functions to
improve performance of reductions. This was before we were able to
specialize. These were refactored a bit in 0c631f8 (using call
overloading instead), and 6e715da (split out into a separate file
functors.jl), before ultimately being deprecated and removed in 2016.
However, it should be noted that this only ever referred to this very
particular design pattern, which hasn't been in the code base since
2016.
The use that is still in there stems from the documentation and was
introduced in Jan 2015 in 11ab1b3. That said, while even this
documentation called the callable objects themselves `functors`, julia
looked a fair bit different at the time with call overloading using a
generic function `Base.call(f, args...)` (i.e. there was a much stronger
distinction between generic functions and ordinary objects). Moreover,
this transformation is functorial in the mathematical sense. That no
longer holds true as much in modern julia. In any case, by 6 months
later (aac4eca) we had decided not to use the term `functor` for this
and switched mostly to `function object` although additional references
remained.
However, as I hope this makes clear, this terminology was never
wide-spread in julia itself.
## Argument
I think the central use of the term `functor` in mathematics and
(compatibly) in functional programming is dispositive of the debate,
particularly given the strong functional programming influences in
julia.
However, suppose we didn't care about that. Even in that case `functor`
would still be bad terminology in modern Julia. In C++, the distinction
is clear. There are first class functions and then there are classes
that implement `operator()` and they are very much not the same, so it
makes sense to distinguish them (even if the precise choice of
terminology is unforunate). In the original version in Julia where we
had `Base.call`, this was arguably analogous, but in modern julia where
there is just one big method table and no fundamental distinction
between functions and other kinds of objects, we can no longer make a
semantic distinction. I also think it's unclear what people exactly mean
by `functor`, and I think for any of the possible meanings there is a
better and more precise term we use more commonly.
1. For something that can be called, I think we generally just use
function, but if you want to emphasize that it applies to non-Function
types as well, `callable` is a fine term.
2. Specifically for structs that have `(::Foo)(a, b)` methods. However,
`callable struct` is precise here.
3. Only for those structs 2 that are also non-singleton or contain
mutable state. I think it's pretty rare to specifically need to refer to
these and I think when people do, they often forget that closure are
also non-singleton and can reference mutable state (through implicitly
introduced boxes). If that's what you mean, I think you just need to be
precise about it.
4. To emphasize the struct that contains such data itself (as opposed to
the function called). Here, I think `function object` is the best
terminology we have, specifically since it emphasizes the object.
It's possible I've missed a meaning that people have in mind, but I
think that's precisely the problem. So, let's remove this term (as we
had already decided 10 years ago).functor from the documentation (JuliaLang#59414)1 parent 50379b9 commit d335458
File tree
6 files changed
+14
-12
lines changed- base
- doc/src/manual
- test
6 files changed
+14
-12
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
260 | 260 | | |
261 | 261 | | |
262 | 262 | | |
263 | | - | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
264 | 266 | | |
265 | 267 | | |
266 | 268 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
915 | 915 | | |
916 | 916 | | |
917 | 917 | | |
918 | | - | |
| 918 | + | |
919 | 919 | | |
920 | 920 | | |
921 | 921 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2658 | 2658 | | |
2659 | 2659 | | |
2660 | 2660 | | |
2661 | | - | |
2662 | | - | |
2663 | | - | |
| 2661 | + | |
| 2662 | + | |
| 2663 | + | |
2664 | 2664 | | |
2665 | 2665 | | |
2666 | 2666 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
179 | 179 | | |
180 | 180 | | |
181 | 181 | | |
182 | | - | |
| 182 | + | |
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
532 | 532 | | |
533 | 533 | | |
534 | 534 | | |
535 | | - | |
| 535 | + | |
536 | 536 | | |
537 | | - | |
538 | | - | |
| 537 | + | |
| 538 | + | |
539 | 539 | | |
540 | | - | |
541 | | - | |
| 540 | + | |
| 541 | + | |
542 | 542 | | |
543 | 543 | | |
544 | 544 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
691 | 691 | | |
692 | 692 | | |
693 | 693 | | |
694 | | - | |
| 694 | + | |
695 | 695 | | |
696 | 696 | | |
697 | 697 | | |
| |||
0 commit comments