Harbour (programming language)

Last updated

Harbour Project
Paradigm multi-paradigm: imperative, functional, object-oriented, reflective
Designed by Antonio Linares
Developer Viktor Szakáts and community
First appeared1999;25 years ago (1999)
Stable release
3.0.0 / 17 July 2011;12 years ago (2011-07-17)
Preview release
Typing discipline Optionally duck, dynamic, safe, partially strong
OS Cross-platform
License Open-source GPL-compatible
Filename extensions .prg, .ch, .hb, .hbp
Website harbour.github.io
Dialects
Clipper, Xbase++, FlagShip, FoxPro, xHarbour
Influenced by
dBase, Clipper
Influenced
xHarbour

Harbour is a computer programming language, primarily used to create database/business programs. It is a modernised, open source and cross-platform version of the older Clipper system, which in turn developed from the dBase database market of the 1980s and 1990s.

Contents

Harbour code uses the same databases and 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), [1] 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 the same functionality of DBFCDX and RDDSIX. NETIO and LetoDB [2] 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 to.

xBase technologies often are confused with RDBMS software. Although this is true, xBase is more than a simple database system as at the same time xBase languages using purely DBF can not provide the full concept of a real RDBMS.

Programming philosophy

Harbour aims to be written once, compiled anywhere. As the same compiler is available for all of the above operating systems, there is no need for re-coding 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, allows for more customisation 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 of 2010 many efforts have been made to make 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 Graphical Terminal emulation, including console drivers, and Hybrid Console/GUIs, such as GTWvt, and GTWvg.

Harbour supports external GUI's, free (e.g. HBQt, HWGui, Mini-GUI (latest version based on Qt and QtContribs [3] ) 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 [4] and supports many language syntax extensions including greatly extended run-time libraries such as OLE, Blat, OpenSSL, Free Image, 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 per-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), FieWin, Clip4Win, and Top Class 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 code on HBIDE Harbour Sample Code.png
Harbour code on HBIDE

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 BY REFERENCE, in such case the Codeblock will "outlive" the routine in which it was defined, and any variables it references, will be a DETACHED 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 Eval( BlockExp ) function.

Variables

All types can be assigned to named variables. Named variable identifiers are 1 to 63 ASCII characters long, start with [A-Z|_] and further consist of the characters [A-Z|0–9|_] up to a maximum of 63 characters. Named variables are not case sensitive.

Variables have one of the following scopes:

LOCAL and STATIC are resolved at compile time, and thus are much faster than PRIVATE and PUBLIC variables which are dynamic entities accessed by means of a runtime Symbol table. For this same reason, LOCAL and STATIC variables are not 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 PRIVATE and PUBLIC 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
  • The ... is a sequence of one or more Harbour statements, and square brackets [] denote optional syntax.
  • The Var:__enumIndex() may be optionally used to retrieve the current iteration index (1 based).
  • The LOOP statement restarts the current iteration of the enclosing loop structure, and if the enclosing loop is a FOR or FOR EACH loop, it increases the iterator, moving to the next iteration of the loop.
  • The EXIT statement immediately terminates execution of the enclosing loop structure.
  • The NEXT statement closes the control structure and moves to the next iteration of loop structure.

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), a 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]
  • The LiteralExp must be a compiled time resolvable numeric expression, and may involve operators, as long as such operators involve compile time static value.
  • The EXIT optional statement is the equivalent of the C statement break, and if present, execution of the SWITCH structure will end when the EXIT statement is reached, otherwise it will continue with the first statement below the next CASE statement (fall through).

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 handling.

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 and 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 and functions in Harbour can be specified with the keywords PROCEDURE, or FUNCTION. Naming rules are the 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 has 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      CLSoPerson := 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 multi-platform.

Development

HBIDE look. HBIDE Editor.png
HBIDE look.

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. [5] As of 2015 Harbour development is active and vibrant.

xHarbour comparison

xHarbour is a fork [6] 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. [7]

GUI libraries and tools

See also

Related Research Articles

<span class="mw-page-title-main">Common Lisp</span> Programming language standard

Common Lisp (CL) is a dialect of the Lisp programming language, published in American National Standards Institute (ANSI) standard document ANSI INCITS 226-1994 (S2018). The Common Lisp HyperSpec, a hyperlinked HTML version, has been derived from the ANSI Common Lisp standard.

<span class="mw-page-title-main">Scheme (programming language)</span> Dialect of Lisp

Scheme is a dialect of the Lisp family of programming languages. Scheme was created during the 1970s at the MIT Computer Science and Artificial Intelligence Laboratory and released by its developers, Guy L. Steele and Gerald Jay Sussman, via a series of memos now known as the Lambda Papers. It was the first dialect of Lisp to choose lexical scope and the first to require implementations to perform tail-call optimization, giving stronger support for functional programming and associated techniques such as recursive algorithms. It was also one of the first programming languages to support first-class continuations. It had a significant influence on the effort that led to the development of Common Lisp.

In computing, an optimizing compiler is a compiler that tries to minimize or maximize some attributes of an executable computer program. Common requirements are to minimize a program's execution time, memory footprint, storage size, and power consumption.

In computer programming, the scope of a name binding is the part of a program where the name binding is valid; that is, where the name can be used to refer to the entity. In other parts of the program, the name may refer to a different entity, or to nothing at all. Scope helps prevent name collisions by allowing the same name to refer to different objects – as long as the names have separate scopes. The scope of a name binding is also known as the visibility of an entity, particularly in older or more technical literature—this is in relation to the referenced entity, not the referencing name.

