Loading ...
Sorry, an error occurred while loading the content.

language issues ( was RE: [hackers-il] [colloq@cs.Technion.AC.IL: Shimon Schocken on Tu esday 05/06/2001] )

Expand Messages
  • Omer Musaev
    ... In some ways, case sensitivity decreases value of self-documentation of programs. It can be very misleading to following function: char *Open( char *foo,
    Message 1 of 1 , Apr 10, 2001
    • 0 Attachment
      > > > a rant on Pascal: how can a language have none of
      > > > case sensitivity
      > > > initialization of const arrays
      > > > no return from functions or procedures (!)
      >
      > I didn't do Pascal for a long time, but:
      >
      > 1) I don't think there is any inherit advantage to case
      > sensitivity over
      > case insensitivity in programming languages. Its more of a
      > matter of taste
      > and common practices.
      > What is very important is the proper use of case in variable
      > names, but this
      > has nothing to do with the language.

      In some ways, case sensitivity decreases value of self-documentation of
      programs. It can be very misleading to following function:

      char *Open( char *foo, long *goo, struct timeval *tv ) ;
      /* almost open(2), which is int open( char*, int ) */

      but this one is even worse:

      int Open( char *fname, int mode ) ;
      /* TOO close to open (2) */

      However, in some cases case sensitivity can help.
      For example consider a following convention:
      we have variables fsize, bsize and ssize, which carry sizes of
      various variable size structures. Constants FSIZE, BSIZE and SSIZE hold
      minimal size of appropriate structures.

      Here, case sensitivity is a win.

      > 2) What do you mean by "no return from functions"? IIRC you
      > call a function
      > and get a returned value, no?

      If I got it right, Muli refers to absence of multiple return points.
      A well known approach in C is to return from function as soon as you
      discover that you can not continue, for example:

      /**
      * read first word from file, convert it to unsigned integer.
      * \return Converted integer value, 0 in case of error
      * \param fname - name of file to read the value from
      */
      #define ERR -1
      #define FSIZE 16
      int read_first_int( char *fname ) {
      char *fmt = "%du" ; /* for fscanf */
      FILE *fd ;
      int val = 0 ;

      if ( !( fd = fopen( fname, "r" ) ) ) {
      return ERR ; /* open failed, return 0 now */
      }
      fclose( fd ) ;
      switch ( fscanf( fd, fmt, &val ) ) {
      case EOF: case 0: return ERR ;
      default: return val ;
      }
      }

      Here we have 2 points of return. Given more requisites for function to
      start doing its job, we can have more of those.

      However, there are 2 techniques for avoiding multiple points of return
      in cases when this approach is not appropriate:

      First is use of conditionals. Abovementioned function can be rewritten in
      following
      way:

      int read_first_int( char *fname ) {
      char *fmt = "%du" ; /* for fscanf */
      FILE *fd ;
      int val = 0 ;

      if ( ( fd = fopen( fname, "r" ) ) ) {
      int fsout ;
      switch ( fscanf( fd, fmt, &fsout ) ) {
      case EOF: case 0: val = ERR ;
      default: val = fsout ;
      }
      fclose( fd ) ;
      }
      else
      val = ERR ; /* open failed, set val to 0 */
      }
      return val ;
      }


      The second is use of goto operator for cheap exception handling:

      #define ERR -1
      #define FSIZE 16
      int read_first_int( char *fname ) {
      char *fmt = "%du" ; /* for fscanf */
      FILE *fd = NULL ;
      int val = 0 ;

      if ( !( fd = fopen( fname, "r" ) ) ) {
      goto out_err ;
      }

      switch ( fscanf( fd, fmt, &val ) ) {
      case EOF: case 0: goto out_err ;
      default: goto out ;
      }
      out_err:
      val = ERR ;
      if ( fd ) fclose( fd ) ;
      out:
      return val ;
      }

      Again, this technique, crude as it is, can be used with some care in cases
      when a programmer must implement constructors for huge structures.

      The point of above snippets is that multiple return points is a nice and
      convenient
      feature. Pascal ( and some other languages, including scheme ) does not have
      it.
      >
      > The worse part about Pascal IMO is that there's no pointer to
      > functions, and
      > no anonymous functions. On the other hand it has nested functions (I
      > think), which I wouldn't mind seeing in more languages.

      Brian Kernighan had written a brilliant critique on Pascal:
      --- Citing BWK ---
      To close, let me summarize the main points in the case against Pascal.

      * Since the size of an array is part of its type, it is not possible
      to write general-purpose routines, that is, to deal with arrays
      of different sizes. In particular, string handling is very difficult.

      * The lack of static variables, initialization and a way to communicate
      non-hierarchically combine to destroy the ``locality'' of a program -
      variables require much more scope than they ought to.

      * The one-pass nature of the language forces procedures and functions to
      be presented in an unnatural order; the enforced separation of various
      declarations scatters program components that logically belong together.

      * The lack of separate compilation impedes the development of large programs

      and makes the use of libraries impossible.

      * The order of logical expression evaluation cannot be controlled, which
      leads
      to convoluted code and extraneous variables.

      * The 'case' statement is emasculated because there is no default clause.

      * The standard I/O is defective. There is no sensible provision for dealing

      with files or program arguments as part of the standard language,
      and no extension mechanism.

      * The language lacks most of the tools needed for assembling large programs,

      most notably file inclusion.

      * There is no escape.

      This last point is perhaps the most important. The language is inadequate
      but
      circumscribed, because there is no way to escape its limitations.
      There are no casts to disable the type-checking when necessary.
      There is no way to replace the defective run-time environment with a
      sensible one, unless one controls the compiler that defines the
      ``standard procedures.''
      The language is closed.

      People who use Pascal for serious programming fall into a fatal trap.

      --- end of citation ---

      You can found this document here:
      http://www.lysator.liu.se/c/bwk-on-pascal.html
    Your message has been successfully submitted and would be delivered to recipients shortly.