Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from static functions to namespaced functions #7

Open
padge opened this issue Apr 6, 2016 · 10 comments
Open

Switch from static functions to namespaced functions #7

padge opened this issue Apr 6, 2016 · 10 comments

Comments

@padge
Copy link

padge commented Apr 6, 2016

It would be awesome if pramda used namespaced functions (use function Pramda\map) instead of static functions (P::map). Is this sort of API possible without requiring PHP 5.6+?

@kapolos
Copy link
Owner

kapolos commented Apr 6, 2016

use function is 5.6+ only but perhaps it would be good to have the next release be 5.6+.

It is unfortunate that there isn't something like use function P\{*} available in any PHP version. My concern is, will typing multiple use function P\someFunction statements on every file in a project become uncomfortable fast? Other than that, I certainly prefer it over static functions of a class.

@padge
Copy link
Author

padge commented Apr 6, 2016

Oh I see the concern... Personally I would prefer typing multiple use function's, but it would be nice to still provide both API's so the user could choose. Would it be possible to leverage __callStatic on the P class?

use function Pramda\map;
// ...

class P {
  public static function __callStatic($name, $arguments)
  {
    if (in_array($name, ['map', /* ... */])) {
      return call_user_func_array($name, $arguments);
    }
  }
}

@kapolos
Copy link
Owner

kapolos commented Apr 6, 2016

I'm sorry, I am not sure what the above snippet intends. use function Pramda\map imports a map function that should exist standalone in the Pramda namespace - how is that connected with the P class?

@padge
Copy link
Author

padge commented Apr 6, 2016

I was just wondering if you could provide both the static methods and the standalone functions in the same version of Pramda (by making use of __callStatic in P):

P::map(function($num) { return $num * 2; }, [1,2,3,4,5]);
// or
use function Pramda\map;
map(function($num) { return $num * 2; }, [1,2,3,4,5]);

@kapolos
Copy link
Owner

kapolos commented Apr 6, 2016

Ah, I see - you mean having the functions defined in the namespace and then creating a stub P class that uses them. Thanks for the clarification!

Since we already have the class with the static functions and there are a lot of self:: calls, we could perhaps do the reverse instead with something like:

// pramda.ns.php
namespace Pramda;
use \P; /* The library, still defined outside of the namespace */

/* Stub */
function map() {
  return call_user_func_array(['P', 'map'], func_get_args());
}
// added in pramda.php
require ("pramda.ns.php");

Each function would need a stub, but that's ok - it can be automated with PHP-Parser if it ever gets tedious.

Regardless of the way, use function Pramda\map will work and P::map will keep working (for those in PHP < 5.6 or those who don't prepending the use function statements).

I like it a lot, thank you very much for the suggestion! 🍻 I will test it and include it in the next release.

@padge
Copy link
Author

padge commented Apr 6, 2016

Excellent - you're welcome! That's great that it will keep working for 5.5, nice revision 👍.

I'll be looking forward to the next release then, and thanks for porting Ramda to PHP! 🍻

@kapolos
Copy link
Owner

kapolos commented Apr 17, 2016

The feature has been implemented in branch 0.10.0

In PHP 5.6+, the first example in the Readme can be now also written as:

use function Pramda\file;
use function Pramda\map;
use function Pramda\compose;
use function Pramda\countBy;
use function Pramda\identity;
use function Pramda\negate;
use function Pramda\sort;
use function Pramda\unary;
use function Pramda\flatten;
use function Pramda\toArray;
use function Pramda\take;
use function Pramda\each;

// The above could be replaced in PHP 7+ with
// use function Pramda\{file, map, compose, countBy, identity, negate, sort, unary, flatten, toArray, take, each}

$text = file('test.php'); // Lazy read line by line with generators

$onlyWords = function ($txt) {
    return preg_split("/[^A-Za-z]/", $txt, NULL, PREG_SPLIT_NO_EMPTY);
};

$wordsPerLine = map(compose($onlyWords, unary('strtolower')));
$getFreq = countBy('identity');
$sortDesc = sort('negate');
$getWordsFrequencyDesc = compose(
    $sortDesc,
    $getFreq,
    'flatten',
    $wordsPerLine
);
$topFiveFreq = compose('toArray', take(5), $getWordsFrequencyDesc); // Just the top 5, for fun
$printEm = each(function($value, $key) {
    echo $key . ": " . $value . "\n";
});

// And now, we apply to the data
$results = $printEm($topFiveFreq($text));

Also, countBy('identity') works because now the library checks to see if the string passes corresponds to any class method, and if it does it calls that in P::apply (which is at the heart of the library).

Another feature is that now this is also possible: countBy(P::identity) (no quotes)

I will close this issue once 0.10.0 lands into master. I'll be more than happy to hear your feedback/ideas.

@ikr
Copy link
Contributor

ikr commented May 2, 2016

@kapolos

It is unfortunate that there isn't something like use function P{*} available in any PHP version.

As of 7.0 one can do this: http://php.net/manual/en/language.namespaces.importing.php#language.namespaces.importing.group

(if that helps :)

@kapolos
Copy link
Owner

kapolos commented May 2, 2016

@ikr

Thank you, certainly 🍻 (I had mentioned it as well in the comment on the snippet above below the use function lines).

In my opinion, it is slightly better but still a bit of a hassle, since you are just expanding the text horizontally instead of vertically. I think a wildcard would have been much more practical. I don't mean to sound like complaining, I find PHP 7 great - I would just love few more extras like this (and "fat arrow" closures).

@ikr
Copy link
Contributor

ikr commented May 2, 2016

@kapolos Right, right. I see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants