• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

A bit of fun - humour around programming languages and tools.

 
Bartender
Posts: 1156
20
Mac OS X IntelliJ IDE Oracle Spring VI Editor Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just a bit of fun; Programmers are also human - you tube - my favourite is the emacs one.  

"Many a word spoken in jest" ;-)
 
Saloon Keeper
Posts: 15630
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The problem with JavaScript (or front-end development languages in general) is the culture.

While there are many that develop with longevity in mind, I feel that the vast majority of front-end developers have a strong "git 'r done" mentality, and when their design is buggy or needs to be extended, they just patch new code in without worrying about backward compatibility. Then, as the video already jokingly pointed out, everybody depending on that code has to fix their own code because the patch broke stuff. This leads to a cascade of patches, until people get fed up and release a whole new framework. This new framework is similarly poorly designed however, because nobody ever learns anything from the previous mistakes.
 
Saloon Keeper
Posts: 27885
198
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The problem with all of the scripting languages is their "git-er-dun!" mentality. Management wants to "see" results, and the current crop of scripting languages almost invariable gratifies that want, as it allows web pages and GUIs to be thrown up rapidly.

Unfortunately, from what I and others have seen over the years is that the total time and effort required for any non-trivial project runs about the same, regardless of what language you use (possibly excepting assembled). Rigorous languages like Java require a lot more work on the preliminary design. Scripting languages reduce that, but at the cost of finding and fixing bugs after the system is in production. I personally hate being shown as an idiot to the entire world, so I'd rather that my worst mistakes be done before the general public can see it, and hence my fondness for Java. But, alas, Management often doesn't see it that way.

As it happens, the other thing I hate about JavaScript in particular is its inside-out threading model. But that's not an inherent property of JavaScript, just the current paradigm. Android also uses this vexing threading model and until Kotlin came along, most Android apps were coded in Java.
 
Stephan van Hulst
Saloon Keeper
Posts: 15630
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What do you mean by the inside out threading model, Tim?
 
Tim Holloway
Saloon Keeper
Posts: 27885
198
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In most GUI systems, such as Java AWT, Swing, and SWT, the GUI/graphics rendering is done in a secondary thread with the business logic in the main thread.

In Android and JavaScript, the main thread handles the graphics. If you have any time-consuming work, you have to hand it off to a secondary thread or the graphics will stall. And in many cases, the system will outright refuse to allow a lot of things such as I/O, database access, network client/server conversations and the like.

It might seem that the choice of one viewpoint over the other wouldn't really matter, but in practice, the communications are a LOT more cumbersome that way. You have to make promises and "await" them. Except that you're nor really waiting, since that would lock up the GUI. Instead it does mumbo-jumbo with callbacks.

That would be bad enough, but when you have a long-running service that itself needs a long-running service, the layers of promises and expectations and callbacks can stack up to unmanageable proportions.

Android has tried to alleviate this by adding features to Kotlin that don't come naturally to Java as it currently exists. and also by tapping into the latest and greatest Java threading APIs. And it isn't helped by the fact that Android's APIs go in and out of style almost as fact as if they'd come from Microsoft. Or that the Internet will cheerfully return deprecated solutions at an equal or higher priority than the current stuff.
 
Stephan van Hulst
Saloon Keeper
Posts: 15630
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:In most GUI systems, such as Java AWT, Swing, and SWT, the GUI/graphics rendering is done in a secondary thread with the business logic in the main thread.


I'm not quite sure I share this view.

In my Swing applications my main thread only serves to set up some initial configuration and to kick off the Event Dispatch Thread. It then terminates. From that point on, I consider the EDT to be the main thread. Any time you want to some long-running business logic outside of the EDT, you have to do it in some background task that is secondary to the EDT.

If you have any time-consuming work, you have to hand it off to a secondary thread or the graphics will stall.


This really isn't different in Java. If a listener triggers, and you do time-consuming work on it without passing it off to an Executor, your Swing UI will also stall.

the communications are a LOT more cumbersome that way. You have to make promises and "await" them. Except that you're nor really waiting, since that would lock up the GUI. Instead it does mumbo-jumbo with callbacks.


I'm also not a big fan of callbacks. But really, the async-await / suspend mechanism that was added to JavaScript, C#, Kotlin and maybe other languages makes asynchronous processing so much more natural and elegant than passing off a background task to a SwingWorker or Executor. Really, it's a big shame that Java doesn't do something like await yet. I imagine they will add it at some point though.

That would be bad enough, but when you have a long-running service that itself needs a long-running service, the layers of promises and expectations and callbacks can stack up to unmanageable proportions.


That might have been true for the old way of dealing with promises and callbacks, but async-await helps get rid of all this mess really nicely.

Just compare this piece of code in Java:

To this piece of code in JavaScript:

I think the second piece of code is much easier to read and more natural to write.

Notice how you don't need separate functions to run a background task without blocking the UI thread. When it hits a blocking call, the UI thread suspends execution of the current function and immediately becomes available to perform other tasks. That same UI thread continues execution of the async function when the awaited result becomes available.

