xp-framework / compiler

Compiles future PHP to today's PHP.
19 stars 0 forks source link

Implement partial function application #113

Closed thekid closed 3 years ago

thekid commented 3 years ago

Examples

This code:

class Person {
  public function __construct(public int $id, public string $name) { }
}

// Returns an array of three Handle instances
$handles= array_map(fn($_) => new Handle($_), [STDIN, STDOUT, STDERR]);

// Use time() function in production, specialized testing clock for unit tests
$time= $test ? new TestingClock() : 'time';

// Executes HTTP request, then returns a function to read the given input stream
$in= $http->get()->in();
$read= fn() => Streams::readAll($in);

// Creates instances from database records and writes them to the console
Sequence::of($conn->query('select * from person'))
  ->map(fn($_) => new Person(...$_))
  ->each(fn($_) => Console::writeLine('> ', $_))
;

...can be rewritten to:

class Person {
  public function __construct(public int $id, public string $name) { }
  public static function from($record) { return new self(...$record); }
}

// Returns an array of three Handle instances
$handles= array_map(new Handle(?), [STDIN, STDOUT, STDERR]);

// Use time() function in production, specialized testing clock for unit tests
$time= $test ? new TestingClock() : time(...);

// Executes HTTP request, then returns a function to read the given input stream
$read= Streams::readAll($http->get()->in(), ...);

// Creates instances from database records and writes them to the console
Sequence::of($conn->query('select * from person'))
  ->map(Person::from(?))
  ->each(Console::writeLine('> ', ?))
;

See also

Depends on xp-framework/ast#26

thekid commented 3 years ago

If we allowed unpacking of placeholders via ...?, we could further simplify the sequence example:

class Person {
  public function __construct(public int $id, public string $name) { }
}

// Creates instances from database records and writes them to the console
Sequence::of($conn->query('select * from person'))
  ->map(new Person(...?))
  ->each(Console::writeLine('> ', ?))
;
thekid commented 3 years ago

When we pass around objects as parameters, the placeholder would have to be able to replace the object in something like the following:

$filtered= Sequence::of(...)->filter(fn($user) => $user->isActive());
$filtered= Sequence::of(...)->filter(?->isActive());

Hrm...

thekid commented 3 years ago

RFC was declined, closing

faizanakram99 commented 7 months ago

RFC was declined, closing

it would have been still a nice feature