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.

trying to put my finger on it

So I am constantly trying to entirely re-evaluate the entire way that I/we currently develop web "applications". There are a few things which profoundly bother me.

Lack of object persistence (I go to a page which is deep with in a business app which requires several "models" to be loaded into memory in order to generate a given interface. Now I want to populate something via ajax so I pass in the relative IDs (or if I am lucky the IDs are in a session, regardless) the page then has to again load those SAME models into memory (temporarily) to fetch some sort of related json tidbit).

Too much coupling to one particular "display stack" i.e. html, css, xhtml, javascript (extjs) - surely my "view" should have the intended layout recorded in a meaningful and timeless manner including callbacks/events and then have it be implemented by what ever adapter/rendering method I choose i.e. html or extjs or svg or what ever comes down the pipeline! this way there is a simple "plugging in" of a new adapter which meets the protocol for rendering and away I go.

My new framework/language/paradigm is going to tackle these problems absolutely.

Monday, December 8, 2008

lisp+smalltalk+php ?

So I am closing on a a complete set of rules for my syntax:

#use . to denote end of statement
#list
:(1 2 3 4).

#boolean
($this == $that).

#block
{$x $y | $x*$y}.

#message
[$object method_call: $arg with:[object method:$sub]].

#use ; to denote "with"
[$object methoda;
methodb;
methodc].

#to emulate int objects anytime a square bracket encounters an int
#it will "cast" as intobject thus:
[1 to: 20 do: {$n | echo $n}].

#transmogrifies to
$intObject(1)->to(20)->apply('lambda_block_n');

#it may be the case that the int methods could be factored into more
#procedural form even such as for loops etc. It all depends on performance.
#but pre-optimization is definitely NOT what I am going for here

The real beauty to this is largely that we can overload operators and not have to use s-expressions to do so i.e. if I decided I wanted / to diff arrays I could easily add a method to the ArrayObject called / which accepts an array as an argument and then calls array_diff between self and the passed array:


[:(1 2 3 4 5) / :(2 4 7)]. #yields (1 3 5 7)

#transmogrified to
arrayObj(1,2,3,4,5)->__SYMB_DIV(arrayObj(1,2,3,4,5));

#hmm may get ugly with nested hash
$hash = :(a:(b:(c:true))).

#it feels unbalanced but
$hash = :(a::(b::(c:true))). #is far worse

