Node Js And Hof Gui Discussion

Continued from NodeJsAndHofDiscussion, which is growing TooBigToEdit.

The desktop applications mostly used OOP for their GUI eventing, not HOF's. And if you want to sell NodeJS to wider audiences, you better get better examples.

Sure, OOP for GUI eventing is fine, though the anonymous classes with a single function that are pervasive in (say) Java would be syntactically cleaner with HOFs and soon will be, given that Java 8 supports lambdas. By the way, I don't want to sell NodeJs to anyone. I'm not a salesman (well, any more -- I have been), I have no interest in sales. There is no "wider audience" for NodeJs, beyond those who need to create event-driven, responsive, highly-concurrent user interfaces. I'm sure that audience can find their way to NodeJs without my help.

"Syntactically cleaner" is often in the eye of the beholder.

That may be true in some general sense, but I think there are few who would argue that a traditional, idiomatic Java event handler like the following...

    myButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
         myLaunch(e.getWhen());
      }
    });
...is even as clean as -- let alone syntactically cleaner than -- the same code using a Java 8 lambda:
    myButton.addActionListener(e -> myLaunch(e.getWhen()));
What's wrong with:
     <button id="buttonX" title="click me" onclick="myLaunch" ... />
     ...
     class myLaunch inherits GUIevent {
        main() {
           console("Clicked on: " & self.eventTime);
           console("Mouse coordinates: " & self.pointerX & "," & self.pointerY);
        }
     }
"myLaunch" would inherit from a GUIEvent class that automatically supplies click time as a class-defined attribute (as well as other commonly needed event attributes such as clicked object ID, mouse coordinates, etc.). No need to dick around with "add listener" bureaucracy. (That stuff may be under the hood, but the app developer rarely has to open the hood that far.) With your approach, you'd have to visit each call to add any new parameters, such as mouse coordinates. Another approach:
     <button id="buttonX" title="click me" onclick="myLaunch(self.GUIevent)" ... />
     ...
     function myLaunch(e) {
         if (isDefined(e)) {  // "e" is an optional gui-event info object
            console("Clicked on: " & e.eventTime);
            console("Mouse coordinates: " & e.pointerX & "," & e.pointerY);
         }
     }
What's wrong with it is that it's not Java. It would, at least, require corrections to the syntax so it's Java, and some XML-to-Java compiler to convert the UI specification to Java. What you call the "'add listener' bureaucracy" is conventional use of the PublishAndSubscribe-like event handler pattern, which allows multiple, independent handlers to act on a single event without having to be related to each other. Could you explain how your approach is syntactically cleaner, or superior to either the usual Java convention of using an anonymous class, or the Java 8 approach of using a HigherOrderFunction? By the way, my GUI example was only intended as an easily-recognisable illustration; it's not the only use of lambdas. Whilst use of Java 8 lambdas will unquestionably simplify GUI coding, they'll simplify any similar use of what would otherwise require (at least) an anonymous class. One more thing: if myLaunch() needs all the information that parameter 'e' (an ActionEvent, in the above) can contain, you simply pass it as an argument to myLaunch(). The Java 8 lambda example would be:
    myButton.addActionListener(e -> myLaunch(e));  
If 'e' isn't needed by myLaunch, it could be:
    myButton.addActionListener(e -> myLaunch());  
I'm not limiting the discussion to Java; I thought we were talking general GUI approaches, not a specific language; for I don't want to debate about specific languages. For most "click on" events, we don't need to see that stuff. If it uses PublishAndSubscribe (or what-not) under the hood or further down the abstraction ladder, that's fine, but don't expose it to the most common case if the most common case doesn't need to show/expose it.

The GUI designer is usually thinking, "I just want to run a snippet of code if the button is clicked", and it may optionally need typical GUI-related info such as the time, coordinates, and target id/ref of clicking, for example. (I modified one of my examples to make the event info parameter optional). In the spirit of WorkBackwardFromPseudoCode, I'm simplifying the common case. I don't want distracting wires from the underlying infrastructure hanging out.

