Scriptor / pharen

Lisp to PHP Compiler
http://pharen.org
BSD 3-Clause "New" or "Revised" License
218 stars 31 forks source link

problem with array (Update: discussion on vectors) #44

Closed francescoagati closed 12 years ago

francescoagati commented 12 years ago

with array inside a function is returned pharenvector

example

[1 2 3 4 5]
(sum [1 2 3 4 5])

is compiled to

use Pharen\Lexical as Lexical;
Lexical::$scopes['plambda'] = array();
array(1, 2, 3, 4, 5);
sum(\PharenVector::create_from_array(array(1, 2, 3, 4, 5)));
Scriptor commented 12 years ago

Yes, this is intentional. I'm experimenting with the idea of using vectors for list literals, similar to how Clojure does it. It means native PHP array functions won't work on them directly, but all Pharen functions that deal with sequences still should. So if sum works with regular Pharen lists, it should also work with vectors. If sum has to take a PHP array and can't work with Pharen's sequences, you can do:

(sum (arr [1 2 3 4 5]))

The first list literal in your example code isn't being compiled to a vector due to a bug, so I'll fix that soon.

francescoagati commented 12 years ago

but in this mode pharen lost the compatibility with php array and function that works with php array. you should implemente inteface arrayaccess for mantain compatibilty with php array.

see this for ducomentation:

http://php.net/manual/en/class.arrayaccess.php

pimple use this for compatibilty with php array:

https://github.com/fabpot/Pimple/blob/master/lib/Pimple.php

at row 33

Scriptor commented 12 years ago

Pharen lists were never actually compatible with PHP arrays, only list literals were. For example, you couldn't do:

(array-sum (map (* 2) [1 2 3]))

This would have always given an error, whether or not it used a PharenVector, since map returns an instance of PharenList.

Also, PharenVector already supports ArrayAccess by inheriting from PharenList. You can see which interfaces PharenList implements here: https://github.com/Scriptor/pharen/blob/master/lib/sequence.php#L13

It's a bug in PHP that implementing ArrayAccess on an object still won't make it compatible with PHP's array-handling functions. All it does is allow you to use the array access syntax:

// Will work, assuming $myObj implements ArrayAccess
$myObj[0];

// Won't work, since PHP provides no way to support it:
array_sum($myObj);

So, in Pharen, you can still do:

(local list [1 2 3])
(:list 0) ; => 1
(:[1 2 3] 0) ; => 1

Vectors also implement the __invoke() magic method, so you can call them as objects and pass the index as a parameter, without using any colons

(list 0) ; => 1
([1 2 3] 0) ; => 1

Of course, as you mentioned the downside is that list literals are not compatible with PHP's array functions anymore. I just wanted to clarify that Pharen's lists themselves were never compatible with PHP. I am open to going back to list literals compiling to PHP arrays instead of vectors. I think using vectors makes it more consistent with the rest of Pharen since direct usage of PHP's arrays is discouraged, but suggestions are welcome :)

francescoagati commented 12 years ago

ok i think you have right. but i think that a compatibility with php array leave open the integration of pharen with many php libraries.

i think at 2 possibility:

also haxe manipulate array and hash in a different mode respct to php

Scriptor commented 12 years ago

Agreed, it's a difficult situation. Perhaps in the future PHP will fix things and allow its array functions to work on objects implementing ArrayAccess and Iterator. For now arr should still work. Your idea for a separate literal syntax could also work on both literals and regular expressions by adding a new reader macro, so the usage would be:

(local list %[1 2 3])
(local list2 %(map (* 2) [1 2 3]))

This would basically just be a shortcut for calling arr, but I'm not sure if it's the best solution.

francescoagati commented 12 years ago

the fix of php you say ,i think will be do in 2016 (seeing the slow time release of version of php :-) ). I think that for now using arr can be a right solution. Using a reader macro could resolve the problem of write more fast code

francescoagati commented 12 years ago

I believe that pharen actually is the best solution for writing right code that compile in php. Other solution like haxe or snowscript are or toomuch static on in alpha state.

Maintain a compatibility with php library is the key change, for become a big project like coffeescript.

francescoagati commented 12 years ago

i have see that also clojurescript use his list for array https://gist.github.com/1141054

Scriptor commented 12 years ago

I think for the most part PHP developers rarely use the array functions on ArrayAccess objects, so this is why this feature doesn't have much demand. I'll stick to arr for now as a reader macro isn't strictly necessary and just adds more syntax bloat.

Thank you, it's good to see the project get appreciated :) I agree that being compatible with existing PHP code from other libraries is important. Once people start using Pharen more it'll be clearer just how it's used with external libraries. It might be more practical to use PHP arrays instead of vectors in that case. Ideally, I'd like the style to be for most Pharen code to be independent and only deal with external libraries at specific points.