#or I could stop being an idiot and use #
[#(1 2 3 4) each {$n | echo $n}].

#my only hesitation is as illustrated here, # is used for comments in c-alikes.

more on syntax

The more I think about it the more it becomes apparent that logically using square brackets for codeblocks/lambdas does NOT make sense for what I am trying to accomplish with let. Using { } for anon blocks and ( ) for lists as well as "grouping" and boolean statements makes much more sense thus saving square brackets for sub-statements and removing [ ] from arrays entirely as they can use dot notation or accessor methods. Consider:

$list = (1 2 3);
$list.each {$x | echo $x};

$number = let ($x = 10){
(add:{$y | $x += $y}
sub:{$y | $x -= $y});
#note if we wanted the method to be named add: we would do 'add:':{$y | $x += $y}
}
$number.add 10; #20
$number.sub 5; #15

#And from last time:
$decide = {$char | $char == a ? sum : mul};

$num = 10;
$letter = a;
$result = [$decide char:$letter] 6 6 ($num + 50);

Notice in the last one that this makes square brackets the equivelant of "apply" and keeps open brackets for grouping and or boolean operation which is what people coming from php would expect. The { } also feels more natural for anon code blocks for php-centric people as well.

Another approach would be using square brackets for "messages" sort of like obj c but more like sugar for dropping dots in objects i.e.

$range = (1..5);
[$list reverse each {echo _}]
#becomes
function block_name($arg0){echo $arg0;}
$list->reverse->each('block_name');

Sunday, December 7, 2008

philosophy of duality of syntax

Now for a more text-ful approach to describing the problem and my approach towards a solution. It's interesting that as I have been slowly changing php to suit my needs I have been grappling with the issue of consistency much like the developers of py3k have. It seems that in an attempt to "make things consistent" they have tried to make everything work like a function i.e. no more print 'string', now it is print('string') - this feels, to me, like they took the wrong fork in the road. Instead of making print work like a function why not make all functions work like keywords/in built functions?

I guess I am in my ivory tower but really if I am going to create a language/dialect which I ENJOY coding in day in/day out I am not worried about backward compatibility and or what people are used to - I am worried about what makes things consistent and beautiful. The obvious choice for the most consistent approach would be straight s-expressions but there is something to be said for the readability of declaration and assignment. My approach is basically s expressions with out the initial brackets i.e.


#LET
$x = func arg:val arg1:val2 arg2:(func1 arga:vara);

#s-expr
(setf x (func arg:val arg1:var arg2:(func1 arga:vara)));


Now I can fully see how the s-expression is more perfectly recursively consistent but I personally find the prior approach more readable and for "in the main" programming it would be the most maintainable.

Something I have been toying with is the idea of how to transmogrify dynamic function calls in s-expressions:


$decide = [$char | $char == a ? sum : mul];

$num = 10;
$letter = a;
$result = ($decide char:$letter) 6 6 ($num + 50);

#should become
$result = sum 6 6 ($num + 50);

#which becomes
$result = sum(6,6,($num + 50));

duality of syntax

So I have hit a bit of a conondrum with my current approach to introducing a new syntax for lambdas in LET/php.

The problem comes from the current use of square brackets to access array elements mixed with my desire for them to be lambda expressions. Consider the following:

$array = (a b c d);
$array [0]; #a

#the function expecting the yield block is passed a block which returns 0
$expecting_yield [0];

#one solution as we have dropped ( and ) for calling functions would be using
#that for array indexes, this would sort of fit with the fact that it is used
#for defining arrays.

$array = (a b c d);
$array(0); #a

$array (a:(b:(c:cat)));
$array(a)(b)(c); #cat

#what about methods stored in arrays?
$number = let($num = 5){
(mul:[$x | $x * $num]
div:[$num/_])
}

#note that _ is for anon vars and _1 _2 is if there are many

$number (mul) 10; #50
#that feels odd.

#using magic __get and keyword param
$number.mul x:10;

#that works well for keys which are strings but what of numeric index?
$array = (1 2 3 4);
$array.0 #1

#perhaps we could be clever enough to turn numeric dots into
$array[0]

#if all arrays are objects then why would you not use an accessor method?
$array = (1 2 cat 4);

#or using an accessor method - thats only one extra char (the .)
$array.at 2; #cat

#maybe removing the [ ] notation will encourage functional programming
#instead of iterating over for loops anyway?

#but what about look ups in a hash table?
$actions = (cat:walks rat:crawls bat:flies);
(cat rat bat).each [$creature |
echo "the $creature {$actions.$creature}";
];

#normal php
$actions = Array('cat'=>'walks', 'rat'=>'crawls', 'bat'=>'flies');
foreach(Array('cat','rat','bat') as $creature){
echo "the $creature {$actions[$creature]}";
}

Friday, December 5, 2008

more on let blocks

So as an aside the two are equivalent:

$func = let($x = 10){
[$y | $x = $x*$y];
}

$func = [$x | [$y | $x = $x*$y]] x:10;

The let block is obviously more readable as you understand you are creating a binding for $x and then using that binding in the let block (in this case to return a function which closes over $x).

So to leverage the power of multiple-transmogrifications the system first translates let blocks to be square lambdas and then the square lambda transmogrification can just handle everything else (including closures). I think it's dope.

Tuesday, December 2, 2008

closures in php

So here is the implementation of closures which my "language" (LET) makes use of. This would normally be another boring attempt at closures in php but I believe it is quite clean. First let me show you the code before transmogrification:


$func = let($x = 10){[$y | $x = $x*$y]};
echo $func y:2; #20
echo $func y:2; #40 (as x is now 20 having been modified by prior call to closure)

Notice the dropped brackets and keyword parameters? Also note the fact that a lambda by default returns the value of it's last statement, the let block is a form of lambda and thus also returns it's last value which is in this case the name of the generated function. Note that this is actually parsing the square lambda to determine if it makes use of any free variables, if so it creates a closure otherwise it will just create a "normal" function. Because of the fact I am parsing and then writing the new php file I can take my time instead of just dumping in get_defined_vars (holy waste of memory batman). Also note that if the square lambda were to have passed in $x as a variable "before the pipe" than it would NOT consider $x a free variable and thus not create a closure.

First the simple class for handling closures

class __Closure{
private $method;
private $env;
function __construct($method, $env){
$this->method = $method;
$this->env = $env;
}

function call(){
$args = func_get_args();
$args[] = $this->env;
return call_user_func_array($this->method,$args);
}
}


And now the transmogrified version of the let statement:


function lambda_closure_0($y,$env){
return $env['x'] * $y;
}

function lambda_func_0($y){
return $GLOBALS['lambda_closure_0']->call($y);
}

function lambda_let_block_0($x){
$GLOBALS['lambda_closure_0'] = new __Closure('lambda_func_0',Array('x'=>&$x));
return 'lambda_func_0';
}

$func = lambda_let_block_0(10);
echo $func(2); #20
echo $func(2); #40

The clever part of this whole thing is determining at parse time which "free" variable are being accessed by the square lambda and then passing them to a new instance of __Closure class by reference (thus: Array('x' => &$x)).

Notice that it is a LOT more code once the let block has been expanded by the tansmogrifier. This is the entire point of the project -expand to verbose and yet simple code which tries to make minimal use of any create_function calls.

When php 5.3 becomes "acceptable" and on all the servers I use then I will make the transmogrifier use the new "uses" clause with the inline function syntax but that's precisely the beauty of the transmogrifier - my syntax stays the same and the underlying php can be optimized instead. This is the art and beauty of meta programming.

Sunday, November 30, 2008

on the road to lisp

So one of my goals with my new syntax was to eliminate the un-necessary. It's funny that as I did that I slowy ended up with a s-expression-like feel. Check it:

#So we start with a function:

function filter($array, $field, $pattern=false, $limit=0, $above=0){
}


#first we make an array of users

$users = Array(Array('name'=>'shaun','age'=>26),Array('name'=>'peter','age'=>60));


#now we can filter it

$newusers = filter($users, 'age', false, false, 25);


#clearly if we didn't have the definition of function right above us it would get confusing. So the first thing that would make it more legible is keyword parameters.

$newusers = filter(array:$users, field:'age', above:25);


#whats nice about that is we can leave out the params we don't need and just pass the ones we do thus allowing functions to start to become more of a DSL. Still this feels akward, what if we dropped the brackets? They're just a security blanket anyway.

$newusers = filter array:$users, field:'age', above:10;


#now we're getting somewhere but why not drop the comas and just infer from the whitespace that there are seperations?

$newusers = filter array:$users field:'age' above:25;


#sweet, but now that we can match functions why not allow "other words" to make it read more like a sentence and just have the parser ignore them? This way we don't clutter our methods, objects and keyword params with meaningless "joining words"

$newusers = filter the array:$users where field:'age' is above:25;


#that would end up getting parsed into:

$newusers = filter($users,'age',false,false,25);


#thus it does not add overhead but creates a much more readable "inline-commented" version which can thus easily modified by someone who did not write the original code or method.

#now what about the array declaration? using our concept of dropping the un-necessary lets use key:value pairs and no commas

$users = ((name:'shaun' age:25) (name:'peter' age:60));


#that definitely feels nicer than php or the json approach in my book. What is the obsession with commas? What purpose do they provide that white space does not?

#the next question is probably: what about inline expressions and or method calls i.e.


function get_users($group,$limit){}

$users = filter array:getusers group: 10 limit: 10 field:'name' pattern:'/[a-z]*/i';


#cleary we have some issues how can the parser group the arguments? well:

$users = filter array:(getusers group:10 limit:10) field:'name' pattern:'/[a-z]*/i';


#holy s-expressions batman!

Wednesday, November 26, 2008

bootstrapping the bootstrap

So to implement lisp in a "non-ugly" manner I am going to first complete my php+ syntax (ruby, python, smalltalk type stuff) and THEN use that to write the lisp transmogrifer. HAHA.

getting emotional over lisp

Man, what a journey. I started this blog quite a while ago with the intention of bringing lisp-esque elegance to php. This led to phparrayplus (which I still think is really cool considering it works in just "normal" php) and fluent expressions being used to implement DSLs. Now I have the transmogrifier which allows me to implement custom syntax in native php with no extra .so or extension. I am now using that same transmogrifier to implement lisp syntax and functionality (yes macros included). It is a thing of great beauty. I keep having moments of "this is genius" paired directly with "this is insane. what am I doing?" hahaha.

Tuesday, November 25, 2008

compilers, transmogrifiers and dragons oh my

So I have been pretty busy implementing the transmogrification library which is allowing me to add new syntax to php which is compiled by php into php. Some of the things I have already implemented include:

let locks, inline lambdas, yield blocks, with blocks, native json, function calls with keyword parameters and "dot [.]" notation for object method/param access... When it's all bug tested we will be releasing it on google code.

the collection space is going to be written using the transmogrifier.

Once we are done with the ruby/python/perl type constructs I am going to be using the lbirary to implement lisphp.

Friday, November 21, 2008

a tasty tidbit to scratch an itch

One of my favorite perl constructs is the ability to put an if statement after a print statement:

print 'test' if($x == 2);

In php that becomes

if($x == 2) echo 'test';

Not strictly longer but the phrasing feels wrong.

Extending the chain class like so I can do this:

class Puts extends Chain{
var $val;
function __construct($val){
parent::__construct();
$this->val = $val;
}

function __if($condition){
if($condition) echo $this->val."\n";
}
}

function puts($string){
$new = new Puts($string);
return $new;
}

$x = 2;
puts('this is an assertion')->if($x == 2);

#this would be nice for debugging
puts('this is a debug message')->if(DEBUG);

Thursday, November 20, 2008

fluent expressions and conditionals

One problem I have encountered when designing "dsl" fluent expressions in php is conditionals.

If you are chaining methods and you have a method a which could fail and thus affect method b it is best to execute them independently and check the validity with an if clause before calling method b.


class Chain{
var $valid;
var $__methods;
var $__class_name;

function __construct(){
$this->valid = true;
$this->__class_name = get_class($this);
$this->__methods = get_class_methods($this->__class_name);
}

function __get($arg){
if(in_array($arg,$this->__methods)){
return $this->$arg();
}
}

function __call($arg,$data){
if(!$this->valid){
return $this;
}
$arg = '__'.$arg;
if(in_array($arg,$this->__methods)){
return call_user_func_array(Array($this,$arg),$data);
}
}

function __if($arg){
$this->valid = $arg;
return $this;
}

function __method1($value){
echo $value."\n";
return $this;
}

function start(){
$this->valid = true;
return $this;
}

function stop(){
$this->valid = false;
return $this;
}
}

function chain(){
$new = new Chain();
return $new;
}
chain()->if(false)->method1('will not display');

$x = 10;
chain()->if($x == 10)
->stop
->method1('wont work')
->if(false)
->start
->method1('will not work - will now')
->if(false)
->method1('will not work either');

Wednesday, October 29, 2008

Ideas for php extension/mod

I am considering different ways in which I could modify php to make it more to my liking. My biggest "want" is probably "code blocks"/functions which can be passed to functions which require a body and NOT having them be strings i.e.

xR(1,100)->reduce({$x,$y | $x*$y});

xR(1,100)->reduce([$x,$y | $x*$y]);

funcname($arg1)[$x | echo $x];

Which would be more of a smalltalk/ruby approach. i like the idea of using { } as it is used through out the language to denote blocks. However, I would also like to see a python/javascript notation for arrays/objects/dictionaries i.e.
[1,2,3,4,5,10] is an array and {a:1,b:23} is an associative array/dictionary. The obvious issue is that { } being used for code blocks and dictionaries would be hard to parse. As I am typing aloud I think that perhaps the | in the code block would suffice but what about code blocks with no parameters? One idea which has occured to me would be to use ( ) for code blocks. i.e.

xR(1,100)->reduce(($x, $y | $x*$y));

Another nice thing would be having keyword paramaters but with json that become easy with an object i.e.

functionName({parama:$a,paramb:$b});

but wouldnt:

functionName(parama:$a, paramb:$b);

I guess thats more python esque.

I mean shit while we're at it lets get rid of -> notation and use. instead so now we have and allow an "implicit code block" to be passed in..:

xR(1,100).reduce($x,$y | $x*$y);

Also I would be implementing most of my hash class "natively" so that all arrays become hash objects with all the methods available so stuff like

[1,2,3,4,5].reduce($x,$y | $x*$y); is applicable as is 'this is a string '.trim().replace('a','b').split(' '); etc.

Numbers could be objects too
1.times(2);

Sunday, June 22, 2008

array to object

So I really get sick of:

if($promotion['req']['min'] > 10)

I love using multidimensional arrays for partitioning data/namespaces for the sake of sanity but the access is really quite.. icky. So I came up with a quick hack to turn a multidimensional array into an object so the above could be more like:

if($promotion->req->min > 10)

It saves a few characters and I think it becomes a LOT more readable as well as easier to comprehend especially on an oo level.

The code is simple/hackish:

class oArray{
/*class to turn a keyed array to object
IF a key is numeric it will be prepended with a letter n i.e. key 2 becomes n2
Really though this is meant for meaningful key=>val relationships
*/
function __construct($array){
foreach($array as $key=>$val){
$key = is_numeric($key) ? 'n'.$key : $key;
$this->$key = is_array($val) ? new oArray($val) : $val;
}
}
}
function oArray($array){
return new oArray($array);
}

You will notice that I have a function called oArray as well as a class which merely wraps the whole "$var = new object(params)" deal as that gets pretty repetitive. So Now I can do:

//instantiation
$promotion = oArray(Array(
'req'=>Array(
'min'=>50,
'max'=>100),
'grants'=>Array(
'limit'=>50,
'type'=>504))));

