Tom Edelson's Songline
Writing about computers, life, and society from the perspective of a "poly Quaker Taoist" living in the Triangle region of North Carolina.


Categories In This Blog:

















Subscribe to "Tom Edelson's Songline" in Radio UserLand.

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.


Friday, April 25, 2008
 


The last five posts in this blog dealt, at perhaps amazing length, with differences between two (of the many) implementations of Scheme, both of them implemented in Java: JScheme and SISC.

In this "postscript", I want to do two things.  The first is to give an overview of the previous five posts in the sequence.  In particular, I want to call attention to the fact that they progressed from talking briefly about my preferences, to discussing a few of the differences between JScheme and SISC in much more detail.  And when I did the latter, I was no longer motivated primarily by a wish to explain my preferences: instead, my goal was to use these differences as examples of much more general points.

After doing that summarizing, I then want to return to the subject of preferences, or rather, of how one would choose between JScheme and SISC.  I want to refer, albeit briefly, to a rather larger number of differences between the two implementations: larger, that is, than the small number covered in the previous posts in the sequence.  This is in order to give a bit more practical help to someone whose interest is in making that choice; and also to make sure that I don't leave you with the mistaken impression that that small set of differences between JScheme and SISC (the ones that I discussed at length as examples of "tradeoffs in language design") is anywhere close to being all the important differences that there are.

The first of these five preceding posts, titled A Better Scheme, announced that, after working with JScheme for several months, I had decided that I preferred SISC ... enough to convert a project in mid-development from using JScheme to using SISC.

That post didn't say very much about why I prefer SISC, making just one general point on that subject, and one more specific one.  The general point was that SISC is "a complete implementation of R5RS, the most recent generally-accepted standard for the language", while JScheme claims only to be a "'nearly complete' implementation of R4RS, the previous version of the standard".  The more specific point was that in JScheme, the "... numeric types are the Java numeric types"; and that in some cases, JScheme gives you wrong answers to simple arithmetic questions.

The next four posts were titled as a series: "Comparing JScheme and SISC: Tradeoffs in Programming Language Design (part 1)" through "... (part 4)", the last of these being the most recent post prior to this one.  These were, in a sense, a continuation of "A Better Scheme", but their focus was different.  They weren't primarily about choosing between JScheme and SISC (even though they certainly presented information that might be relevant to that).  While it's a stretch, one could say that their point of view was that of a language implementor, rather than that of a [potential] user of a language implementation.

That statement would indeed be a stretch, because I wasn't writing for language implementors.  I was writing for Scheme programmers .... especially those who have reason to want access to Java code from their Scheme code ... which is to say, potential users of JScheme [and/]or SISC.  However, I wanted to give these readers a bit of appreciation for the language implementor's perspective.  In particular, I wanted to give some examples of how implementation choices may (in fact, pretty inevitably do) involve tradeoffs, in the sense that a single implementation decision may have consequences that users are apt to like ... and other consequences that many users will not like ... where there's no way to separate them, to have the "good" consequences without the "bad" ones.

It took me four long posts to deal with just two of these examples.  Each of these two examples was at least partly about how you invoke Java code from your Scheme code, in JScheme or in SISC.  There's no question of "following the Scheme standard" here, because the Scheme standard says nothing about how to do this.  Thus the implementors of JScheme and of SISC each designed their own extensions to the language for this purpose, and I was comparing those two designs.

The first example was entirely about how you do Scheme access to Java: it directly compared the syntax and semantics of how you do this in each.  This was the primary subject of the first two posts in the series.  I noted that JScheme's way of doing this, the "JavaDot notation", makes for more succinct code than does SISC's way of doing the equivalent.  On the other hand, one may (or may not) regard the JavaDot notation as a major departure from the simplicity and consistency of the Scheme syntax, and object to it accordingly.  So that's a tradeoff, at least if you do interpret the JavaDot "syntax" in that way, and do regard Scheme's simplicity of syntax as important.

The second example of a tradeoff took up the third and fourth posts in the series.  These returned to the subject of numeric data types (and limited themselves, just in order to narrow the topic, to integer data types in particular).  The underlying difference here is the fact that JScheme labels each integer value as belonging to one of the several built-in Java integer types, while to SISC (and to the R5RS standard), an integer is just an integer ... from the user's point of view, at least.

Each of the built-in Java integer data types has a fixed size in the computer memory, and, therefore, a fixed range of values that can be represented.  In Java itself, and in JScheme, this entails that some arithmetic calculations (namely, those whose true result is outside the range of representable values) produce answers that, mathematically, are simply incorrect.  This doesn't happen in SISC; I think that this can be counted as an advantage of SISC over JScheme.1

On the other hand, the same decision, to let the JScheme integer data types be the Java integer data types, also allows for greater simplicity (again, as compared with SISC) in how one calls Java from JScheme.  To give the Scheme programmer the ability to call Java (or, to an extent, any other language), a Scheme implementation must match up the arguments supplied by the Scheme code with the parameters required by the available Java methods.  In JScheme, since each integer argument is already tagged as one of the specific Java types, this matching process is straightforward.

The same matching process in SISC, which doesn't have such a one-to-one correspondence of types, could lead to ambiguities as to which Java method is to be called.  To prevent such ambiguities, SISC requires (and, so far as I can see, must require) that the Scheme programmer explicitly do a data type conversion before passing a Scheme value to a Java method.  Since that's [a little bit of] extra code to write, it counts as an advantage that JScheme has over SISC.

