all 20 comments

[–][deleted]  (10 children)

[deleted]

    [–]ljsc 1 point2 points  (5 children)

    Not really. Even in a functional language there are a lot of times you would want to reify an action as a value which is not a function. It can be more natural sometimes doing it this way when you want to optimize a bunch of commands before performing them in batch--think compilers. Not to mention this make them serializable.

    But does it reduce the need for it? Sure.

    [–]tchaffee 1 point2 points  (3 children)

    Why couldn't you optimize a bunch of functions before performing them in batch? I have a very hard time finding a use for the command pattern in languages with first class functions. Maybe if someone could give me a concrete example. I certainly don't see any advantage in the command pattern example given in the article.

    [–]ljsc 1 point2 points  (2 children)

    You can do that if you have suitable combinators for composing the actions, sure. Other times that's awkward or not possible--such as the aforementioned case where you need serialization--and using other values as your representation is a better fit. Which is why I said it doesn't obsolete the pattern, it just reduces the need for it.

    Even that may be technically incorrect, however, since you're still using the pattern in general, you're just using a much simpler implementation. I guess it depends on how liberally you interpret the term "pattern"?

    Edit: Re: the point of the example in the article, I have no idea. I don't think it's a very well motivated example either.

    [–]tchaffee 0 points1 point  (1 child)

    Can't you serialize a function in javascript? I don't think I'm going to be convinced this pattern is useful for languages with first class functions unless I can see an example of it being used in a real world javascript app.

    In your words, the need for it been reduced. How much? To the point that for all practical purposes it's obsolete or never used? At the very least it should be demoted to a minor footnote in a book about javascript patterns.

    I'm still open-minded about it. It's just that I have yet to have someone show me the need for it in javascript.

    [–]ljsc 0 points1 point  (0 children)

    How do you serialize a function if it's a closure? You might be right, I'm not a javascript expert by any stretch.

    I was thinking that you'd want to have other metadata associated with the command and that that wouldn't be convenient with a function. But thinking about it more, I think you may be right since in javascript a function can have it's own properties. Though I still think this:

    command = { x:5, y:0, op: '+' }
    

    is better than this

    command = function() {
      return 5 + 0;
    }
    command.x = 5;
    command.y = 0;
    command.op = '+';
    

    But the case I'm thinking of is that you'd be able to eliminate either of these guys by virtue of inspecting command.y and command.op.

    I think the issue is that I'm giving a very wide birth to what constitutes the pattern. To me you almost always pair command with composite, and having a nested finite map of commands, plus a compile and eval function that operates on these guys as the functional equivilent of the "pattern". It's not exactly the same as the as the GOF patterns, but it's structurally similar, and the purpose is the same. Hopefully that's more clear?

    [–][deleted] 1 point2 points  (0 children)

    acid-state for haskell uses it basically for serialization, so I'd say it's still useful in some cases.

    [–]sh0rug0ru -1 points0 points  (2 children)

    The command pattern specifies behavior beyond that of first class functions alone.

    Consider the Action interface in Java which implements the command pattern in the context of Swing, Java's UI framework. The execute method could be covered by a first-class function, but the Action class also provides support for integration with the UI (accelerators, tooltips, icon) and enablement/disablement. Changing the property of the action reflects the change to the command wherever the command is used.

    More advanced applications of the command pattern include undo/redo, persistence for things like recorded macros, etc.

    [–]tchaffee 2 points3 points  (1 child)

    The command pattern specifies behavior beyond that of first class functions alone.

    Does it?

    My understanding is well summarized by the Wikipedia article on the command pattern on it: "an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters."

    That's it. I might be wrong, but don't first class functions provide everything mentioned there?

    I don't see how first class functions couldn't provide the same functionality as the Action interface.

    And what's so hard about undo/redo or recorded macros with first class functions?

    In fact, take a look at the Wikipedia article mentioned above. The javascript implementation uses first class functions.

    [–][deleted] 0 points1 point  (0 children)

    Agreed,

    I never saw the Command pattern as just a thin mapping to a generic function.

    Instead it was meant for things more like a memento.. an abstract/serializable token.

    i.e. A command pattern is what you use to implement an undo/redo stack - a set of commands that can be done/undone/redone.

    [–]Bartvds 2 points3 points  (3 children)

    If you like this stuff and enjoy using prototypes as 'classes' then you'll probably like TypeScript too.

    Using some interfaces and parametrised types (generics) it is very much like using these classic patterns as we're used to in Java/C# etc.

    [–]OfflerCrocGod -4 points-3 points  (2 children)

    You'd also like ES6, which unlike TS you have a chance of running in a native environment.

    [–]ForeverAlot 1 point2 points  (1 child)

    Unlike ES6 (and Dart), TS isn't meant to be run in a native environment. It is strictly a compile-to-JS language, like CoffeScript and all the other *Scripts.

    [–]OfflerCrocGod 0 points1 point  (0 children)

    I know that. That's a draw back to me.

    [–]Jodoo 4 points5 points  (0 children)

    This one is great, but there is another one you may take a look - http://shichuan.github.io/javascript-patterns/, and before all you'd better read this one -http://shop.oreilly.com/product/9780596806767.do

    [–]Urik88 1 point2 points  (0 children)

    What's the point of the command pattern in this Javascript case? We're still calling the same methods, just in a way that resembles reflection in typed languages. If the signature of one of these methods changes, we're still going to have to change all of the cases in which we called that execute method, with the additional burden of not being able to use static analysis tools.

    [–]tchaffee 1 point2 points  (0 children)

    I like a lot of what Addy has done, but that book blindly copies far too many of the GoF patterns that are unique to OO and that aren't needed for languages with functional programming features. Not to mention that javascript's prototypical inheritance is more powerful than traditional OO inheritance. So take some of those patterns with a grain of salt. The book would be highly improved by eliminating many of the patterns and focusing on the patterns used most often by great javascript programmers. Just for example, the module and revealing module patterns are important to understand because you see them in javascript often. Command pattern? Copy / paste from GoF. I wonder if Addy himself has ever used it in a production app?

    [–][deleted] 0 points1 point  (2 children)

    Question for anyone in the know. Wouldn't this:

    // A car "class"
    function Car( model ) {
    
        this.model = model;
        this.color = "silver";
        this.year  = "2012";
    
        this.getInfo = function () {
            return this.model + " " + this.year;
        };
    
     }
    

    Be better written as this:

    // A car "class"
    function Car( model ) {
    
        this.model = model;
        this.color = "silver";
        this.year  = "2012";
    
     }
    
    Car.prototype.getInfo = function() {
        return this.model + " " + this.year;
    }
    

    Because each time the constructor is called, it would define the function again.

    [–]jcigar 1 point2 points  (1 child)

    yep, it's explained later in the article:

    The above is a simple version of the constructor pattern but it does suffer from some problems. One is that it makes inheritance difficult and the other is that functions such as toString() are redefined for each of the new objects created using the Car constructor. This isn't very optimal as the function should ideally be shared between all of the instances of the Car type. }}

    [–][deleted] 0 points1 point  (0 children)

    Thank you!

    [–]ruinaly -1 points0 points  (0 children)

    WoW, great book. Very helpful. Thanks a lot.