The GUI designer doesn't deal with code. He or she defines forms or Web pages using code or a forms painter / page designer or a wire framer; the most technical aspect of the job is giving each UI element a unique name. It's the programmer who pairs element names with runnable code. Of course, sometimes the programmer is also the GUI designer, but not always, so design and coding should be clearly separable.

     class buttonFooClick inherits guiEvent;
        self.objectToWatch = "buttonFoo";  // ID as defined in GUI XML
        self.addClickWatch();  // tell it to watch for clicks
        self.addDoubleClickWatch();  // we'll also watch for DC for the hell of it
        main() {
          console("Clicked button foo at " & self.eventTime);
        }
     }
     // fancier versions may be able to watch multiple objects via an addIdToWatch() method[1]
     .
     // Variation B
     class buttonFooEvents inherits guiEvent;
        self.objectToWatch = "buttonFoo";  // ID as defined in GUI XML
        method onClick() {   // override stub method
          console("Clicked button foo at " & self.eventTime);
        }
        method onDoubleClick() {
          console("Double-Clicked button foo at " & self.eventTime);
        }
     }
Java or not, I still don't see how your examples are syntactically cleaner -- remember, that's what started this thread -- than using a HigherOrderFunction.

Maybe that part is subjective. I find it more natural and suspect most developers will agree.

What is it about buttonFoo.addClickListener(e -> console("Clicked button foo at " & e.eventTime)) that is less natural than the above?

For one, it's not clear what "e" is, nor how or where buttonFoo is defined.

Where buttonFoo is defined isn't shown in the anonymous class example, either. We assume it exists. The parameter name 'e' was chosen to match the anonymous class example, but it probably should be something more readable. How about this: buttonFoo.addClickListener(actionEvent -> console("Clicked button foo at " & actionEvent.eventTime))

    class buttonFoo inherits gui::button {  // Example 8462
          self.location = [etc.];
          self.title = "Click Me!";
          method onClick(event) {   // override stub handler method
            console("Clicked button foo at " & event.eventTime);
          }
    }
    // See footnote [1] for an instantiation note.
     block X (optional stuff) {   // example 4726
       block body
     } // end block X
            /* with anonymous inner class */
            myButton.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                 myLaunch(e.getWhen());
              }
            });
            /* or with Java 8 lambda */
            myButton.addActionListener(e -> myLaunch(e.getWhen()));
. At this point I'll say I find the OOP example personally more intuitive; and it's not objectively clearly less code. And I suspect most developers in the shops I typically work at would prefer the OOP version.

It's clearly less code -- there are fewer tokens, if nothing else. Are you sure it's not just because you're more used to the anonymous class version? The lambda can be considered mere syntactic sugar, otherwise equivalent. Surely less keystrokes to achieve the same thing is good? If you're uncomfortable with the type inference and would prefer to see an explicit type, this is equivalent: buttonFoo.addClickListener((ActionEvent actionEvent) -> console("Clicked button foo at " & actionEvent.eventTime))

It's roughly about the same. Plus the attributes and methods have explicit names which can make it easier to follow in debuggers. Anonymous functions have no printable identifier.

How could the code size be "roughly the same"? Obviously, it isn't.

Anonymous functions don't need a printable identifier. When tracing in a debugger, the flow of control comes from the calling context and goes into the function body when appropriate, and comes out and returns to the calling context when done, like with any other function.

It just seems easier to understand the debugger output and error messages if important code-blocks have explicit textual names. The option of looking at or pointing at code is available under both techniques, but names are not.

Loops, if statements, case statements don't have explicit textual names. Why should a function without a name be a problem but a loop without a name is not? They're both just a block of code.

They don't share dual contexts like HOF's do.

What are "dual contexts"?

They share some context with both the caller and callee.

So do loops. What's outside the loop and inside the loop are shared.

Another issue is that all the methods for a given button object would be packaged together. With HOF's, the equivalent can be scattered about. I will agree that sometimes that is a good feature, but most of the time they are best kept together. Thus, HOF's are generally anti-module. -t

What's scattered about? All methods for a given button object are still packaged together. Note that the usual Java code with an anonymous class...

    myButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
         myLaunch();
      }
    });
...is conceptually equivalent in every way, but less code using a Java 8 lambda:
    myButton.addActionListener(e -> myLaunch());


Foot Notes

[1] If the event ID's and type combinations become complex or a large volume, then a many-to-many ControlTable may be a better way to manage such. How the table actually calls code depends on many specifics of the architecture, language, etc. That's an interesting question, but for now I'll stick with OOP examples instead of TOP examples. If one is managing boat-loads of associations, tables tend to be superior to code-centric approaches in my opinion. See TableOrientedGuiDiscussion for more.

Use of HOFs may be even better. See http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html under "Improving Code with Lambda Expressions". Or, if your environment supports it, you can even store HOFs in tables. See http://dbappbuilder.sourceforge.net/docs/AnonymousAndFirstClassOperatorsInTutorialD.pdf

