The Artima Developer Community
Sponsored Link

Weblogs Forum
User Interface Programming in the (Near) Future

4 replies on 1 page. Most recent reply: Sep 27, 2011 10:53 AM by Chris Ryland

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 4 replies on 1 page
Bruce Eckel

Posts: 874
Nickname: beckel
Registered: Jun, 2003

User Interface Programming in the (Near) Future (View in Weblogs)
Posted: Sep 21, 2011 2:12 PM
Reply to this message Reply
Summary
In my article on JavaScript, I observed that we need a new language that generates good and safe JavaScript, so that you no longer have to think about either JavaScript issues or cross-browser problems. Little did I know that the solution(s) had already appeared in the form of JQuery and CoffeeScript.
Advertisement

Here is the earlier article.

The fact that there have been so many JavaScript libraries attempting to solve the problem, and that the solution appears in not one but two pieces perhaps makes it understandable that it's not initially obvious. But once you see how well the solution works, you'll shake off the shackles of the old, and unleash your UI creative potential. This combination is compelling enough that Rails has included it as part of the standard distribution.

If you want to work across desktops, pads and handhelds, HTML5 looks like the only reasonable choice. And Windows 8 looks like it is going to be heavily based on HTML5, so these tools will also come in handy for that.

jQuery

The browser problem is big. The amount of money that companies have invested to compensate for browser incompatibilities is huge. Entire jobs have been dedicated to that one issue.

Many have attempted to solve it by creating JavaScript libraries. Because of the size and pain of the problem, many libraries were created, and because this was primarily an open-source market and unencumbered by money, a solution has (relatively rapidly) evolved. I'm quite glad I only showed up after things have been sorted out.

The clear winner is jQuery. Go to the site and you'll not only see thorough documentation including lots of tutorials, but also the plugin framework that allows lots of other people to create easy-to-use add-ons. There are tons of plugins, including the very impressive jQuery UI.

A particularly nice way to browse through the library is Visual jQuery. There are a number of books out -- I have jQuery in Action and jQuery Cookbook but I hardly touched them before starting to write code -- the online resources are very good, and you can also find lots of examples in blogs.

jQuery is a facade over both JavaScript and the browser DOM. If you do everything via jQuery calls, you insulate yourself against cross-browser issues and also many of the gotchas of JavaScript -- however, you're still programming in JavaScript (a problem we solve in the next section).

Basically what jQuery allows you to do is discover parts and pieces of your UI and manipulate them. "Manipulate" means pretty much anything you can imagine, including modifying the CSS, creating and responding to events, Ajax, and all kinds of effects which, in combination with some of the mind-blowing plugins out there, rival what you can do with Flex. All this runs in the browser, without any browser plugins like Flash, Java or SilverLight.

You'll see more when we get to the example.

CoffeeScript

Although jQuery solves your browser issues, you're still working with a language (JavaScript) that wants to bite you at every turn (see the aforementioned previous article). Wouldn't it be nice to be able to program using a modern language that feels like Python, Ruby and Scala?

That's what CoffeeScript does. You write in a very spare and clean object-functional language, and it compiles into safe JavaScript. Other than being able to transparently call functions in the JavaScript library, you don't even have to think about JavaScript (well, except when debugging, but even that might be a temporary issue).

The CoffeeScript site is very well done; it has a nice introduction and there are numerous resources including a screencast introduction; there was also a recent presentation at JavaZone which is quite good and not linked from the CoffeeScript site.

My favorite book so far is the free, online Little Book on CoffeeScript (except for the last chapter, which I found muddied the waters). I've also been reading CoffeeScript: Accelerated JavaScript Development which I like -- the voice makes for pleasant reading -- but which is slightly odd in places, nonetheless quite useful. There's even a chapter on using CoffeeScript with jQuery which I found helpful (and another indication that the combination of the two is the future of UI).

My Favorite Example: The Changing Color Grid

Although I will let the jQuery and CoffeeScript resources cited above be your full introduction to the language, I'll show you an example here that is one I tend to create whenever exploring a new UI development system; it's sort of my "hello, world" for UI.

