F.E.L.T.

Functionally Equivalent Language Translation

Coding for PHP

PHP was one of the original sources of inspiration for writing FELT. I like PHP but I hate the syntax of it. I love LISP. LISP is tight, compact, concise and yes, after a while you really don't see the parentheses. Honest, you just don't.

So I thought to myself how nice it would be to be able to use the LISP s-expression format but have it run as PHP. It wasn't long before I expanded that to Javascript and CSS as well... if you are coding a web-site I figured it'd be nice to do it in one language mind-set and let the computer take the strain, that's what they are for after all.

Variable Naming

The PHPCoder class automatically creates a mangled name based upon what you use as the variable name. In most cases this will work but if you should attempt to create a FELT name that doesn't meet PHP-s requirements for a variable name then an exception is thrown culminating in an error message for you to read. It has a short-form string for each character it allows and rather than show you the code, here are some FELT variables and the resulting PHP variable names.

(defvar simple 0)
(defvar simple-name 100)
(defvar last@count 42)
(defvar top-ten% (array))
(defvar mad-name-!@#$%^&* :why?)

The resulting PHP output from the above is...

$simple = 0;
$simple_name = 100;
$last_at_count = 42;
$top_ten_per_ = array();
$mad_name__bang__at__hash__dlr__per__crt__amp__star_ = "why?";

As you can see, the 'fancy names' get mangled into something that the PHP parser will accept as a valid variable name. It may look ugly but it works.

So, within reason you can use whatever you like within the context of a variable name definition. I find that the ability to put things like -> in a name makes for more readable names, especially for functions. In the LISP world the -> is quite often used as part of names for things that convert a type into another type, for example:

(defun date->mysql () )
(defun int->string () )
(defun dbrecord->mime64 ())

and of course the PHP we get is...

function date__gt_mysql(){}
function int__gt_string(){}
function dbrecord__gt_mime64(){}

Function Naming

Naming functions is pretty much the same as that for variables except for a few little rules about how certain characters are treated.

Dash is an Underscore

One of the things I like about FELT coding for PHP is that I don't need to use the SHIFT key nearly as much as I used to. Why is this? Simple... the FELT back-end PHPCoder class automatically converts a dash into an underscore for you. This means that you can use the dash key (unshifted underscore) as though it was that character and it will convert it for you. If you do use the underscore it will still work but I find it less effort. It also makes nicer function names and variable names.

Pre-Defined Constants

FELT assumes that anything defined as ALL_UPPERCASE is either something that your FELT code has created with the DEFINE instruction or something that already exists within the current scope of the application being executed. For example, to write to a file with file_put_contents in append mode in FELT, you would code it like this:

(defvar buffer (get-log-data))
(file-put-contents "logfile.txt" buffer FILE_APPEND)

The above snippet produces the following PHP code:

$buffer = get_log_data();
file_put_contents("logfile.txt", $buffer, FILE_APPEND);

Special Names

There are certain variable names that are allowed to pass through the name mangling process unchanged and also certain character combinations as well to allow for a more relaxed coding style if you know that you are only going to generate PHP as the target.

NULL, TRUE and FALSE → () / #t / #f

In FELT, you can use the () token to mean NULL. If you want to use NULL as a constant then you are free to do so but remember that it may produce non-portable code, and must be used in upper-case form only. Thus the portable way to use whatever passes as null is ().

Again, for TRUE and FALSE you are free to use those values, again they must be in uppercase or they will be interpreted as variable names. A limitation of the system for now but hardly a great set-back.

So, to summarise:

The Scope Resolution operator → (::)

When two consecutive colons are placed together inside a function name or variable name they are passed through as you would expect them to for PHP code. This means that making a static function call can be done as it would be done in PHP, like so:

(Classname::function 1 2 3)

Note: This is non-portable to other target languages so be careful over the use of this form. As stated before, if you know that PHP is the only output target then feel free but if you plan to port it to some other back-end later, say Javascript, then it will not work. To remain portable it is best to use the (CLASS-CALL...) or (:: ) instructions in their long hand format, that way the selected back-end code can deal with it correctly.

Here are some examples to show you how to do it right!

;; making a static function call the 'wrong' way
(Foo::Bar 'cool')

;; making it the 'right' way i.e. language neutral / portable
(:: Foo Bar 'cool')
(class-call Foo Bar 'cool')

;; evaluated code in all three cases is...
Foo::Bar('cool');
Foo::Bar('cool');
Foo::Bar('cool');

Writing Functions → DEFUN/FUNCTION

As a wannabe full-time practitioner of functional programming (FP), the use of the word 'function' somewhat irks me but nonetheless the term is out there, has been for a long long time and is common enough to be understood despite its more rigorous definition with the confines if FP. Also, as stated before, the initial instruction set of FELT is deeply rooted in that of PHP and so there are two instructions that can be used, both meaning and doing the same thing:

(function test1 (arg1)
  (return (+ 1 arg1)))

(defun test2 (arg2)
  (return (+ 2 arg2)))

Anonymous Functions → DEFUN*/FUNCTION*/LAMBDA

Sometimes you need to define a function that has no name, for example, the PHP function array_map has as its first parameter a callback type, which, with more recent and capable versions of PHP, allow you to define a function 'there and then', otherwise called an anonymous function. How do we do this in FELT? Simple, we used what is called the 'starred variant' of the normal DEFUN command. This is the same as before but with an asterisk immediately after the word 'defun' or 'function', with no intervening whites-pace and then the function parameters are given. An example:

(defvar values (array "I" :like "FELT"))
(array-map (defun* (each)
             (emit "Value: " each))
           values)
;; which is the same as...
(array-map (function* (each)
             (emit "Value: " each))
           values)
;; also the same as for Lisp folkd ;)
(array-map (lambda (each)
             (emit "Value: " each))
           values)