Tutorial D, uuuuuugh.

That's not the point.

I'd think that whether the snippets were functions, methods, or HOF's should be a hidden detail. We won't want to have to expose and/or require repetitious scaffolding code to each snippet. But all that depends on how parameters and scope is handled for a particular DB or language.

Likewise, do you think, say, loops should be a hidden detail? I agree that we shouldn't have to "expose and/or require repetitious scaffolding code", but that's precisely what facilities like HOFs can help with. Again, see http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html under "Improving Code with Lambda Expressions" which is precisely about eliminating repetitious code.

The devil's in the details. If it requires syntax and keywords that are not relevant to task at hand, they should be removed or made optional. I'd have to study a given proposal. The PDF above gives this example:

  OPERATOR ( a INTEGER , b INTEGER ) RETURNS INTEGER ; RETURN a - b
  ; END OPERATOR 
It seems the "Operator" block construct is unnecessary. Instead, this can be in a "cell":

  ( a INTEGER , b INTEGER ) RETURNS INTEGER ; RETURN a - b;
A row already has a unique identifier such that we don't need a function/method name either. (Although naming as an option would be nice.)

In the PDF above, there aren't function/method names. Yes, the anonymous operator syntax is painfully verbose, but as noted in footnote #6, "Whilst [the syntax is] verbose, it is intentionally in keeping with existing syntax. As Tutorial D is intended primarily for pedagogical purposes, it is appropriate to favour consistency over brevity. However, the author grew weary of endlessly typing OPERATOR during this phase of Rel development and so created a shorthand form of anonymous operator definition, using a pair of digraphs in place of “OPERATOR” and “END OPERATOR” which the author has deemed too aesthetically heinous to mention here.

We don't need (mandatory) digraphs either. Brevity is not the main problem though, it's distraction and confusion from "funny syntax", such as causing unfamiliar error messages if typed wrong. My main point is that if you strip out such irrelevancies, the app developer cannot tell if they are HOF's or functions or methods or gerbils and under the hood, and it could be any of the four as long as it "works".

Perhaps consider having a separate column for parameters and the body. Or perhaps create a parameter DataDictionary for that part. The syntax of the body block would then be dirt-simple: no outer wrapper or funny or special syntax needed; just plain-jane code. -t

If the parameters and body are in separate columns, how would you define an anonymous operator that isn't stored in a table at all? What happens if you project out the body column without the parameters, or the parameters without the body? What would that mean?

I'm glad some are at least looking at TOP-based code management, even if it is Tutorial D.

The RelationalModel related to programming language design is a rich and active research area.


An Attempt at a Summary Opinion

The scoring of the examples seem to be heavily dependent on GUI library design and possibly the language used. I have not seen any inherent and clear simplification from HOF's for decent libraries (or libraries tuned for the use/audience). Perhaps they are an improvement under poorly designed GUI libraries, but there may be other ways to create screwy libraries that make HOF's score poor. (I cannot think of any at this time, so don't ask.) Time is better spent on designing decent GUI OOP libraries or wrappers than on evangelizing HOF's. --top

Good. That's another one cleared up. He's seen no decent libraries. there are may be other ways to create screwy libraries, so go design some gui libraries. Forget about that HOF stuff. Who needs it? -- ChaunceyGardiner

{Indeed. It also ignores why HOFs are used, even inside GUI libraries. See, for example, http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html under "Improving Code with Lambda Expressions".}

I consider frequent need for HOF's by typical application developers to be smell (a yellow alert) that the libraries (or wrappers) are poorly designed. This pattern is found in NodeJsAndHofDiscussionTwo also: if the "timer" library is redesigned, we don't need HOFs, and I believe most developers will find the OOP version more "natural" (maps to expectations of block grouping, etc.). The real fix is better libraries or wrappers. I believe OOP provides better accountability and modularization on both the button and timer example, and I believe most regular developers will agree. (No, I don't have formal studies; it's based on my lifetime WetWare-related observations.) HOF fans will balk, but so be it: let the FP fanboys have their hoots and hollers, but I predict the rest of the world will eventually walk over them and ignore them like they did before in the 80's. I'd be willing to bet most regular developers will look at these two examples and say, "Top is right, with good library design, we don't really need HOF's, and HOF pushers have been exposed as loud zealots." -t

Granted, with "stiff" or poor languages or entrenched libraries, it may be difficult to create decent API's or wrappers, and this is where HOF's may have some benefit: work-arounds to crappy libraries under crappy languages. But in my opinion it's better to evangelize good library and/or language design rather than better band-aids. You guys are evangelizing the wrong thing. If you wish to formally claim "HOF's help one to deal with poor languages/libraries/API's", I WON'T challenge that claim at this time. A go? I'm giving you a partial victory if you want it. (And Oracle/Java are not going to admit their GUI libraries are crap. It's better PR to talk up the band-aid.) -t

