Falcon (programming language)

FalconplLogo.png

The Falcon Programming Language, with Falcon P.L., Falconpl or Falcon being short names, is an open source, multi-paradigm programming language. Design and implementation is led by Giancarlo Niccolai.

History

A small project, HASTE, developed in 2002, in an attempt to create a small fast Virtual Machine, soon evolved into The Falcon Programming Language.

Philosophy

Rather than focusing on one programming style or paradigm, Falcon merges several different styles into a single framework.

At the implementation level, Falcon is driven by the concept of service, where the scripting engine is seen as a service for scripts, modules and in embedded applications when not used as a stand-alone tool.

Hello Falcon

Although there are various forms of basic I/O, an example Hello World using fast print:

> "Hello World!"

Supporting Unicode, below is an internationalized example of introductions:

// International class; name and street 
class 国際( なまえ, Straße ) 
   // set class name and street address 
   नाम = なまえ 
   شَارِع   =  Straße 
   // Say who am I! 
   function 言え!() 
     >@"I am $(self.नाम) from ",self.شَارِع 
   end 
end 
// all the people of the world! 
民族 = [ 国際( "高田 Friederich", "台湾" ), 
   国際( "Smith Σωκράτης", "Cantù" ), 
   国際( "Stanisław Lec", "południow" ) ] 

for garçon in 民族: garçon.言え!()

Data Types

  • Nil - The nil keyword, a non-value.
  • Integer - an integer 64 bit value.
  • Numeric - An IEEE 64 bit floating point value.
  • Range - a triplet of lower bound, higher bound and step.
  • MemBuf - Raw memory buffer, where each location is an unsigned 1, 2, 3, or 4 bytes integer.
  • Function - Functions (callable entities).
  • String - Mutable sequences of UNICODE characters (but they can be used as byte buffers).
  • Array - Mutable sequences of items.
  • Dictionary - Mutable ordered set of key/value pairs; the key can be any Falcon item.
  • Object - Instances derived from classes or stand-alone classless objects.
  • Class - Classes, entities that can create instances.
  • Method - Immutable pairs of instances and functions to be applied on them.

Paradigms

Falcon merges six major programming paradigms.

  • procedural
  • functional
  • object oriented
  • prototype OOP
  • message oriented
  • tabular programming

Procedural

Procedural programming is supported through classic function declarations and calls. Every function supports implicitly variable parameter calls and named/positional parameters. A set of procedural style statements (as i.e. for, while, if, switch statements) is provided.

The following, a complete procedural program, highlights a few of the design decisions in Falcon that can reduce the headaches with pre-body-post processing inherent in some programming tasks.

function sayList( saying )
   for elem in saying
       >> elem
       formiddle: >> " "
       forlast: > "!"
   end
end

sayList( List("Have", "a", "nice", "day") )

Functional

Falcon has an evaluation engine called Sigma-reductor, which allows programmers to write pure functional programs, not differently from what is seen in Lisp. The intermixed programming style allows use of different paradigms (such as OOP or procedural approaches) in functional sequences, or to use functional evaluations during the course of otherwise procedural programs.

Functional sequences are represented by standard language arrays; this means that sequences can be created, inspected and changed dynamically by the program itself, either across different evaluations or during the course of a Sigma-reduction evaluation. The following example does that by changing a special variable reference, called late binding in a list loop.

 seq = [ printl, '"', &value, '"' ]
 
 dolist( function(p); seq.value = p; eval(seq); end,
         ["Have", "a", "nice", "day"] )

Standard arrays can be called as functions if their first member is itself a callable item, as in the following example.

 [printl "Prompt> "]( "Real data to print" )

One-level functional sequences (as in the above example) can be conceptually treated as cached calls, and once assigned to a variable, they are morphologically equivalent to a function symbol.

The functional paradigm includes an out of band item marker. Items can receive an oob flag marker which can be tested through language operators and functions and indicate a special meaning for values traveling in functional sequences. For example, many functional loops, as floop and times can perform loop restarts or can be interrupted by returning either a out of band 1 or 0 from any of the involved functions. The map function, transforming all the values in an array through a mapping function, will ignore the returned value (discarding it) if it's an out of band nil; in this way, it is possible to perform map-and-filter operations in place.

Object Oriented

The Falcon Programming Language provides an OOP paradigm with classes, an inheritance model, class-static members, property initializers and instance constructor. Multiple inheritance is supported under the condition that at most one underling ancestor class is reflecting native data. Access to base class members is supported.

