Remove all uses of the term functor from the documentation
#59414
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 functionBase.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 termfunctorfor this and switched mostly tofunction objectalthough 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
functorin 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
functorwould still be bad terminology in modern Julia. In C++, the distinction is clear. There are first class functions and then there are classes that implementoperator()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 hadBase.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 byfunctor, and I think for any of the possible meanings there is a better and more precise term we use more commonly.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,
callableis a fine term.Specifically for structs that have
(::Foo)(a, b)methods. However,callable structis precise here.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.
To emphasize the struct that contains such data itself (as opposed to the function called). Here, I think
function objectis 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).