












                            
                                                     
                                                                 
                                                                 
                                ////////    //    //    //   
                               //    //    ///   //    //    
                              //    //    ////  //    //     
                             ////////    // // //    //      
                            //          //  ////    //       
                           //          //   ///    //          
                          //          //    //    ///////    
                                                                 
                                                                 
                                                             
                                                            
                                                            
                                  Pascal NewsLetter         
                                       Issue #1              
                                      May, 1990             
                                                            
                                                            
                                  Editor: Pete Davis         
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                            
                                                                
                    The Programmer's Forum BBS is the home of
                    PNL. It can be reached in Washington, DC at
                    (202)966-3647. Information is available 
                    through the following locations:        
                                                            
                    FidoNet: Pete Davis@1:109/138           
                    GEnie: PDAVIS5                          
                    BitNet: HJ647C@GWUVM & UE356C@GWUVM     
                                                                
                                                            














                                                            
                                                            
                                                            
                                Table Of Contents           
                                                            
                                                            
                                                            
          Introduction .......................... Page 3  (Pete Davis)
          Generic Structures in Turbo Pascal .... Page 5  (Pete Davis)
          Turbo Pascal Program Optimization ..... Page 10 (Pete Davis)
          Conclusion ............................ Page 16 (Pete Davis)






















                                               
          Turbo Pascal is a Registered Tradmark of Borland
          International.
































                                  Introduction



               Well, welcome to the  premier issue of the Pascal  News

          Letter. Since this is  the first issue, it's  important that

          the purpose of  the newsletter be  stated. I run a  bulletin

          board in Washington, and I often come across newsletters and

          magazine. I  have yet  to  find any  geared towards  Pascal,

          though.  (Save  for a  few  which  aren't really  worthy  of

          mention.)  Because  I  use  Pascal  quite  often,  I  became

          frustrated that there  wasn't a free source  of information.

          Sure, I could  go out and buy some magazines that are Pascal

          oriented, but  when there  are newsletters  like CNews,  and

          MicroCornucopia  about,  why should  I  have to  bother with

          that? There should be a Pascal oriented one. Well, now there

          is.  

               My  main purpose  with the newsletter  is to  provide a

          good place for the solutions to common problems. Many people

          have  questions regarding pascal and have  a lot of problems

          getting those questions  answered. There are  also a lot  of

          people  with  fantastic  concepts and  ideas  waiting  to be

          passed around, but  no means to  pass it around. There  will

          now be a  way. Because this is the first issue, all articles

          are written by  myself, this is also  why it might be  a bit

          skimpy. Hopefully this will improve  with further issues. It

          is my  hope that people with interesting  ideas and concepts

          will  pass them  along  to me,  preferably  with an  article


                                                                     3














          attached.

               Most of the  articles are geared towards  Turbo Pascal.

          This is not meant as a  limitation, however. Turbo Pascal is

          about as  standard as  the IBM  compatible pascal  compilers

          get. Many of the ideas will be portable to other versions of

          pascal, if possible.

               Like many of  you, I'm sure,  I'm a busy person.  Doing

          this newsletter will  take a significant amount  of my time,

          but from  this, I would like  to explain my articles  a bit.

          Complete pieces of  code are  not always provided.  Instead,

          partial pieces of code  and algorithms will make up  a large

          part of my articles. (I am only  speaking for myself and not

          others, who in  the future may  provide full pieces of  code

          for the newsletter.) My  purpose is to get the  concepts and

          ideas across and  let you, the  reader, implement them in  a

          way that suits you.

               I am  very fond of  feedback, and  would love to  get a

          message  now and  then  about what  you, the  reader, thinks

          about PNL,  and what you would like to see in future issues.

          Please feel  free to  send your  feedback, suggestions,  and

          articles,  especially,  to any  of  the above  addresses. As

          editor,  you  may  expect several  topical  changes  to your

          articles, but nothing major.

                                              Pete Davis

                                              Editor




                                                                     4














                       Generic Structures in Turbo Pascal

            

               I have to  thank my  current professor, Raymond  Thomas

          for the ideas and concepts covered in this article. Although

          I had thought only  a bit about the generic  structures, his

          class forced me too look at them more closely. 

               The  structure  provided  in our  class  was  a generic

          linked list, but  the idea can  be carried out into  several

          other implementations. The  idea is to  have a unit of  code

          that  can  be re-used  for  different  types  of  data.  For

          example,  one  could  write  a   unit  that  performs  stack

          operations of POP and PUSH, but have it be able to work with

          integers, strings, real  numbers, or  even records. This  is

          very useful if you  want to write units and  distribute them

          in the public  domain or  as shareware, and  have people  be

          able to use them for themselves. Such procedures as  generic

          linked  lists, stacks,  queues,  B-Trees, sorting  routines,

          etc...

               There are several  features of  Turbo Pascal that  make

          this possible. Among them is the untyped pointer, the SizeOf

          function, the Move, GetMem, and  FreeMem procedures, and the

          untyped parameter. 

               The heart of any  generic structure is going to  be the

          source   of  information   about  the   structure  and   the

          information holder. In  our example, it  is going to be  the

          head of the stack:


                                                                     5

















          type
            StackPtr = ^StackItem;
            StackItem = record
              NextItem : StackPtr;
              DataItem : pointer;
            end;

            HeadPtr = ^Header;
            Header = record
              Size  : word;
              Top   : StackPtr;
            end;


               Now for a bit of  an explanation of our stack. For  the

          most part,  it follows  the standard  structure of  a linked

          list implementation  of a  stack. The  main differences  one

          notices are the Size (in the Header record) and DataItem (in

          the StackItem record).  Size is the  size of the data  items

          being  placed in  the stack.  This is  where  Turbo Pascal's

          SizeOf function comes  in handy. To  show how this works,  I

          will present the StackInit procedure.



          procedure InitStack(var H_Ptr : Header; ItemSize : word);

          begin
            New(H_Ptr);
            H_Ptr^.Size := ItemSize;
            H_Ptr^.Top  := nil;
          end;


               A typical call to the InitStack procedure would be like

          this:

          InitStack(H, SizeOf(MyData));




                                                                     6














               Now, let's examine the  StackItem record. The  DataItem

          field provides only a generic pointer. Here is where the big

          difference between the  Generic Data Structure and  the Pre-

          Defined Data Structure  shows itself. Because DataItem  is a

          Generic pointer, it has  no size associated with it.  One is

          unable  to  use  the  New and  Dispose  procedures  for  the

          individual  data items  in the stack.  Instead, the  New and

          Dispose procedures are used to handle the StackItem records,

          while  the GetMem and FreeMem procedures  are used to handle

          the data  in those StackItem records. Here  is a sample of a

          Push procedure:


          procedure Push(H_Ptr : Header; var Data);

          { Notice that Data is an un-typed variable }

          var
            ANode : StackPtr;  { Our temporary node }

          begin
            { Allocate memory for the node itself. }
            New(ANode);  

            { Allocate space for the user's data and set a 
              pointer to it in ANode.                      }
            GetMem(ANode^.DataItem, H_Ptr^.Size);

            { Since it's a stack, and it's the newest item,
              have it point to the previous top of the stack }
            ANode^.NextItem := H_Ptr^.Top;

            { and have the new top point to our new node }
            H_Ptr^.Top      := ANode;

            { Now physically move the data from it's current
              unprotected space, and into the space acquired for it.}
            Move(Data, ANode^.NextItem^, H_Ptr^.Size);
          end;




                                                                     7














               Ok, so now we have our Push procedure. The comments are

          a little  thick, but  they can be  removed to  make it  look

          nicer.  I don't  really think  I need  to go  into  too much

          discussion of the operations in the  Push procedure, for the

          most part they are pretty straight  forward. I would like to

          caution about  the use of  the Move procedure,  however. You

          need  to know exactly where you  are moving your data to and

          from. It  might take a little  work to get  exactly what you

          want. 

               Now,  what  good  is a  stack  that  you  can only  put

          information into, and not get any back? Not much, so here is

          the Pop procedure:



          procedure Pop(H_Ptr : Header; var Data);

          { It would be nice to have the Pop procedure be a function 
            returning the value, but we can't return an untyped  
          value                                                   }

          var
            ANode : StackPtr;   { Our temporary node }

          begin
            { First, make sure we're working with a
              non-empty stack!                      }
            if not StackEmpty(H_Ptr) then
              begin
              
                { Set ANode to the top of the list }
                ANode := H_Ptr^.Top;

                { Have the Top now point to the second item
                 in the list                                  }
                H_Ptr^.Top := ANode^.NextItem;

                { Move the contents of the data to the user's
                  variable.                                   }
                Move(ANode^.DataItem^, Data, H_Ptr^.Size);


                                                                     8














                { Return our data's memory and our node
                  itself to the heap.                         }
                FreeMem(ANode^.DataItem, H_Ptr^.Size);
                Dispose(ANode);
              end
            else
              ... Error routine goes here ...
          end;
            

               Well, that just about covers  the basics of our generic

          data structure. I  left out some  of the routines, but  they

          should be  pretty easy to  add. For example,  the EmptyStack

          function would return a boolean value of true  if H_Ptr^.Top

          was nil. So, I'll  leave the rest of it to you.  There are a

          multitude  of  possibilities  and  uses   for  generic  data

          structures.  It's just  one more  way to make  your routines

          'user friendly'.




























                                                                     9














                        Turbo Pascal Program Optimization



               This   article  will   cover  a   portion  of   program

          optimization in Turbo Pascal.  I say it  covers a portion of

          optimization  only  because  optimization  is  such  a  vast

          subject that it would be impossible to cover completely in a

          single  article. I  also gear it  towards Turbo  Pascal, but

          most  of  the tips  here  will  apply to  almost  all pascal

          compilers.



          WHERE TO OPTIMIZE:



               The  most  important step  in  optimizing a  program is

          deciding where to  optimize. A good programmer  is compelled

          to  optimize  as he/she  writes  the  code. This  is  a good

          programming  practice,  which  once  you  know most  of  the

          important optimizations secrets, is easy to implement as you

          code. A big  problem occurs when  you try to optimize  after

          writing the  code. The reason this is a problem is one tends

          to try to  optimize every  bit of code.  This is  incredibly

          time  consuming   and   usually   results   in   only   mild

          improvements. Knowing where to optimize, however, can save a

          lot of time in coding and a lot of time in execution. 

               There are a lot of  places where optimization will make

          huge improvements in code speed. Learning to recognize where

          your program is  spending it's  time is easy  once you  know


                                                                    10














          what to look  for. First of  all, loops! Loops should  stick

          out like  a sore  thumb when  optimizing a  program. A  user

          recently  came into  work  with a  program  that he  thought

          wasn't working. He  complained that  he had let  it run  for

          fifteen minutes and  still didn't get his  results. Although

          his program was  only about 20 lines of code,  it would take

          at least 2 hours to run. Why? He had 4  loops. Each loop was

          inside another loop.  That adds up pretty  quickly. Each one

          looped 100 times. Now, let's figure  out how many loops that

          is: 100 * 100 * 100 * 100 = 100,000,000 loops total. To make

          things worse, he  had some pretty heavy  calculations inside

          the inner loop.  Ok, so  loops are definitely  one place  to

          look for optimization.

               Don't just look at loops, though, look at what's inside

          a loop. Sometimes redundant data is placed inside loops that

          can  be taken out of the loop. Declaring a variable inside a

          loop that is always the same: 

          example ->

          for x:=1 to 80 do
            begin
              y:=1
              gotoxy(x,y);
              write('x');
            end;


               Here  we have the  variable y being  declared 80 times,

          while it never  changes. This  can be fixed  by declaring  y

          before  entering into  the  loop.  This  is a  very  obvious

          example, but sometimes it isn't quite so obvious.


                                                                    11














          SPEED vs. SIZE



               Optimization really  covers two areas: Speed  and Size.

          Unfortunately, optimizing for one usually ends up making the

          other  worse.  There  are  some  exceptions,  however,  like

          passing variable  parameters as opposed  to value parameters

          as we'll  cover later.  Speed  is almost  always of  primary

          importance and I will usually emphasize it. 



          VALUE vs. VARIABLE PARAMETERS



               When writing procedures or functions, there  is usually

          a  little  thought about  whether to  use variable  or value

          parameters. The normal train  of thought is that you  pass a

          variable parameter  only if  that value  will change  in the

          procedure or  function. Now lets look at  what actually goes

          on behind the scenes. When a parameter is a value parameter,

          there are  no changes made  to the  actual variable  itself.

          This means  that an exact copy  of the variable  needs to be

          made in memory. With  a character or byte value,  this isn't

          real  significant, but  what if  you're passing an  array of

          1000 integers. That means an exact  copy of 2000 bytes needs

          to be copied in memory. This not only takes time but it also

          takes up quite a bit of memory. If your routine is recursive

          or  occurs  inside a  loop,  you  are looking  at  a serious

          decrease in speed and a huge increase in memory use. One way


                                                                    12














          to  repair  this  is to  pass  variable  parameters whenever

          possible. There are some times when it is impossible to pass

          a  variable parameter.  In these  cases you'll be  forced to

          pass a value parameters. 

               For   those   unfamiliar   with  variable   and   value

          parameters, here are two examples:



          procedure ShowIt1(S : string);

          begin
            write(S);
          end;

          procedure ShowIt2(var S : string);

          begin
            write(S);
          end;

               The first procedure,  ShowIt1, uses a  value parameter.

          This means that an exact copy of the string S has to be made

          in  memory. Since a string can be up to 255 characters, this

          can add up.

               The second procedure uses a variable parameter. Instead

          of passing a complete copy of the variable, a pointer to the

          string S  itself is  passed. Since  this pointer  is only  4

          bytes long, you can make a very significant improvement.



          COMPILER DIRECTIVES



               When  testing a  new program, it  is very  important to

          have  compiler  options, such  as  range checking  and stack


                                                                    13














          checking active. Truth  is, though,  that these options  add

          quite a  bit  of time-consuming  code to  your programs.  Of

          course, it is good  to have them in  when writing the  first

          copy of your program, but when compiling a final version, it

          is a good idea  to disable these options. The  results are a

          significant increase in speed, and a nice cut in the size of

          the final program.



          IF/THEN vs. IF/THEN/ELSE vs. CASE



               The  last point of  optimization that  I will  cover in

          this issue is the decision structures. Here is a short piece

          of code. The variable C is type char:



          1>  ---- IF/THEN ----
          if C = 'A' then writeln('You Win!');
          if C = 'B' then writeln('You Lose!');
          if C = 'C' then writeln('Tie Game!');

          2> ---- IF/THEN/ELSE ----
          if C = 'A' then writeln('You Win!') else
          if C = 'B' then writeln('You Lose!') else
          if C = 'C' then writeln('Tie Game!');

          3> ---- CASE ----
          case C of
            'A' : writeln('You Win!');
            'B' : writeln('You Lose!');
            'C' : writeln('Tie Game);
          end;


          The first example is  the slowest of  the three. It is  also

          the  least  clear  of the  code.  It  is  rarely a  required

          structure, and can usually be  replace by the more efficient


                                                                    14














          IF/THEN/ELSE structure.  When possible,  though, one  should

          use the CASE structure. It is  the best method for something

          like  the  above  coding. It  is  faster  and  requires less

          memory.














































                                                                    15














                                   Conclusion



               Well, like I  said in the  beginning, this is a  little

          skimpy, but it  is the first  issue. I hope  to have a  more

          full second  issue.  If you  have  some good  ideas,  please

          submit them. Since this is the end of the spring semester, I

          will  be  looking  at  quite  a  bit  more  time  as  summer

          approaches.  So,  with my  extra  time and,  hopefully, your

          submissions,  the second and later issues  will be larger. I

          am  also planning on including  complete pieces of code with

          the newsletter itself.

               Please send your submissions to the addresses provided.

          I hope you enjoy this and I look forward to your comments!




























                                                                    16







