ARSC HPC Users' Newsletter 349, September 29, 2006

Haiku To Klondike

  Loopmark listings quiet Vector registers grow cold   The truck is coming

by:   Tom Baring,   Erstwhile "Vector Specialist"   (Never a poet)

New works by Miho Aoki and Bill Brody in Special Exhibition

ARSC Faculty Joint Appointment Miho Aoki and retired ARSC staff member Bill Brody both have works on display in:

"POLARities: Aesthetics / Experiments / Observations"

"POLARities" features recent works by a selection of Alaskan artists exploring the connection between science and technology and the artists' inspiration and creative processes. It is on view at the UA Museum of the North from September 16 through October 29, 2006. See:

http://www.uaf.edu/museum/exhibit/special.html

This is presented in conjunction with the October 2006 AAAS Arctic Science Conference in Fairbanks, Alaska. The artists will discuss their work as one session of this conference:

http://www.arcticaaas.org/meetings/sessions.html#session2

Java for Fortran Programmers: Part III

[[ Thanks to Lee Higbie of ARSC for this tutorial. ]]

The topic today is:

  • How Java's OOP syntax differs from that of Fortran and C

Fortraners be wary: Java is case sensitive and statements end with a semicolon. It is much like C, with most basic syntax taken directly from C. The biggest difference between Java and C/C++ syntax is the removal of many of the error-prone constructs such as automatic type conversion, use of non-Boolean data types as Boolean, and easily changing pointer values.

Gee, sounds pretty good so far. Next, the devilish details. Coming from an imperative language background, for me the biggest conceptual hurdle for using an object oriented programming language is that the most important "arguments" to most functions are part of the object, not arguments to the function. Syntactically they precede the function name ("method" name, actually) and don't look at all like arguments. E.g., In Fortran you might say this:


    call draw_rectangle (x1, y1, x2, y2, red, blue)
where the fifth parameter is for the border color and the sixth is for the center color. In Java, this becomes:

    rectangle.draw (red, blue);
where the rectangle "object" has a draw "method" that uses the rectangle's internal variables for its corners. In effect, the rectangle knows where it is and draws itself.

If you want to draw nr rectangles, you might have this in Fortran:


    do i = 1, nr
      call draw_rectangle (x1(i), y1(i), x2(i), y2(i), red, blue)
    enddo           ! end do loop on i drawing rectangles
The Java code would more likely look like:

    for (int i = 0; i < nr; i++) 
    { 
      rectangles[i].draw(red, blue); 
    } // end for loop on i
   
drawing rectangles (A minor safety feature in the above Java sample is that the scope of i is the loop. Java encourages variables to be declared only for the block where they are required, often only inside a single statement.)