I like to see what it takes to create a grid of colored boxes and then randomly change those colors. This is by no means a perfect exploration of a UI system, but it gives you a good feel about what it's like to develop with. Considering the difficult experience I had with JavaScript years ago, CoffeeScript + jQuery is a delight to use. Indeed, even considering all the UI libraries I've looked at over the years, this system is certainly one of the best, especially when you take into account the ever-expanding ocean of jQuery plugins.

jQuery works by hooking into your HTML and modifying it. This "hook" can be virtually anything from tag types to styles to individual identifiers. To start with, we'll use the id "board"of a single paragraph as our hook:

<!doctype html>
<html>
    <head>
    <title>CoffeeScript and jQuery Make a Color Grid</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="grid.js"></script>
    </head>
    <body>
    <p id="board" align="center"></p>
    </body>
</html>

Note the inclusion of jquery.js, which is all you need do to add jQuery. The grid.js is the JavaScript file that will be generated by our CoffeeScript code. So all the browser sees is HTML and JavaScript.

Let's create the CoffeeScript in pieces. We're going to create a table filled with rows of cells of blocks of color. Here's a CoffeeScript function to create one of those cells:

cell = (row, col) ->
  "<td id='#{row}X#{col}' style='border-style:solid;border-width:8px;'></td>"

Like JavaScript, everything in CoffeeScript is a variable -- including a function. To make cell a function, we assign it to a function. A function is defined as an argument list in parentheses followed by an arrow, followed by the function definition. Basically, all functions are defined as anonymous functions, and we can choose to assign them to variables if we want. So here, cell is a function that takes two arguments.

Like Python, blocks of code are determined by indentation, and the de facto standard indent size in CoffeeScript is 2.

Like Scala, the last expression in a function becomes the return value. So here, we're returning a string. Note the #{row} and #{col}; within a double-quoted string; these expressions substitute the row and col variables into the resulting string. This becomes the unique id for that cell, which we'll use later to discover and manipulate that cell using jQuery.

You can also see that I have not established the color of the table cell yet. We'll do that later, also using jQuery.

Now let's create a row of these cells:

row = (ncols, row) ->
  '<tr>' +  (cell(row, col) for col in [0..ncols]).join('') + "</tr>\n"

The parenthesized expression is a comprehension, just like in Python. The square brackets create a list, and the .. produces a range. Once the list of cells is created, it is joined together using the JavaScript join() function -- note how transparent it is for CoffeeScript to call JavaScript functions, just like Scala calling Java functions.

Finally, the whole table:

table = (nrows, ncols) ->
  '<table>\n' + (row(ncols, n) for n in [0..nrows]).join('') + '</table>'

This will be inserted into the paragraph in our HTML.

Now we want to create a random RGB color:

randomRGBColor = ->
  val = -> Math.floor(Math.random()*255)
  "rgb(" + val() + "," + val() + "," + val() + ")"

If you have no arguments for your function, you can just leave out the parentheses for the argument list. Note that val is a nested function, and that one-line functions just put the code on the same line as the arrow.

The randomize function steps through all the cells and change the CSS border-color for each one using jQuery:

randomize = (nrows, ncols) ->
  for r in [0..nrows]
    for c in [0..ncols]
      $('#' + "#{r}X#{c}").css("border-color", randomRGBColor())
  setTimeout (-> randomize nrows, ncols), 1000

The $ calls jQuery, and the expression in parentheses right afterward tells jQuery what we're looking for. Here, the initial # means we're looking for an id (a leading . would mean a class name, and there are others). Once we find the component with that id, we use the jQuery css() method to change the border-color to a randomly-selected color. Finally, we use JavaScript's setTimeout() function to call this function again after 1 second.

Every program needs a main(). In jQuery, this must be attached to the point in the lifecycle after the page is loaded and is ready, so that jQuery can find the components you're looking for. In CoffeeScript, your main() looks like: $ ->:

$ ->
  rows = 30; cols = 60
  $("#board").html(table rows, cols)
  randomize rows, cols

Semicolons are normally unnecessary in CoffeeScript because it recognizes line breaks after complete expressions to be the end of that expression. If you want to put more than one expression on a line, you separate them with semicolons.