//access
if($promotion->req->min <= $promotion->grants->limit);
v.s.
if($promotion['req']['min'] <= $promotion['grants']['limit']);

This was all blatantly inspired by the way you can access objects in emcascript. I know that this is really a total abuse of php and oo design but when you are working with legacy systems sometimes you'll do anything to interject some semblance of sanity. Also I was listening to john zerzan lectures whilst I composed this. Maybe that explains why I would so something so meaningless; almost in opposition to his stance on technology.

Sunday, June 1, 2008

All is not quiet

So I have been working through project euler using my Hash class and some of its helpers and I am totally pleased with my results. A lot of my solutions are as short if not shorter than the python and ruby offerings. Saying that some of the later problems that don't relate to list comprehension are not aided by my Hash class but it's all the more reason to brush up on my math chops and extend the language in ways that CAN help with such problems. I would love to post some of my solutions on here but it's considered bad form to post them in public. I do want to be the first person to complete all of them in PHP as thus far no one has.

Tuesday, May 20, 2008

Added diff and intersect to the Hash object making the primes example even smaller.

/*python version*/
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]

/*common php version*/
$noprimes = xR(2,8)->mapf('xR($x*2,50,$x)->out()')->flatten();
$primes = xR(2,50)->diff($noprimes);


Or as a lovely one liner


$primes = xR(2,50)->diff(xR(2,8)->mapf('xR($x*2,50,$x)->out()')->flatten());


A little less readable for sure but the reality is it can be done and it fits the true definition of "one liner" by sliding in at the 79th column.

Saturday, May 17, 2008

inline lambda with out a wrapper function

So here is my implementation to allow for inline lambda functions:

This is built on top of my fn (anonymous function which is written to defun directory), fnx (function with one variable called x) and sfnx (single command which should be returned with one variable passed in called x).

The only thing I had to add was a GLOBAL variable called $_ which is an array (I initially called it $L but I like how $_ feels more like a piece of syntax than a variable name). In fn when it gets the name via md5 it then sets $_[$name] = $name; so that you may use it as follows:


echo $_[sfnx('$x')]('hello world');

You can use this how ever you would normally use a function (nested, in function calls etc.)

I mean "with out a wrapper function" because this could be accomplished with a function like: inline($args,$body,$arg1..$argn) which would create the anonymous function and call it with arg1..$argn and return the value.

echo inline('$x','return $x;','hello world');

As you can see it's doable but I guess I like the "feel" of the first one.

I should mention I was inspired by Peter Goodmans i/o reader blog post on a similar tip here: Hacking variable composition - another approach to php lambdas

anonymous function caching

