From: invalid@invalid.invalid   
      
   John Ames writes:   
   > Richard Kettlewell wrote:   
   >   
   >> I don’t get on well with Java either, but I think the last two   
   >> examples are written in an unnecessarily obscure fashion. I think you   
   >> would normally write the following:   
   >>   
   >> Integer a = 2, b = 3;   
   >> Integer c = Integer.max(a, b);   
   >>   
   >> ...which is certainly a trifle verbose, but not actively misleading.   
   >   
   > I could've been clearer, I s'pose, but it was my point that there are,   
   > for a random subset of math functions, multiple ways to write the same   
   > thing, using classes with no direct relationship - java.lang.Math isn't   
   > a subclass of java.lang.Number and its subclasses, nor the other way   
   > around, nor is there some kind of Math interface that they both   
   > implement. (In fact, these methods aren't even part of Number - they   
   > only belong to its subclasses individually!)   
   >   
   > Why, then, do they duplicate functionality? Why some methods and not   
   > others? Why are the methods for specific Number types static instead of   
   > specific to the object, so that one could at least have Math.round(num)   
   > for arbitrary number variables, but Double.round() for reflexive   
   > rounding of a specific Double object?   
   >   
   > It's just arbitrary and weird.   
      
   It’s not like Java has a monopoly on being arbitrary and weird!   
      
    int fputs(const char *s, FILE *stream);   
    int fprintf(FILE *stream, const char *format, ...);   
      
   Whether the stream argument is first or last depends which function   
   you’re using.   
      
   Another:   
      
    int putc(int c, FILE *stream);   
    int fputc(int c, FILE *stream);   
      
   Two interfaces with the same name, except putc is allowed to be a macro   
   and evaluate ‘stream’ more than one. In practice it usually isn’t for   
   reasons related to threading and if you do want an optimized version the   
   language has supported inline functions for the last quarter century[1],   
   but we still have this weirdness in the standardized API due to the   
   limitations of 1970s compiler capabilities.   
      
   Another:   
      
   printf is equivalent to fprintf but with stream=stdout. But puts is   
   _not_ equivalent to fputs but with stream=stdout, it adds an extra   
   newline.   
      
   Another:   
      
   Inside a function, static means an object has static storage duration   
   (and this seems etymologically justifiable); outside a function it means   
   it has internal linkage, which feels like they just need a keyword and   
   picked one that didn’t yet have a meaning in that slot. (Subsequent   
   additional meanings of ‘static’ continue the pattern...)   
      
      
   I’d suggest that any language that doesn’t start out with odd corners   
   like this will grow them over time as it responds to new thinking, new   
   requirements, etc.   
      
      
   [1] makes me wonder when explicitly-marked inline functions were   
    invented. Maybe a question for the C++ timeline thread.   
      
   --   
   https://www.greenend.org.uk/rjk/   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|