Thursday, September 23, 2010

Perl & Javascript: 7 common features

Javascript which is used mainly in the browser and now also extends its power on the server side (http://nodejs.org/) shares some features with an other programming language, perl.
perl community is very active and you can always find a module that does exactly what you need for your next project.95% of the time, somebody has already done the hard work for you! perl is a very nice language that shares some programmatic idioms with Javascript.
Both language contains a lot of treasure and a short entry could not list them all (perl is very very extra feature rich!) but we will see some common idioms in this entry!

literal notation


Javascript is well known for the literal notation which has made is way through JSON.
Let's see the javascript way of creating some data:

Javascript way

var myObject = {name:"john",age:24};  //a hash/object

var myArray   = [1,2,3,"hi"]; //an array

var myJSONLike = { //JSON like structure
   title :"my title",
   entry: [
      {
         id:1,
         content:"hi"
      },
      {
        id:2,
        content:"good bye"
      }
  ]
};

Perl way

my $object = {name=>"john",age=>24};  #a hash/object

my $array   = [1,2,3,"hi"]; #an array

my $JSONLike = { #JSON like structure
   title =>"my title",
   entry => [
      {
         id=>1,
         content=>"hi"
      },
      {
        id=>2,
        content=>"good bye"
      }
  ]
};

As you can see, javascript uses ":" to separate key/value pairs in the hash/objects where perl use "=>".
You can notice also that javascript uses the "//" for a single line comment where perl uses "#".
Variables in perl must all use a sigil ("$" sign here,but there is also "@" and "%" and some few others!) to specify the kind of data type you use (an array, a hash, a list, a reference,etc,etc).
An other difference is that perl uses the keyword "my" to declare a variable whereas javascript uses the keyword "var".
In javascript, the scope is only at the function level, which means that "var" will limit the scope of a variable to a function whereas in perl, the scope of a variable is at the block level:

for(var i=0;i<=10;i++){
  doSomething(i);
}
console.log(i);//10 - exist out of the for block

function looping() {
   for(var i=0;i<=10;i++){
      doSomething(i);
   }
}
console.log(i);//error - exist only in the function scope

for(my $i=0;$i<=10;$i++){
  doSomething($i);
}
print $i;#nothing or an error if you are in strict mode

Block level scoping offers better granularity and javascript 1.7 in FF offers the "let" keyword that allows finer tune of the variable scope.
The way you access the data differs too:

 var hash = {name:"john"};
 hash.name; 
 my $hash = {name=>"john"};
 $hash->{name};

Javascript uses the "." notation whereas perl use the "->" notation. There are more things that could be explained regarding perl variables but as you can see javascript and perl literal notation is quite similar.

Anonymous functions


Both perl and javascript offers anonymous functions:

javascript way

var testing = function () {};

perl way

my $testing = sub() {};

I guess the obvious difference is that javascript uses the "function" keyword whereas perl uses the "sub" keyword.

Closure

Closure allows you to trap the value of a variable:

javascript way

function evenCounter() {
    var i =0;
    return function() {
         return i+=2;
   }
}
var evens = evenCounter();
evens(); // 2
evens();//  4
evens();//  6

perl way

sub even_counter {
   my $i = 0;
   return sub {
        return $i+=2; 
   }
}
my $evens = even_counter;
$evens->();#2
$evens->();#4
$evens->();#6
#or
&$evens; #8

In javascript the camelCase convention is used but in perl it is the hyphen convention that is most used. Obviously you are free to choose whatever convention you feel more comfortable with.
In perl, functions (subs) return the last statement so the "return" is not mandatory but preferred for readability.
In perl, subs do not need to be called with "()" but this is necessary in javascript to differentiate from a simple variable.

Function introspection


Perl and javascript offers way to get some information about the context things are happening. Here is a little example:

javascript way

function service() {
  return 'service is used by: '+service.caller.name;
}

function consumer() {
   return service();
}
consumer();//service is used by: consumer

perl way

sub service { 
    return 'service is used by: '.(caller(0))[3]; 
} 
sub consumer {
    service();
} 
consumer();//service is used by: main::consumer

Here many things to notice:
In javascript you can get access to a function caller via functionName.caller.name or arguments.callee.caller.name where as in perl you use the caller() function.
In Perl functions can return an array or a string according to the context.
Therefore:
my $package = caller;#return the package name
my ($package,$file,$line)=caller; #return a list of variables.

That's why the code enclose the call to caller(0) with "()" to force a list context.
Then we access the 4th parameter of the list (counting from 0) that contains the function name.
Concatenation of strings in javascript uses the "+" sign but perl uses the "." sign.
Perl returns the name of the function and its package. The default being "main::".
There's no such concept in javascript.

Function arguments


Both perl and javascript allows you to access the arguments via a magic variable.

javascript way

function service() { 
     return arguments.length; 
} 
function consumer() {
    service('hi','there');
} 
consumer();//2

perl way

sub service { 
    return scalar @_; 
} 
sub consumer {
    service('hi','there');
} 
consumer();#2

Javascript uses the arguments keywords which is an array like object containing all the arguments passed to the function whereas perl uses the @_ variable which is also a list of all the arguments passed to the function.
In javascript we can access the number of arguments by using the length property.
In perl, we use the "scalar" keyword which forces a string context where perl returns the number of element in the list.

Javascript 1.7 in FF

Firefox has introduced new constructs that make javascript/perl a little bit more alike.
You must specify the version of javascript:
<script type="application/javascript;version=1.7">
</script>

destructing assignments

Create and assign in the same time. Less temporary variables required, neater code!

javascript way

var a,b;
[a,b] = [1,2];  
 
[a, b] = [b, a];  

console.log(a,b);//2,1

perl way

my ($a,$b) =(1,2);

($a,$b)=($b,$a);

print $a,',',$b;//2,1

In javascript you use the array notation on the left and right side of the assignment whereas in perl you use the list notation "()".

In javascript you can send multiple values by using the array notation, it will be handled differently according to the context, a la perl!

javascript way

function multiValues() {
    return [1,2];
}
var [a,b]= multiValues();//list context
var a = multiValues();//array context

perl way

sub multi_values() {
    return (4,5);
}
my ($a,$b)= multi_values;#4,5
my $c = multi_values;#5 - last element in the list
#or
sub multi_values() {
    return wantarray? (4,5):[4,5];
}
my ($a,$b)= multi_values;#4,5
my $c = multi_values;#array containing 4,5

In perl, if you use a scalar context when returning a list, you will get the last element in the list but we can use the wantarray function that let us know in which context the function is being called.

array comprehensions


Array comprehensions allow you to build a set of value in one line instead of using a loop.
Building an array containing 1 to 100:

javascript way

var numbersTo100 = [i for each (i in range(1, 100))]; 

perl way

my $numbers_to_100 = [1..100]; 

perl uses ".." to specify the range whereas javascript uses the range() function.
You can also create more complex data:

javascript way

var evens = [i for each (i in range(0, 21)) if (i % 2 == 0)];  

perl way

push @evens,($_%2==0) ? $_ : next  foreach (0..21);

Perl uses the "$_" variable that is set automatically in different occasions,here the use of foreach.

Conclusion


We've seen some constructs that are somehow similar in both javascript and perl. Don't hesitate to post similar patterns in other languages!

1 comment:

Anonymous said...

hmm, maybe some one could make up a javascript library that allowed you to use Perl syntax in javascript. Since they use similar logic maybe it would be simple./