What is a "stiff" language? Aren't HigherOrderFunctions a way of making a "stiff" language less stiff? Of course, there are potential alternatives to HigherOrderFunctions, but HigherOrderFunctions have specific benefits in specific cases that make them a worthwhile option.

I think this debate is increasingly a demonstration of TopVsOthers.

OOP-everywhere fans used to "gang up" on me also. Same pattern. It appears to be THREE pro-HOF dudes, hardly a representative sample. As I mentioned before, I use to get a fair amount of "fan mail" from those who agreed with my opinion but didn't want to jump into the heat of the battles. (I don't publish an email address anymore.)

TopVsOthers has nothing to do with "ganging up" on anyone, and everything to do with personal preference. Note that it is balanced and non-judgemental.


Incidentally, here is how multiple different kinds of events, and wild-card event handling, can be interfaced up:

    class ButtonFoo inherits gui::Button {  // Example 8473
          self.location = new Point(34, 129);
          self.title = "Click Me!";
          method onClick(event) {   // override stub handler method
            console("Clicked button foo at " & event.eventTime);  // sample usage
          }
          method onMouseOver(event) {...}
          method onMouseOut(event) {...}
          method onDoubleClick(event) {...}
          method onFocus(event) {...}  
          method onBlur(event) {...}  // lost focus
          method anyEvent(event) {...}   // roll-your-own or micro-manage
    } // instantiation note at [1]
Do you really expect the user to define a new class for each button? That seems painfully tedious, even more so than the current Java idiom of defining event handlers ("listeners") as anonymous classes -- the tedium of which is one of the reasons for introducing lambda expressions in Java 8. Your suggestion is just the sort of thing that makes FunctionalProgramming proponents decry the verbosity of OOP.

What's the alternative? Those attributes and event handler blocks have to go somewhere. And note that an IDE can actually create the classes, it doesn't have to be hand-coded. That technology was available back in the days of early VB classic even. And I personally believe it's better modularization to have all the button-related attributes and methods in a single module rather than scattered about (at least for text-centric coding).

The general alternative is to define one instance of the generic Button class per button, unless you need a new category of ButtonS. All attributes -- event handlers, titles, text, colours, etc. -- are set on a per-instance basis. All the button-related attributes are then associated with their appropriate button instances. Since a button's event handlers typically affect the context in which the button is defined, the event handling code appropriately belongs to that context rather than the button. One approach to defining event handlers is to use Java 8 lambda expressions. Another alternative -- one commonly seen today -- is to define event handlers using anonymous inner classes. Whether code is generated by some external technology, or written by hand, why have more code than you need?

It's still not clear to me what your complaint is. "Appropriately" by what standard? It's not more code or more typing, at least not by a substantial margin (+/- about 20%). What is "tedious" exactly and how are you measuring that and comparing to the allegedly non-tedious counter-example(s)? It might cause difficulties in languages that prefer one-file-per-class, but that's a language-specific issue.

What's tedious is defining a new class for each instance. By the way, I have added code to your example to create a button instance, set the 'location' attribute to something realistic, and changed the capitalisation slightly to reflect Java/C# conventions. Without requiring new class definitions, and using Java 8 lambdas, the above could be:

    Button buttonFoo = new Button(); 
    buttonFoo.location = new Point(34, 129);
    buttonFoo.title = "Click Me!";
    buttonFoo.onClick.add(event -> console("Clicked button foo at " & event.eventTime));
    buttonFoo.onMouseOver.add( ...etc... );
    buttonFoo.onMouseOut.add( ...etc... );
Now it's syntactically simpler than your example, requires no new classes, and can support both single and multiple event handlers per event with the same construct.

    buttonFoo.title = "Click Me!";   // Example 7392
    // lots of code in between...
    buttonFoo.onClick.add(event -> console("Clicked button foo at " & event.eventTime));
    // lots of code in between...
    buttonFoo.onMouseOver.add( ...etc... );