As anyone who has dabbled with php create_function etc. will be able to tell you there are inherent memory leak issues with its implementation. From what I understand it does not apply garbage collection to them for one reason or another (I am going to research this further). Well here is the solution I have been using.

Define a directory where your anonymous methods will sit. I call mine 'defun'.

I have a method called fn($args,$body) which when called will make an md5 of the args+body, this is then prefixed with anon_ and called $name(as it could yield a name with a number as first character which is disallowed in php). I do a file_exists on $name to see if there is a file with that same name (and md5 fingerprint). If not I create it as a proper php file and close it. Then it does a require_once on $name and returns $name as this is what call back methods use to access it.

The only thing I have been worried about is the possibility of md5 collision? Anyway you see an increase of 100% the second time you run a script as it is just doing require_once instead of fwrites.

Friday, May 16, 2008

Prime numbers in PHP

More fluent interface goodness.

// PRIME NUMBERS IN 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]


//PHP
$noprimes = xR(2,8)->for_each('xR($x*2,50,$x)->out()')->flatten();
$primes = xR(2,50)->if_only('!xH('.$noprimes->implode().')->in($x)');


Edited above to reflect the fact I have aliased filterf with if_only (I would love to use if but it is clearly reserved) and mapf with for_each (again would love to use just for, each foreach etc.). Still I feel it reads a lot cleaner.

