Hubbry Logo
Clipper (programming language)Clipper (programming language)Main
Open search
Clipper (programming language)
Community hub
Clipper (programming language)
logo
7 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Clipper (programming language)
Clipper (programming language)
from Wikipedia
Not found
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
Clipper is a procedural, language and belonging to the family, primarily designed for creating database-driven business applications. Originally developed by Nantucket Corporation and released in 1985 as a tool to compile code from the III database management system into fast, standalone executables, it extended dBase's capabilities with improved performance and additional programming constructs. The language originated from Nantucket's efforts to address the demand for a native for , with its first version, Winter '84, shipping on May 25, 1985. Early seasonal releases, such as Summer '85 and Summer '87, quickly gained market share by offering enhanced flexibility, including the ability to link with code and support for larger applications, running on systems with at least 256 KB of . In 1990, 5.0 introduced rudimentary object-oriented features, though it faced criticism for bugs; subsequent patches and versions like 5.2 (1993) and 5.3 (1995) from Computer Associates—following their 1992 acquisition of Nantucket—added refinements such as better database utilities and linker support. Key features of Clipper include a (RTL) for database operations, an interactive fullscreen , and utilities for tasks like report generation, SQL query processing, and file browsing, making it suitable for corporate and screen-based interfaces. Later versions incorporated mouse support, query optimization for efficient data filtration, and compatibility with graphical elements, though it remained oriented toward character-mode DOS environments. While Clipper's development ended with patch 5.3b in 1997, its influence persists through open-source successors like Harbour, which modernize the syntax for contemporary platforms.

Overview

Origins and Relation to dBase

Clipper was developed in 1985 by Nantucket Corporation, a company founded by Barry ReBell and , specifically as a for III, Ashton-Tate's popular database . The idea originated from discussions between ReBell, a , and Russell, an Ashton-Tate employee, who recognized the limitations of III's interpreted execution and the need for a tool to compile its code into more efficient standalone applications. Nantucket's first version, known as Clipper Winter '84, shipped on May 25, 1985, targeting systems and enabling developers to transform scripts into executable programs without runtime dependencies on the interpreter. This compilation capability addressed key shortcomings in dBase III, which relied on interpretive processing that limited performance in demanding business environments, such as and . By generating native code executables, Clipper significantly improved runtime speed and allowed for larger, more robust database-driven applications, making it a vital extension for professional developers working in the xBase ecosystem. Nantucket marketed early versions, including the Summer '87 release in December 1987, as fully compatible dBase III compilers, emphasizing their role in streamlining the creation of deployable business programs. At its core, Clipper implemented a superset of dBase III syntax, preserving the original's database commands and logic while introducing elements that were absent in the base system, such as user-defined functions, arrays, and enhanced control structures. This extension aligned with Nantucket's philosophy of empowering developers with unrestricted tools, allowing seamless migration of dBase code while adding capabilities for modular and efficient application development.

Core Design Principles

Clipper is fundamentally a procedural and imperative programming language, designed to provide high-level abstractions tailored for database-centric applications. It emphasizes through constructs such as user-defined functions, procedures, and control structures like DO WHILE loops, FOR...NEXT iterations, IF...ENDIF conditionals, and DO CASE...ENDCASE cases, enabling developers to build modular, sequential logic without low-level system management. This paradigm prioritizes ease of use for business application development, where database operations form the core , allowing programmers to focus on data manipulation rather than underlying hardware details. A primary design goal of Clipper was to maintain compatibility with syntax and semantics while introducing compilation capabilities to enhance efficiency and portability across DOS platforms. By emulating III PLUS commands and file formats, such as databases and NDX/NTX indexes, Clipper allows seamless migration of existing scripts into compiled executables, but it verifies and optimizes code during compilation to produce standalone .EXE files that run faster than interpreted sessions. This compilation process targets 2.0 or later systems (with 3.1+ for networks), requiring minimal resources like 256K RAM, and supports cross-platform deployment through standardized DOS calls and configurable runtime environments, ensuring applications function consistently without platform-specific adjustments. Central to Clipper's architecture is the use of bundled runtime libraries to create self-contained applications that do not rely on the runtime environment. Libraries such as CLIPPER.LIB for core functions, EXTEND.LIB for advanced database and UI features (e.g., screen handling with @...SAY...GET and printing utilities), and OVERLAY.LIB for enable developers to link all necessary components into a single executable, supporting up to 255 open files and features like error handling via ERRORSYS.PRG. This approach eliminates external dependencies, allows distribution, and facilitates robust, standalone deployment for database-driven tasks. While the core language remains function-based, relying on global variables and a rich set of built-in functions for operations like file locking (FLOCK(), RLOCK()) and data processing (SEEK(), EOF()), Clipper 5.0 introduced rudimentary object-oriented features, including support for classes and methods, while the Extend System enabled integration with and assembly code for modular extensions.