In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function with the value or reference to which the name was bound when the closure was created. Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

In computer programming, a parameter or a formal argument is a special kind of variable used in a subroutine to refer to one of the pieces of data provided as input to the subroutine. These pieces of data are the values of the arguments with which the subroutine is going to be called/invoked. An ordered list of parameters is usually included in the definition of a subroutine, so that, each time the subroutine is called, its arguments for that call are evaluated, and the resulting values can be assigned to the corresponding parameters.

<span class="mw-page-title-main">C syntax</span> Set of rules defining correctly structured programs

The syntax of the C programming language is the set of rules governing writing of software in C. It is designed to allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide relatively high-level data abstraction. C was the first widely successful high-level language for portable operating-system development.

<span class="mw-page-title-main">For loop</span> Control flow statement for repeated execution

In computer science a for-loop or for loop is a control flow statement for specifying iteration. Specifically, a for loop functions by running a section of code repeatedly until a certain condition has been satisfied.

<span class="mw-page-title-main">Foreach loop</span> Control flow statement for traversing items in a collection

In computer programming, foreach loop is a control flow statement for traversing items in a collection. foreach is usually used in place of a standard for loop statement. Unlike other for loop constructs, however, foreach loops usually maintain no explicit counter: they essentially say "do this to everything in this set", rather than "do this x times". This avoids potential off-by-one errors and makes code simpler to read. In object-oriented languages, an iterator, even if implicit, is often used as the means of traversal.

xHarbour is a free multi-platform extended Clipper compiler, offering multiple graphic terminals (GTs), including console drivers, GUIs, and hybrid console/GUIs. xHarbour is backward-compatible with Clipper and supports many language syntax extensions, greatly extended run-time libraries, and extensive third party support.

The computer programming languages C and Pascal have similar times of origin, influences, and purposes. Both were used to design their own compilers early in their lifetimes. The original Pascal definition appeared in 1969 and a first compiler in 1970. The first version of C appeared in 1972.

Haxe is a high-level cross-platform programming language and compiler that can produce applications and source code for many different computing platforms from one code-base. It is free and open-source software, released under the MIT License. The compiler, written in OCaml, is released under the GNU General Public License (GPL) version 2.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

In programming languages, a label is a sequence of characters that identifies a location within source code. In most languages, labels take the form of an identifier, often followed by a punctuation character. In many high-level languages, the purpose of a label is to act as the destination of a GOTO statement. In assembly language, labels can be used anywhere an address can. Also in Pascal and its derived variations. Some languages, such as Fortran and BASIC, support numeric labels. Labels are also used to identify an entry point into a compiled sequence of statements.

The syntax and semantics of PHP, a programming language, form a set of rules that define how a PHP program can be written and interpreted.

<span class="mw-page-title-main">Rexx</span> Command/scripting/programming language

Rexx is a programming language that can be interpreted or compiled. It was developed at IBM by Mike Cowlishaw. It is a structured, high-level programming language designed for ease of learning and reading. Proprietary and open source Rexx interpreters exist for a wide range of computing platforms; compilers exist for IBM mainframe computers.

OptimJ is an extension for Java with language support for writing optimization models and abstractions for bulk data processing. The extensions and the proprietary product implementing the extensions were developed by Ateji which went out of business in September 2011. OptimJ aims at providing a clear and concise algebraic notation for optimization modeling, removing compatibility barriers between optimization modeling and application programming tools, and bringing software engineering techniques such as object-orientation and modern IDE support to optimization experts.

Racket has been under active development as a vehicle for programming language research since the mid-1990s, and has accumulated many features over the years. This article describes and demonstrates some of these features. Note that one of Racket's main design goals is to accommodate creating new programming languages, both domain-specific languages and completely new languages. Therefore, some of the following examples are in different languages, but they are all implemented in Racket. Please refer to the main article for more information.

PL/SQL is Oracle Corporation's procedural extension for SQL and the Oracle relational database. PL/SQL is available in Oracle Database, Times Ten in-memory database, and IBM Db2. Oracle Corporation usually extends PL/SQL functionality with each successive release of the Oracle Database.

<span class="mw-page-title-main">Nim (programming language)</span> Programming language

Nim is a general-purpose, multi-paradigm, statically typed, compiled high-level systems programming language, designed and developed by a team around Andreas Rumpf. Nim is designed to be "efficient, expressive, and elegant", supporting metaprogramming, functional, message passing, procedural, and object-oriented programming styles by providing several features such as compile time code generation, algebraic data types, a foreign function interface (FFI) with C, C++, Objective-C, and JavaScript, and supporting compiling to those same languages as intermediate representations.

References

  1. "Harbour" . Retrieved 3 September 2020.
  2. "LetoDB". Sourceforge.net. Retrieved 9 December 2013.
  3. "QtContribs - Harbour Qt Projects". SourceForge.
  4. "Official Harbour page". The Harbour Project. Retrieved 9 December 2013.
  5. "harbour 路 GitHub". Github.com. Retrieved 9 December 2013.
  6. "About xHarbour". Xharbour.org. Retrieved 9 December 2013.
  7. "xhb-diff.txt". GitHub . Retrieved 9 December 2013.
  8. vailtom (17 August 2009). "Harbour MiniGUI Extended Edition. | Free Communications software downloads at". Sourceforge.net. Retrieved 9 December 2013.