The $("#board") tells jQuery to find any and all components with that id (in our HTML, there's only one). The jQuery html() method inserts its argument as HTML. The argument is a call to our table() function, but note that -- like Ruby and Scala -- we don't need to use parentheses around the arguments.

Once the table has been inserted, we call randomize() and the flashy blinking colors begin!

While developing, you can tell the CoffeeScript compiler to run in the background and compile your code every time you save it. In my case, all the above code was in a file called grid.coffee so the command-line for continuous compilation is:

coffee -w -c grid.coffee

For monitoring and debugging, the docs tell you to install FireBug on FireFox, but I discovered that the Chrome browser has very nice debugging built-in: select the wrench on the right side, then tools, then JavaScript Console. Note that all debugging messages will refer to the generated JavaScript rather than the CoffeeScript source, so you must at least be comfortable with JavaScript.

Limitations

As incredible as the CoffeeScript/jQuery combination is, there are limitations.

Programming environments. These are not like FlexBuilder (yet), but I suspect we might see them -- perhaps even from Adobe. I'm used to being on the bleeding edge, so I just installed CoffeeScript-mode for emacs.

Debugging. As noted, debugging tools work only with the generated JavaScript, and your primary way of communicating program status is with console.log. Again, I'm used to the bleeding edge so I didn't have any complaints about the tools at hand.

The combination of CoffeeScript and jQuery looks like a juggernaut to me. They solve so many of the previous problems that it's breathtaking. I don't see jQuery being unseated anytime soon; it will just continue to grow. I really like CoffeeScript, but someone could conceivably come along with a much better language and unseat that sometime in the future. But for now, my UI issues are resolved.


Nemanja Trifunovic

Posts: 172
Nickname: ntrif
Registered: Jun, 2004

Re: User Interface Programming in the (Near) Future Posted: Sep 21, 2011 2:24 PM
Reply to this message Reply
CofeeScript is nice, but we should also mention GWT and Script# which enable using statically typed languages (Java and C#) for generating JavaScript.

I prefer using vanilla JavaScript though, but understand why some people don't.

Rusco rebhan

Posts: 2
Nickname: rebhan
Registered: Aug, 2007

Re: User Interface Programming in the (Near) Future Posted: Sep 22, 2011 3:38 AM
Reply to this message Reply
Excellent Article Bruce !

A quick tip for node on windows users: "coffee -w" does not (yet) work with the latest unstable node 0.57 version, see:
https://github.com/joyent/node/issues/1358

I personally am careful when I read "this is the future...", because progress never stops.

I personally would like to see a language which allows me to do optional static typing, that is: the developer and not the language designer decides whether a type identifier is necessary or not.
I hope at least that sth. like http://disnetdev.com/contracts.coffee/ will get integrated into CS main trunk soon.

Having done some large scale jQ + CS programming, the usage of a framework becomes necessary, my favorite is
http://angularjs.org/, it has it's roots in Flex Databinding and Xforms.See also: https://github.com/addyosmani/todomvc
Have Fun !

Kevin Dangoor

Posts: 1081
Nickname: tazzzzz
Registered: Jul, 2003

Re: User Interface Programming in the (Near) Future Posted: Sep 22, 2011 9:15 PM
Reply to this message Reply
> CofeeScript is nice, but we should also mention GWT and
> Script# which enable using statically typed languages
> (Java and C#) for generating JavaScript.
>
> I prefer using vanilla JavaScript though, but understand
> why some people don't.

In my opinion, the reason CoffeeScript has garnered a lot of attention is the fact that it is semantically equivalent to JS and generates JS that is very similar to what a human would write. The same cannot be said for something like GWT.

This makes the learning curve shallow, the surprises few and the cost of switching back to plain JS minimal.

Chris Ryland

Posts: 1
Nickname: cpr
Registered: May, 2003

Re: User Interface Programming in the (Near) Future Posted: Sep 27, 2011 10:53 AM
Reply to this message Reply
Bruce--

Agreed 100%. You could be even more aggressive in your non-use of parens, and, I think, clearer:

row = (ncols, row) ->
'<tr>' + (cell row, col for col in [0..ncols]).join('') + "</tr>\n"

and

$ ->
rows = 30, cols = 60
$("#board").html table rows, cols
randomize rows, cols

, etc.

Flat View: This topic has 4 replies on 1 page
Topic: Speaking in Grenoble, France and Stockholm Previous Topic   Next Topic Topic: Odersky Explains Shared-Memory Concurrency


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us