Hacker News new | ask | show | jobs
by karantza 5433 days ago
I think an example is in order. I'm going to code up a simple event dispatching algorithm in three languages. They'll have the same functionality. I consider myself fluent in all three, and I'll write them in the most consise and style-respecting way I can.

C++:

    #include <vector>
    #include <string>
    #include <iostream>
    typedef void (*hndlr)(std::string);

    class Event {
      private:
        std::vector<hndlr> handlers;
      public:
        void Listen(hndlr handler) {
          handlers.push_back(handler);
        }
        void trigger(string arg) {
          for (std::vector<hndlr>::iterator i = handlers.begin(); 
              i != handlers.end(); i++) {
            (*i)(arg);
          }
        }
    };
    
    void h1(std::string arg) { 
      std::cout << "First handler got " << arg << std::endl;
    }
    void h2(std::string arg) { 
      std::cout << "Second handler got " << arg << std::endl;
    }
    
    void main() {
      Event event;
      event.Listen(h1);
      event.Listen(h2);
      event.Trigger("something happened!");
    }
Lua:

    event = {listeners = {}}

    function event.listen(self, handler) 
      if (type(handler) ~= "function") return end
      table.insert(self.listeners, handler) 
    end
    
    function event.trigger(self, arg) 
      for handler in self.listeners do handler(arg) end
    end
    
    event:listen(function(text) print("First handler got "..text) end)
    event:listen(function(text) print("Second handler got "..text) end)
    event:trigger("something happened!")
    
C#:

    using System;
    public delegate void HandlerDelegate(string arg);

    class Main {
      static event HandlerDelegate Event;
      static void Main() {
        Event += (arg) => { Console.WriteLine("First handler got" + arg); };
        Event += (arg) => { Console.WriteLine("Second handler got" + arg); };
        Event("something happened!");
      }
    }
    
    
Now, go ahead and say that choice of language doesn't matter. You might not need lambdas, or first-class functions, or event handlers, and a good programmer can make the same algorithm "work" in any language. But by choosing a more powerful and expressive language, you can get those algorithms done in a way that's more readable, maintainable, and faster to code, which in the end is what really matters.
2 comments

Also fun: The only one of these that works when a callback removes itself from the event list in its own callback routine is C#. You get a hanging iterator in C++, and removing items from a table mid-iteration in Lua is undefined (though in practice usually works).

To make this case work properly, the place I work for has a 335 line C++ template class. This is all time that the developer could have spent actually building our product.

The C++ version could be greatly simplified by using boost::bind. It'd still be shorter and clearer than a Java equivalent that had to bung in anonymous classes and other crap to create a proper dispatch.

Your point, however, totally stands.