F.E.L.T.

Functionally Equivalent Language Translation

FOR

(for initialisers termination-cond step-updates loop-body)
    where
      initialisers     := ((init-1) (init-2) .. (init-N))
      termination-cond := expression
      step-updates     := ((upd-1) (upd-2) .. (upd-N))
      loop-body        := [ expression, ]

(for ((= i 1) (= total 0)) (<= i 5) ((incf i) (incf total i))
   ;; body expressions here...
)

See also FOREACH UNTIL WHILE

A value counting looping construct. The initialisers are grouped inside (), don't forget that.. The termination is a normal FELT expression. The step updates are also grouped within (). The loop body is zero or more FELT expressions.


Standard Looping

The for construct is common in nearly every language out there and FELT provides a way to do this that allows for cross-language deployment. It may be a little uglier and slightly more verbose than 'language X' but remember what FELT does and it shouldn't really be a worry.

Initialisation Expressions

The first thing to note that is all initialisation expressions are grouped within a single (). That is important as the outermost parenthetical grouping is what FELT assume to contain all of the intialiasation expressions for the entire loop. You will soon know if you get it wrong.

You can place an valid FELT expression into the initialisation expressions, once again the only proviso is that the chosen back-end coder can sucessfully turn it into valid code for its target language.

Termination Condition

The termination condition follows the initial expressions. This is the same structural format as most other languages and so it should be easy to remember. The termination condition must be a valid FELT expression; as simple or as complex as you like. Again the only constraint on what you enter is that it must translate into back-end code to be of service.

Step-update Expressions

As for the initialisation expressions, these must also be grouped within ().

Simple Example

Let's just code a really simple and primitive (but effective nonetheless) timing loop that just wastes a whole bunch of time. Sometimes this is useful to slow things down between steps of a process so that you have time to click windows on the screen, examine log files and many other uses.

(for ((i=0)) (< i 10000000) ((incf i)))

That little one liner will burn a lot of CPU time and not really do much but hey, maybe that's what you wanted to do. Anyway, here is what the above looks like as PHP:

for($i = 0; ($i) < (10000000); ($i++)) {}

And as JavaScript:

for(i = 0; (i) < (10000000); (i++)) {}

A more complex example

OK... let's write a function that will be given an array of integers, and our job is to return the largest integer and also the total and average of those values. How would we do that using a FOR instruction with FELT?

It sounds straight-forward but remember that PHP and JavsScript have different ways of determining the length of an array. The first to tackle then would be some code that knows when either language is being coded for and hands back the appropriate value. Let's do that first and then we can write the common code and then run it with some data.

Here is the solution to getting the length of an array, note that we are using the Node.js back-end so we can use the console output later on:

(defun cruncher (numbers)
  (#f:when PHPCoder
    (defvar nlen (count numbers)))
  (#f:when NodejsCoder
    (defvar nlen numbers.length))
)

What this says is... define a function called 'cruncher' that takes a single argument called 'numbers'. Next it says that for PHP generation we should call a function, count and pass it the numbers value and assign the return value to local variable 'nlen'. For JavaScript generation it just copies the value of the 'length' field of the array into 'nlen' instead.

Just to prove that the above works, let's examine the PHP and JavaScript output and then move on to the rest of the code we have discussed. Here's the PHP:

function cruncher($numbers) {
  $nlen = count($numbers);
}

And the javaScript:

function cruncher(numbers) {
  var nlen = numbers.length;
}

So you can see that we so far have language-portable way to determine the length of that array. (Yes, we could use ALEN/@# but I wanted to make this a more FELT-heavy example just so you can see how it handles cross-language situations!)