F.E.L.T.

Functionally Equivalent Language Translation

DEFVAR / :=

(defvar var-name 100)                  ; simple assign
(defvar var-name (+ (a-func 1 2) 12))  ; complicated assignment
(:= var-name "Short-form of defvar")   ; simple string assign
(:= var-name (+ 10 32))

Define a variable for subsequent use. Some languages insist that you formally declare your variables before you can use them. To do that, use this instruction the first time you reference a new variable. PHP doesn't require this. javaScript does.


Define a new variable

Most scripting languages are pretty lax when it comes to having you formally declare a new variable before you can use it and most if not all compiled languages pretty much insist that you must declare your variables before you can use them as the compiler needs to know how much space to allocate on the local stack frame for them.

In order that you produce portable code you should always declare new variables within a function by using DEFVAR or the short-hand form := as this indicates to the back-end coder that it should produce a declaration and not just a simple assignment.

PHP Example

Let's define a simple function that declares two local variables, one using DEFVAR and one that just assigns a value to a variable. Then we can see the PHP code and examine the difference:

(defun defvar-example1 ()
  (defvar good-var 100)
  (= bad-var "Naughty!"))

and the PHP rendered out is:

function defvar_example1() {
  $good_var = 100;
  $bad_var = "Naughty!";
}

Notice the difference? There isn't one! That's because as we have already said, PHP doesn't require that you explicitly state the names of new variables, it just creates them as and when you want to use them.

So what happens if we run that code through the javaScript coder instead, will it work as expected?

JavaScript Example

(defun defvar-example1 ()
  (defvar good-var 100)
  (= bad-var "Naughty!"))

with the JavaScript being output like so:

function defvar_example1() {
  var good_var = 100;
  bad_var = "Naughty!";
}

This time you can visibly see the difference; the DEFVAR instruction brought the good_var variable into local scope by using the javaScript var declaration syntax, this is a good thing. It means that we know that irrespective of what passed before, that this variable, for the lifetime of this function is ours to do with as we please! Some people call this "unintended variable capture", I call it sloppy.

On the other hand, bad_var is possibly a disaster waiting to happen... if there is currently no variable called bad_var then we should be OK, however if there is a variable at file level scope then guess what, we just accidentally clobbered it and now we have a bug to sort out when things unexpected begin to happen.

FELT does not know what your target language is when you write it, and therefore the onus is on you to follow the best-practice rules so once again I say, if you are absolutely sure that you are just using FELT with a single target in mind, don't break the rules because one day you may decide that your PHP only project might be good running under Node.js instead and you will find it riddled with lots of irritating bugs and things because of scoping rules being different.

Portability and DEFVAR

Some languages do not insist that you declare your variables before you use them, in which case you can safely use the = instruction to assign an initial value to the variable in the knowledge that it will be brought into existence at that point in the code.

However, the real "Tao of FELT" if there is one is writing code that can be minted out for as wide an audience of back-end coders as possible; that maximises your efforts.

There is another instruction, DEFVAR that is the 'correct' way to define a variable before it is used. Therefore it is highly recommended that all variables are initially brought into scope using it rather than =.

Here is how you should do it:

(defun simple-total (a b)
  (defvar total 0)
  (setq total (+ a b))
  (return total))

which would be rendered into PHP as follows:

function simple_total($a, $b) {
  $total = 0;
  $total = ($a + $b);
  return $total;
}

And in javaScript:

function simple_total(a, b) {
  var total = 0;
  total = (a + b);
  return total;
}

Here you can see that because we used DEFVAR we have the var keyword in place to introduce the variable, now if we changed the original FELT example so that we had used the assignment operator instead, we will see that although the PHP code still works,

(defun simple-total (a b)
  (= total 0)
  (setq total (+ a b))
  (return total))

which again, rendered into PHP looks like this:

function simple_total($a, $b) {
  $total = 0;
  $total = ($a + $b);
  return $total;
}

And in JavaScript:

function simple_total(a, b) {
  total = 0;
  total = (a + b);
  return total;
}

The JavaScript code is now "dangerous" in that there is a possible bug waiting to be discovered because although the code is not in error, at run time, if there is no "total" variable at file scope, as there isn't one at function scope, then something bad is going to happen.

Always use DEFVAR for the first use of a variable. Stay portable. If it feels like too much typing then remember you can use the := short form instead.