The above code is a very simple example but it shows the form; here is the rendered PHP code and Javascript code for comparison. If we had used the PHP sprintf function then the code would not have worked as Javascript has no direct equivalent. Here's the output code, PHP first:

$values = array("I", 'like', "FELT");
array_map(function ($each) {echo "Value: ", $each;} , $values);

and the Javascript:

var values = ["I", 'like', "FELT"];
array_map(function (each) {document.write("Value: "+ each);} , values);

Note that the above still wouldn't work on Javascript as there is also no array_map function either! This is the 'art' of writing FELT code that is portable. There are target specific pre-processor commands that can help with things like this, [see here for details.] Of course for portable array iteration like this you should have used the FOREACH instruction like so:

(defvar values (array "I" :like "FELT"))
(foreach (values v)
  (emit "Value: " each))

which when rendered as PHP and Javascript looks like this, first PHPCoder...

$values = array("I", 'like', "FELT");
foreach($values as $v) { {echo "Value: ", $each;} }

and this for the JSCoder back-end:

var values = ["I", 'like', "FELT"];
for(var v in values) {document.write("Value: "+ each);}

Writing Classes (and Interfaces) → CLASS/INTER

Object oriented (OO) development is still pretty popular and so FELT needs to be able to support languages that have the notion of 'classes' and 'interfaces'. To create PHP classes with FELT is pretty easy once you've gotten used to the instruction format. It may seem a little odd at first but remember, with the flick of a switch you can generate code for any other language that a back-end coder class has been written for... hence the seemingly 'bloated' syntax at times.

Define a Class

Let's start with a really simple class that contains nothing at all and has no super-class nor implements any interfaces of any description:

(class Foo)
(defvar foo (new Foo))
(var-dump foo)

OK, the generated PHP code and a var_dump() of that is here:

$foo = new Foo();
var_dump($foo);

Evaluated:
object(Foo)[28]

Class with Super-class

The syntax for a simple class is: (CLASS Class-name). If you want to say that it is derived from a super-class then all you do is wrap the Class-name and the super-class name in parentheses and you're done. Here's an extension to the class we defined earlier:

(class Foo)
(class (Bar Foo))
(defvar bar (new Bar))
(var-dump bar)