Development and Version History

Nantucket Corporation Era

Nantucket Corporation was founded in 1984 by Barry ReBell and with the goal of creating a for Ashton-Tate's III database , addressing its limitations in speed and functionality for application development. The company's inaugural product, Clipper, debuted as the Winter '84 version on May 25, 1985, functioning as a native code that transformed III scripts into efficient, standalone executables for DOS environments. Early releases adhered to a distinctive seasonal naming scheme, reflecting the company's roots. These included Summer '85, Winter '85 (released January 29, 1986), Autumn '86 (October 31, 1986), and culminated in Summer '87 (December 21, 1987), which introduced version numbering starting at 5.0 and switched to a more efficient C compiler for improved performance. Subsequent updates under , such as 5.01 (April 15, 1991), continued to refine the toolset while maintaining compatibility with standards. Key innovations during this period enhanced Clipper's capabilities beyond basic compilation. The Autumn '86 release added network support and expanded file handling, including files for structured data and DBT files for memo fields, enabling better integration with multi-user environments. 5.0 (1990) introduced local variables for scoped data management within procedures and functions, reducing global pollution, alongside multi-module compilation via dynamic overlays in the RTlink system, allowing larger applications to be built from multiple source files without exceeding memory limits. Nantucket's independent development of concluded in June 1992, when the corporation was acquired by Computer Associates International for approximately $190 million, shifting control and future enhancements to the larger entity.

Computer Associates Acquisition and Evolution

