entirely new world of Clipper Programming Insights. It may sound like C
programming insights or Pascal programming insights...
How many of you use Clipper ?
How many of you have had a chance to use Clipper 5.0 ?
How many have been mildly "shocked" by 5.0 ?
How many of you have previously developed in C or Pascal ?
How many of you have previously developed in Actor or SmallTalk ?
How many of you are getting tired of raising your hands ?
How many of you want think its fun and want to spend the entire 90
minutes doing it ?
Look toward the past...
C, BASIC, Pascal, Ada, COBOL, Forth, Fortran, SmallTalk.
Clipper didn't develop in a vacuum it may have it's roots in dBASE
but dBASE didn't develop in a vacuum either.
Information is all around us...
Books on Clipper, dBASE and C, OOPs, Actor, compilers, assembler
Non-language specific books on the language fundamentals
Object-oriented Software Construction by Bertrand Meyer
1988 Prentice-Hall International (ISBN 0-13-629049-3)
Object-Oriented Programming Featuring Actor by Marty Franz
1990 Scott, Foresman and Company (ISBN 0-673-38641-4)
Compiler Design in C by Allen I. Holub
1990 Prentice-Hall, Inc. (ISBN 0-13-155045-4)
The C Programming Language by Brian W. Kernighan and Dennis Ritchie
1978, 1988 Prentice-Hall, Inc. (ISBN 0-13-1103262-8)
The Elements of Programming Style by Kernighan and Plauger
1974 McGraw-Hill Book Company (ISBN 07-034199-0)
Good algorithms remain good algorithms regardless of the language in
which they were originally expressed, regardless of the date when they
were originally conceived and regardless of the original planet their
authors' lived on.
They aren't always written in Clipper.
They are often written in C, BASIC or Pascal.
They are not that difficult to convert.
From The Elements of Programming Style
First published in 1974 and references to material written in 1965.
Write clearly - don't sacrifice clarity for "efficiency"
Replace repetitive expressions by calls to a common function
Parenthesize to avoid ambiguity
Don't compare floating point numbers solely for equality
In The C Programming Language a simple example of C code is used to
illustrate C syntax and program structure. The code, reprinted here
outputs a simple table of Fahrenheit temperatures and their centigrade
or Celsius equivalents.
< C code >
< Clipper 5.0 code >
< compile and link >
A simple example using Pascal...
Mastering Turbo Pascal 4.0, Second Edition by Tom Swan
1988 Hayden Books (ISBN 0-672-48421-8)
The following code to perform a binary sort is given as an example of
how to write in Turbo Pascal.
< Pascal code >
< Clipper 5.0 code >
< compile and link >
A terrific example using Z-80 Assembler...
Z80 Assembly Language Programming by Lance A. Leventhal
1979 Osborne/McGraw-Hill (ISBN 0-931988-21-7)
< Assembler code >
< Clipper 5.0 code >
< compile and link >
The IsBitOn() function was written and uploaded to NANFORUM by
Ted Means, the author of (among other things) DBFtrieve a Btrieve
library for Clipper S'87 and 5.0, in response to another member's
request for a way to test individual bits.
Don't judge a book by it's subject matter...
Mr. Leventhal, discusses the stages of software development
o Problem definition
o Program design
o Maintenance and redesign
Do these things sound familiar? It almost seems that designing
applications in Z80 assembler in 1979 is similar to designing
applications in Clipper in 1990.
Among the many things I learned was how a seven-segment LED operates
and programmed the routine accordingly.
If it's insights you want...
Program in "computerese" not in Clipper. Learn to control a computer
by "using" the language and avoid just "learning the language". It
may only be a subtle difference but try looking at this way:
1) I want to be able to clear the screen, position the cursor,
prompt for input and output some text
2) I want to be able to use the CLEAR SCREEN command and the
@ SAY / GET and READ commands
Clipper 5.0 introduces significant enhancements
1) I have more ways to do what I want
2) heck there are more things to remember now
Keep the goal in mind
What do I want to do not how am I going to do it
"pick a command, find a use for it" methodology.
A technique I use in my Introduction to Programming with Clipper course
comprises a series of very simple tasks typically starting with the
Clipper equivalent of the ever popular C "Hello World" program.
@ 1, 0 say "Hello World"
? "Hello World"
Keep an eye toward to future...
Which brings us to the object-oriented programming (OOP) paradigm.
Nantucket development has expressed their committment to developing
future products based upon the principals of an object-orientated
language. Continuing my "nothing new under the sun" line of thought
it turns out that OOPs isn't "new" either.
Simula, developed in Norway in the 1960s is considered to be the first
object-oriented programming language. Smalltalk, another OOP language
developed at Xerox's Palo Alto Research Center (PARC) followed. Through
the years interest grew as newer versions were developed but until only
recently micro computers lacked the needed power to support Smalltalk
implementations. Machines built around Intel's 80386 and 80486 chips
and Motorola's 68040 CPUs, coupled with vast amounts of main memory and
large, fast disk drives have opened up micro-computing OOPs style.
The way that I see it...
A synopsis of the OOP paradigm and my views on it's importance were
published in the Feb '90 issue of Reference(Clipper).
The original code samples provided were all written in Summer '87
An Object-Oriented Approach to the Clipper Language
by Thomas Leylan
What I'm going to show you is not OOPs. I do like to receive mail
but I don't want to receive too many letters from Smalltalk, Actor,
and Eiffel programmers reminding me that Clipper is not an OOPs
language. I realize that.
What it is...
What I WILL demonstrate is an "object-oriented" thought process.
Object-oriented programming is much more than simply the buzzword
for the 90's... ("database servers" IS the buzzword by the way).
OOPs, some background...
Software development styles aren't static.
spaghetti code, "structured", modular "goto-less" programming
interaction of the structured modules with one another
isolated operating system, CPU and hardware specific routines
Four principals traditionally define an OOPs language.
Encapsulation, Polymorphism, Inheritance, Dynamic binding
The idea that code and data are intimately wrapped together and
that access to a particular chunk of data, (an object's data)
should be restricted to that object's methods. Methods being
what you or I would call functions and procedures.
non-encapsulation CLEAR ALL
Greek "polymorphos", having, assuming or occurring in various
forms, characters or styles.
It is the idea that you can send the same "message" to different
classes of objects and that each will be interpreted correctly.
They won't do exactly the same thing but each object will "open",
"close" and "show" in a way that makes sense to that particular
The ability to define new classes of objects from existing classes.
Decendent classes can add new traits and modify existing traits.
"Square", "Rectangles", "Polygons", "Shapes"
"Menu" is a specialty "Box"
Binding is the process of matching methods and their data.
In Clipper and C the binding usually takes place at compile time
but in Clipper we can alternately force late binding through the
use of macros. OOPs languages carry late binding to the extreme
and call it dynamic binding.
25 line by 80 column assumption is "bound" into the application
at compile time.
Binding can be delayed. Checks the video mode at start of app.
It still precludes the setting of the video mode while "in" our
application. The latest possible binding would involve checking
the display mode each time that the screen or menu was displayed.
Objects ? ... we don't need no stinkin' objects...
A software object is much like any physical object in that it has
attributes (data). Software objects also have methods (code).
The code and data together form an object.
Objects are classified into types, the types are called "classes".
A class can be defined for characters, for strings and for numbers,
checks, receipts and account numbers, shapes or boxes.
Boxes are particularly good for describing OOPs-like concepts because
they are about as concrete as things get in computer software and they
have attributes that we can easily identify.
Yeah, but what can they do...
An object's class defines what methods it has available to it. Boxes
for instance can be drawn, saved, restored, moved and sized. Most
objects can be asked for information about themselves. From a box
object we could inquire about it's position, size, color, frame and
Okay, but how can I talk to a box...
The operations which affect objects are called "messages".
Nothing wrong with either approach and I could change my mind but
for now I'll stick with plan "A".
Purists will point out that, with the exception of the "new" message
I shouldn't have to preface my messages with the object type. I
should, for example, be able to simply request that an object "show"
itself without having to say BoxShow.
Great, what should I say to a box...
Creating a living and breathing object is called "instantiating".
When a particular box is instantiated, a "help box" for example,
the attributes for that particular box are assigned.
Boxes as we know have properties of height and width, position (as
defined by row and column coordinates on the screen), color, frames
and in my definition they have shadows. It is important to note
that my boxes are two dimensional. They have no planar coordinate,
i.e. they have no depth. If they had a sense of depth I'd probably
call them windows.
So teach me Box Talk...
Some methods are common to all object classes.
BoxNew() Instantiates an object of class "Box"
BoxKill() Destroys a previously instantiated object
BoxTop() Returns the current top row value
BoxLeft() Returns the current left column value
BoxLength() Returns the current length value
BoxWidth() Returns the current width value
BoxColor() Returns the current color string
BoxShadow() Returns the current shadow value
BoxFrame() Returns the current frame string
BoxTitle() Returns the current title string
BoxBottom() Returns the current bottom row value
BoxRight() Returns the current right column value
BoxSet() Updates the specified attribute
BoxShow() Displays the specified box
BoxUnshow() Un-displays the specified box
BoxDrag() Allows re-positioning of the box
BoxResize() Allows re-sizing of the box
BoxPaint() Updates the screen image of itself
BoxSave() Saves the position, size and a screen image
BoxClear() Clears the interior of a box object
BoxSay() Places string text within the box
BoxaSay() Places array text within the box
BoxGet() Gets input from within the box
BoxPick() Creates a picklist of items within a box and
permits the selection of one of those items
A Quick Once Through...
/* set environment */
local xCursor, xScoreboard
xCursor := set( _SET_CURSOR, SC_NONE)
xScoreboard := set( _SCOREBOARD, .F.)
Before a box can be referenced it must be instantiated with BoxNew.
A box representing the workspace should be created.
bhScrn := BoxNew( 0, 0, 24, 80, "B/B,,,,", 0, " ", "")
The drag and resize messages require a domain to operate within
and the workspace box object must be passed as a parameter.
Notice that there is no shadow on the workspace box.
One sample box scenario :
bhScrn := BoxNew( 0, 0, 24, 80, "B/B,,,,", 0, " ", "")
bhDemo := BoxNew( 0, 0, 9, 36, "+W/BG,+GR/W,,,+W/BG", 2, "ÚÄ¿³ÙÄÀ³ ",;
" The Title ")
BoxSay(bhDemo, 1, 1, "Some text in the box")
BoxSay(bhDemo, 1, 1, "More text in the box")
/* reset environment */
set( _SET_CURSOR, xCursor)
set( _SCOREBOARD, xScoreboard)
Some things about my stuff...
Play with the boxes as they exist but not finished.
There are many sub-classes of "Box" that I have yet to implement
including a number of "specialized" boxes. Among these are
"MenuBox", "ListBox", "DialogBox" and probably a few others.
Each shares attributes and methods with the plain old box but
each has a well defined set of additional functionality.
Perhaps you've noticed that I made my generic box do double duty
which in the strictest OOPs terms I really shouldn't be doing.
There is the BoxPick() function available to the generic "Box"
class but the array of choices is external to the box. A better
solution would have been the invention of a "MenuBox" sub-class
which incorporated the menu array as an additional attribute.
You will definitely notice that I have not provided a BoxGet()
function. Obviously I could have plopped a GET and READ in a
function and sort of would have done it but I'm determined to
have all the "parts" of my box work cohesively and a problem
surfaces when you allow re-sizing of a box with active gets.
I really do plan to solve these problems but my life_object is
preciously short of the "time" attribute at the moment. However
as those of you who know me can attest, I firmly believe that if
one can find the time to make excuses one can find the time to
accomplish the task... so that said I'll set about to "objectify"
more of my usual tools and suggest that you consider doing the same.
For now, read through the documentation and coding samples provided
on the disk and forward any questions you might have to me in care
Why it's important...
Clipper 5.0 incorporates new features.
Code blocks which are traditionally found only in OOPs languages.
Static and local scoping of variables.
Contained on the conference diskettes are both the code and some
reasonable documentation for the box class routines.
12 more things before you go...
I wouldn't want anyone to leave before I've given you something to
argue about amongst yourselves over dinner, so let me present:
Tom Leylan's One Dozen Instant Insights
On the macroscopic scale :
o Pseudocode first, Clipper code second
o Don't settle for less than perfect (or at least not much less)
o Avoid causing side-effects with your code
o Avoid using Clipper side-effects
o Create small, reuseable, self-contained functionalia
On the microscopic scale :
o Declare the scope of all variables
o Use manifest constants
o Use double equal (==) for equality tests,
colon equal (:=) for assignment
o Always save and restore environmental "states"
Use the SETCOLOR() function instead of the SET COLOR TO command
Use the SET() function instead of command for all SET
o Use the SAVESCREEN() and RESTSCREEN() functions not the SAVE
SCREEN and RESTORE SCREEN commands
o Don't use DO WHILE or FOR... NEXT for timing or delay loops