Wednesday, September 30, 2009

APL jot dot in scheme and php

So I am implementing APL in php... As a matter of practice of course I am prototyping things. The ultimate scheme yields an oo/fluent expression approach but immediately here is how I would implement jot dot in php and scheme:

PHP:

function jotDot($fun, $v1, $v2) {
$result = array();
foreach($v1 as $x) {
$result[$x] = array();
foreach($v2 as $y) $result[$x][$y] = $fun($x, $y);
}
return $result;
}


Scheme:

(define (mapcar func list)
(if (null? list) '()
(cons (func (car list)) (mapcar func (cdr list)))))

(define (jotDot func v1 v2)
(mapcar (lambda (x) (mapcar (lambda (y) (func x y)) v2)) v1))


I am not going to lie - the scheme is definitely more elegant but it is not as readable as the php. I think that is sort of interesting. Maybe mapcar is not the right abstraction for the job and there is a better approach. Oh yeah in APL:

The eventual "fluent expression" APL->php interpreted code to do something like calculating a times table up to 12 would look like:

$V = APL()->indexGenerator(12);
$V->jotDot('times', $V);

Monday, July 27, 2009

more php5 musing

Whilst in normal php-land another livable library for me is going to be my phparrayplus leveraging anon functions.


$results = StaticClass::methodReturnsArray($arg)->eachPair(function($i, $x){
return $x->lookMaNoTmpVars($i + 1);
});


In my opinion so much prettier than

$results = StaticClass::methodReturnsArray($arg);
foreach($results as $i=>$x){
$results[$i] = $x->lookMoCrappTastic($i + 1);
}

Monday, July 20, 2009

curry in php 5.3

Here is curry in php 5.3

function curry(){
$args = func_get_args();
$fn = array_shift($args);
return function() use(&$fn, &$args) {
$nargs = func_get_args();
foreach($nargs as $narg) $args[] = $narg;
return call_user_func_array($fn, $args);
};
}

$add20 = curry(function($a, $b){return $a + $b;}, 20);
echo $add20(5); #25

Friday, July 3, 2009

php 5.3 y combinator and other musings

Whenever I get excited about php 5.3 and start foaming at the mouth about lambdas/closures etc. I think I probably just come off like a wing nut. So here is the "canonical example" converted from the work of this dudes javascript example: http://rayfd.wordpress.com/2007/05/06/y-combinator-for-dysfunctional-non-schemers/


function apply(){
$args = func_get_args();
return call_user_func_array(array_shift($args), $args);
}

function Y($f) {
$recur = function($r) use($f) {
return function($n) use ($f, $r) {
return apply($f($r($r)), $n);
};
};
return $recur($recur);
}

$fibo = Y(function($f) {
return function($n) use ($f) {
if($n <= 2) {
return 1;
} else {
return $f($n - 1) + $f($n - 2);
}
};
});

echo $fibo(15); #610

You'll notice the main trick is the explicit closures using the "use" keyword. I think I almost DO like this solution as it is rather explicit about what vars you are closing over.

Here is another example taken from the first chapter of SICP:

define('tolerance', 0.00001);

function fixed_point($f, $first_guess){
$close_enough = function($v1, $v2){
return (abs($v1 - $v2) < tolerance);
};

$try = function($guess) use(&$try, $f, $close_enough){
$next = $f($guess);
return $close_enough($guess, $next) ? $next : $try($next);
};

return $try($first_guess);
}

echo fixed_point('cos', 1.0); #0.7390822985224
echo fixed_point(function($y){return sin($y) + cos($y);}, 1.0); #1.2587315962971

Other than the ugliness that is the mandatory return statements and semi-colons even for the last/only statement in a function... I actually sort of dig this.

The only trick in this example is "use(&$try, ..." clause which passes a ref to $try so the function can call itself.

Here are some more cool scheme tricks. Creating cons, car, cdr, lst etc. from closures:

function cons($x, $y){
return function($m) use(&$x, &$y){
return $m ? $x : $y;
};
}

function car($z){ return $z(true); }

function cdr($z){ return $z(false); }

define('nil', null);

function lst(){
$args = func_get_args();
return cons(
array_shift($args),
empty($args) ? nil : call_user_func_array('lst', $args));
}

function length($items){
return $items == nil ?
0 :
1 + length(cdr($items));
}

function append($list1, $list2){
return $list1 == nil ?
$list2 :
cons(car($list1), append(cdr($list1), $list2));
}


Obviously the performance implications here have not been explored - it's purely academic but interesting to see what is now possible.

Want to implement your own objects? Here is a perl-esque approach returning a hash of functions and using a ref to $self for accessing methods within the object:

function person($age){
$self = array(
'get_age' => function() use(&$age){
return $age;
},
'set_age' => function($new_age) use(&$self, &$age){
$age = $new_age;
return $self['get_age']();
}
);
return $self;
}
$peter = person(20);
echo $peter['get_age'](); #20
echo $peter['set_age'](50); #50
echo $peter['get_age']() #50


Another thought that came to mind was "ghetto macros" by either abusing the $GLOBALS var to create functions or returning an array one could extract into an environment of their choice. Behold:


function many_methods($name, $x){
$GLOBALS['get_'.$name] = function() use(&$x){
return puts($x);
};

$GLOBALS['set_'.$name] = function($y) use(&$x){
$x = $y;
};
}
many_methods('tony', 20);
$get_tony(); #20
$set_tony(500); #500
$get_tony(); #500

function clean_many($name, $x){
return array(
'get_'.$name => function() use(&$x){
return puts($x);
},
'set_'.$name => function($y) use(&$x){
$x = $y;
});
}

function inner_scope(){
extract(clean_many('walter', 400));
$get_walter();
$set_walter(500);
}

etc. etc. etc.

Wednesday, June 24, 2009

recess framework and metacircularity

The collection space has been in the process of an overhaul for some time now in preparation for some huge structural and philosophical changes that we have in the pipeline. One of the biggest challenges has been committing to a framework for php. I have evaluated (and used for client projects etc.) zend, cake, codeigniter etc. and all of them fall short of making me feel like they are increasing my productivity rather than getting in my way as they weakly attempt to adhere to design patterns. I have been working on my pet framework in the background for some time but even that I would not want to commit to for a project of this magnitude as it bumps documentation up in priority for other developers to be able to be productive with out me guiding them through things.

So what then? Recess (http://www.recessframework.org/) has shown up and been the only framework in php that I've kept my eye on and been constantly more impressed rather than more disappointed when I start looking into the internals. Being a young project I feel it is an ideal candidate for a lot of the code generation and object modeling tools that I have been playing with for voltron. Once cspace is live (july 9th) I plan on formalizing a lot of the tools that have helped me with Recess - mainly the object browser/editor and metacircular parser. What does that mean? It means I can edit files in and editor or individual methods through a browser based object browser/editor and not have an issue. I have another approach for views which I may offer up but it seems like Recess has some cool stuff in store so I will wait and see. But for cspace I am going forward with our view approach (no html, s-expression format called LET).