...and here is the generated PHP code and evaluation:

class Foo {}
class Bar extends Foo {}

$bar = new Bar();
var_dump($bar);

Evaluated:
object(Bar)[33]

Using Interfaces

Having establish that (CLASS Foo) gives a vanilla class and that (CLASS (Foo Super-class)) is how we inherit from a super-class, how do we instruct FELT to inform the back-end coder that we also want to use one or more interfaces from other places?

To use just a single interface or to use multiple all you do is place an s-expression within the class definition that starts with the keyword :implements follows by one or more interface names, separated with spaces not commas. Remember that lists in FELT are white-space separated.

(class (Foo Bar)
  (:implements Iterator MineA Theirs-B))

Note that you only have to put the (:implements ...) inside the class definition somewhere. Usually you would put it at the top for readability but FELT will pick it up anywhere within the class definition. Here's the resulting PHP code for the above class:

class Foo extends Bar
  implements Iterator, MineA, Theirs_B {
}

OK, now we have seen how to declare a class, with or without a super-class, and also how to state that the class implements as many interfaces as we desire... how do we now add behaviours to the class and any instances that we may create of it?

Static (Class) Methods and Instance Methods → DEFUN/DEFUNC

We'll cover static methods first as that is sometime all you need of a class; a handy place to group a couple of logically related functions that actually need no instance data to operate.

Let's create a simple class that converts things from one type to another, and we'll use the fancy '->' in the names as well just to show off. Here then is how to implement a class that is essentially a bucket of static helper functions:

(class (Foo Bar)
  (defunc Foo->Raw (aFoo)
    (return "rawdata")
  )
  (defunc Raw->Foo (raw-data)
    (return (new Foo raw-data))
  )
)

and here's the generated PHP code for the above class:

class Foo extends Bar {
static function Foo__gt_Raw($aFoo)
       {return "rawdata";}

static function Raw__gt_Foo($raw_data)
       {return new Foo($raw_data);}

}

Note that I've aligned the parentheses more like a PHP program would just to show where the functions are. Normally one would pack them all up to save vertical space.

So, all you do is add a 'c' (for Class) to the instruction that you would normally use like so:

Access Control → +/#/- suffixes

Currently everything appears to be public, which is the default for PHP, but what if we wanted to make something private or protected? Calling upon a 'standard' amongst a lot of UML tools, FELT allows for some variations on the DEFUN/FUNCTION instruction so that you can specify the visibility of a function. A simple example ought to be enough, and then we'll move on to using classes, both ones that FELT generates and ones that may be require-d from existing code stock.

