Functions and Classes are first-class in Java et.al. also for a while. It’s also possible to pass around a class (not the instance of the class). And yet, due to the static type nature, any class receiving a class as a parameter creates a source dependency and the compiler enforces that the class is known (compiled). Because a class is a concrete thing. That’s why in statically typed languages one uses interfaces and that’s where Abstract Factories, or dependency injection comes in. Since Lisp is dynamic and classes are basically represented by just symbols the handing of this is a bit easier and less clunky. But fundamentally, you also can’t create an instance of a class in Common Lisp from just the symbol. The class definition must be known.
Manfred
Am 06.02.2021 um 22:50 schrieb Scott McKay swmckay@gmail.com:
We’ve never needed them in Common Lisp because:
- functions have always been first class
- classes have always been first class
In a clunky language like Java, you go through all these gyrations whereas in Lisp you just pass a function or a class as a normal argument to avoid wiring in dependencies.
—Scott
On Feb 6, 2021, at 4:39 PM, Manfred Bergmann manfred.bergmann@me.com wrote:
You have a class. This class uses some other class. But by using or creating an instance of this other class directly you create a dependency on something concrete. That’s not what you want, because you might want to replace this with something else if required. For example with a mock or fake implementation in a test. ‚Dependency injection‘ allows you to declare this dependency with just an interface/protocol and have some other facility (the dependency injection framework) ‚inject‘ a concrete object at run-time. A similar thing could certainly be done by just using a constructor parameter (strategy pattern). But I think the important part here is the dependency on just an interface and not on a concrete implementation. For flexibility.
Manfred
Am 06.02.2021 um 22:27 schrieb Marco Antoniotti marco.antoniotti@unimib.it:
I know I could look it up in Wikipedia, but posing the question here may probably generate more amusement.
WTF is a “dependency injection”?
MA
On Sat, 6 Feb 2021 at 22:18, Scott McKay swmckay@gmail.com wrote:
Nobody in the list community ever invented a fancy pants term like “dependency injection” because it’s so obvious how to do this that nobody thought to give it a name.
—Scott
On Feb 6, 2021, at 4:07 PM, Manfred Bergmann manfred.bergmann@me.com wrote:
Am 06.02.2021 um 21:44 schrieb Luís Oliveira luismbo@gmail.com:
On Sat, 6 Feb 2021 at 20:07, Rudi Araújo rudi.araujo@gmail.com wrote: Class::newInstance() doesn't have any parameters (also, it's deprecated: better to use getConstructor() or getDeclaredConstructor() and call newInstance() on it).
I guess this bit about getConstructor() explains why it'd be more convenient to use a Factory, or the Factory method pattern, or some dependency injection framework.
Yeah. Could be. But this constructor thingy could be hidden in a function similar as you would create a constructor function make-foo in Common Lisp. The reflection stuff is not considered a good practice in certain types of applications.
Dependency injection is about something else IMO. Well, Abstract Factory is about it, too, inversion of control. It allows you to create something without having to know the concrete type and without having to have a source dependency on it. In Common Lisp this could be solved easily by just separating a protocol from the implementation, maybe in separate packages.
Manfred
-- Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01 DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it Viale Sarca 336 I-20126 Milan (MI) ITALY