Wandering through the libraries

Ka-Ping Yee ping@lfw.org
Mon, 12 Oct 1998 00:24:37 -0700 (PDT)


On Sun, 11 Oct 1998, Mark S. Miller wrote:
>     static public String aan(String rec) {
[...]
> What should I do with the "sometimes y"?

It's almost always a consonant at the beginning of a word.  I think
"a" in front of a y is pretty safe.
 
> If you know a better heuristic, I'd live to hear it.

Nice typo.  Don't kill yourself over this issue! :) :)

> I write "an herb", "a
> heuristic", and "a UFO", but this code won't.  Oops, it will say "a UFO"
> since I forgot to be case insensitive!  Is this a bug or a feature?
 
A feature?  :)  Well, the "a" or "an" being returned is always lowercase,
which would make it less likely that the next word is an all-caps
pronounceable word...

But what if you wanted "A" or "An"?

Then again, "a unit", "a uniform", "an underling"... argh!  Forget it!

*sigh*.  I hate English.

> >Is this method really necessary?
> 
> I probably shouldn't have put it into String, but I'm not sure where I
> should put it.  I HATE the annoying messages I get from programs that don't
> get "a" vs "an" right on the simple cases.

I found it quite curious that you put this method in there.  Actually,
i can't remember when (if ever) i last wanted to choose between "a" and
"an"... when i'm printing messages i most often worry about singular or
plural (and that is practically impossible to automate).

I don't have a clear memory of such cases, but i bet a lot of the time
"the" would work as well... tell me, how does this keep coming up for you?

> >Why is "/" named "approxDivide"?  All operations are limited by
> >the precision of the registers anyway... does "/" do something
> >different from the "/" we know, say, in C?
> 
> What's this register stuff??  We is talkin' SEMANTICS!!  On IEEE double
> precision floating point numbers, "/" does indeed do what Java does, and
> what I think C does by default -- double precision IEEE round to nearest.

What i meant was, i don't see why "/" requires a name like "approxDivide"
when "-" is not "approxSubtract", "*" is not "approxMultiply" etc.  Whenever
the result is a floating-point number, we accept the limitations of
floating-point and live with them...

> Given just double precision floating
> point and unlimited precision integers, I cannot provide an accurate
> integer division operation, so what are the alternatives?

Hmm.  So are you saying, in E, 5 / 4 == 5/4.0 == 5.0/4.0 == 1.25, and
5 _/ 4 == 5.0 _/ 4 == 5.0 _/ 4.0 == 1?

I *like* being able to tell the type of the result from the operator
rather than the operands.  I think this was a good move.

> There is no semantics in common between what Java's "/" does on integers
> and what it does on floating point numbers.  My choice: "/" is shorthand
> for "approxDivide", and it means "the IEEE double precision floating point
> number closest (by round to nearest) to the quotient of the two numbers,
> whatever they are".

This is good, and i think it is reasonable and consistent to simply
call this "divide" -- given that, for example, even "-" only gives
you "the IEEE double-precision floating-point number closest to the
difference of the two numbers" (e.g. 1e45 - 1e-45).

> >Is it necessary to introduce the extra method calls "isLTZero"
> >"isGEQZero" etc. with comparisons?  Can't you just expect the
> >compareTo method to return a familiar numeric value that you
> >can test directly?
> 
> Let's say that compareTo always returned -1, 0, 1, or NaN.  What would you
> have "x <= y" expand to?

x compareTo(y) <= 0, i suppose.  But the "<=" here means a
primitive "<=" in the kernel, not a method call.  I mean,
it's got to bottom out somewhere.  What i was trying to say
is that i don't see what the extra indirection buys you since
doubles are a built-in type anyway.  Surely you don't expect
people to override the meanings of "isLTZero" and friends?

> >I think calling atan2, min, max as methods on a double looks
> >pretty weird... min and max in particular are probably best
> >provided with a tuple or an unlimited number of arguments,
> >aren't they?
> 
> Ok, I buy it for min and max.  What's your beef with atan2?  How about cos?

All the one-argument functions like cos and sqrt do make sense
in a reverse-Polish-esque sort of way.  I'm not screaming to
have the "atan2" method removed (or even the "min" or "max" methods
removed for that matter)... i just hope that "x atan2(y)" is not
the *only* way to call atan2, as it will look a little strange to
some people.  Presumably there is some sort of math package
with all kinds of stuff in it, where min, max, maybe even
mean, mode, median, stdev -- whatever -- would go...

Funny, now that i think of it, i suppose if you wanted to say

    x := 1e99
    while (...)
        {
        y := ...
        x := x min(y)
        }

to accumulate a minimum, i suppose in that case "x min= y"
would mean something.  But i don't know if it's worth extending
the (operator)= syntax to (method)= just for that.

This example leads me to ask -- are there readily-available
constants for the positive and negative double-precision
floating-point numbers of greatest and smallest magnitude,
and +/- infinity for big integers?