(class Test
  (defun- a ())
  (defun# b ())
  (defun+ c ())
)

and the PHP code again:

class Test {
  private function a() {}
  protected function b() {}
  public function c() {}
}

The above also applies to instance methods as well. To sum it up then, the following character when placed after the DEFUN/FUNCTION causes the access to be as follows:

- => private
# => protected
+ => public

Static (Class) Variables → CVAR

Cool, we can now define a class, add interfaces, super-classes and static methods. Adding instance methods is pretty much self-explanatory, and if you haven't guessed it already the instructions DEFUN, DEFUN-, DEFUN#, DEFUN+ or FUNCTION, FUNCTION-, FUNCTION#, FUNCTION+ are all you need to know and use!

Class Constants → CONST

Now it might be useful to know how to add constants to a class definition so we can avoid the use of 'magic numbers' in our code. It is always good practice to have constant values define with a readable label and a comment... the target language won't know or care but code is for people, not computers.

To introduce constants, we use the CONST instruction. This instruction takes a list of parenthesized terms, the first of each is assumed to be the name of the constant, the second is the value, like this...

(class (Foo Bar)
   (:implements IBaz)

   ;; define some constants
   (const (one-at-a-time 100))

   ;; or multiple definitions at once...
   (const
       (FOO-1   1234)
       (FOO-2   "Hello World")
       (FOO-ON  1)
       (FOO-OFF 0))

   (defun instanceMethod ())
   (defunc# staticMethod ()))

Currently FELT insists that the right hand side of constant is a simple expression i.e. a simple string or a number... if that turns out to be a restriction then I will remove it... I have not done a Java back-end yet but already I think this is a restriction as Java allows you to combine things to create a 'public static final' type of member. Time will tell. Anyway, to round it all of, here is the generated PHP code for the above class:

class Foo extends Bar implements IBaz{
  const one_at_a_time = 100;
  const FOO_1 = 1234;
  const FOO_2 = "Hello World";
  const FOO_ON = 1;
  const FOO_OFF = 0;
  function instanceMethod() {}
  protected static function staticMethod() {}
}

Static (Class) and Instance (Member) Variables → CVAR/MVAR

Declaring instance variables (member variables) and class variables is done with almost the same instruction:

The main difference in PHP is that class variables are 'static' such that regardless of how many instances of a class exist, there is only ever one instance of that variable. This is very often used to implement the singleton pattern.

Here is a simple class with examples showing how to declare both types with various access levels, again using the +/#/- modifiers as for functions etc. Here it is:

(class Foo 
  (cvar on-my-own-no-value)
  (mvar also-single-no-data)
  (cvar# (hostname "serving.beer.com")
         no-value-var
         (username "freebeer")
         (password "fr33b33r"))
  (mvar- (x 1) (y 2) (z 0)))

and the generated PHP output for this class:

class Foo {
  public static $on_my_own_no_value;
  public $also_single_no_data;
  protected static $hostname = "serving.beer.com";
  protected static $no_value_var;
  protected static $username = "freebeer";
  protected static $password = "fr33b33r";
  private $x = 1;
  private $y = 2;
  private $z = 0;
}

Using the 'this' variable → MY

As FELT attempts to generalise across different target languages it uses the word MY to refer to something within scope of the current object on those languages that support the OO paradigm.

I chose the word because it reads more naturally. I tend to think of objects as little individuals and words like "me, my and mine" all seem more natural. Not all languages use this, for example, another language I dearly love, Smalltalk, uses the word self when referring to the object in scope.

You can think of the MY instruction as being a short-form for the instance method call, ->, a few examples are given here and hopefully that is enough to explain its usage:

(class Foo
  (mvar a b c)
  (defun __construct (anA aB aC)
    (= (my :a) anA)
    (= (my :b) aB)
    (= (my :c) aC)))

Note that you have to use the :keyword form here, this is one of the few exceptions when, for PHP at least when the term :foo does not evaluate to "foo".

The corresponding PHP code for the above example is:

class Foo {
  public $a;
  public $b;
  public $c;
  function __construct($anA, $aB, $aC)
        {$this->a = $anA;
        $this->b = $aB;
        $this->c = $aC;}
}

The keyword can be used to call functions on the instance as well, remember that the form (my ???) is the same as (-> this ???) and the ? can be a field name, a variable name or a function call. Again, a few examples to make it clearer:

(my a)                  => $this->$a;
(my :a)                 => $this->a;
(my (f1 42))            => $this->f1(42);
(my (f1 (my :data f)))  => $this->f1($this->data->$f);

Writing Interfaces

PHP along with many other OO languages allows you to define what is commonly known as in "interface". An interface is a contract that the writer of the implementing class guarantees; the interface says what functions will be available irrespective of the actual run-time concrete implementation, and what parameters those functions take, their types and the return value.

FELT allows interfaces to be defined using the INTERFACE instruction. Here is a very simple interface and a class that uses it. There isn't really much more to say about interfaces!

(interface Nellie
  (defun open (filename))
  (defun close (handle)))

How would this be used in a class? Here is a concrete class that uses the above interface, following the rules as described earlier in the CLASSDEF, using the :implements keyword:

(class Nobby
  (:implements Nellie)

  (defun open (filename)
    (emit "Opened " filename "\n")
    (return NULL)) ;; test handle

  (defun close (handle)
    (if handle
        (fclose handle))))

When converted to PHP (in the same file) and executed we get the following output as PHP code:

interface Nellie {
  function open($filename);
  function close($handle);
}

class Nobby implements Nellie{
  function open($filename) {
    echo "Opened ", $filename, "\n";
    return NULL;
  }
  function close($handle) {
    if ($handle) {
      fclose($handle);
    }
  }
}

Instantiating Classes → NEW

Having defined a class, or just wanting to use some other existing class library is equally simple, the NEW operator does the job. The first argument is always the name of the class or a variable containing something that is a String that will be used as the name of the class.

That raises one issue that hasn't so far been raised: constructors and all the other related functions; destructors, the magic functions etc. Simple! The PHP coder doesn't mind at all that you would use a double underscore to start a function name, so guess what, here's a constructor in a class and then some:

(class Foo
  (defun __construct ())
  (defun __destruct ())
  (defun __call (name arguments))
  (defun __set (name value))
  (defun __get (name))
  (defun __isset (name))
  (defun __unset (name)))

and of course you get what you'd expect, working PHP code:

class Foo {
  function __construct() {}
  function __destruct() {}
  function __call($name, $arguments) {}
  function __set($name, $value) {}
  function __get($name) {}
  function __isset($name) {}
  function __unset($name) {}
}

Right then, having seen that 'magic functions' are not that special after all, now we can see how easy it is to actually create an instance of a class, let's see two ways of creating the class Foo:

(defvar foo1 (new Foo))
(defvar foo-class :foo)
(defvar foo2 (new foo-class))

and we get the following PHP output:

$foo1 = new Foo();
$foo_class = 'foo';
$foo2 = new $foo_class();

If the constructor requires arguments then just hand them in after the name of the class, just like any other function call. That's the FELT one-syntax-rule again. No exceptions. Here is an example using the SimpleXML extension:

(defvar xmldata "Make your presence FELT!")
(defvar xml (new SimpleXMLElement xmldata))
(defvar strap (call xml :strap))
(emit strap)

and the PHP code and evaluated output is:

$xmldata = "Make your presence FELT!";
$xml = new SimpleXMLElement($xmldata);
$strap = $xml->strap;
echo $strap;

Evaluated:
Make your presence FELT!

Method Chaining → CALL/->

We saw in the last example a CALL instruction being used, it could also have been expressed in a form more familiar to PHP programmers, the -> operator. Here's the previous example but with the alternative form:

(defvar strap (-> xml :strap))

It will generate exactly the same code. One of the nicer things you can do if you design a class properly (by always returning the $this pointer in place of any other return value) then you can 'chain' calls together which leads for neat and readable code.

FELT lets you chain calls using the same syntax rule: (function arg1 arg2 ... argN), both for the call instruction and the chained calls, again there are no exceptions to the rule.

If you remember that things in () are function calls, and everything else is a string or variable reference, you can quite easily build complex chained calls. The simplest thing to do is just show some examples and the PHP code and leave it at that.

(defvar foo (new Foo))
;; calls...
(-> foo (open "eric"))
(call foo (fn1 1) (fn2 :test) (fn3))

;; calls, capturing the return value...
(defvar x (call foo (open "ernie")))

;; some field access as well... by name and through a variable
(defvar y (-> foo :state (reset)))
(defvar st :state)
(defvar z (-> foo st (reset)))

and the PHP code for the above chained calls:

$foo = new Foo();
$foo->open("eric");
$foo->fn1(1)->fn2('test')->fn3();
$x = $foo->open("ernie");
$y = $foo->state->reset();
$st = 'state';
$z = $foo->$st->reset();

Portability Notes

It is vital to remember that FELT is a translation system; if you use a function called 'foo' then it is assumed that that function will exist at run-time in the target environment. If it doesn't then something is going to blow chunks.

It is possible to do something in FELT that when translated causes a syntax error. In this case, you will see a listing of the PHP coder that was generated and the error message. As you get to know FELT, this will happen less and less and soon you will forget you are using PHP at all other than the function names you use are the PHP library... so is PHP its syntax, its library, both or none of the above? ;)