Git Product home page Git Product logo

nspl's People

Contributors

chriscalo avatar ihor avatar jejung avatar thmx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nspl's Issues

Head and tail

Hello

I notice that there are no head and tail equivalents for functional programming. I did notice that there is a first and a drop($sequence, 1), which are equivalent in functionality. Perhaps it would be interesting to simply alias these two? They make implementing recursion in a functional way somewhat more expressive.

Also, thanks for this neat library! Of all the libraries that have some functional programming functionality, I must say this one seems the most extensive up until now. I even decided to prioritize implementing use statement generation for qualified functions and constants in Serenata (PHP language server) to smoothen use of this library.

Allow functions to work with strings

Strings are treatable as lists of characters. Having functions such as with, map, ChainableSequence, and so on support strings, makes it easy to loop over them or perform other operations on them.

Converting a string to an array is straightforward:

$charList = [];

for ($i = 0; $i < mb_strlen($yourString); ++$i) {
    $charList[] = mb_substr($yourString[$i], $i, 1);
}

This should also support Unicode characters. Optionally, if you want to treat strings as a list of bytes (I would not make this the default, though, since it's not intuitive):

$byteList = [];

for ($i = 0; $i < strlen($yourString); ++$i) {
    $byteList[] = $yourString[$i];
}

Thanks!

Strict error

I am not sure if this is the same as issue #1 but when I do the following:

use const nspl\args\string;
use function nspl\args\expects;

expects(string, 1);

I get:

PHP Strict error: Only variables should be passed by reference

Strict mode warning

With E_STRICT enabled, the inclusion of your library produces the following warning:

Strict Standards: Declaration of nspl\ds\DefaultArray::fromArray() should be compatible with nspl\ds\ArrayObject::fromArray(array $array) in ...\vendor\ihor\nspl\nspl\ds\DefaultArray.php on line 70

update doc

I tried installing via

$ composer require ihor/nspl (this was really retrieving ^1.0)

as suggested by the github documentation but was met with quite a few errors. I then updated to the latest "1.1.*-dev" code and the errors went away. Maybe the docs can be highlighted to use the latest version to save new users from thrashing about to get it to work since the api (at least for the nspl\args namepace) has changed quite a bit.

Best way to achieve partial application with operator functions

op defines some useful function equivalents for operators, such as sum. Unfortunately, these don't take more than two arguments, which makes it impossible to partially apply an additional value into them. What would be the best solution to achieve this?

I've thought about allowing them to accept arbitrary arguments, but in the strictest sense they are correct as they are (most of them are monoids, after all).

Another solution may be to provide an additional function, like so:

function infinitize(callable $function, int $arity): callable
{
    $looper = function (...$arguments) use (&$looper, $function, $arity) {
        $intermediateResult = $function(...array_slice($arguments, 0, $arity));
        $remainingArguments = array_slice($arguments, $arity);

        return $remainingArguments === [] ?
            $intermediateResult :
            $looper($intermediateResult, ...$remainingArguments);
    };

    return $looper;
}

This would allow making these functions infinite, for example:

assert(infinitize(sum, 2)(1, 2, 3, 4, 5) === 15);
assert(rpartial(infinitize(sum, 2), 5)(1, 2, 3, 4) === 15);

But perhaps there already is an easier way to achieve this?

If not, feel free to pluck this function and pop it in the library if you want, it may need some additional exeption handling, in that case.

[RFC] Auto-currying

Hi 👋

First of all: THANK YOU for this awesome library, I can now make use of some of my FP and Ramda knowledge in PHP 👍

One thing I miss from Ramda though is the default currying of the lib functions. Would you be open to seeing this feature implemented? I’m personally willing to pour some work into it if deemed relevant.

For example, without default currying:

<?php

private function calculateAverageRating(): float
{
    if (!count($this->ratings)) {
        return 0.0;
    }
​
    return pipe(
        $this->ratings,
        partial(map, methodCaller('getScore')),
        partial(reduce, sum),
        rpartial(div, count($this->ratings))
    );
}

…and with default currying:

<?php

private function calculateAverageRating(): float
{
    if (!count($this->ratings)) {
        return 0.0;
    }
​
    return pipe(
        $this->ratings,
        map(methodCaller('getScore')),
        reduce(sum),
        rpartial(div, count($this->ratings)) // here the code won’t benefit from auto-currying since we still need to «revert» the parameter order, but anyway
    );
}

This can’t impact all functions though, as it must not change their signature or internal logic, for example pipe() works quite differently than Ramda’s implementation, and we pass the data to it as the first argument, so I guess currying pipe() by default does not really makes sense in that context. And obviously, higher-order functions like the ones in the nspl\f namespace are not good candidates for this either, for obvious reasons. I guess trying to implement this only for nspl\a and nspl\op functions could be a good start.

Also, one way to keep strict backward compatibility could be to create «parallel» namespaces that would mirror the original ones, only their functions would return the curried versions of the original ones. For example we could create a nspl\c\op.php that would contain the nspl\c\op namespace, containing all the curried versions of the functions in nspl\op.

The implementation could stay very simple and reuse the lib’s existing curried() function, so for example:

namespace nspl\c\op;

use const nspl\op\sum as _sum;
use function nspl\f\curried;

function sum(...$args)
{
    $curriedSum = curried(_sum);

    foreach ($args as $arg) {
        $curriedSum = $curriedSum($arg);
    }

    return $curriedSum;
}

(This implementation is obviously stupid, but it serves illustration purposes only.)

What do you think? This is a very raw proposal and of course there is a lot of potential side-effects, so let’s discuss about it! 🙂

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.