> >What's the point of the "yourself" method?  (If anything, i
> >would prefer that it be called "self"... i'd like not to personify
> >my objects if i can help it.)
> 
> I love to personify them, especially Alice, Bob, and Carol!  "yourself" is
> used in the implementation of partial-ordering in the network protocol, and
> isn't expected to be otherwise useful.

Okay.  Just curious what it was for.

> I won't call it "self"
> because that is the conventional instance variable name by which an object
> refers to itself.  Even though message names and variable names are in two
> separate namespaces (verbs vs nouns) I like to avoid using the same name
> for two different meanings.

I agree -- this is a sound principle.
 
> >Why would one ever want fileUrl: instead of file:?  Is the syntax
> >and behaviour of URIs in the language documented somewhere yet?
> 
> "fileUrl:x" would evaluate to a java.net.URL object
> http://java.sun.com/products/jdk/1.2/docs/api/java/net/URL.html whereas
> "file:x" would evaluate to a java.io.File object
> http://java.sun.com/products/jdk/1.2/docs/api/java/io/File.html

Are you going to be using the set of allowed characters in URLs
from RFC 1738 to define the syntax for what comes after the ":"?

I wonder if this will be the first time an RFC becomes part of
a programming language syntax definition. :)

> within the curlies, "return" is bound to an Ejector.  What do you think
> about renaming Ejector "EscapeHatch"?

I like that name.  Both names are okay with me, actually, though i
suppose it's easier to guess what "EscapeHatch" is related to since
it contains the word "escape".

> Programmers already have to remember too many
> exceptions to what should have been simple rules.  Let's stick with a
> simple rule for midCaps.

Okay.  Consistency is good.  I am sorry that my weird sense of
aesthetics has me in the habit of avoiding midCaps -- i will just
have to learn to correct that sense of aesthetics when working with E.

> >Is there an easy "x in set" test?  cf. Python
> >
> >    if platform in ['windows', 'winnt', 'win95']:
> >        print "Warning: your computer will probably crash today."
> 
> 	if (["windows", "winnt", "win95"] asSet containsKey(platform)) {

Hmmrrm.  Kind of wordy.  I realized just now -- i suppose you could write

    if ([platform] asSet <= ["windows", "winnt", "win95"]) {

(assuming the second argument gets coerced) though i'm not sure how
apparent the meaning is there.

Isn't there a simple linear-searching "contains" method for sequences?
I think that would be generally useful -- for small sets like this,
it is probably too much effort to hash the keys and convert the thing
to a mapping before doing a lookup.  This:

   if ["windows", "winnt", "win95"] contains(platform) {

is about as good as you can expect it to read, if the element you're
testing comes after the set (and i guess you're not going to be able
to put it in front of the set without special keywords like "in").
 
> >Also, Python permits chaining comparison operators so you
> >can do a quick-n-easy range test:
> >
> >    if 3 < x < y <= 8:
> >        ...
> 
> I do like this.  How do they do it?  What's the BNF?

The productions are:

comparison:     or_expr (comp_operator or_expr)*
comp_operator:  "<"|">"|"=="|">="|"<="|"<>"|"!="|"is" ["not"]|["not"] "in"

The documentation says:

    Comparisons yield integer values: 1 for true, 0 for false. 

    Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent
    to x < y and y <= z, except that y is evaluated only once (but in both
    cases z is not evaluated at all when x < y is found to be false). 

    Formally, if a, b, c, ..., y, z are expressions and opa, opb, ..., opy
    are comparison operators, then a opa b opb c ...y opy z is equivalent
    to a opa b and b opb c and ... y opy z, except that each expression is
    evaluated at most once. 

    Note that a opa b opb c doesn't imply any kind of comparison between
    a and c, so that, e.g., x < y > z is perfectly legal (though perhaps
    not pretty). 

I was going to suggest in an earlier message that you consider the
possibility of "and", "or", "not" operators, because they really are
much easier on the eyes than "&&", "||", "!()" ... but i was afraid
you would be too reluctant to rename the "and" and "or" methods for
implementing & and |.  (Well, actually, there isn't a collision
here because the identifier following "to" is not an expression,
so you could allow both "x < 0 and y < 0" and "...to and(y):...",
but i thought you wouldn't like that context-sensitivity either.
If it were me i would seriously consider doing it that way...)
Anyway, did i guess right?
 
> I will continue to support containsKey, as Java folk expect it.  For
> reasons stated earlier, I hate "haskey", and "hasKey" isn't a big enough
> improvement to introduce it *in addition to* containsKey.  However, if a
> good short single word can be found....?

Well... after all, since it's called a mapping... how about "maps"?

    if mapping maps key {
        value := mapping[key]
        ...
    }

You know... the ellipsis has shown up so many times in my examples
now, and i bet it will occur in print, too, that i wonder if maybe it
isn't better to just stick with the backslash for line-continuation.
It's a familiar beast.  I also saw the ".." operator in your grammar
table somewhere... what about the possibility of mistyping or
confusing ".." with "..."?

> 	Thanks for wonderful questions & suggestions!

Thanks for tolerating all the demands and diversions!


Ping                                            Talk back to the Web!
<ping@lfw.org>                                       http://crit.org/