There is also no need to pass callbacks to Promise objects in deeper and deeper callback scopes. All of this is handled automatically by the await keyword.
 
Tim Holloway
Saloon Keeper
Posts: 27885
198
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK let me ty this again. I posted this 2 hours ago, previewed for the usual glaring typos, published it and now it's gone without a trace.

I don't recall exactly what my main task model has been for Swing, but in more primitive times, there was an event loop and you dispatched off that loop. Swing internalized that loop, I think and uses callbacks. But it's still about the same thing, and for that matter, so are webapps, allowing for certain obvious differences.

Most UI actions are light enough to run synchonously, so a Swing app can directly issue I/O reads, database queries, and even some network interactions without any special support code in the callback/action processor. And a simple "x = stream.readLine()" is a LOT simpler than an awaited equivalent.

Here's one of the nightmares I've worked on, apologies for the length:


It's worth noting that someone has actually attempted to make a synchronous MySQL interface for NodeJS, but it was broken when last I checked.

You can tell how much pain it caused me to get to this point by looking at the commented code/log tracing.

Nor is it the only such abomination I've had to create. I have another that provices a ReST service. And another one in Python that has to do much the same thing in order to handle incoming Bluetooth Low Energy events. They were excruciating to write and no less so to maintain.

I'm a basically linear person. I can deal with fork/join and general multi-tasking, but the mess that systems like JavaScript employs is a real stresser. I can't just fork off a child and check on it whenever, I have to deal with the results in code that can actually precede in source form, though not in time, with what comes back. Which means that I have to keep the consequences in my head while I should be working on other operations. I get in constant fights about what methods to tag as async and await and where to put them. And when I design libraries like the one above, their callers have to be aware of the sync/async nature of the methods they call and code accordingly.

In short, it takes a lot of the fun out of software design.
 
Stephan van Hulst
Saloon Keeper
Posts: 15630
366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I see what you mean, but I would argue that the mess is mostly caused by db.each() accepting a callback, rather than it returning a Promise.

It's the callbacks that are making the code so non-linear and hard to read. If db.each() had returned a Promise, the code probably would have been much easier for you to trace, exactly because async-await does a lot of the work to make it more linear.

I took a small part (the worst part) of your code and I refactored it, assuming that db.all() uses Promise instead of callbacks *. (I replaced each() with all(), because all() is easier to use if you're going to store all rows in memory anyway.

* : there is a library that wraps around sqlite3 that does exactly this.

In short, I absolutely understand your frustration, but I think that your frustration is directed at the wrong target.

  • Callbacks, bad.
  • Promise, bad without async-await.
  • Promise, good with async-await.


  • To drive the point home, the following two snippets are functionally identical:


    In both cases, doInBackground() returns a Promise. The difference is that without async-await, you have to manipulate the promise directly, passing it callbacks.

    With async-await, the whole Promise wrapper becomes implicit: await automatically unwraps the Promise returned from the async steps, leaving you to process the intermediate result in a linear fashion. When you return a value from an async function, it automatically gets wrapped into a Promise for you.

    The second snippet is more verbose, but that's only because I'm demonstrating that with async-await, you can once again handle errors the way the Lord intended: Using try-catch, rather than more callbacks.
     
    Tim Holloway
    Saloon Keeper
    Posts: 27885
    198
    Android Eclipse IDE Tomcat Server Redhat Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    That misses the point. And yes, I'm sure that code is ugly, because I mostly just screamed at it until I got something that I did what was necessary. It's also likely that the mysql library I am using wasn't friendly to ".all", as I had previously used that concept for the weather display app, which has to return data from 3 aggregated upstream web services. Even then I had to supply callbacks, though.

    I couldn't give the caller a promise, I had to return it actual DATA. Synchronously, not as something from the background. One of the biggest frustrations I had was that even after all the mucking about with async/wait, the data I stuffed into the return variable often wasn't actually there when I needed it.

    On top of that, as I said, if you use an async service, then everything above it has to be re-coded to work with an async service, because this is coming from the main thread. It's no "black box" routine.

    There is a time and a place where I'd want stuff like async/await, but while you may think that's simple and elegant, to me, it's nowhere near as simple and elegant as a "rs = connection.query(SQL); while(rs.next()){append ... }". It's not like the async code does any of that work for me, so instead I have 2 jobs to do instead of one.
     
    Marshal
    Posts: 28263
    95
    Eclipse IDE Firefox Browser MySQL Database
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Peter Rooke wrote:Just a bit of fun; Programmers are also human - you tube - my favourite is the emacs one.  



    I didn't watch the video, but I started reading the comments because they are often pretty informative. And I can read a lot faster than people can talk so I find reading text more comfortable than watching videos. Besides, videos make you watch sequentially whereas reading doesn't. Anyway when I saw a comment comparing the speaker to Blippi I knew I had chosen correctly, because I would have had to reach through the screen and strangle him.
     
    Don't play dumb with me! But you can try this tiny ad:
    a bit of art, as a gift, that will fit in a stocking
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic