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).

Friday, December 19, 2008

templating dsl

So I am evaluating different ways of using my new "view adapter" templating engine. Sparing the details I would like to try out a few different versions of syntax. Straight php, s-expressions and then let/smalltalk.

#PHP
$layout = Array('border_layout',
'center' => 'this is the center',
'south' => Array('border_layout',
'north' => 'this is the north of the south',
'south' => 'this is the south of the south'),
'north' => Array('form', 'method'=>'POST', 'with'=>Array(
Array('input', 'name'=>'first_name', 'label'=>'First Name'),
Array('submit', 'value'=>'Save')));


One nice thing about the php approach is that I can combine integer indexed with associative indexed arrays thus Array('submit', 'value' => 'Save') becomes possible as opposed to Array('type' => 'submit', 'value' => 'Save'). Clearly the adapter has to know that [0] is the type and thus shift that off before rendering the rest of the component.

#LET
$layout = [border_layout
center:'this is the center'
south:[border_layout
north:'this is the north of the south'
south:'this is the south of the south']
north:[form method:post with:[
[input name:first_name label:'First Name]
[submit value:Save]]];

As let sits atop php the same combination of integer indexed and associative indexes applies here too. Clearly replacing => with : and dropping quotes around single word keys and value makes things nicer as does making the commas optional as lists are white space seperated. As a note the reason I am dropping quotes is that within let there are no constants unless they are class constants. Thus there would never be a time you "accidentally" used a constant instead of a key. Also [] is not used for indexes or pushing values onto array in LET as it is more "smalltalk esque" in that you use methods for all things. And the reason I am not using [$var|$body] for code blocks is that I am using {$var|$body} as they are not used in smalltalk and coming from c/php { } feels right to me to denote a block of code.

#S-EXPR
$layout = (border_layout
(center 'this is the center')
(south (border_layout
(north 'this is the north of the south')
(south 'this is the south of the south'))
(north (form method:post with:(
(input name:first_name label:'First Name')
(submit value:Save))))

S-expressions will always have a certain element of "balance" about them not afforded by any other syntax, next to let I prefer this for sure. Except this is not strictly "lisp"y in that I am using key:value pairs intead of :key value or (key value) groupings.

#JSON
$layout = {border_layout:{
center: 'this is the center',
south: {border_layout:{
north: 'this is the north of the south',
south: 'this is the south of the south'}},
north: {type:'form', method:'post', with:{
{type:'input', name:'first_name', label:'First Name'},
{type:'submit', value:'Save'}}};

Json is again consistent but there is no way of doing the {control, key:value} trick here except for maybe {submit:1, key:value} but that feels pretty hackish. Still at least you don't have to write Array() all over the place!

Saturday, December 13, 2008

nodes relating to nodes to relate to nodes

A design decision which I made early on was to have the simple concept of nodes which can relate to nodes to describe their very relation by more node relations. haha sound confusing? The main point of actually using a node itself to describe a relationship is for that reason exactly: to be able to store node content to describe that particular relationship. i.e. if you were to model a recipe perhaps you would want to give a more meaningful description of each ingredient in the recipe beyond just what the ingredient is and it's quantity. thus you end up with


apple pie (recipe)
-> (recipe ingredient) -> apple (fruit)
-> 1/2 cup (measurement)

-> (recipe ingredient) -> margarine (food)
-> 1 pound (weight)



I think that makes sense the trick is that each word in parentheses is indicating what type of node it is. The generalization of this relation is:


(recipe) -> (recipe ingredient) -> ((food) (measurement))


So there is a relation between recipe and recipe ingredient types. Then there are two more relations between recipe ingredient and food and measurement. You will notice that this means the relation is valid for anything descending from the specified type i.e. weight extends measurement and fruit extends food thus both beig valid relations.

Another example would be a "record"

(record) -> (pressing) -> ((format) (color) (pressing number) (number pressed))
-> (relased by) -> (band)


the point is that the structure of the node types is by nature hierarchical merely to allow the inheritence/cascading of relations. But the way the instances of nodes relate is not hierarchical at all in that any node can relate to any other node so long as the relation is established and in the main I think that is going to remain entirely open except for in the case of "system structures" i.e. want lists and "collection space collections".

collections of collections and relations of relations

I am constantly torn between the necessity of hierarchy in classifying data and the equal necessity to allow all things to remain miscellaneous. With the new collectionspace data structure I feel I am finding that middle ground at last. The key is allowing relationships between nodes to be freely described and extended. The one node which I feel is going to provide the most interesting use is the collection - which is sort of funny as it makes the name of our site relevant again in the context of our new knowledge base.

  • node

    • person

    • place

    • thing

      • record

      • shirt

      • book


    • concept

      • belief

      • date

      • number

      • measurement

        • mass

        • weight

        • volume

        • pressure

        • force

        • distance

        • time


      • color


    • collection

      • group of people
        • band

      • group of things
        • want list
        • have list





I feel this is a good start

Wednesday, December 10, 2008

On Authors and Hackers

I strive to be an author. If I were to write a piece of prose like people write "production" and "enterprise" code you would think I was trying to convey tourettes onto paper. This is not programming. It is a reflection of the neurosis created by capital.

Tuesday, December 9, 2008

initial impressions of seaside

So this is the second time I have tried to "get into" seaside and my initial impression is "man thats a lot of classes" it just feels like total overload but I know that is because I am browsing everything available within squeak as well as smalltalk - still I am just recording my impression so I can come back later and reflect upon it.

I really like the idea of storing class definitions within a db including hierarchy, methods, properties etc. and then fwriting them as actual php class files when necessary. I see this as a sort of compromise/middle ground between the apache and smalltalk image approach. I think that is definitely the direction I will be going with this eventual framework. I want to provide the minimal class hierarchy necessary to create powerful web applications with out including all of the stuff necessary for operating upon the kitchen sink.

The ability to quickly fly through classes/methods and make and commit changes is awesome. It would be pretty easy to include version control this way too!

The other idea based on this structure would be actually storing session instances of given classes.... that's something I am chewing on though in the back of my mind - but for editing/developing I think this idea has wings. Already got a basic interface together using extjs. It will be sweet when things are to the point that I can re-write it in the new language/framework but sometimes a bootstrap is necessary.

Another thing I am for sure wanting to start messing with is the idea of render/adapter-context-free views in that I can define how an interface works with out worrying about the actual display code wether that is html/css or pure extjs etc it should still function with out extra work on my part once the initial adapter is written. So the first step is coming up with what the "interface" for such an adapter would be. An interesting thing to consider is how would one action/view be rendered differently based upon extjs or plain html.