Harbour (programming language)

Harbour is a computer programming language, primarily used to create database/business programs. It is a modernized, open sourced and cross-platform version of the older Clipper system, which in turn developed from the dBase database market of the 1980s and 1990s.
Harbour code using the same databases can be compiled under a wide variety of platforms, including Microsoft Windows, Linux, Unix variants, several BSD descendants, Mac OS X, MINIX 3, Windows CE, Pocket PC, Symbian, iOS, Android, QNX, VxWorks, OS/2 (including eComStation and ArcaOS), BeOS/Haiku, 
AIX and MS-DOS.
History.
The idea of a free software Clipper compiler had been floating around for a long time and the subject has often cropped up in discussion on comp.lang.clipper. Antonio Linares founded the Harbour project and the implementation was started in March 1999. The name "Harbour" was proposed by Linares, it is a play on a Clipper as a type of ship. Harbour is a synonym for port (where ships dock), and Harbour is a port of the Clipper language.
In 2009 Harbour was substantially redesigned, mainly by Viktor Szakáts and Przemyslaw Czerpak.
Database support.
Harbour extends the Clipper Replaceable Database Drivers (RDD) approach. It offers multiple RDDs such as DBF, DBFNTX, DBFCDX, DBFDBT and DBFFPT. In Harbour multiple RDDs can be used in a single application, and new logical RDDs can be defined by combining other RDDs. The RDD architecture allows for inheritance, so that a given RDD may extend the functionality of other existing RDD(s). Third-party RDDs, like RDDSQL, RDDSIX, RMDBFCDX, Advantage Database Server, and Mediator exemplify some of the RDD architecture features. DBFNTX implementation has almost same functionality of DBFCDX and RDDSIX. NETIO and LetoDB provide remote access over TCP protocol.
Harbour also offers ODBC support by means of an OOP syntax, and ADO support by means of OLE. MySQL, PostgreSQL, SQLite, Firebird, Oracle are examples of databases which Harbour can connect.
xBase technologies often is confused with a RDBMS software. Although this is true, xBase is more than a simple database system as the same time xBase languages using purely DBF can not provide full concept of a real RDBMS.
Programming philosophy.
Unlike Java which is intended to be write once, run anywhere, Harbour aims to be write once, compile anywhere. As the same compiler is available for all of the above operating systems, there is no need for recoding to produce identical products for different platforms, except when operating system dependent features are used. Cross-compiling is supported with MinGW.
Under Microsoft Windows, Harbour is more stable but less well-documented than Clipper, but has multi-platform capability and is more transparent, customizable and can run from a USB flash drive.
Under Linux and Windows Mobile, Clipper source code can be compiled with Harbour with very little adaptation. Most software originally written to run on Xbase++, FlagShip, FoxPro, xHarbour and others dialects can be compiled with Harbor with some adaptation. As 2010 many efforts have been made to turn the transition from other xBase dialects easier.
Harbour can use the following C compilers, among others:
GCC,
MinGW,
Clang,
ICC,
Microsoft Visual C++ (6.0+),
Borland C++,
Watcom C,
Pelles C and
Sun Studio.
Harbour can make use of multiple Graphic Terminal emulations, including console drivers, and Hybrid Console/GUIs, such as GTWvt, and GTWvg.
Harbour supports external GUIs, free (e.g. HBQt, HWGui, MiniGUI (latest version based on Qt and QtContribs) and commercial (e.g. FiveWin, Xailer). HBQt is a library providing bindings to Qt. HBIDE application is a sample of HBQt potential.
Harbour is 100% Clipper-compatible and supports many language syntax extensions including greatly extended run-time libraries such as OLE, Blat, OpenSSL, FreeImage, GD, hbtip, hbtpathy, PCRE, hbmzip (zlib), hbbz2 (bzip2), cURL, Cairo, its own implementation of CA-Tools, updated NanFor libraries and many others. Harbour has an active development community and extensive third party support.
Any xBase language provides a very productive way to build business and data intensive applications. Harbour is not an exception.
Macro Operator (runtime compiler).
One of the most powerful features of xBase languages is the Macro Operator '&'. Harbour's implementation of the Macro Operator allows for runtime compilation of any valid Harbour expression. Such a compiled expression may be used as a VALUE, i.e. the right side of an assignment (rvalue), but such a compiled expression may be used to resolve the left side (lvalue) of an assignment, i.e. private, or public variables, or a database field.
Additionally, the Macro Operator may compile and execute function calls, complete assignments, or even list of arguments, and the result of the macro may be used to resolve any of the above contexts in the compiled application. In other words, any Harbour application may be extended and modified at runtime to compile and execute additional code on-demand.
The latest Macro compiler can compile any valid Harbour code including code to pre-process before compile.
Syntax:
The text value of the expression '...' will be compiled, and the value resulting from the execution of the compiled code is the result.
 &SomeId
is the short form for &( SomeId ).
 &SomeId.postfix
is the short form of &( SomeId + "postfix" ).
Object oriented programming.
Programming in an OOP style is a broader issue than a specific library or a specific interface, but OOP programming is something many Clipper programmers have come to expect. CA-Clipper 5.2 and especially 5.3 added a number of base classes, and a matching OOP syntax. Libraries such as Class(y), Fivewin, Clip4Win, and TopClass provide additional OOP functionality.
Harbour has OOP extensions with full support for classes including inheritance, based on Class(y) syntax. OOP syntax in Harbour is very similar to that of earlier Clipper class libraries so it should be possible to maintain legacy Clipper code with minimal changes.
Syntax and semantics.
Harbour as every xBase language is case insensitive and can optionally accept keywords written just by their first four characters.
Built-in data types.
Harbour has six scalar types : Nil, String, Date, Logical, Numeric, Pointer, and four complex types: Array, Object, CodeBlock, and Hash. A scalar holds a single value, such as a string, numeric, or reference to any other type. Arrays are ordered lists of scalars or complex types, indexed by number, starting at 1. Hashes, or associative arrays, are unordered collections of any type values indexed by their associated key, which may be of any scalar or complex type.
Literal (static) representation of scalar types:
Complex Types may also be represent as literal values:
Hashes may use "any" type including other Hashes as the "Key" for any element. Hashes and Arrays may contain "any" type as the "Value" of any member, including nesting arrays, and Hashes.
Codeblocks may have references to Variables of the Procedure/Function>method in which it was defined. Such Codeblocks may be returned as a value, or by means of an argument passed , in such case the Codeblock will "outlive" the routine in which it was defined, and any variables it references, will be a variable.
Detached variables will maintain their value for as long as a Codeblock referencing them still exists. Such values will be shared with any other Codeblock which may have access to those same variables. If the Codeblock did not outlive its containing routine, and will be evaluated within the lifetime of the routine in which it is defined, changes to its "Detached Variables"(s) by means of its evaluation, will be reflected back at its parent routine.
Codeblocks can be evaluated any number of times, by means of the function.
Variables.
All types can be assigned to named variables. Named variable identifiers are 1 to 63 ASCII characters long, start with codice_1 and further consist of the characters codice_2 up to a maximum of 63 characters. Named variables are not case sensitive.
Variables have one of the following scopes:
 and are resolved at compile time, and thus are much faster than and variables which are dynamic entities accessed by means of a runtime Symbol table. For this same reason, and variables are exposed to the Macro compiler, and any macro code which attempts to reference them will generate a runtime error.
Due to the dynamic nature of and variables, they can be created and destroyed at runtime, can be accessed and modified by means of runtime macros, and can be accessed and modified by Codeblocks created on the fly.
Control structures.
The basic control structures include all of the standard dBase, and Clipper control structures as well as additional ones inspired by the C or Java programming languages:
Loops.
 [DO] WHILE "ConditionExp"
 [LOOP]
 [EXIT]
 END[DO]
 FOR "Var" := "InitExp" TO "EndExp" [STEP "StepExp"]
 [LOOP]
 [EXIT]
 NEXT
 FOR EACH "Var" IN "CollectionExp"
 ["Var":__enumIndex()]
 [LOOP]
 [EXIT]
 NEXT
In the "FOR" statement, the "assignment" expression is evaluated prior to the first loop iteration. The "TO" expression is evaluated and compared against the value of the control variable, prior to each iteration, and the loop is terminated if it evaluates to a numeric value greater than the numeric value of the control variable. The optional "STEP" expression is evaluated after each iteration, prior to deciding whether to perform the next iteration.
In "FOR EACH", the "Var" variable will have the value (scalar, or complex) of the respective element in the collection value. The collection expression, may be an Array (of any type or combinations of types), an Hash Table, or an Object type.
IF statements.
 IF "CondExp"
 [ELSEIF] "CondExp"
 [ELSE]
 END[IF]
"..." represents 0 or more "statement(s)".
The condition expression(s) has to evaluate to a "LOGICAL" value.
SWITCH statements.
Harbour supports a SWITCH construct inspired by the C implementation of switch().
 SWITCH "SwitchExp"
 CASE "LiteralExp"
 [EXIT]
 [CASE "LiteralExp"]
 [EXIT]
 [OTHERWISE]
 END[SWITCH]
BEGIN SEQUENCE statements.
 BEGIN SEQUENCE
 [BREAK]
 [Break( ["Exp"] )]
 RECOVER [USING "Var"]
 END[SEQUENCE]
or:
 BEGIN SEQUENCE
 [BREAK]
 [Break()]
 END[SEQUENCE]
The BEGIN SEQUENCE structure allows for a well behaved abortion of any sequence, even when crossing nested procedures/functions. This means that a called procedure/function, may issue a BREAK statement, or a Break() expression, to force unfolding of any nested procedure/functions, all the way back to the first outer BEGIN SEQUENCE structure, either after its respective END statement, or a RECOVER clause if present. The Break statement may optionally pass any type of expression, which may be accepted by the RECOVER statement to allow further recovery handing.
Additionally the Harbour "Error Object" supports "canDefault", "canRetry" and "canSubstitute" properties, which allows error handlers to perform some preparations, and then request a "Retry Operation", a "Resume", or return a Value to replace the expression triggering the error condition.
Alternatively TRY [CATCH] [FINALLY] statements are available on "xhb" library working like the SEQUENCE construct.
Procedures/Functions.
 [STATIC] PROCEDURE "SomeProcedureName"
 [STATIC] PROCEDURE "SomeProcedureName"()
 [STATIC] PROCEDURE "SomeProcedureName"( "Param1" [, "ParamsN"] )
 INIT PROCEDURE "SomeProcedureName"
 EXIT PROCEDURE "SomeProcedureName"
 [STATIC] FUNCTION "SomeProcedureName"
 [STATIC] FUNCTION "SomeProcedureName"()
 [STATIC] FUNCTION "SomeProcedureName"( "Param1" [, "ParamsN"] )
Procedures/Functions in Harbour can be specified with the keywords codice_3, or codice_4. Naming rules are same as those for "Variables" (up to 63 characters non-case sensitive). Both Procedures and Functions may be qualified by the scope qualifier "STATIC" to restrict their usage to the scope of the module where defined.
The "INIT" or "EXIT" optional qualifiers, will flag the procedure to be automatically invoked just before calling the application startup procedure, or just after quitting the application, respectively. Parameters passed to a procedure/function appear in the subroutine as local variables, and may accept any type, including references.
Changes to argument variables are not reflected in respective variables passed by the calling procedure/function/method unless explicitly passed BY REFERENCE using the "@" prefix.
PROCEDURE have no return value, and if used in an Expression context will produce a "NIL" value.
FUNCTION may return any type by means of the RETURN statement, anywhere in the body of its definition.
An example procedure definition and a function call follows:
 x := Cube( 2 )
 FUNCTION Cube( n )
 RETURN n ** 3
Sample code.
The typical "hello world" program would be:
 ? "Hello, world!"
Or:
 QOut( "Hello, world!" )
Or:
 Alert( "Hello, world!" )
Or, enclosed in an explicit procedure:
 PROCEDURE Main()
 ? "Hello, world!"
 RETURN
OOP examples.
Main procedure:
 #include "hbclass.ch"
 PROCEDURE Main()
 LOCAL oPerson
 CLS
 oPerson := Person():New( "Dave" )
 oPerson:Eyes := "Invalid"
 oPerson:Eyes := "Blue"
 Alert( oPerson:Describe() )
 RETURN
Class definition:
 CREATE CLASS Person
 VAR Name INIT ""
 METHOD New( cName )
 METHOD Describe()
 ACCESS Eyes INLINE ::pvtEyes
 ASSIGN Eyes( x ) INLINE iif( HB_ISSTRING( x ) .AND. x $ "Blue,Brown,Green", ::pvtEyes := x, Alert( "Invalid value" ) )
 PROTECTED:
 VAR pvtEyes
 ENDCLASS
 // Sample of normal Method definition
 METHOD New( cName ) CLASS Person
 ::Name := cName
 RETURN Self
 METHOD Describe() CLASS Person
 LOCAL cDescription
 IF Empty( ::Name )
 cDescription := "I have no name yet."
 ELSE
 cDescription := "My name is: " + ::Name + ";"
 ENDIF
 IF ! Empty( ::Eyes )
 cDescription += "my eyes' color is: " + ::Eyes
 ENDIF
 RETURN cDescription
Tools.
All tools are multiplatform.
Development.
Today Harbour development is led by Viktor Szakáts in collaboration with Przemysław Czerpak who also contributes many components of the core language and supplementary components. HBIDE and some other components especially HBQt, are developed by Pritpal Bedi. Other members of the development community send changes to the GitHub source repository.
As of 2015 Harbour development is active and vibrant.
xHarbour comparison.
xHarbour is a fork of the earlier Harbour project. xHarbour takes a more aggressive approach to implementing new features in the language, while Harbour is more conservative in its approach, aiming first of all for an exact replication of Clipper behaviour and then implementing new features and extensions as a secondary consideration. It should also be noted that Harbour is supported on a wide variety of operating systems while xHarbour only really supports MS Windows and Linux 32-bit.
The Harbour developers have attempted to document all hidden behaviour in the Clipper language and test Harbour-compiled code alongside the same code compiled with Clipper to maintain compatibility.
The Harbour developers explicitly reject extensions to the language where those extensions would break Clipper compatibility. These rejections were softened recently since the new Harbour architecture allows extensions out of the core compiler.
A detailed comparison between extensions implemented in Harbour and xHarbour can be found in the source repository of the project on GitHub.