As for "appropriately", what I mean is that event handlers typically affect the dialog or window in which they're defined, not just the button that invokes them. Thus, a realistic example snippet might look like:
    void launchProcessing(ActionEvent event) {
       buttonFoo.enabled = false;
       textboxName.enabled = false;
       buttonCancel.enabled = true;
       processingAnimatedGif.start();
       startProcessing(event.eventTime);
    }
    //
    Button buttonFoo = new Button(); 
    buttonFoo.location = new Point(34, 129);
    buttonFoo.title = "Click Me!";
    buttonFoo.onClick.add(event -> launchProcessing(event));
Note that launchProcessing is an event handler for buttonFoo, but it can also be invoked as an event handler for other widgets. Because it might need to be invoked by multiple widgets, and because it interacts with other form elements (e.g., textboxName, buttonCancel, processingAnimatedGif) and methods (e.g., startProcessing), it belongs to the form/window/dialog in which buttonFoo is defined rather than being defined as part of a ButtonFoo class.

The class approach does not prevent using a shared routine.

    method onClick(event) {   
      formContext.launchProcessing(event);
    }
Sure, but now you're just using awkward syntax to delegate event handling to formContext.launchProcessing, and you still don't have an easy means to have an onClick event launch multiple actions where some actions are defined by the form rather than the author of the button. Use of onClick.add(...) means onClick.add(...) can be invoked by the author of the button, but also by the form in which the button is used.

I'm not sure what you mean by "awkward syntax". It's pretty much an old-fashioned call to a subroutine. How is that "awkward"? I don't know what you mean by the last sentence. There is a misunderstanding in here I suspect.

By "awkward syntax", I mean you're still using a class definition for essentially nothing more than assigning event handlers.

No, it also contains attributes, and perhaps other event handlers.