So we have a second example of an advantage and a disadvantage, flowing from one and the same design decision: a tradeoff.  Such tradeoffs are one reason why language design (or even the "implementation" of an existing language, because in real life, that still entails design decisions) is more difficult than it may look (to some).  This is a valuable thing to be aware of, partly because one may then notice that the same is true of the design of programs in general ... at least, in those cases where it makes sense to judge a program by more than just whether it meets the explicitly stated requirements.

I have used selected differences between JScheme and SISC as a vehicle for making some very general points about programming.  If I just left it at that, though, I might give some readers the mistaken impression that the differences I have mentioned thus far are the only differences between JScheme and SISC.  So, before leaving the topic of "Comparing JScheme and SISC", I want to dispel that impression.

There are many more differences between these two Scheme implementations.  Most of these differences (at least, if you can judge by the documentation) consist of features that SISC has, and JScheme doesn't.

Some of those features are specified by the R5RS standard, so that their absence in JScheme is a special case of the general statement that SISC is a more complete implementation of that standard.  One important feature in this category is the ability to create "syntactic extensions" of Scheme in Scheme, also known as "macros".  JScheme doesn't support these, whereas SISC does.

But a greater number of the features that SISC has, and JScheme doesn't have, aren't in R5RS: they are useful extensions to standard Scheme.  The SISC user manual describes too many of these to list here.  Here are three that may be regarded as important in various quarters:

  • An exception handling facility.

  • An object system: a way to define classes in Scheme code.

  • What could be called a "plug-in" architecture: a defined way to write Java code that implements new Scheme procedures.

SISC, in short, comes with a lot more stuff than JScheme does.  It's probably this, more so than the few specific differences that I examined in preceding posts, that primarily leads me to the conclusion that you almost have to prefer SISC over JScheme.  That is, it's hard for me to see how you could conclude otherwise, if you wish to use one implementation for all your Scheme programming needs, and you need to write a number of practical (and possibly large) programs.

The conclusion is strengthened if you add one more thing to your list of desiderata: if you prefer to use facilities already defined in Scheme, as opposed to explicit calls to Java code, where possible.  That's because you can pretty much do anything in JScheme that you can do in Java, but as compared to SISC, it's more often the case in JScheme that making explicit calls to Java is the only way to accomplish a task.

It's entirely appropriate, then, that JScheme's biggest claim to fame be that it provides easy access to Java.  A JScheme programmer depends more on explicit access to Java than a SISC programmer does, in order to get work done.  JScheme, as compared with SISC, seems more like a scripting language for Java.  SISC seems more like a Scheme implementation which "happens" to be written in Java ... though that fact about it means that you also can explicitly access Java from SISC, when you wish.  (And really, it isn't much more difficult.)

As a postscript to the postscript which is this post, I will add that, judging by my own experience, one of the greatest advantages of JScheme, in practice, may be something not mentioned so far.  That would be the fact that, to one category of potential users, JScheme has less of a learning curve, at the beginning.  I am referring to programmers who want or need to learn and use Scheme, but who are just beginning to do so.  Presuming that he or she also will be needing to make use of Java libraries, such a programmer, in learning to use either JScheme or SISC, is learning how to access Java from Scheme, and learning the Scheme language in general, at the same time.

This is something that one would prefer not to have to do, unless one were even more of a glutton for punishment than I am.  In such circumstances, when one hasn't yet reached a comfort level in "standard" Scheme programming, one is especially likely to look for the simplest possible way of accomplishing some additional task, such as invoking Java from Scheme.  And to such a Scheme newbie, that's what the JavaDot notation looks like: this person cares less about whether it may dilute the pristine simplicity of the Scheme syntax, and more about the fact that you have a one-screen "cheat sheet" which tells you how to do what you need to do.2

And that's where I pretty much was, when I first had to choose which Java-based Scheme to use: I'd been wanting to program in Scheme for years, and felt I understood the concepts pretty well; but I knew that there's a big difference between that and having some significant practice under your belt.  You could call it the difference between "knowing about" and "know-how".

So I chose to use JScheme for my first substantial Scheme project.  The project turned out to be a good bit more substantial than it seemed at first (don't they all?), and so it came to pass that, well before it was done, my perspective had changed.  Now I was comfortable with the basics of Scheme.  As a result, learning to use a modestly more complicated interface to Java was not nearly as scary as it had been a few months earlier.  In fact, the cost of doing that was now less, in my eyes, than the cost of finishing the project without access to the additional features offered by SISC.

Remembering this sequence of events helps to keep me from thinking that the original decision to start with JScheme was a "mistake". It was the right thing to do at the time, and perhaps not just in the sense that it appeared to be right, from my perspective at the time.  I might well recommend that someone else follow the same path -- that is, start with JScheme, with an awareness that one may switch to SISC fairly soon -- if that person were starting out in similar circumstances, with similar goals.



1This fact also returns to one of the topics of "A Better Scheme" (namely wrong arithmetic answers), and explains how and why these occur.

2Another reason why SISC looks scary, to a Scheme newbie, is the fact that the previously-mentioned SISC user manual is entitled "SISC for Seasoned Schemers".

Categorie(s) for this post: Scheme.



4:35:32 PM    comment []



Click here to visit the Radio UserLand website. © Copyright 2008 Tom Edelson.
Last update: 5/6/08; 4:12:12 PM.
April 2008
Sun Mon Tue Wed Thu Fri Sat
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30      
Mar   May