The Command pattern, in its most basic form, could also be considered as implementing 1st class functions by wrapping them into objects.
So if you're using a functional langage, there's a good chance you're wondering why consider both of the above as "design patterns", as you're seing them as basic things, and the compiler implements them for you.
The visitor pattern addresses doing multiple dispatch in a single dispatch language.
> The Command pattern, in its most basic form, could also be considered as implementing 1st class functions by wrapping them into objects.
BTW, that's not really true; first class functions are not a replacement for commands. Commands are about turning behavior into state so it can be stored and executed, potentially replayed for example, at a later time. Commands aren't just functions, even languages that have first class functions still use the OO command pattern when doing things that benefit from command patterns.
First-class functions plus partial application do that trivially. (First-class functions provide the ability to store a generic command, partial application let's you get a specific instance with local state that can be “replayed” against a different external state object.)
Many times commands come with multiple actions, to allow execution and rollback, require being able to be serialized to disk to database and replayed later, or are used to better organize and plug in extension commands to large code bases. None of these cases are amenable to first class functions.
The command pattern isn't just a hack around not having first class functions, we still use command even when first class functions are available. You aren't going to extend Photoshop with a new filter using a first class function; you're going to write a plugin which is a command pattern for filter execution.
Stop trying to tell me what first class functions can do, I'm fully aware, I use them every day and have for nearly 20 years. You aren't talking to some kid who never heard of functional programming.
> BTW, that's not really true; first class functions are not a replacement for commands.
Please note that you're extrapolating from my post: this isn't what I said.
We still need this pattern: there's no way you're going to implement "undo" using only first-class functions, and I'm well aware of that.
In some specific situations, though, we don't need it anymore, like when connecting a GUI "save" button to a "document.save" function.
- In Java [2] or C++, to implement that pattern, you may have to define an abstract class, or a class with some abstract and some concrete methods, and subclass it, and in the subclass, redefine some of the abstract methods (of the superclass) concretely. (Maybe interfaces can be used here instead of abstract classes/methods - in Java. Haven't used Java for a while, so not sure right now.)
- In Python, you can just do:
def transform(input, output):
# Code here to read data from input, transform it, and
# write the transformed data to output.
Now let's say the code in the transform function does input.read() and output.write() (with maybe some way to indicate when the end of input is reached, like the null string is used in Python). In other words, methods like those of Python file objects are used for reading and writing. Given all this, you can now pass objects of any types as arguments for the input and output parameters, as long as they implement a read and a write method respectively, and the code will just work.This has been described as "smooth seamless polymorphism" in Python. It's also known as duck typing.
https://en.wikipedia.org/wiki/Duck_typing
[1] The Template Method Pattern is one of the ways in which frameworks (as opposed to libraries) are implemented. The abstract methods of the framework are implemented concretely by your code that the framework then calls, using the Hollywood principle - Don't call me, I'll call you, a.k.a. Inversion of Control (IoC).
https://en.wikipedia.org/wiki/Template_method_pattern
https://en.wikipedia.org/wiki/Inversion_of_control
[2] Note that what I wrote is based on knowledge of older versions of Java - newer versions may have features that make the pattern simpler to implement, maybe without abstract classes/methods.