5 ms·
An abstraction is not useful, in fact it's downright harmful, if it does exactly the same thing as what it abstracts over, but more verbosely. A lot of these p
by anon4 13y ago
An abstraction is not useful, in fact it's downright harmful, if it does exactly the same thing as what it abstracts over, but more verbosely.
A lot of these patterns you're used to seeing in Java stem from Java's static nature.
Here's a car factory in javascript:
function makeCar(dealerName) { return new Car(dealerName); }
And here's a configured car factory:
var myCarProvider = makeCar.bind(null, "my dealer");
It makes precisely zero sense to create abstractions that reimplement core language features. That would be like writing a C function to add two uint8_ts, or a macro that expands to inline assembly to convert a float to an int32_t. You already have these things built-in, you don't need a gorillion enterprisey patterns.
- rafekett 13y agoi don't think you actually understand these patterns or how they're used. it's useful when you have multiple implementations of `Car` that you want to use under different circumstances. Or when `Car` is dependent on static configuration that might depend on the host it's running on, or might be different in development/testing/production.
- tomp 13y agoI don't think you understand functional programming. function makeAppropriateCar(cargo) { if(cargo == "people") return new Automobile(); else if(cargo == "boxes") return new Truck; else ... } function makeLocalCar(settings) { var car = new Car({'color': settings.get('new_car_color')}); car.set_origin(settings.get_hostname()); return car; } function makeDebuggingCar() { if(global_settings.DEBUG && !global_settings.PRODUCTION) return new Car({'loglevel': LOGLEVEL_DEBUG}); else if(global_settings.DEBUG && global_settings.PRODUCTION) // testing return new Car({'loglevel': LOGLEVEL_INFO}); else // production return new Car({'loglevel': LOGLEVEL_WARNING}); }
- rafekett 13y agoOk, now try maintaining that when there are 15 types of cars and cars are used in dozens of services. You're imperatively expressing a dependency graph that you could (and would benefit from) defining declaratively at a larger scale. I'd recommend reading the user guide for Guice for balance before you respond. It's worth seeing how nice DI can be.
- zoomerang 13y agoWhat does your example have to do with functional programming? You've written two factories, pretty much exactly how AngularJS uses them, in an imperative style. Regardless of which, this doesn't in any way solve the issue Angular Services are designed to solve (IoC).
- yesiamyourdad 13y agoThis example actually really sucks. Advocating for case statements shows that either you've never worked on a truly large project or you've never had to go back and modify your own code 2 years after the fact. If you really understood functional programming, you'd see an if/case statement as an opportunity to replace conditional with a function. I started to write up an example, but since we're talking about the imaginary abstract Vehicle implementation, it's not worth dignifying. If programmers didn't switch jobs every 12-18 months and didn't see 100K LoC as a "large project", these "all frameworks suck" rants might turn into useful discussions of how one can organize code such that it's understood by more than the original author. That goes for frameworks too. If you have to rely on one of the core developers responding to a post on Google Groups or SO as your support mechanism, you've made the world less simple.
- Kroem3r 13y agoIt's a fine example. Are you saying that 3 case statements is too many? Why optimize the code to support cases that don't actually exist yet? Or even better, why optimize the code in ignorance to how it will need to be optimized in 2 years?
- hackNightly 13y agoNone of these are examples of functional programming except that you wrote some functions.
- amalcon 13y agoThis of course has nothing to do with staticness, and everything to do with Java's lack of first-class functions. In any flavor of ML, for example, nonzero-argument versions of this pattern are slightly cleaner (the exact pattern is unnecessary due to immutable state). > or a macro that expands to inline assembly to convert a float to an int32_t This sort of thing is actually useful on occasion, because it allows you to specify the exception handling you actually want (what to do on inf/-inf/NaN). Of course, it's better do it with a pure C function, but it's still a "reimplementation of a language feature". Of course, you only ever do this when you want subtly different behavior than the language provides, so I think your larger point still stands.
- haberman 13y agoHere's a car factory in javascript [...] And here's a configured car factory Great, now where is the part where the code that provides the "my dealer" string can be completely unaware that makeCar() exists? Oh, it doesn't exist? That's the problem that Angular DI is solving.
- klmr 13y agoHere: var factory = makeCar; The whole point of having first-class functions is that you can assign them. The problem a factory solves is precisely the lack of this assignability (which is why a constructor function is wrapped in a class).
- zoomerang 13y agoYou're completely missing the point and solving the wrong problem. Function or class, its a minor semantic difference for the same thing. The issue is not how you define your factories, it's how you pass them around and use them in a component that has no knowledge of the outside world.
- tomp 13y ago> it's how you pass them around and use them in a component that has no knowledge of the outside world You pass it as a function argument. function needs_to_make_a_car(car_maker, road) { var car = car_maker() car.drive_on(road) } To which you would probably reply: "But that's exactly what FactoryFactory/DependencyInjection/... pattern is!" To which we would reply: "Exactly, which are just fancy words for the re-and-re-discovered concept of functional programming."
- Glide 13y agoExcept you don't touch on other aspects of what makes IoC containers useful in the real world. I've seen XML configurability used as an extension point for code that would otherwise be closed. I've seen bugs happen because the lifecycle of objects have been mismanaged. You're conflating that things can be done more elegantly using functional programming to think it belongs in a functional paradigm. IoC containers in .NET are easier to use and more elegant because of functional programming constructs, but their existence doesn't remove the need to have them.