Saturday, July 17, 2010

solving the word cube in voltron

In response to: http://programmingpraxis.com/2010/07/13/word-cube/


/* returns array of words found in the 9 letters provided */
function solveCube($letters) {
$words = newType(TFile, 'words.txt')->splitBy("\n");

return newType(TString, $letters)
->asArray
->powerSet('contains', $letters[4])
->map('permutations', I('asString')->in($words))
->map('join');
}

echo solveCube('ncbciune');


There are a few alternative ways that could be written and I am not sure if the idea of just having an optional filter as arguments to powerSet and permutations is entirely intuitive but the reality is that w/o the filter permutations will die on anything over 8 unless you crank the memory up in php.ini and thats just filthy.

Next post I will delve into iterative permutation and powerset internals on Array as that is obviously where the meat of that solution lies.

Monday, July 5, 2010

voltron model calculated fields

In the field definition of a voltron model you usually specify the field and the type as a key => val associative array. In the case that you have a calculated field the current practice is to specify field => array(Type::Calculated, 'methodNameOnRecord'). With fluent lambdas I have added a short cut:


class TimeRecord extends Voltron_Model
{
protected $table = 'time_record';

protected $fields = array(
'id' => Type::Primary,
'created' => Type::Timestamp,
'created_hour' => Type::Calculated('created')->asDateTime->formatAs('H'));
}


The magic lies with in the created_hour type definition which can also be written as Type::Calculated(I()->created->asDateTime->formatAs('H')).

Because of the oo and fluent nature of Voltron the majority of calculated fields can be defined this way rather than requiring an actual method definition in the record class.

Wednesday, June 30, 2010

voltron and "fluent lambdas"

For lack of a better name I am sticking with "fluent lambda" which essentially is how I get around the lack of nice lambdas in php. Even in php 5.3 I find the function($val) { return $val + 1; } syntax to be overkill. I would much rather see L(val)->add(1)

Lets say you have a list of names and you want to reverse them, uppercase them and then join them by an & symbol. Currently in raw php you have a few options but the cleanest is probably something to the effect of either:

Idiomatic php:

$names = array('peter', 'paul', 'mary');
foreach($names as $key => $val) {
$names[$key] = strtoupper(strrev($val));
}
echo join('&', $names);


Functional php:

$names = array('peter', 'paul', 'mary');
echo join('&', array_map(create_function('$val', 'return strtoupper(strrev($val));'), $names));


Functional php 5.3:

$names = array('peter', 'paul', 'mary');
echo join('&', array_map(function($val) { return strtoupper(strrev($val)); }, $names))


Voltron:

$names = newArray(VString, 'peter', 'paul', 'mary');
echo $names->map(L(val)->reverse->upper)->join('&');


This works by the global function L which takes either 'key' or 'val as an argument and then returns a created function which passes along the same method chain.

Where the real advantage comes to not passing around "string lambdas" i.e. the create_function approach - is when you start dealing with nested lambdas i.e.

functional php:

$listOfList = array(
array('a', 'b', 'c'),
array('d', 'e', 'f'));

echo join('<hr>', array_map(create_function('$val', 'return join(\',\', array_map(create_function(\'$val\', \'return strtoupper($val);\'), $val));'), $listOfList));


Voltron:

$listOfList = newArray(VArray,
newArray(VString, 'a', 'b', 'c'),
newArray(VString, 'd', 'e', 'f'));

echo $listOfList->map(L(val)->map(L(val)->upper)->join(','))->join('<hr>');


So whats next? I am probably going to integrate this with my closure class from my lisp so that you can pass in vars, but immediately my needs are mainly for calling methods on objects in a given array. But I can imagine that being one of the first annoyances people run into.

Basically I am trying to get at the idea that oneliners don't have to be made of gnarleston heston.

perl:

@p=(0,1);until($#p>20){print"$p[-2]\n";push @p,$p[-2]+$p[-1]}


Voltron:

echo newRange(0, 1)->expand(L(x)->add(y), 20)->join("\n");


Here is an example of finding primes.

Python:

noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
primes = [x for x in range(2, 50) if x not in noprimes]


Voltron:

$noprimes = newRange(2, 8)->map(N(VRange, L(y)->times(2), 50, y))->flatten;
$primes = newRange(2, 50)->diff($noprimes);

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.