To recap, the previous
post began a comparison of how Java methods are called in Java,
JScheme, and SISC, and gave an example, using the after
method of the
java.util.Date class, of "equivalent" calls in each.
In Java:
boolean later = date2.after(date1);
In JScheme:
(define later (.after date2 date1))
In SISC:
(define later
(->boolean ((generic-java-method 'after) date2 date1)))
There are two differences between the JScheme and SISC versions.
One is SISC's call to the ->boolean primitive: there
is nothing explicit in the JScheme version that corresponds to
this. Let's talk briefly about that first, to get it out of the
way, for now ... planning to come back, in a subsequent post, to the
issues around it.
If you remove that altogether, the SISC version becomes
(define later ((generic-java-method 'after) date2 date1))
and that is, by itself, a valid call to the after
method. I added the call to ->boolean because
you need it in order to make the SISC version truly equivalent to
the JScheme version: given a Java method that returns a boolean,
calling that method from JScheme gives you a Scheme boolean, which can
be used "as is" in, for example, a Scheme "if "
construct. In SISC, on the other hand, a Java boolean is not the
same thing as a Scheme boolean: you have to convert the former to the
latter, by calling ->boolean , in order to use the
result as you'd expect to be able to use a boolean value in Scheme.
With that gone, the remaining difference is that the JScheme version
has this:
.after
where the SISC version has this:
(generic-java-method 'after)
We know what the SISC version means: apply a procedure,
generic-java-method , to the literal
symbol after . We also know that this will return a
"generic Java method", which is a special type of procedure; when that
procedure is, in turn, applied to the arguments date2
and date1 , the specific Java method to be called will be
determined from the types of those arguments.
Now how are we to understand the simple ".after " that
JScheme uses to equivalent effect? We might, by analogy, think
that in JScheme, the period just before "after " does what
the application of generic-java-method does in SISC: that
". " in JScheme, when it appears just before a symbol, is
a function, or operator, or something, which is applied to a symbol
and returns a "generic Java method". But, from a Scheme
programmer's point of view, that would be dreadfully ugly.
Scheme doesn't have "operators", and in order to write an expression
that denotes the application of any procedure, macro, or built-in
syntactic form, you have to enclose that expression in parentheses.
In other words, it would be a minor deviation from Scheme syntax if
the JScheme version of
(generic-java-method 'after)
were to be
(. 'after)
It would be a violation because the R5RS Scheme standard doesn't allow
a symbol name to begin with a period: in my opinion, a relatively
small matter. But allowing the JScheme programmer to denote the
same thing by just
.after
(while still regarding it as the application of some sort of
procedure) ... that's a much more major deviation from Scheme
syntax. For a while, I did interpret JScheme's "Java Dot
notation" that way, and during that time, I did, indeed, consider it
to mar the elegance of the Scheme language.
I have one data point suggesting that at least one other Scheme
programmer has had this type of negative reaction to the "Java Dot
notation". That data point is to be found at
http://lambda-the-ultimate.org/node/936.
That's a forum post on
the Lambda the
Ultimate site, titled "Yearning for a practical scheme".
I want to direct your attention, more specifically, to the reply
headed
"Some
thoughts", by
user bitwize
. He or she writes (in part):
SISC is fully R5RS compliant, supports the full numeric tower,
tail-call optimisation, all of that beautiful stuff. It has an
*extensive* support for bringing Java objects and methods into the
Scheme world and though it's somewhat more cumbersome to use than
cute little hacks like JScheme's JavaDot, too much (syntactic) sugar
is bad for you.
I am interpreting what is said here about "JavaDot" as expressing a
complaint similar to the one I outlined above. (If this
misconstrues what was meant, my apologies
to bitwize .) And by the way, "too much (syntactic)
sugar is bad for you" is a great quote.
However, is it actually applicable here? Should we be
regarding the "Java Dot notation" as syntactic sugar, JScheme's
".after " as an abbreviated notation for, but
semantically equivalent to, SISC's
(generic-java-method 'after)
... ? It might seem that the answer has to be "yes", since in
the present example, they produce the same effect (modulo the bit
about how JScheme's
(.after date2 date1)
returns an actual Scheme boolean, while SISC's
((generic-java-method 'after) date2 date1)
returns something which still has to be converted into one).
But wait. There's another way to understand "Java Dot" locutions
like .after . We can regard ".after "
as just a plain old symbol name, and posit that JScheme has, in
effect, predefined a whole bunch of symbols ... all the ones
whose names have one of the forms specified in
the Java
Dot Notation documentation ... as referring to [what SISC
would call] "generic Java methods", field accessors, and the like.
Before you call the men in the little white coats to haul me off to
the looney bin, let me hasten to assure you that I don't believe that
JScheme actually works this way. It couldn't; it would have to
predefine an infinite number of symbols. But this seems to me to
be an alternate, more acceptable metaphor for how JScheme
works. We shouldn't take it literally, but we can understand
JScheme as working "as if" this had been done. It's "more
acceptable" in the sense that if we read the code this way, then the
notation does not violate the standard Scheme syntax in any really
gross way. (Again, it does violate it, in that the standard says
that a symbol name can't begin with a period; but I hope you'll agree
that that is a smaller, less repulsive sort of violation.)
And I will further claim that, in the light of a couple of details
about how JScheme works, this metaphor also provides us with a more
accurate conceptual (though not literal) model of those workings than
the one which regards the dot as a funny sort of procedure name.
The first of those details is: in JScheme, you can write something like
(define my-after .after)
and subsequently, my-after will [also] do
what .after did before.
The second detail, which I find considerably more convincing than the
first, is that in JScheme you can also write, say,
(set! .after
(lambda (arg1 arg2)
(list arg2 arg1)))
and thereafter, .after will, indeed, function
consistently with this new definition of it; more generally, you
can redefine any of these symbols that has a name in "Java
Dot" format. This makes perfect sense if you conceptualize these
character sequences as [names of] predefined symbols, and no sense if
you conceptualize them as expressions in which the dot, by itself, is
some sort of off-syntax procedure name. And I understand the
latter way of looking at them to be the one which treats the "Java Dot
notation" as "syntactic sugar".
Once I adopted this "predefined symbols" model, I stopped regarding
the "Java Dot notation" as repulsive or unclean ... despite the fact
that I probably do fit the stereotype of Scheme enthusiasts as
"purists" about keeping the simplicity of the language
inviolate. Predefining a whole bunch of symbols ... even an
infinite number of them ... doesn't violate the simplicity of the
language; it just means that you have a lot of libraries readily
available. Which, come to think of it, could be considered to be
the point of having Java-based implementations of Scheme.
One could certainly regard all this as being of small moment,
especially since I do, nevertheless, prefer SISC to JScheme (for most
purposes). But it seemed to me worthwhile to be clear about
which (alleged) reasons for doing so I find valid, and which I don't.
Categorie(s) for this post:
Scheme.
9:04:38 PM
|