[Indeed, hence "essentially nothing more than assigning event handlers". You don't need a class definition to assign attributes either. -DavidMcLean?]

Sorry, I don't know what you are getting at. Scattering methods and initializing attributes all over the place is uncivilized write-only HackerLanguage clutter. I bet your basement bedroom has pizza and underwear stuck to the ceiling. Your mom is too scared to even try to clean it. "Hi Mom, would you like HOF a slice also? I'll get the ladder. Oh wait, which one's the pizza and which the underwear?" Are modules out of style now?

[Nice rant. (I mean that sincerely. It was actually pretty funny.) Did you see your other correspondent's code sample (described as a "realistic example snippet")? It doesn't scatter buttonFoo's customisation -- it's all in one place. Related code is still grouped; however, it's not always necessary for the thing that groups related code to be a class. We have functions and (indeed) modules too, after all. If you're going to insist classes are the only appropriate grouping tool, why only apply that rule to GUI widgets? Why not replace for loops with a For class, which you must subclass and overload the methods init(), condition(), increment(), and block() to use? -DavidMcLean?]

You seem to be arguing that since our army pocket knife has 12 blades already, we should go ahead and add 13. I don't know if OOP could replace loops and similar self-rolled blocks. I haven't given it much thought. Humanity settled on certain conventions and those conventions improve communication/code-reading because we all learn a semi-standard: mental QwertySyndrome perhaps. If starting over, like the cockroach may do after we nuke ourselves to extinction, they can consider such.

And an OOP language could potentially allow adding or redefining methods away from the original declaration/class, per below. But I suspect it's not common because the need didn't exist. If HOF usage exposes gaps in existing OOP languages, then perhaps such languages will make method definition more flexible. -t

[Loops can be replaced by an OO class fairly trivially by doing what I just said, but it would be verbose and horrible to work with, as well as conceptually messy since the base class wouldn't ever be directly usefully instantiable. The same applies to GUI widgets. That was my point. Flexible (e.g., external to the class) method definitions are allowed in the more capable of dynamic languages, but I see no way they actually help solve this issue. -DavidMcLean?]

If we make some things too easy, it encourages messes and inconsistency and JobSecurity MentalMasturbation. This is back to the GreatLispWar again. A Lisp-like language doesn't need any built-in block or types since they can all be added via libraries or app developers as they please. But so far I don't see how it applies to GUI widgets, I only see how it plugs problems/limits in Java and/or it's GUI system.

[If making some things too easy produces messes, inconsistencies, and JobSecurity MentalMasturbation, why don't we stop making things easy? Why don't we remove the existing easy syntax for expressing for loops and replace it with a class that must be subclassed to use? Why not do the same for while loops? Why not demand that even all named functions are defined by subclassing a Function class and overriding its call() method, instead of using function definition syntax? Why not design your language such that variable declarations are only allowed in the form of subclasses of the Variable class? Making things "too easy" encourages programming -- heck, making things easy is the entire point of designing a programming language. -DavidMcLean?]

Where a "rule of thumb" works and where it doesn't is ultimately determined by observation. My observations and talks with managers and lead developers leads me to make certain conclusions. Your observations appear to differ. AnecdoteImpasse. Same ol' same ol.

[A "rule of thumb"? What are you talking about? -DavidMcLean?]


Footnotes

[1] The GUI controller could do the equiv of the following line such that explicit instantiation coding may not be necessary. Auto-instantiation (or equiv) would be part of the button master class(es). And a switch or override may be available to deactivate auto-instantiation when desired. Further, languages that blur distinction between objects and classes may not need an instantiation step altogether. -t

       Button buttonFoo = new ButtonFoo(); // traditional instantiation example
How would the "GUI controller" automatically instantiate a Button, and where and when would it do so? What is a "button master class" and how is "auto-instantiation (or equiv)" part of it? Please be explicit, and illustrate with code.

It highly depends on the language, where languages that blur the distinction typically don't need ANY instantiation. I am not a Java programmer so won't attempt a Java example. In some languages perhaps auto-instantiation is not possible and the coder would have to explicitly add a line like the above. (Ideally I'd prefer a DualTypingLanguage where the architect can optionally "lock" objects/classes and multi-instantiation as needed.)

Could you give an example of a language that blurs the distinction and so doesn't need any instantiation?

Let me clarify something. If objects and classes are essentially the same thing, then making a "class" such as Example 8462 is the same as instantiating an object. So, yes, we are "instantiating an object", but we don't need a "double" instantiation to give a class an object-like interface.

The syntax of Example 8462 implies static classes, which means you're going to have to instantiate an instance of buttonFoo somewhere. However, I can imagine that the language used in Example 8462 creates a new class via (say) the 'extends' keyword (in place of 'inherits'), but if you use the 'inherits' keyword (as you've done) it creates a new class and implicitly creates an instance of that class stored in a constant with the same name as the class. That would work. Of course, we can imagine anything we like with imaginary languages.

By the way, what is a "'double' instantiation"? Whilst it is entirely reasonable for classes to be implemented using 'class' objects, or to replace static classes and 'class' objects with prototype objects, you still have to ask the static class, or the 'class' object, or the prototype to provide you with each new instance. Even the implicit instantiation I've described above using the 'inherits' keyword is still an explicit request for instantiation.

I used certain pseudo-code keywords in an attempt to make the examples clearer, but didn't necessarily mean to borrow all concepts for similar-looking languages. For the samples, I'll assume ObjectsAreDictionaries and classes and objects are same thing and defining a class creates an object then and there. "Class" is just a more convenient way of initializing an object, and establishes the parent. "Inherit" means that an internal link is set to a parent object/class, and if a given attribute or method is not found in the current object/class, the interpreter/compiler traverses up the parent branch until it finds that keyword defined.

We could design the language to allow defining or re-defining methods if we really wanted to "scatter them all over" per above. (I'm not necessarily condoning it, but considering it terms of an exploratory option.) It could look something like:

  // Example 8490 -- Simplifying the re-defining of methods in OOP
  class myButton inherits gui::Button {
    myAttribute = 7;
    onClick(event) {...}  // method (this version skips need for "method" keyword)
  }
  ...
  myButton.onClick(event) {newStuff();}  // redefine method
The redefined one would still have the same parameter scope as if it were in the class such that "event" is still valid (which is defined in parent class "Button" or higher).

I don't know if there are any existing languages that do all these things in one, but my point is that language-specific issues seem to be the driving factor, not some inherent weakness of OOP, that keeps them from being competitive with HOF's, or at least doing the "tricks" you show, irregardless of whether those tricks are a good thing in practice, such as (re)defining methods away from the class.

[You actually can define methods like that in RubyLanguage (using normal method definition syntax) and PythonLanguage (using first-class functions, as is the only method definition option in JS). But does that help? You're still using a class definition to create an instance, and still you aren't addressing obvious concerns like "two handlers on one event". -DavidMcLean?]

Continued at NodeJsAndHofGuiDiscussionTwo


CategoryJavaScript, CategoryConcurrency, CategoryFunctionalProgramming CategoryDiscussion


EditText of this page (last edited August 30, 2014) or FindPage with title or text search