Skip to content
Uğur Güney edited this page Sep 7, 2019 · 2 revisions

Exercise 08 - Kick Forward

Other names:

  • Continuation-passing style
  • Crochet loop

First tried to place functions at module-level and call them from main function.

function read_file(string $filepath, (function(mixed, mixed): void) $func): void {
  $text = \file_get_contents($filepath);
  $func($text, filter_chars);
}

function filter_chars(string $text, (function(mixed, mixed): void) $func): void {
  $pattern = re"/[\W_]+/";
  $replaced = Regex\replace($text, $pattern, ' ');
  $func($replaced, normalize);
}

...

function main(): void {
  read_file($filepath, filter_chars);
}
  • this didn't work, because can't refer functions this way.
  • tried to be smart and wrap functions in lambda expressions
function main(): void {
  read_file($filepath, $x ==> filter_chars($x));
}
  • But this won't work because filter_chars takes two arguments, the second being the next function in callback chain.
  • which will result in putting the whole chain in the main function instead of locally determining next function in the previous function.
  • I need to refer to the functions just using their names, without dealing with arguments.
  • Hence went with the solution of putting all functions into a class and make them static. Now I can refer them via HH\class_meth(Functions::class, 'FUNC_NAME').

When declaring functions I chose to make the type of every second argument (function(mixed, mixed): void) $func.

  • I could have used the first argument to indicate the type of the input and get rid of the mixed.
  • However, there is no way of getting rid of the second mixed. Any attempt to reduce the type to a function will end up needing to putting the types of the whole callback chain there. Hence went with symmetry, since we already had given up on well typing in this style.
  • Though $func has to be (function(): void) and can't be mixed. Otherwise can't call $func() in the body.
Clone this wiki locally