endel / js2php

JavaScript (ES6) to PHP source-to-source transpiler.
https://endel.github.io/js2php/
MIT License
333 stars 41 forks source link

inline anonymous functions #9

Closed francescoagati closed 10 years ago

francescoagati commented 10 years ago

php don't support inline anonymous function.

this js code

var x = (function(x) {
  return x + 1;        
})(1);

is compiled in this php

<?php
$x = function ($x) use (&$x) {
return $x + 1;
}
(1);

but should be

<?php
$tmp_function_000001 = function ($x) use (&$x) {
return $x + 1;
};
$x = $tmp_function_000001(1); 
endel commented 10 years ago

@francescoagati thanks for your time reporting this.

I've ended up reusing the same variable name, as you can see in this example:

input

var inline = (function(i){
  return i;
})(5);

var_dump(inline);

output

<?php
$inline = function ($i) {
return $i;
}
;$inline = $inline(5);
var_dump($inline);
francescoagati commented 10 years ago

Thanks @endel i am trying to transcompile coffeescript code in php using js2php.
This solution of inline anonymous function don't work always for me.

This is a example of coffescript array comprehension that isn't compiled correctly with js2php.

This is the code in coffeescript

defenders = for player in players when player.role is 'DIF'
  player.name

this is the code compiled in javascript

var defenders, player;

defenders = (function() {
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = players.length; _i < _len; _i++) {
    player = players[_i];
    if (player.role === 'DIF') {
      _results.push(player.name);
    }
  }
  return _results;
})();

and this the php code compiled with the last version of js2php

<?php
$defenders = null;
$player = null;
$defenders = function () {
$_i = null;
$_len = null;
$_results = null;
$_results = array();
for ($_i = 0, $_len = count($players);$_i < $_len;$_i++) {$player = $players[$_i];
if ($player->role === 'DIF') {
array_push($_results, $player->name);
}}return $_results;
}
();

in this case the variable defenders isn't used first as function to invoke the anonymous function. I don't understand the differences between your example and my. Your work and my not.

Thanks Francesco

endel commented 10 years ago

Hey @francescoagati, got it!

My first attempt just cover with variable declarations (var x = (function()...), now it's fixed for assignments too (xxx = (function()...))

One important thing to note is that . will be transpiled to ->, so you'll need to be using classes for your players. For arrays you'll need to use []

Example with arrays:

players = [{name: "One", role: 'DIF'}, {name: "Two",role: 'N'}, {name: "Three",role: 'N'}]
defenders = for player in players when player['role'] is 'DIF'
  player['name']
var_dump(defenders)
francescoagati commented 10 years ago

thanks @endel now work really good. i really like your idea of compiling js in php, without runtime code