Instance structure is fixed and immutable, but due to Falcon functional nature where functions are seen as just a special kind of data, it is possible to set instance members to plain data or functions (making them methods) dynamically. Functional sequences can be assigned to properties, in which case they become functional methods for the given OOP instance.

Falcon supports stand-alone objects, which can be either classless or derived by class ancestors, which are instantiated and readied before the Virtual Machine executes the main script. Instance Resolution order is tracked by the Falcon Linker to ensure proper initialization of stand-alone objects, which may refer one another in program modules.

Class instances can be created through functional sequences, as instancing a class is morphologically equivalent to calling its symbol, and so, evaluating a functional sequence whose first element is a class has the effect of creating an instance.

Falcon OOP model is completed by operator overloading, which allows to create classes on which the mathematical and logical operators have a special behavior.

Prototype Object Oriented

Prototype OOP is similar to OOP, but it drops the concept of classes. Instances are all classless, and their structure can be dynamically changed. Falcon language dictionaries (ordered key/value pair collections) can include functions; dictionaries can then be blessed to inform the language that they are to be treated as classless instances, and applying dot accessor causes their values to be treated as properties or methods. In the following example, a dictionary becomes an object:

dict = bless([ 'state' => 0, 'incme' => function(); self.state++; end ])
dict.incme()
> dict.state  // will print '1'

Bindings in arrays works similarly.

array = [1,2,3]
array.showMe = function()
   for item in self
       > item
   end
end

array.showMe()

Message Oriented

Message Oriented programming allows indirect calls to one or more registered listeners when a message is broadcast. The contents of the message are arbitrary and can include any language item, including but not limited to classes from which to create instances, functional sequences or tables. Listeners can either compete to receive the message and exclude the others, or participate in building a common reply to the message in ordered steps. Messages can be broadcast and require an immediate reply or can be left in the environment to be received and processed by latecomers (termed assertions in Falcon).

Message oriented programming has a direct interface into the Virtual Machine, on which external native modules and embedding applications can interact. For example, a multithreaded application may throw into the virtual machine messages coming from different threads, for serialized processing at script level and later broadcast of processed solutions directly from within the scripts.

Tabular

Tabular programming can be seen as a special extension of OOP programming, where a class is represented by a table, whose columns are properties and where each row is an instance. Other than keeping all the instances together, and allowing each instance to work on the surrounding rows of the parent table, modification on the table are dynamically reflected into every instance.

Tables offer a means to select behaviors between a finite set of choices, or to mix behaviors and merge them, providing fuzzy logic engines. As each row, actually a Falcon array, can contain both table-specific data and logic or private logic (via array bindings), an entity selected in a table via global selection logic can provide specialized working abilities.

Features

Along with the multiple paradigms, Falcon presents a variety of different features for programmers.

Template Documents

