GithubHelp home page GithubHelp logo

pawaclawczyk / scalp Goto Github PK

View Code? Open in Web Editor NEW
18.0 7.0 1.0 85 KB

Some Scala useful classes ported to PHP.

PHP 99.63% Makefile 0.37%
php7 try try-catch immutable option maybe types pattern-matching

scalp's People

Contributors

pawaclawczyk avatar

Stargazers

 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

Forkers

simonlucalandi

scalp's Issues

Iterator of placeholder replacements is advanced not only when replacement is consumed.

See line 40. Iterator should be advanced only when placeholder is replaced with value.

private function applyArguments(array $arguments): array
{
$argsIterator = new \ArrayIterator($arguments);
$replacePlaceholders = function ($arg) use ($argsIterator) {
$replacement = $arg === __ && $argsIterator->valid()
? $argsIterator->current()
: $arg;
$argsIterator->next();
return $replacement;
};
return array_map($replacePlaceholders, $this->arguments);
}

Type PartialFunction

Type partial function represents a function which is undefined for some elements of the domain.

Example

f(x) = 42 / x is not defined at x equal 0

Minimal interface

interface PartialFunction
{
    public function isDefinedAt($x): bool;
    public function __invoke($x);
}

Maybe some additional logic and encapsulation in trait could be a good idea.
TDB

Abstraction around regular expressions

Example of current usage of regular expression.

private function elementId(string $propertyName): Option
{
    preg_match('/^_(\d+)$/', $propertyName, $matches);

    return isset($matches[1]) ? Some((int) $matches[1]) : None();
}

Complex type deconstruction

Scalp\PatternMatching\Deconstruction trait provides construct and deconstruct methods, holds internally data that represents construction arguments.

Problem related with current implementation:

  1. Destruction::construct must be called manually with right arguments. It's easy to forget or passed wrong arguments.
  2. Constructor arguments are duplicated, one copy is managed by object and second is hold inside trait.

Improvement proposals:

  1. Destruction::deconstruct could throw exception when trying to deconstruct object that was never constructed.
  2. Trait should be replaced with abstract class, __construct should be used to bind type construction arguments. In this case __construct should be protected agains extension in subclasses. Abstract method should be provided to let subclasses do finish object construction.

Currying?

I see that scalp has a partial function, but it looks like said function expects that all arguments will be passed during invocation. What would it take to add a currying?

Shorthand for creating function that calls a method on its arguments

Example of usage with map method.

class Counter
{
    public static function zero(): Counter
    {
        ...
    }

    public function increment(int $step = 1): Counter
    {
        ...
    }
}

$res0 = Some(Counter::zero())
    ->map(__::increment())
    ->map(__::increment())
;

println($res0);

$res1 = $res0
    ->map(__::increment(3))
;

println($res1);
Some[Counter](Counter(2))
Some[Counter](Counter(5))

Extended handling by name parameters

In some of methods in Scala's implementation of Option and Try parameters are passed by name. In PHP we do not have such possibility and we have to pass evaluated instances of expected type. As an extension we could allow to pass zero parameter functions that returns expected type.

Partial application of function

Examples of partially applied

  • functions
  • anonymous functions (closures)
  • class static methods
  • object methods
  • callable objects
function f($x, $y) { return ... }

$g = function ($x, $y) { return ... }

class F
{
    public static function sf($x, $y)
    {
        return ...
    }

    public function m($x, $y)
    {
        return ...
    }

    public function __invoke($x, $y)
    {
        return ...
    }
}

$fc = new F();

papply(f, __, 2);              // => f(__, 2)
papply($g, __, 2);             // => $g(__, 2)
papply(F::class, 'sf', __, 2); // => F::sf(__, 2)
papply($fc, 'm', __, 2);       // => $fc->m(__, 2)
papply($fc, __, 2);            // => $fc(__, 2)

Passing PFA as argument of flatMap or recoverWith generates error.

flatMaps and recoverWith are protected with check that ensures the passed callable will return an expected type ie. Option or TryCatch.

In case of passing partially applied function the real function is wrapped in callable that does not have return type hinting.

Callable type restrictions

At this moment Success::flatMap and Failure::recoverWith functions use function restrictCallableReturnType to check whether callable passed as argument has defined return type to TryCatch. It rises TypeError in case when return type is not defined or it is different than expected.

The proposal is to add checks enforcing also callable arguments types, ie example check input argument of callable passed to TryCatch::map or TryCatch::filter or similar functions. Type checks could be also used for checking consistency of functions passed to methods like TryCatch::transform.

Instead of using functions that throws TypeError directly we can introduce checkers returning boolean type and use them in combination with assert.

Patterns for types with variadic constructor like Tuple

Right now when type is matched it is expected that number of provided patterns must be the same as number of arguments used for construction. This behavior is unexpected when discussing types constructed with variadic number of arguments. It could be possible to provide different case pattern for different number of arguments in constructor.

In example below three commented statements will be break by InvalidPatternsNumber exception.

<?php

declare(strict_types=1);

require_once __DIR__.'/../vendor/autoload.php';

use Scalp\Collection\Tuple;
use function Scalp\PatternMatching\match;
use function Scalp\PatternMatching\Type;
use function Scalp\PatternMatching\Any;
use function Scalp\println;

function tupleName(Tuple $tuple): string
{
    return match($tuple)
        ->case(Type(Tuple::class, Any()), function () { return 'Singleton'; })
        ->case(Type(Tuple::class, Any(), Any()), function () { return 'Pair'; })
        ->case(Type(Tuple::class, Any(), Any(), Any()), function () { return 'Triple'; })
        ->case(Type(Tuple::class), function () { return 'Other tuple'; })
        ->done();
}

//println(tupleName(new Tuple(1, 2)));
println(tupleName(new Tuple(1)));
//println(tupleName(new Tuple(1, 2, 3, 4)));
//println(tupleName(new Tuple(1, 2, 3)));

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.