In June 1992, Computer Associates International Inc. acquired Corporation, the original developer of the compiler, to bolster its position in the software market and integrate with its existing database tools like CA-dBFast. The acquisition, valued for 's expertise in database development environments, led to the rebranding of the product as CA- and a shift from 's seasonal naming convention (e.g., Summer '87) to a numbered versioning system starting with CA- 5.01a later that year. Under Computer Associates' ownership, CA-Clipper saw continued evolution with the release of version 5.2 in February 1993, which included refinements to the replaceable database driver (RDD) architecture for better extensibility, followed by bug-fix updates up to 5.2e in February . The pivotal CA-Clipper 5.3 arrived in June , introducing capabilities through class definitions, inheritance, and methods, while maintaining with procedural code; this allowed developers to create more modular applications without a full , as CA-Clipper was not positioned as a purely object-oriented language. Version 5.3 also added native GUI elements such as buttons, list boxes, and check boxes via the , enabling basic graphical interfaces in DOS environments and paving the way for integration with CA-Visual Objects, a Windows-native successor released in that supported ODBC and SQL database connectivity for enterprise applications. Additionally, 5.3 enhanced SQL connectivity through extended RDD support and database engines compatible with SQL servers, facilitating hybrid dBase-SQL workflows. Subsequent maintenance releases included CA-Clipper 5.3a in May 1996 and the final commercial version, 5.3b, in May 1997, which focused on stability and minor optimizations without major new features. Efforts during this era included pilot projects for Windows compatibility, aiming to port DOS-based Clipper applications to 16-bit Windows environments, though these were limited in scope and ultimately transitioned into the full Windows development framework of CA-Visual Objects rather than a direct Clipper upgrade. By the late 1990s, as Computer Associates prioritized enterprise and mainframe software solutions over PC-based tools, CA-Clipper received diminished support, reflecting the company's broader strategic shift toward larger-scale systems management products. This de-emphasis culminated in 2002 when CA sold the Clipper source code to GrafX Software Development Tools, Inc., ending active commercial development.

Language Features

Syntax and Data Types

Clipper's syntax derives from the family, featuring a straightforward, English-like structure that emphasizes readability for database-oriented programming. The language is case-insensitive, meaning commands, functions, and keywords can be written in uppercase, lowercase, or mixed case without affecting execution. Statements and commands typically conclude at the end of a line, with semicolons being optional and rarely used except in specific contexts like multi-line strings in functions such as Alert(). User-defined functions are declared using the FUNCTION keyword followed by the function name and optional parameter list, while procedures—subroutines that do not return values—are defined with the PROCEDURE keyword in a similar manner. For instance, a simple function might begin as FUNCTION AddNumbers(n1, n2) and end with RETURN n1 + n2. Clipper employs dynamic typing, where variables do not require explicit type declarations; their data types are determined at runtime based on assigned values, with implicit conversions occurring as needed—for example, a numeric value assigned to a character variable results in string conversion. The supported data types include Character for strings (enclosed in quotes, padded with spaces to fixed lengths in some contexts), Numeric for integers and floating-point numbers (initialized to zero), Logical for values represented as .T. (true) or .F. (false), Date for calendar dates in the format YYYYMMDD, Memo for long text fields, for collections of elements, Codeblock for fragments, and NIL for uninitialized or null values. These types facilitate flexible data handling, particularly in database applications, though Memo fields are often linked to external files for storage efficiency. Variable scoping in Clipper is managed through explicit declarations to control visibility and prevent naming conflicts. PUBLIC variables are accessible throughout the entire program, including all procedures and functions, and are declared with the PUBLIC statement followed by the variable name and optional initializer, such as PUBLIC nGlobal := 0. PRIVATE variables are visible within the declaring procedure or function and its callers but hide any PUBLIC variables of the same name, declared via PRIVATE in a similar syntax. LOCAL variables are restricted to the scope of the procedure or function where they are declared, making them ideal for temporary computations, as in LOCAL cTemp := "example". Arrays and codeblocks follow the same scoping rules when declared with these keywords. Arrays in Clipper are dynamic or fixed-size collections that can hold mixed data types, declared either as an empty array with aData := {} or a fixed-length one using the Array() function, such as aData := Array(5). Elements are appended dynamically with the AAdd() function; for example:

LOCAL aList := {} AAdd(aList, "Item1") AAdd(aList, 42)

LOCAL aList := {} AAdd(aList, "Item1") AAdd(aList, 42)

This grows the array by one element each time, inserting the specified value (or NIL if omitted) at the end. Codeblocks provide a mechanism for creating anonymous, executable snippets akin to closures, enabling dynamic behavior in loops, callbacks, or evaluations. The syntax encloses parameters after a pipe symbol within curly braces, followed by the expression, as in { |nValue| nValue * 2 }. Codeblocks are evaluated using the () function; a representative example is:

[LOCAL](/page/.local) bDouble := { |n| n * 2 } ? Eval(bDouble, 5) // Outputs: 10

[LOCAL](/page/.local) bDouble := { |n| n * 2 } ? Eval(bDouble, 5) // Outputs: 10

This allows passing custom logic to functions like AEval() for array processing without defining full procedures.

Database and File Management

Clipper's database management revolves around the (dBase File Format), a structure that stores records in fixed-length fields, supporting data types such as character, numeric, date, and logical. This format enables efficient storage and retrieval for applications, with each DBF file containing a header describing field names, types, and lengths, followed by the data records. Clipper applications primarily interact with DBF files through high-level commands that abstract underlying file operations. To open a DBF file, the USE command specifies the file alias and work area, allowing multiple files to be handled simultaneously across up to 250 work areas managed by the SELECT command. For instance, SELECT 1 followed by USE customers NEW opens the "customers.dbf" file in work area 1. Adding records uses APPEND BLANK, which adds an empty record to the end of the file and positions the record pointer there, while REPLACE updates field values in the current record, such as REPLACE name WITH "John Doe". These operations ensure data persistence without direct file manipulation. Indexing enhances query performance by creating separate index files: NDX for single-key indexes in earlier versions and CDX for multiple tags in later ones, compatible with FoxPro. The INDEX ON TO command builds an index file based on a key expression, such as INDEX ON upper(custname) TO custndx, ordering records alphabetically by customer name. Clipper supports up to 99 tags in a compound index file (CDX), with the controlling index set via TO. For relational operations, Clipper employs SET RELATION to link parent and child work areas, automatically skipping to matching records in the child file as the parent moves. For example, after opening orders in work area 1 and details in work area 2, SET RELATION TO orders->orderid INTO details connects them by order ID, enabling master-detail navigation without explicit joins in code. The JOIN command merges two files into a new based on a FOR condition, as in USE customers; USE invoices; JOIN WITH invoices TO purchases FOR custid = customers->custid, creating a Purchases.dbf with combined fields for reporting. This approach simulates relational joins programmatically. File input/output extends beyond DBF to sequential and random access for text (TXT) and printer (PRN) files using low-level functions. FOPEN(, ) opens a file handle for reading (mode 1) or writing (mode 2), followed by FREAD(, @, ) to read data into a buffer or FWRITE for output. For example, to read a TXT file: nHandle := FOPEN("data.txt", 1); cData := space(1024); nRead := FREAD(nHandle, @cData, 1024); FCLOSE(nHandle). The COPY TO [DELIMITED|SDF] command exports DBF data to TXT with customizable delimiters, while PRN support directs output to printers via SET PRINTER TO. Multi-user environments rely on locking mechanisms to prevent data conflicts: FLOCK() attempts a file-level lock, returning true if successful, while LOCK attempts a record lock on the current record. In network setups, operations like APPEND BLANK or REPLACE trigger automatic locks, with UNLOCK releasing them; failure to lock prompts retries or errors. This ensures in shared DBF files. Clipper provides SQL-like querying through DBF functions rather than a full SQL engine, using LOCATE FOR to search records and CONTINUE to find subsequent matches. For example, LOCATE FOR amount > 1000 scans the current index or natural order, positioning the pointer on the first match. More complex filters use SET FILTER TO, applying conditions across work areas. Full SQL support arrived only in later versions via replaceable database drivers (RDDs), but core Clipper emphasizes procedural navigation over declarative queries. Error handling in file operations uses the ERRORBLOCK() function to set a code block that intercepts runtime errors, such as file-not-found (error 1001) or lock failures (error 32). For instance, a handler might check the Error object's arguments: IF oError:genCode() == 32; ALERT("Record locked"); ENDIF, allowing recovery like retrying the operation or closing files with CLOSE ALL. This prevents abrupt termination during I/O failures.

Programming Practices

Basic Constructs and Control Flow

Clipper's basic constructs provide imperative control flow mechanisms derived from its heritage, enabling sequential, conditional, and repetitive execution of statements within procedures or functions. These include conditional branching with IF...ENDIF and DO CASE...ENDCASE, looping via DO WHILE...ENDDO and FOR...NEXT, and subroutine definitions through FUNCTION and PROCEDURE statements. Expressions within these constructs operate on Clipper's core data types, such as logical (.T./.F.), numeric, character, and date values, evaluated from left to right with standard operator precedence. The IF...ENDIF structure handles conditional execution by evaluating a logical condition and executing the associated statements if true (.T.), with optional ELSEIF and ELSE clauses for alternatives. Syntax is: IF ... [ELSEIF ...] [ELSE ...] ENDIF, where control passes to the first true condition or the ELSE block if none match, then proceeds after ENDIF. This construct supports nesting and is semantically equivalent to DO CASE...ENDCASE for simple binary decisions. For multi-way branching, DO CASE...ENDCASE evaluates successive CASE conditions until one is true, executing its statements until the next CASE or ENDCASE; an optional OTHERWISE clause handles unmatched cases. Syntax: DO CASE CASE ... [CASE ...] [OTHERWISE ...] ENDCASE, allowing unlimited cases without performance penalties from nesting multiple IFs. Looping constructs facilitate repetition: DO WHILE...ENDDO executes a block while a condition remains true, checking the condition before each iteration and supporting EXIT to terminate early or LOOP to skip to the next check. Syntax: [DO] WHILE ... [EXIT] [LOOP] ENDDO, commonly used for indefinite iterations like processing until a file ends. FOR...NEXT provides counter-controlled loops, incrementing (or decrementing with STEP) a counter from start to end values. Syntax: FOR := TO [STEP ] ... [EXIT] [LOOP] NEXT, ideal for fixed iterations such as array traversal, with the counter reevaluated each time. A representative example for database record processing is: DO WHILE !EOF()

... SKIP ENDDO, where EOF() checks the end-of-file, SKIP advances one record, and the loop continues until no more records remain. User-defined functions and procedures modularize code, with FUNCTION declaring a return-value subprogram and PROCEDURE a void one. FUNCTION syntax: [STATIC] FUNCTION [()] [LOCAL/STATIC/MEMVAR declarations] RETURN , where parameters are passed by value (or reference with @), locals are scoped to the function, and RETURN mandates a value of any type. Procedures use similar syntax: [STATIC] PROCEDURE [()] [declarations] [RETURN], returning NIL implicitly and invoked via DO or () syntax. Both support , parameter skipping (checked via NIL or PCOUNT()), and static scoping for file-local visibility; parameters are formal locals receiving arguments. For instance, a might compute: FUNCTION Add(nA, nB) RETURN nA + nB, called as Add(3, 4). Error handling employs BEGIN SEQUENCE...END for structured exception management, akin to try-catch, capturing runtime errors or explicit BREAKs. Syntax: BEGIN SEQUENCE ... [BREAK []] [RECOVER [USING ]] ... END SEQUENCE, where an error or BREAK branches to RECOVER (optionally assigning the error object to via USING), allowing recovery code like or retrying with LOOP; unhandled cases proceed to END. This integrates with the global ERRORBLOCK() for custom handlers but provides local control without halting execution. Clipper programs are structured as .prg source files containing these constructs within a main procedure or called subroutines, compiled via CLIPPER.EXE to intermediate .obj files embedding runtime code and library references, then linked (e.g., with BLINKER) into executables; early versions lacked native modules, relying on explicit linking for multi-file projects.

Advanced Programming Techniques

Clipper 5.0 introduced object-oriented programming capabilities, enabling developers to define custom classes using the CLASS and END CLASS constructs, along with METHOD definitions for object behaviors. These classes support instance variables and methods invoked via the message-sending operator :<message>[(<arguments>)], such as myObject:processData(). Inheritance is achieved by specifying a parent class in the class declaration, allowing derived classes to extend or override methods from superclasses, with dynamic polymorphism facilitated through method resolution at runtime. To invoke a superclass method explicitly, developers use the ::Super:<MethodName>() syntax, promoting code reuse and modular design in complex applications. Predefined classes like Error for runtime error handling and Get for input field management exemplify these features, providing built-in methods such as varPut() for data assignment. Libraries and extensions significantly enhance Clipper's functionality for advanced development, with CA-Clipper Tools offering over 800 utility functions for tasks including graphics rendering, report generation, and system-level operations. These libraries are compiled into .lib files and linked during the build process, allowing seamless integration of utilities like window management and data visualization without altering core language syntax. User-defined libraries further extend this by packaging custom functions into reusable modules, often distributed as or commercial add-ons to accelerate development of database-driven applications. Integration with external languages like C enables performance-critical extensions through the EXTERN directive, which declares C functions for linking into Clipper executables via the Extend API. This allows developers to call C routines directly from Clipper code, passing parameters such as strings or numerics, and is particularly useful for low-level operations like custom I/O or algorithmic computations not natively optimized in Clipper. For graphical user interfaces, third-party tools like FiveWin provide class-based wrappers around Windows APIs, predating Computer Associates' full acquisition and enabling event-driven GUI development with controls such as buttons and dialogs. Code blocks support event-driven programming by encapsulating executable code as data, defined with {|| <expression>} and evaluated via functions like EVAL() or passed to database operations for conditional logic. This allows dynamic behavior, such as customizing browse table actions in a TBrowse object where user-supplied code blocks handle data retrieval and display updates. Macros enable metaprogramming through the & operator for text substitution or runtime compilation, as in &<varName> to execute variable-stored commands, facilitating flexible code generation and indirect invocation in procedural scripts.

Market Adoption and Legacy

Commercial Penetration and Decline

Clipper achieved widespread commercial adoption in the 1980s and early 1990s, particularly for building DOS-based database applications in business sectors such as , inventory management, banking, and . Its compiler capabilities allowed developers to create standalone executables from dBase-compatible code, facilitating efficient deployment of small-scale database systems without runtime dependencies. Millions of such applications were developed during this era, underscoring Clipper's role in powering vertical markets like retail and for small and medium-sized enterprises (SMEs). Key market factors driving this penetration included Clipper's affordability and speed of development. By 1990, Nantucket Corporation's 5.0 retailed for $695, making it accessible compared to more expensive enterprise tools of the time. Nantucket reported $35 million annual revenue in 1991, enabling of custom . This low barrier to entry, combined with Clipper's procedural syntax optimized for database operations, positioned it as a preferred choice for SMEs seeking cost-effective solutions over proprietary alternatives. Clipper's decline began in the mid-1990s as the computing landscape shifted toward Microsoft Windows and graphical user interfaces (GUIs), exposing limitations in its DOS-centric design. The language struggled to adapt, with developers increasingly demanding GUI capabilities that Clipper's core architecture did not natively support. Competition intensified from GUI-focused tools like Microsoft's (introduced in 1991) and (evolving to by 1995), which offered seamless Windows integration and faster prototyping for client-server applications. Computer Associates' acquisition of in 1992 exacerbated the downturn over time, as CA shifted focus to CA-Visual Objects—a Windows-oriented successor—but provided inadequate support amid bugs and compatibility challenges. Post-acquisition, CA continued DOS enhancements until 1995 before underinvesting in Visual Objects' marketing and refinement, culminating in its final major release (version 2.5) in 1997. By the early 2000s, Clipper's relevance in new commercial database development had sharply diminished, with programmers migrating to more versatile platforms like and to meet evolving GUI and scalability demands.

Community Revivals and Modern Successors

Following the decline of official commercial support for , third-party developers introduced tools to extend its capabilities into modern environments. Alaska Xbase++, developed by Alaska Software starting in 1997, provides a 32- and 64-bit Windows-compatible platform that maintains full compatibility with Clipper applications while adding support for , , and integration with . This tool enables the modernization of legacy Clipper code without requiring extensive rewrites, targeting enterprise applications that need graphical user interfaces and database connectivity. Similarly, FiveWin, released in 1997 by FiveTech Software, serves as a class library add-on for Clipper, allowing developers to create native Windows GUI applications using familiar syntax and wrapping functions for dialogs, menus, and controls. Open-source initiatives emerged in the late to ensure Clipper's longevity through cross-platform portability and enhancements. The Harbour Project, initiated in 1999, is a free, open-source that achieves 100% compatibility with Clipper while introducing object-oriented features, multi-threading, and support for platforms including , Windows, macOS, and embedded systems. Harbour extends the language with libraries for SQL via ODBC, TCP/IP networking, and modern data formats, making it suitable for database-driven business applications. A of Harbour, xHarbour, originated in the early (around ) to pursue more aggressive development, emphasizing support and additional extensions like enhanced runtime libraries for OLE, , and graphical terminals that blend console and GUI elements. As of 2025, active communities sustain these projects through platforms like , where Harbour and xHarbour maintain repositories with ongoing contributions for bug fixes and minor enhancements, including xHarbour's Release 10287 in January 2025 and Harbour's continued snapshot builds. These efforts focus on legacy maintenance, particularly for Y2K-compliant systems in and banking sectors that rely on Clipper-derived code for and reporting, often opting for incremental migrations to Harbour to avoid full rewrites. For instance, Harbour's version 3.0.0, released in 2021, includes built-in support for and XML parsing, facilitating integration with contemporary web services in embedded and business environments, though no major architectural breakthroughs have occurred between 2020 and 2025, with development emphasizing stability across forks.

References

Add your contribution
Related Hubs
User Avatar
No comments yet.