Falcon allows scripts to be part of text documents, with the preprocessor <? .. ?> or '''

' directive. Scripts saved as ".ftd" files are treated as text documents and simply echoed until one of those processor directives is encountered. Inbound scripts are executed as in the following.ftd'' example:

  You called this script with <? print( args.len() ) ?> parameters.

FTD documents can be merged with normal Falcon scripts to form applications, where the presentation logic is in dynamic templates (the FTD files), and the application logic is stored in Falcon modules.

FTD documents can be used in driving dynamic websites. Some popular webservers (currently Apache 2), have modules which directly parse and execute ".fal" and ".ftd" scripts, providing an API which integrates in the webserver engine. It is also possible to use dynamic FTD pages along with CGI scripts.

Exceptions

Falcon supports error handling via the raise, try and catch statements. The raise statement can throw any Falcon item, including nil, numbers, strings, objects and so on. Library functions and external modules will usually raise instances of the Error class, or instances of a class derived from that.

The catch statement can be used to catch any type of item, a certain type (i.e. strings or integers), or instances from a certain class. Caught classes are organized on a hierarchical base, so that it is possible to provide more generic error handlers like the following example (TypeError is a library class derived from Error):

try
   ... code that can raise ...
catch TypeError in error
   ... if we mixed up types ...
catch Error in error
   ... another generic error ...
catch StringType in error
   ... an explicit raise "something" was issued ...
catch in error
   ... no idea of what has been raised.
end

The in clause of the catch statement is optional (this means that the error itself may be discarded).

The catch statement mimics the select statement, which can be used to switch on the type or class of a given variable.

Explicit string expansion

Falcon includes an '@' unary string expansion operator that returns a string with inline '$' variable references replaced. This operation allows for formating during the substitution.

For example:

 a = 123456.789
 v = "formatted as"
 s = "a = $a, $v $(a:12rg3,.2), rounded hex as $(a:C)"  
 printl( @ s)

Which prints:

 a = 123456.789, formatted as   123,456.79, rounded hex as 0x1E241
 

  • the value
  • the value right-aligned in a width of 12 with a grouping of 3 using comma and then rounded to 2 decimal places
  • the value in upper-case hexadecimal (rounded up to closest integer) prefixed with '0x'.

Embedable runtime

Falcon is designed for embedding into and extending other systems with a linkable runtime library, libfalcon.

Documentation Generator

Falcon ships with an integrated documentation system, called faldoc, which is specifically designed to provide Falcon based libraries (be they native C++ code or module sets written in Falcon) with maintainable documentation.

Virtual Filesystem

All I/O operations happening at engine or at virtual machine (script execution) level are delegated to a centralized Virtual Filesystem Provider, to which external modules or embedding application facilities are allowed to register dynamically. Subscribed Virtual Filesystems abstract I/O operations as directory read, file creation and stream opening, and can be addressed from within scripts by URI. This makes it possible to load modules or open resources from any VFS (as network resources or compressed/crypted archives), which may include special virtual locations provided by third party modules and/or by applications embedding the engine.

Concurrency support

In versions up to 0.8.x, the Threading module provides full multithreading to scripts. The multithreading model is agent oriented, and data across threads must be explicitly shared through several possible sharing mechanisms. Each thread runs a different virtual machine, which runs separately from any operation happening in the others (as i.e. garbage collection). This allows for efficient parallel processing and 0 contention outside the control of the script developer.

Coroutines

Falcon supports quasi-parallel coroutining. Coroutines are code executed in time slices or during idle times by the Virtual Machine. They provide a lighter parallel approach than the full threading model and allow full visibility of program global data through different coroutines. Explicit cooperation of each coroutine is required, (i.e., each coroutine must check for data availability before blocking reads).

Metacompiler

The Falcon compiler contains a meta-compiler that supports macro expansions. A Falcon Virtual Machine in the standard compiler drives the meta-compiler. Output generated from the meta-compiler is sent to the language lexer as if part of the original source. Using ... escape sequences, it is possible to dynamically write the contents of the program being compiled by printing it:

 $$printl( "printl( 'Hello world' )" )$$

The keyword macro provides a simplified candy-grammar interface to compile-time meta-programming.

Native internationalization

Strings prefixed with an 'i' are recognized as exported (international) strings. Declaring the language used in a module through the directive statement, it is possible to indicate which is the native language in which strings are written, as in the following example:

 directive lang=fr_FR           // uses 5 characters ISO language code
   
 > i"Bonjour à tout le monde!"

A command line tool called fallc is provided to export 'i' strings into XML definition files, which can be used as templates to provide translations into different languages.

The translated string table is applied to the modules at load time.

Feathers

Supporting modular programming, Falcon ships with Feathers, the Standard Module suite. Feather modules currently include:

  • Compiler - Reflexive compiler and dynamic plugin loader module.
  • Configuration Parser - Complete configuration file parser support.
  • MXML - Very fast and simple Minimal XML parser (compatible with XML 1.0).
  • Process - Interface to cross platform process support (start, kill, pipes...)
  • Regular Expressions - PCRE 7.x compatible regular expression library interface.
  • Socket - BSD sockets cross platform networking support.
  • Threading (since 0.9.0) - Multithreading structures support.
  • ZLib - Interface for simple compression routines.

Implementation

The core VM and official modules, (including Feather modules and other community provided support modules) are all written in C++. Some very low level module and engine elements are written in C and Assembly.

Availability

Falcon is distributed through installers on Mac OS X and MS-Windows systems (where building and installing is a more articulated process), or through self-building source packages on various open systems as Linux or OpenSolaris.

On the latter systems, The Falcon Programming Language is usually supported and generally kept up to date on various distributions, among which:

  • Ubuntu
  • Fedora
  • Gentoo
  • Slackware
  • Arch Linux
  • Mandriva
  • openSUSE
  • SUSE Enterprise Linux

The Falcon Programming Language is available on Solaris based OS distributions through the Blastwave project, and through the AuroraUX distribution of the OpenSolaris system.

References

es:Falcon (lenguaje de programación) it:Falcon (linguaggio di programmazione) zh:Falcon编程语言