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);
Wednesday, October 29, 2008
Sunday, June 22, 2008
array to object
So I really get sick of:
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:
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:
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:
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.
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.
Or as a lovely one liner
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.
/*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
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.
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.
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.
// 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.
Subscribe to:
Posts (Atom)