Here are eight additional differences between Java and C++ (or Fortran).

  1. Java has no explicit pointers. Object names are pointers but they allow no manipulation. They can be subscripted or arrayed, but Java programmers typically don't even think of them as pointers any more than Fortran programmers think of common-block names as pointers.

  2. Variables can be subscripted with any number of subscripts, but the language is really intended only for singly subscripted Arrays. Each array subscript uses its own brackets and the lower bound is always 0. Subscript references cannot be out of range. If an array subscript is not within the declared or implicit range, an interrupt will be generated. I have found no way to disable this feature.

  3. Except in a few specific situations, there is no automatic type conversion. For example:

    
        int i = 1;
        ...
        if (i) { .....  // Wrong!
    
    This must be written as something like:
    
        if (i==1) { ....
    

    Type conversion, called "casting" in Java as in C, must be explicit in all non-trivial situations. It is denoted by putting the new type in parens:

    
        float f1, f2 = 1;  // Permissible. Java will cast 1 to 1.0
        double d1, d2 = 0; // Permissible. Java will cast 0 to 0.0
        f1 = d1;           // Illegal, precision might be lost
        f2 = (float) d1;   // Okay. Casting tells the compiler it's okay
        d2 = f1;           // Permissible. RHS higher precision than LHS
    
  4. Starting with Java 1.5, also called Java 5, when you declare a collection of some type of data, you should declare the type so the compiler can verify that the operations are legal. In older versions you have to explicitly cast the result to the new type. In Java 5:

    
        Vector <String> vecStrings = new Vector <String> ();
    
    With this declaration, javac, the Java compiler, can verify that any assignment to a vecStrings component is a String. Previous to Java 5, the declaration would lack the angle bracket type declaration and to use one of the elements of the Vector you had to cast the result from an Object to a String:
    
        String str = (String) vecStrings.elementAt(i);
    
    (In this older Java, you could store any type of object into vecStrings and would only discover the error at execution time when the cast failed. A vector is a collection like an array, but it can grow arbitrarily and must be accessed with specific methods like the elementAt method used above; it does not use subscripts.)
  5. There are scores of packages in Java, the standard ones are listed at http://java.sun.com/j2se/1.5.0/docs/api/, but there is no include capability. A class or all the classes in a package can be imported, which means they can be referenced by their simple name. Ugh, that's confusing; some examples should help. Most programs begin with a series of imports:

    
        import java.higbie.*;  // to access any class of the package higbie
        import java.higbie.Debug;  // imports only my Debug class
    
    with either of these statements preceding the class statement, I can use Debug like any other declared name:
    
        Debug deb = new Debug (args);
    
    If the package higbie is not imported, then the declaration would have to be
    
        higbie.Debug deb = new higbie.Debug(args);
    
    and every time I wanted to reference Debug, I would have to use the fully qualified name, higbie.Debug.
  6. Blocks are delineated by braces. For example, whenever more than a single statement is under control of a for or an if statement, the statements must be enclosed in braces. Most commonly you'll see something like:

    
        for (int i = 0; i < max; i++) {
        ...
        }  // end for loop over i
    
    or,
    
        if (condition) {
        ...
        }  // end if condition
    
    Braces are similarly used to delineate the statements of methods and classes. In one of the few bits of context-sensitive syntax in Java, they are also used to initialize arrays. In that special case, because they are part of a single statement, a semicolon is required afterward:
    
        int [ ] iarray = {3, 1, 4, 1, 5, 9, 2, 3};
    
    Here the bracket pair [ ] indicates that an array (subscripted variable) is being declared.
  7. Java has 50 keywords and two other reserved words. For example, goto is a reserved word but is not a part of the language. You cannot use goto as a variable, but goTo is fine.

  8. A method can declare that it generates ("throws," in Java) an exception, and any user of that method must either deal with the exception or pass it up the calling hierarchy where it will have to be vetted.

    For example many I/O methods can throw exceptions for missing files or attempting to access something that doesn't exist. Users of any of these methods must provide code to catch the exception or their code will not compile. If they chose to pass the exception to their caller, then the caller must also vet ("catch," in Java) it. For most of the GUIs that control scientific/engineering applications this is not particularly important. It is important on large team projects, where an unvetted exception could result in a lost customer bank deposit, say.

    One final note on syntax. There are three types of comments in Java.

    1. A double slash introduces a comment that extends to the end of the line. This is one of the few places where an end-of-line character is significant.

    2. A /* starts a comment that ends on the first */ encountered. This means that double slash comments can be nested inside /*

    3. .. */ comments but not other /* ... */ comments. If you commonly remove code from execution by commenting it out, they you should predominantly use // comments.

    4. /** ... */ comments. For the compiler, javac, these are just like the /* ... */ comments. However there is another tool, javadoc, that produces standardized code documentation. All the descriptions on Sun's web page, ...j2se/1.5.0/docs/api/, are produced with javadoc. Like javac, javadoc checks the code as well as the javadoc comments. Thus, at some level, it ensures that documentation is up-to-date. If a /** ... */ comment describes a method and its argument list does not agree with with the method's actual list, a diagnostic will be generated.

--

In this installment, I've covered some of the major differences between the syntax of Java and that of C++ and Fortran. For the next chapter I will present a "Hello Bill" program -- with a button.

Quick-Tip Q & A



A:[[ I'm curious what other people use for their shell prompt setting.  
  [[ (Your prompt is set via the "PS1" environment variable under
  [[ sh/ksh/bash and via the "prompt" variable under csh/tcsh.)



  #
  # Thanks to Jed Brown: 
  #

  I like color prompts.  This one gives me lots of information, but
  doesn't take a huge number of characters.  From my .bashrc

  
 # Some useful escape sequences
  
 bold="\[\033[;1m\]" nbold="\[\033[;0m\]"
  
 normal="\[\033[0m\]"
  
 red="\[\033[31m\]"
  
 green="\[\033[32m\]"
  
 yellow="\[\033[33m\]"
  
 magenta="\[\033[35m\]"
  
 cyan="\[\033[36m\]"
  
 
  
 # shows command number, return value in magenta if nonzero, username in
  
 # yellow, host in red, tty in cyan, path in green
  
 PS1="\#$bold$magenta\$([ \$? -eq 0 ] 

 echo -n \" \$?\")$nbold $yellow\u$red\h$cyan\l $green\w$normal\\$ "

  Slightly off topic, but we can also put useful things in our title bars:

  
 case "$TERM" in
  
 xterm*
rxvt*)
  
     PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007"'
  
     ;;
  
 screen)
  
     # With this escape sequence, screen can put the current command in its title bar.
  
     # Make sure to include in .screenrc the following line
  
     #     shelltitle "$ 
"
  
     if [ $UID -ne 0 ]; then
  
         PROMPT_COMMAND='echo -ne "\033k\033\134"'
  
     fi
  
     ;;
  
 *)
  
     ;;
  
 esac


  #
  # Rich Griswold
  #

  I use ZSH (http://zsh.sourceforge.net/) for my shell, and I have
  two prompts depending on whether I'm using a console or an xterm.
  The second prompt is basically the same as the first, without the
  prompt colorization (which some consoles don't support) and the xterm
  title bar hack.  These prompts work in ZSH 4.0 and later.

  case $XTERM in
    xterm* 
 aixterm 
 dtterm 
 hpterm)
      export PS1=
  $'%{\e]0;%(#.ROOT .)%m:%~\a\e[1;%(#.31.32)m%}%~ %(?.:\).:\() > %{\e[0m%}'
      ;;
    *)
      export PS1="%(#.ROOT .)%m:%~ %(?.:).:() > "
      ;;
  esac

  Explanation: 
    ${            Start escaped string
    \e]0;         Escape to change the xterm title bar
    %(#.ROOT .)   Print the text "ROOT " if running as root
    %m            Print the machine name
    :             A literal
    %~            Print the path, using ~ for the home directory
    \a            Ends the xterm title bar escape
    \e[1;         Escape to change the text color
    %(#.31.32)m   Use red text if running as root and green otherwise
    %}            End the escaped string
    %~            Print the path, using ~ for the home directory
    %(?.:\).:\()  Print :) if the last command was successful and
                  :( if the last command failed (non-zero return code)
     >            A literal
    %{            Start another escaped string
    \e[0m         Reset the text color to the default
    %}            End the escaped string



  #
  # Greg Newby
  #

  Here's a fancy prompt I've used for years for csh variants.  From my
  .cshrc:

  # This works well, but some portable systems change their
  # hostname when using DHCP:
  set hn=`hostname -s`

  # This one won't change:
  set hn='aquila'

  # Set the "$prompt" variable, and make an alias to set the prompt,
  # at the same time:
  alias sp  'set prompt="${hn}(`whoami`) [\\!] `dirs
sed -e '\''s
 .*

'\'' -e '\''s
.*[^/]\(/[^/]*/[^/]*\)
..\1
'\''` } "'

  # This insures that the directory section of the prompt is set
  # whenever I change directories:
  alias cd 'cd \!*;sp'

  # This sets the prompt in my .cshrc
  sp


  So, here's my prompt when I'm in my home directory:

          aquila(newby) [1015] ~ } 

  A little explanation:

  I like to have multiple terminal windows open.  Rather than using
  different colored terminal backgrounds or something similar, I just
  have the prompt show me which system I'm on.  I have the prompt show
  my username, also, in case I have used "su" to become another user.
  Note that I run the "whoami" command before every prompt, so you might
  skip this if you don't ever change usernames.

  In the square brackets is the history number.  In csh, I can use "!1015"
  to rerun command #1015...this is a nice feature when the command you
  want is still on your screen.

  Demystifying the whole prompt:

          ${hn} is the hostname
          `whoami` inserts the username ($USER is often the same)
          \\! inserts the current history number
          dirs lists the current directory
          
sed ... transforms the current directory to just take the 
                  three last parts of the director path, if it's long
          } is just a divider (followed by a space) between the prompt
                  and what you type

  The directory listing is a nice feature, since otherwise you might
  end up with very long directory paths as you navigate a Unix system.
  One of the most common problems that new (and more experienced!) people
  have with Unix/Linux is keeping track of which directory they are in.
  This prompt helps address that challenge.

  Even so, the directory component can sometimes push the active
  part of your prompt far to the right of your screen.

  I also use zsh, which is a shell with many characteristics of
  bash/ksh/tcsh.  Since many systems assume you have a more direct
  descendant of sh or csh, zsh isn't a good choice for ARSC's large
  systems, where some of the general settings for all users won't take
  effect with zsh.

  For the curious, this is the prompt I use with zsh:

          PS1=$'%{\e[1;36m%}%m(%n) %~ [%!] > %{\e[1;0m%}'

  It has a similar output as my csh example above.  The main difference
  is that it also uses ANSI color, so my prompt is cyan (but the commands
  I type are white).  Using different prompt colors on different systems
  might help keep all of those terminal windows separate...





And a bonus answer, to issue 344:
A:[[ I have an existing library written in C/C++ that I would like to
  [[ call from a python script.  Is there a way to call this existing
  [[ code without reimplementing the code in python? 


  # 
  # Thanks to Martin Luthi, who's catching up on old email:  
  # 

  There are many ways of doing this.

  o There is the ctypes module, that allows to directly link into *.dll
    (Windows) or *.so (Unix) libraries (part of Python 2.5., external
    module for older versions)

    
http://starship.python.net/crew/theller/ctypes/


  o SWIG (as already mentioned) 
http://www.swig.org


  o SIP 
http://www.riverbankcomputing.co.uk/sip/


  o Boost Python (for C++ libraries, quite heavyweight)
    
http://www.boost.org/libs/python/doc/


  o weave (great for snippets of C code that get directly embedded in
    Python source code): 
http://wiki.python.org/moin/weave


  Here's a comparison: 
    
http://www.boost.org/libs/python/doc/comparisons.html


  Also take a look at the Python website:
    
http://docs.python.org/ext/ext.html 
Q: I use the Unix system call:

    int getgroups (int gidsetlen, gid_t *gidset)

This stores a list of values of type gid_t into the simple, C-style
array, gidset.  However, I'm using C++, and want to use the vector
container class from the Standard Template Library to operate on
the list.

Generalizing the question, what's the best way to copy a simple array
into an STL vector object?  Is this as good as it gets?

     for (int i = 0; i < numberOfArrayElements; i++) 
     {
         theVector.push_back ( theArray[i] );
     }  

[[ Answers, Questions, and Tips Graciously Accepted ]]


Current Editors:
Ed Kornkven ARSC HPC Specialist ph: 907-450-8669
Kate Hedstrom ARSC Oceanographic Specialist ph: 907-450-8678
Arctic Region Supercomputing Center
University of Alaska Fairbanks
PO Box 756020
Fairbanks AK 99775-6020
E-mail Subscriptions: Archives:
    Back issues of the ASCII e-mail edition of the ARSC T3D/T3E/HPC Users' Newsletter are available by request. Please contact the editors.
Back to Top