If JavaScript Were Such A Great Language ...
... why aren't its extra-web-browser versions being used widely.
Here's my observation: If people wanted to, they can use JavaScript for:
- Windows shell scripting (JScript Windows scripting host)
- General purpose Windows/.NET programming (JScript.NET)
- General purpose dynamic language programming for the JVM (Rhino)
- General purpose Unix shell scripting (xpcshell)
- Scripting applications (for C++, Java, .NET applications through one of the above technologies)
All of the above technologies have existed for at least five years, some even ten. But if people are using JavaScript for non-web programmings, they are not talking about it.
Something to think about on a Monday morning.
Closures Comes To C++0x
Hurb Sutter: For me, easily the biggest news of the meeting was that we voted lambda functions and closures into C++0x. I think this will make STL algorithms an order of magnitude more usable, and it will be a great boon to concurrent code where it's important to be able to conveniently pass around a piece of code like an object, to be invoked wherever the program sees fit (e.g., on a worker thread).
Here is the report.
Here is an example:
double min_salary = .... .... double u_limit = 1.1 ∗ min_salary; std::find_if(employees.begin(), employees.end(), [&](const employee& e) { return e.salary() >= min_salary && e.salary() < u_limit; });
Here are some of the finer points of the syntax and semantics:
- An lambda expression has the general form [...](...)...{...}
- The [...] portion serves as a lambda introducer, it also indicates which local variables, or this, are captured from the environment
- The optional (...)... portion declares the parameters, thrown exceptions and return types of the lambda expression
- The {...} portion contains the code of the lambda expression
- Lambda expressions evaluates to closure objects, which are function objects whose classes are implicitly defined and named. There's no duck typing here. The duck typing happens in the template system
The simplest lambda expression in C++ is thus
[]{ }
which captures no local variables, takes no parameters, and performs no actions when invoked.
The most useful lambda expression will be introduced by [&], which captures every free variable in the lambda expression by reference. The [=] introducer introduces a lambda expression that captures everything by value. The [] captures nothing.
The lambda introducer may also contain an explicit list of variable names or this, in which case they are captured by the lambda expression whether explicitly referenced by the lambda expression body or not. I haven't figured out how this could be used except that it may make local variables live longer.
In C++, the closure feature is more of a syntactic sugar for function objects.
One irony here is that while in the past, we have strived to turn for loops into for_each statements, closures will make those for_each statements look (mostly) just like the for loops.
Friday Scala Quiz: DSL This!
Write a valid Scala program that contains the following passage:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
For the humor-impaired, this quiz is meant as a sarcastic jab at my Scala-pursuing friends. ;-(
If you are still intrigued by the idea, please be advised that the trivial answer of putting the whole thing in triple quotes is inappropriate in the context of a DSL.
A Little C++ To Boost Your Spirit
C++: The Ultimate DSL
Take a look at the following snippet of valid C++ code ...
group = '(' >> expr >> ')'; fact = integer | group; term = fact >> *( ('*' >> fact) | ('/' >> fact) ); expr = term >> *( ('+' >> term) | ('-' >> term) );
... and tell me C++ is not the perfect language for DSLs! ;=)
Seriously, I copied down the above from Adam Mitz's OCI internal C++ lunch talk about Boost.Spirit yesterday.
Boost.Spirit documentation: Spirit is an object-oriented recursive-descent parser generator framework implemented using template meta-programming techniques. Expression templates allow us to approximate the syntax of Extended Backus-Normal Form (EBNF) completely in C++.
The Spirit framework enables a target grammar to be written exclusively in C++. Inline EBNF grammar specifications can mix freely with other C++ code and, thanks to the generative power of C++ templates, are immediately executable. In retrospect, conventional compiler-compilers or parser-generators have to perform an additional translation step from the source EBNF code to C or C++ code.
As parser generators go, Boost.Spirit is pretty powerful stuff. As an example, Adam redid Mark Volkmann's Math example from the ANTLR 3 talk, ASTs and all.
Geeky as Boost.Spirit may seem, can think of one occasion in past projects where we could have used it instead of coding a recursive descent parser by hand.
Scala: Still Uncomfortable After Five Years
I am a good pragmatic programmer. I follow the The Pragmatic Programmer recommendation of learning a new programming language a year. At least I try to.
But I'm having trouble with Scala.
Last Friday, at the OCI internal Java lunch, Tim Dalton gave a presentation on Scala. This one is very similar to the one Tim gave at the St. Louis JUG last year. As I did last time, I went to scala-lang.org and downloaded the latest version of the language and played with it this weekend. I got scala-2.7.0-final this time, replacing the scala-2.4.0 I downloaded last time.
As if the world is conspiring to push me into Scala-land, InfoQ also released a presentation on Scala by Lex Spoon from the Scala core team. I also found Ted Neward's "The busy Java developer's guide to Scala" series of articles at IBM developerWorks. And to round out the outside stimulus package, I can't say the blatant self-promotion of their own Scala book, in the form of online advertising at Artima, has gone unnoticed by me. I don't know if Bruce Tate is on board this time. But he should. Scala seems like a pretty powerful language to kayak or mountain biking with!
I other words, the three year hype cycle for Scala has started, at least in my books. It may very well have began a little while earlier, in December 2007, when Artima announced The Book. And I'll make a mental note to reexamine the adoption of Scala in December 2010.
Back to Scala the language.
First of all, let me explain the title of this post a little bit. I'm not sure of how long I have been in the mode of "learning Scala"—get a new version of the package, print out the tutorial and language reference, and start at page 1, only to give it up a few pages into the tutorial, either because the code in the tutorial doesn't compile, or another Slashdot discussion pulled my attention away from it—sort of like the way I tried to "learn Russian".
Secondly, notice that I used the word uncomfortable, which is different from other more objective descriptions like "Scala sucks," or "Scala is the next big thing." The latter description I've used in jest at the office where I know people will see through it right away. (This, by the way, will replace my earlier line: "Use Ruby on Rails! You don't even have to write a line of code. Just think about it, and it will be done!" Now that the Ruby on Rails hype has died, that line is no longer funny.)
Scala is uncomfortable for me, because it is too different from what I use on a daily basis, Java and C++. Here's my list:
Conceptual Hurdles
Pattern matching. I fully understand the power of pattern matching from Haskell's pattern matching and Scheme syntactic extensions. Pattern matching is purportedly a big innovation of Scala in that it mixes pattern matching into an OO language.
However, pattern matching in Scala is exactly the point at which I would spend time trying to understand it, trying to master it, trying to learn to use it. I understand the syntax. I understand the explanation that the speakers in presentations gave. I do get to the part where I say "This is cool." But I never get to the point where I would see a problem and say "This problem is best solved with pattern matching, let me fire up Scala and code the solution."
The same feeling I have with Common Lisp CLOS, Scheme hygienic macros, Perl globs, and the whole Tcl language.
Syntax Hurdles
The semi-colon. This should be an easy one to overcome, but it's not. I was doing a little bit of Scala and Java this weekend, in Vim, of course. And at one point my mind went completely blank as to whether I should type a semi-colon at the end of a line. I caught myself thinking "This is the end of a line. Should I type a semi-colon here? I don't know!!!" And I was editing a Java file.
Arbitrary Differences
At least from a Java developer's point of view. The syntax for the default constructor, the post-fix type declaration, the use of [] for type parameters and for List literals, the use of Unit for void, etc., are examples of where Scala deviates from Java. Either using a different notation for things that are available in Java, or using notations that are used for one thing in Java to mean a different thing in Scala.
I understand the origins of these differences. They are more similar to Haskell or ML or some other functional languages then Java. So, naturally, a question I have is why isn't Scala being pushed as heavily to the functional programmers as it is to the Java programmers?
Syntactic Sugary Trickery
There is a dizzying array of syntactic sugar in Scala, most of them geared toward making Scala a perfect language for constructing DSLs. The optional omission of the dot when calling a method on an object, the optional omission of the parentheses when calling a method on an object with no arguments, one argument or more arguments, the way an infix operator on a class is declared with the "unary_" keyword, the liberal use of the "_" (the underscore) character to mean different things in different contexts, the way a infix method could be declared to be not only right-associative, but right-applicable, making it possible to write Scala code right-to-left, etc., could only be classified as syntactic tricks in the tradition of Perl.
While each of these tricks is simple when viewed individually, their aggregate effect is code that needs non-trivial thinking on the part of the programmer.
Scala Is More Different
For a language that is hailed as the next big thing, at least on the JVM, my feeling is that Scala is more different from Java than, say, Groovy, BeanShell, and maybe even Jython. As a consequence, the jump from Java to Scala is not an easy one.
One refrain that I hear again and again in the Java closures debate is "Don't complicate Java even more with closures. If you want closures, just use Scala." With all the differences I outlined above, I believe "just use Scala" is not as easily doable in this context. (BTW, I was struck by the similarity between the syntax of Scala closures and the BGGA closures.)
Scala is to Java as C++ is to C?
One thing that is mentioned in the second Ted Neward article is the possibility of using Scala as a better Java the way Bjarne Stroustrup advocated C++ as a better C.
I think that is a viable way of driving Scala's adoption. And indeed, Scala contains enough goodies to allow the Java programmer to write more concise programs without losing type safety and performance. This is an advantage of Scala over Groovy. A better "better Java", maybe?
But really, to make Scala mainstream would require commitment and investment, just like anything else, from C++ to Java to .NET/C# to Groovy. One or more industrial strength, focused, well financed companies need to spring onto the scene to offer continued Scala productization and support for the long term.
How Would You Have Reacted...
... if C|Net tells you Microsoft to work with Eclipse on Java?
Well, Ted Neward is setting us an example:
Ted Neward: My first reaction has to be characterized as... WTF?!?My second reaction has to be characterized as... WTF?!?
There's some serious credulity issues here. Not credibility, mind you, because I believe the reporter is entirely accurate in this story, but credulity. As in, "That's incredulous!", which is another way of saying...
WTF?!?
Ted went on to remind us how Sun and Microsoft fought over J++, and how J++ had delegates way back when, and how C# 3.0 has lambda expressions which are a natural outgrowth of delegates, and how Java people is still longing for something similar called closures.
I think the real story is not as incendiary. Microsoft is helping Eclipse with porting SWT from Win32 to WFP, just like they would help any other Win32 application to port to WFP. It's not a big deal.
If you are a little bit curiouser, you would do a Google search on the Eclipse guy's name that was mentioned. I did. And what did I find?
See, things aren't always what the press-releases make you to believe. You see, SWT relies more on the underlying system, and the underlying system is going out of their ways to help SWT. Good for SWT. (And Microsoft, and Apple! Where is Gtk+? Red Hat, Novell, Sun (a big GNOME backer), are you listening?)
High School Mathematics Education
The state of high school education is a hot topic among some of my friends and colleagues. I have heard older people say that the US high school education, especially mathematics and sciences, has declined considerably over the past fifty years. I've also heard people who received high school education from a different part of the world and also experienced indirectly the US system, either through their children going through it, or through their contact with graduates of the system, that the level of US mathematics and sciences education is not as high as in other countries.
The counter argument of course is that when such generalized statements are made, they are only anecdotal and are not backed up by statistics or any kind of research data.
I went on the internet (of course the internet knows it all) in search of any evidence that will support either side of the argument. Alas, I couldn't find any concrete evidence either. But I did find the following items:
- A US documentary film named Two Million Minutes that followed six high school students in the United States, China, and India
- Some Chinese high school mathematics tests. This is a district wide midterm for the first semester of High-3. (The Chinese system goes E1-E6, M1-M3 and H1-H3, so H3 is roughly equivalent to 12th grade in the US)
I haven't see the documentary myself, but am fascinated by some of the discussions on their blog, especially by the contrast between the reactions from ordinary people and those from US educators.
As for the Chinese high school mathematics test, here is one of the problems translated into English:
(16) (This problem is worth 13 points)
Given the function f(x) = x + 4 / x 2.
(I) Find the interval over which f(x) is monotonically decreasing;
(II) Find the maximum and the minimum of f(x) when x ε [1, 4].
Keep in mind that this is part of a 120-minute test consisting of 20 problems worth a total of 150 points. So the students have about 10 minutes to finish the problem.
- Can your high school senior correctly solve the problem in the allotted time?
- Is this problem on par in difficulty with the ones your high school senior get from school?
- What if you are not from the US or China? Is the problem easier or harder than your typical assignments?
- What if you are from way back when? 50's? 60's? 70's? 80's? 90's? Is this comparable to what you have to go through?
Alex Miller: Exploring Terracotta
Last night's St. Louis JUG featured Alex Miller from Terracotta talking about his company's flagship product Terracotta.
I deliberately refrained from learning anything about Terracotta before I came in. And I was not disappointed by Alex's delivery. My perception of Terracotta has changed from "expensive magic better not to touch" to "open source distributed shared memory technology for the JVM," still magical, but its "magic I can believe," or even "magic I can Xerox."
The presentation slides and code examples are up on the JUG website. So I won't bore you with things that you can read there.
I'll just mention a few things that you won't get from reading the slides.
- Alex came in wearing one of these:
- Our "Which version of Java are you using?" poll proir to the talk netted One(1) still on 1.3, Five(5) still on 1.4, about Ten(10, I didn't have enough time to count all hands) on 5. Charles Sharp, who was the MC, did not ask about 6 or 7. So the rest of the 31 audience members are either on 6 or not using Java at all. There were a few recruiters sitting at the back
- Recruiting is still strong. OCI/Advantage Consulting, Comsys, TDK Technologies, Harpoon Technologies are all looking for Java talents in the St. Louis job market. Comsys provided three gift cards totalling $100 as door prizes
- As usual, someone got a free IntelliJ IDEA license
- Terracotta also provided an iPod Shuffle to raffle off. Thank them
- Brian Gilstrap wrote a Swing app while Alex was talking for selecting random dates used when the free gifts were given away at the end of the talk to people whose birthday matches the selected date. It's pretty cool
- Terracotta has about 50 people, 20 of them technical, distributed geographically, "a distributed team working on a distributed infrastructure"
- Scott Bale, who was in attendence, who also works for Terracotta, will give a talk about Google Guice in our May meeting. "How to migrate away from Spring IOC to Guice" will be covered
- Our own Charles Sharp, whom if he had a website or blog I haven't been able to find it, will talk about JUnit 4 in next month's meeting. "How to migrate away from JUnit 3 to JUnit 4" will be covered
OK, on to Terracotta. These are just my impressions, and I could be wrong:
- It allows multiple JVMs to share data in a thread safe way
- In Eclipse with the Terracotta plugin, you can add the "Terracotta nature" to any Java project
- Plugins for IntelliJ IDEA or NetBeans is not planned, so if you want to use Terracotta, you have to use Eclipse, whcih is fine with me because Eclipse is free
- Adding the Terracotta nature won't change your Java code. It does add a tc-config.xml file to the project and the menu item "Run with Terracotta" to the place where you usually see "Run as a Java application"
- When you do choose "Run with Terracotta", the Terracotta plugin will remind you "You haven't started the Terracotta server yet, would you want me to start it for you on port 987 (I don't remember the exact port number)?" You say yes. Then you can run the client (your application), multiple times if you want to see what Terracotta will do
- The Terracotta clients communicate with the server through unicast TCP
- The default tc-config.xml does nothing to your application, to take advantage of the Terracotta server, you have to add classes, fields, and the type of lock to the config file. These are done through menu items and wizards
- The word "dso" appears in the configuration file. It stands for "Distributted Shared Memory"
- A "bootjar" is generated on the fly the first time you run the application as a Terracotta client. It depends on your app and your version of the JDK. It is prepended to the bootclasspath when the JVM is started
- The Terracotta runtime intercepts bytecode level stuff (like field access or method invocation) to hook in its own magic
- It uses, as far as I can see, a Terracotta proprietary protocol to communicate changes in object states from the client to the server
- The server is more like a database then an event hub or message hub
- As long as the server is up, clients can go down and then up and still see its shared state preserved inside the server
- The server can be started with persistence turned on, in which case even if both the client and the server were shut down the client states are preserved on disk. Bring up the server again, and then the clients, the previously saved states are visible again
- The server uses Berkeley DB Java Edition to accomplish this
- The server is monitorable with JMX. The next version of the product will have an admin console that allows one to monitor a lot more of the innards of the server
- "Bytecode modification is not scary."
- "Redmonk just wrote about us."
- Q: How do you make money?
A: We make money through support and licensing and maybe an operators edition that has visualization tools. - Q: What about Tangasol?
A: I know very little about their product. They are expensive at tens of thousand dollars per CPU. - Terracotta has a Maven like repository that contains some of the most popular open source Java libraries already instrumented by Terracotta
- It's open source
Thursday Ant Quiz
I'm tearing my hairs out, so I think you should do the same. I'll make you, as a matter of fact, by way of a Thursday Ant quiz:
The Set Up: There are two files in the current directory: Foo.java and Foo.class.
Q: Write an Apache Ant 1.7.0 compatible build.xml file in the directory, which, when invoked with the ant, removes Foo.class but not Foo.java. You cannot use the word "Foo" in the build file.
No Googling, no peeking into the online Ant manual or any Ant books.
Java, Bash, Cygwin, ...
I haven't used the A, B, C, ... style title for a while. Today's post calls attention to all distributors of Java products that provides a Windows batch file and a Unix shell script to run their product:
YOUR SHELL SCRIPT DOESN'T WORK FOR CYGWIN
The problems usually stem from the assumption that a shell script works in the Unix like environment where paths are separated by a ":". Well, for Java under Cygwin, this assumption is no longer valid because the Windows version of the JDK commands such as java or javac expect the CLASSPATH environment variable and the arguments to the -classpath and -bootclassapth command line options to be in the Windows format—with a ";"-separator.
As an example, here is the java shell script shipped with the CICE/ARM closures prototype:
#!/bin/sh CICEARM_HOME=`dirname $0`/.. java -Xbootclasspath/p:$CICEARM_HOME/lib/rt.jar "$@"
There are two problems with this script. First, it's self recursive, so you cannot put the directory that contains this script into your PATH, or it will call itself in an infinite loop. That's easily fixed by resolving the java call not through the PATH but through JAVA_HOME:
#!/bin/sh
CICEARM_HOME=`dirname $0`/..
"${JAVA_HOME}/bin/java" -Xbootclasspath/p:$CICEARM_HOME/lib/rt.jar "$@"
That brings us to the second problem: the mis-interaction between the Unix style directory names and path separators that bash uses and the JDK commands. If I install the CICE/ARM prototype in the /opt/cicearm-b05 directory, and add /opt/cicearm-b05/bin to my PATH, the above script will expand a simple java Foo command into:
C:\Program Files\Java\jdk1.6.0_10/bin/java -Xbootclasspath/p:/opt/cicearm-b05/bin/../lib/rt.jar Foo
Notice here that we are passing a Cygwin style path /opt/cicearm-b05/bin/../lib/rt.jar to the java command, which will interpret the path as a Windows style path. Most of the time, this will lead to the wrong result.
Fortunately, Cygwin provides a command cygpath that can be used to convert the Cygwin style path into a Windows style path. With the help of this command, and a little bit of uname magic to detect if the bash script is running in Cygwin, we can make the script run properly in Cygwin:
#!/bin/sh CICEARM_HOME=`dirname $0`/.. # detect Cygwin cygwin=false; case "`uname`" in CYGWIN*) cygwin=true; esac BCP=${CICEARM_HOME}/lib/rt.jar if $cygwin; then BCP=`cygpath --path --windows $BCP` fi "${JAVA_HOME}/bin/java" -Xbootclasspath/p:${BCP} "$@"
I know there are not a whole lot vocal Cygwin users out there. Most users would just fix their bash scripts for Cygwin quietly and move on. But for projects still in development, doing the same modification for every snapshot release becomes tiresome very quickly. That's why I usually send my modifications back to the project. And sometimes they even took it.
Here Comes The Cute Logo ...
And The Friday Quiz
... for Java closures:
According to my cute logo theory, which I put forth 1590 days ago,
Me: In the software world, things that have a cute logo, be it an operating system, an application, a programming language, or a middleware product, win.
And here's this week's Friday Quiz (It's not Friday here yet, but close enough):
Q1: What flavor of Java closures does this logo represent?
Q2: Write a valid Java closures program that contains the string represented by the logo.
Taking The J Off The JVM
(Via Slashdot.)
Kas Thomas, Analyst at CMS Watch: Sun Microsystems CEO Jonathan Schwartz, speaking at the SugarCRM Customer and Developer Conference earlier this month, made a pronouncement that went largely unnoticed by industry pundits. "I think what you'll see from Sun," Schwartz remarked, "is that we're just going to take the 'J' off the 'JVM' and just make it a 'VM'."
This is the first time I've seen this quote. Slashdot used the quote in the context of Sun's hiring of the lead Jython developer. Although I cheered the news for Python and Jython's sake, I'm not sure how to react to this quote as a Java developer.
I guess I should accept it as something inevitable. The JVM is a pretty good runtime engine, and it seems a waste to keep it all to Java itself.
But the argument can also go the other way around. Java is a decent language, and it seems a waste to target it only to the JVM. I've seen three very public attempts at targeting Java to other platforms:
- The GNU gcj project, which added a Java front end to the GCC compiler collection, so that we can target Java programs directly for the x86 platform.
- Google's Android project, which targets Java program for the register-based vertual machine called Dalvik
- The IKVM project, which targets Java programs for the .NET runtime
I think as main stream scripting languages crowd into the JVM, Java the language needs to do the opposite—spreading out to other runtimes.
I think in the long term, Java should not be expected to be the most performant language on the JVM, as it is today, for Java used to be a strictly interpreted and slow language just like the other scripting languages. As Java's performance was boosted over the years, so will the other scripting languages'.
Java the language needs to seek new living spaces, new runtimes, and new places where it will shine.
That, or, in five years we'll all need to learn a new language. (In case you haven't figured it out, Java the language is no longer strategic to Sun.)
Sun Loves Jython Too
Tim Bray: As anybody who watches this space knows, we’ve been pouring increasing amounts of love on dynamic languages recently. Well, er, on Ruby, to be precise. But you know, Ruby’s not the only game in town. So, as of this morning, noted Pythonista Ted Leung and Jython lead Frank Wierzbicki are joining Sun.
Ted Leung: Today is my first day as a Sun employee.
Frank Wierzbicki: So what does this mean for Jython? First off, just in case anyone is worried: Jython is going to remain completely open source. Sun has applied for memebership to the PSF and the PSF will continue to be the steward of Jython's code. This move by Sun means that Jython is going to get some of the attention that it needs to move forward.
I have always thought of Jython as the original JVM language that started it all. It's nice to see Jython getting the same amount of attention as JRuby.
With Groovy and Scala getting very active support from capable companies like G2One and Artima, that leave only Perl...