private Expression noteOn(List<Expression> args, String caller) {
      
      // check to make sure we got the right number of arguments
      if ( args.size() != 4 ) {
         System.err.println("noteOn expected 4 arguments and got " + args.size() );
         return new Void();
      } 
      
      long msgTime = System.currentTimeMillis() + new Double( args.get(0).show(defSubst, caller) ).longValue();
      int message = ShortMessage.NOTE_ON;
      int channel    = new Integer( args.get(1).show(defSubst, caller) ).intValue();
      int noteNumber = new Integer( args.get(2).show(defSubst, caller) ).intValue();
      int velocity   = new Integer( args.get(3).show(defSubst, caller) ).intValue();

      if ( Interpreter.DEBUG ) {
         System.out.println(msgTime + "," + message + "," + channel + "," + noteNumber + "," + velocity);
      }
      
      // the side effect of this function is what's important
      TimeMessagePair newPair = new TimeMessagePair(msgTime, message, channel, noteNumber, velocity);
      TimeMessagePairs.addPair(newPair);

      // return void
      return new Void();
   }