Purpose

The purpose of this blog is going to be me showing side by side all (well maybe not the ray tracer...) of the exercises from Paul Grahams ANSI Common Lisp in both CLisp and PHP. I will be creating a number of "helper" classes etc. to make the PHP side of things more livable (including a way of caching anonymous functions and thus not ending up with memory leaks... I think).

For now here are some examples of my Fluent Hash class in action with some list comprehension comparisons to python and lisp.


Note that xH and xR are shortcuts for creating a "new Hash" or creating a new hash
and immediately calling it's range method i.e
$new = new Hash();
$new->range(10);

/* python versions
S = [x**2 for x in range(10)]
V = [2**i for i in range(13)]
M = [x for x in S if x % 2 == 0]
P = [str(round(355/113.0, i)) for i in range(1,6)]
F = [x.strip() for x in [' banana', ' loganberry ']]
VEC = [2, 4, 6]
X = [3*x for x in vec if x > 3]
X1 = [[x,x**2] for x in vec]
*/

//PHP
$S = xR(10)->for_each('pow($x,2)');
$V = xR(13)->for_each('pow(2,$x)');
$M = xH($S)->if_only('$x % 2 == 0');
$P = xR(1,6)->for_each('round(355/113.0,$x)');
$F = xH(' banana', ' loganberry ')->map('trim');
$VEC = xH(2,4,6);
$X = xH($VEC)->if_only('$x > 3')->for_each('3*$x');
$X1 = xH($VEC)->for_each('Array($x,pow($x,2))');

/*common lisp
(loop for x from 0 to 100 if (> (* x x) 3) collect (* 2 x))
*/

//PHP
$C = xR(100)->if_only('($x*$x) > 3')->for_each('2*$x');


Now I am wondering if if_x and for_x would work equally well semantically... It would save a few characters but really I feel if_only and for_each are pretty verbose/explicit. One issue is map takes the name of a callback where as for_each takes the body and wraps map.. so semantically for_each should be for_eachu or something to denote it is a user defined function body expected/passsed... OR maybe for_each taking a body and map taking a function actually makes more sense in the first place!?