<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8582403812843601208</id><updated>2011-10-13T04:24:15.148-07:00</updated><category term='metaobject protocol'/><category term='tail call optimization'/><category term='scheme'/><category term='apl'/><category term='soy'/><category term='factorial'/><category term='javascript'/><category term='phlisp'/><category term='voltron'/><category term='mop'/><category term='php'/><category term='hackernews'/><category term='smalltalk'/><category term='dsl'/><category term='unit testing'/><category term='phutility'/><category term='lisp'/><category term='fluent expressions'/><category term='phmop'/><category term='portofcall'/><category term='higher order operands'/><category term='tco'/><title type='text'>Common PHP</title><subtitle type='html'>An exploration of the limits of PHP</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-458491200491153310</id><published>2011-08-17T09:53:00.000-07:00</published><updated>2011-08-17T10:06:27.505-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='dsl'/><title type='text'>php 5.4 - skin deep syntactic sugar</title><content type='html'>I was quite excited to see that php 5.4 was getting some sugar for array definitions. e.g. "array(1,2,3)" would finally become "[1,2,3]". I was also excited to see "array dereferencing" was fixed or accessing an array by index after it is returned from a function e.g. "func()[index]". However let us be clear in noting that this does NOT mean it has attained the flexibility one would anticipate. For instance you can not immediately access an array after declaring it such as "['name' =&gt; 'peter', 'age' =&gt; 30]['age']" results in a syntax error. Of course you could combine both of the new features to do "func(['name' =&gt; 'peter', 'age' =&gt; 03])['age']" - which probably covers the majority of ways in which it &lt;i&gt;would&lt;/i&gt; be used. The other issue I have is the inability to access a function upon it's return from function application e.g. "func(1)(2)" will result in a syntax error. This is problematic for higher order techniques that benefit dynamic languages.  &lt;br /&gt;&lt;br /&gt;Why would anyone want features such as those I have outlined above? People designing "in language" domain specific languages benefit greatly from such flexibility. Particularly in a language which already limits facilities for creating such mythical beasts. &lt;br /&gt;&lt;br /&gt;That being said - I will gladly let go of my personal hack for passing in name/value pairs to a function which I have lovingly/jokingly referred to as "appositive expressions" e.g. "func('key', 'value', 'key2', 'value2')" can now become "func(['key' =&gt; 'value', 'key2' =&gt; 'value2'])". It is not surprising at all that php finally gets this feature as ruby finally bit the bullet and now accepts the json esque ":" in place of the "hash rocket =&gt;". '&lt;br /&gt;&lt;br /&gt;I should mention that the addition of "traits" will go miles in cleaning up some otherwise convoluted approaches to attaining mixins in php! I am very excited to see how this is utilized by the different frameworks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-458491200491153310?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/458491200491153310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=458491200491153310' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/458491200491153310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/458491200491153310'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/08/php-54-skin-deep-syntactic-sugar.html' title='php 5.4 - skin deep syntactic sugar'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-1459210023245589386</id><published>2011-06-07T23:08:00.000-07:00</published><updated>2011-06-09T23:30:01.466-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='apl'/><category scheme='http://www.blogger.com/atom/ns#' term='soy'/><category scheme='http://www.blogger.com/atom/ns#' term='higher order operands'/><title type='text'>smalltalk, apl, soy lisp, and higher order operands</title><content type='html'>APL, Smalltalk, Lisp. The holy trinity of programming languages. In this post I aim to better explain the Soy Lisp syntax which allows for all three to coexist. &lt;br /&gt;&lt;br /&gt;Consider first the ability to drop parens when an expression is terminated via ".":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(func arg1 arg2)&lt;br /&gt;//becomes&lt;br /&gt;func arg1 arg2.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This creates an immediate problem w/ disambiguation when dealing with arguments, well thankfully we do not lose the ability to return to s-expressions when required e.g.:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;func arg1 (func2 arg1 arg2).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What else can we glean from smalltalk? Perhaps the ability to cascade via ;, e.g.:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(((func arg1) arg2) arg3)&lt;br /&gt;//becomes&lt;br /&gt;func arg1; arg2; arg3.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In prior posts I have shown my preference for "square lambdas" e.g: [x | x y]. So I will not continue to rant about the benefits here. The last thing I will borrow from smalltalk is keyword constants (whilst keeping lisp keywords) e.g.:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(func :keyword1 var1 :keyword2 (lambda (x) (x :says 'peter))&lt;br /&gt;//becomes&lt;br /&gt;func keyword1: var1 keyword2: [x | x says: 'peter].&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The above assumes func is a higher order function which knows how to dispatch keyword selector arguments, which is essentially how I would implement a smalltalk esque language on top of soy. &lt;br /&gt;&lt;br /&gt;I think it is clear that functional programming in lisp can benefit from the smalltalk syntax whilst not losing the power of macro expansion and s-expressions. &lt;br /&gt;&lt;br /&gt;This brings us to APL the other language I have toyed w/ writing interpreters for. The real crux of apl is working with higher order operators. e.g. reduce which takes on the left hand an operator which it then uses to reduce a set of numbers on the right. In traditional prefix notation this would end up like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;((/ +) 1 2 3 4)&lt;br /&gt;//not bad but noisier than&lt;br /&gt;+ / 1 2 3 4.&lt;br /&gt;//which becomes&lt;br /&gt;(+ / 1 2 3 4)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Which works just fine because + is a higher order operator which knows if its first argument is another operator it should return a function which does a + reduction.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(- (+ 5 5) 5)&lt;br /&gt;//becomes&lt;br /&gt;5 + 5 - 5.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In soy the latter works because numbers are "higher order operands" which can consume operators and return functions which consume more operators/operands as expected. Stay tuned for a web repl for those interested in playing with this. Bare in mind that both forms in all of these examples work with in the same environment as this is all syntactic sugar! Lisp wins again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-1459210023245589386?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/1459210023245589386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=1459210023245589386' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1459210023245589386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1459210023245589386'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/06/smalltalk-apl-soy-lisp-and-higher-order.html' title='smalltalk, apl, soy lisp, and higher order operands'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-9094028867362022810</id><published>2011-05-27T15:21:00.000-07:00</published><updated>2011-05-27T16:22:10.530-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='phutility'/><category scheme='http://www.blogger.com/atom/ns#' term='hackernews'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Keyword Functions in PHP</title><content type='html'>So, as spurned by a &lt;a href="http://news.ycombinator.com/item?id=2592154"&gt;comment on hacker news&lt;/a&gt; relating to the lack of ability for keyword arguments in php I figured I would expound more upon the &lt;a href="http://www.github.com/shaunxcode/phutility"&gt;Phutility library&lt;/a&gt;, in particular the Func module.&lt;br /&gt;&lt;br /&gt;Check it out: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#say you have a function (perhaps defined by you, perhaps not)&lt;br /&gt;&lt;br /&gt;namespace SomeNamespace;&lt;br /&gt;use Phutility\Func; &lt;br /&gt;&lt;br /&gt;function testFunc($name, $eyes, $hair = 'blonde', $age = 0, $weight = 200, $goatFace = 'definitely') {&lt;br /&gt;    return array(&lt;br /&gt;        'name' =&gt; $name, &lt;br /&gt;        'eyes' =&gt; $eyes, &lt;br /&gt;        'hair' =&gt; $hair, &lt;br /&gt;        'age' =&gt; $age, &lt;br /&gt;        'weight' =&gt; $weight,&lt;br /&gt;        'goatFace' =&gt; $goatFace);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#if you want a keyword wrapper for it:&lt;br /&gt;&lt;br /&gt;$testFuncWrapper = Func::keyword('\SomeNamespace\testFunc'); &lt;br /&gt;&lt;br /&gt;$result = $testFuncWrapper(&lt;br /&gt;    age, 30,&lt;br /&gt;    name, 'peter'&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;/*would yield a $result of&lt;br /&gt;array(&lt;br /&gt;    'name' =&gt; 'peter',&lt;br /&gt;    'eyes' =&gt; 'blue',&lt;br /&gt;    'hair' =&gt; 'blonde',&lt;br /&gt;    'age' =&gt; 30,&lt;br /&gt;    'weight' =&gt; 1200,&lt;br /&gt;    'goatFace' =&gt; 'definitely'&lt;br /&gt;)&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;# If you want to not have a variable func you would need to do something like:&lt;br /&gt;function TestFuncWrapper() {&lt;br /&gt;    static $wrapper; &lt;br /&gt;    if(!$wrapper) {&lt;br /&gt;        $wrapper = Func::keyword('\SomeNamespace\TestFunc');&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return call_user_func_array($wrapper, func_get_args());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#a little gnarlier but this is the price we pay to call it like:&lt;br /&gt;&lt;br /&gt;$result = TestFuncWrapper(&lt;br /&gt;    goatFace, 'NoWay'&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;#oops this would yield an exception because name and age are required!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If this is at all interesting to you and you'd like to use it or contribute, the source and tests are all &lt;a href="http://www.github.com/shaunxcode/phutility"&gt;up on github&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-9094028867362022810?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/9094028867362022810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=9094028867362022810' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/9094028867362022810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/9094028867362022810'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/05/keyword-functions-in-php.html' title='Keyword Functions in PHP'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-4342985168004318512</id><published>2011-05-25T15:25:00.000-07:00</published><updated>2011-05-25T15:28:15.666-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><title type='text'>On unit testing</title><content type='html'>When ever I am confronted with a problem with a code base, my first reaction is: "&lt;b&gt;wtfutfts&lt;/b&gt;" meaning "where's the fucking unit tests for that shit". No unit tests? Now you know your first move in providing resolution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-4342985168004318512?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/4342985168004318512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=4342985168004318512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/4342985168004318512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/4342985168004318512'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/05/on-unit-testing.html' title='On unit testing'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-7302552814742379878</id><published>2011-05-25T14:39:00.000-07:00</published><updated>2011-05-25T19:13:33.979-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='metaobject protocol'/><title type='text'>Alternative s-expression syntax for Soy Lisp</title><content type='html'>Soy is the name of my lisp dialect (previously called lisphp, and before that phlisp). This is quite a radical departure from standard lisp s-expression but not so far as to, say have infix notation or "sweet expressions". Rather this is a simple inverse of s-expression e.g.:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(if (predicate arg1 arg2)&lt;br /&gt;    (thenFunc arg2)&lt;br /&gt;    (elseFunc arg3))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Becomes:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if(predicate(arg1 arg2)&lt;br /&gt;   thenFunc(arg2)&lt;br /&gt;   elseFunc(arg3))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Your first question should be, "but wait! what about homoiconicity and the ability to have quasiquote macro definitions!?". I'm glad you asked, I have two proposals. 1) allow for a s-expression macro syntax, 2) allow for quasiquote to start with an atom:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defmacro(eat-apple person number-of-apples&lt;br /&gt;         `person-eat(,person 'apple ,number-of-apples))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You may have noticed the other drawback with this syntax is that it makes having macros which handle sublists a tad more difficult. As any atom followed by (, applies the atom to the arguments inside of the parens. This can be resolved by using rest args for forms which anticipate the last expression to be treated as a lambda. Also Soy allows for [ | ] lambda forms and { } vector/dicts. So it is also possible that would resolve any ambiguities.&lt;br /&gt;&lt;br /&gt;One of my major ambitions with this is to have a very simple syntax for exploring alternative object models, similar to my previous post about an alternative object model for javascript. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;simple keyword selector&lt;br /&gt;some-object(set-first-name: 'peter and-last-name: 'jenkum)&lt;br /&gt;;chaining &lt;br /&gt;some-object(some-keyword: arg1 selector: arg2) &lt;br /&gt;           (chained-selector: arg3 takes-closure: [ a | a(message: arg4)])&lt;br /&gt;           (another-chained-selector: [_(anon-var)])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I really dig how close this comes to snythesizing what I love about smalltalk w/ lisp w/o really forsaking either.&lt;br /&gt;&lt;br /&gt;One of the real "wins" with this is when you have function returning functions .. n you don't end up w/ a massive amount of nesting. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(def adder [x | [y | [z | + x  y z]]])&lt;br /&gt;(((adder 6) 7) 8)&lt;br /&gt;&lt;br /&gt;def(adder [x | [y | [z | +(x y z)]]])&lt;br /&gt;adder(6)(7)(8)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I think the latter reads in a much more obvious "left to right" fashion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-7302552814742379878?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/7302552814742379878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=7302552814742379878' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/7302552814742379878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/7302552814742379878'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/05/alternative-s-expression-syntax-for-soy.html' title='Alternative s-expression syntax for Soy Lisp'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-1365484117728991826</id><published>2011-05-23T15:39:00.000-07:00</published><updated>2011-05-23T15:44:05.988-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='metaobject protocol'/><title type='text'>simple keyword message selectors for javascript</title><content type='html'>As I have been messing with alternative object systems for php one of the ones I came up with was ab(using) the __invoke magic method to take a keyword argument list and find a given selector based upon it. I realized this could be done in an even more trivial manner in javascript using the object syntax and returning a new object w/ the dispatch mechanism rather than "return this". &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var Klasses = {&lt;br /&gt;    'Person': {&lt;br /&gt;        'selectorPart1:selectorPart2': function(a, b) {&lt;br /&gt;            console.log('called with ' + a + ' and ' + b);&lt;br /&gt;            return obj(this);&lt;br /&gt;        },&lt;br /&gt;        'subSelector': function(a) {&lt;br /&gt;            console.log('subselector with:' + a + ' for ' + this.name);&lt;br /&gt;            return obj(this);&lt;br /&gt;        },&lt;br /&gt;        'get': function(field) {&lt;br /&gt;             console.log(this.name + ' over-ride of get with ' + field);   &lt;br /&gt;        }&lt;br /&gt;    },&lt;br /&gt;    '*': {&lt;br /&gt;        'get': function(field) {&lt;br /&gt;            if(this[field]) {&lt;br /&gt;                return this[field]&lt;br /&gt;            } else {&lt;br /&gt;                throw new Exception('No field ' + field);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var obj = function(self) {&lt;br /&gt;    return function(selector) {&lt;br /&gt;        var sel = [];&lt;br /&gt;        var args = [];&lt;br /&gt;        $.each(selector, function(k, v) {&lt;br /&gt;           sel.push(k);&lt;br /&gt;           args.push(v);&lt;br /&gt;        });&lt;br /&gt;    &lt;br /&gt;        var selectorName = sel.join(':');&lt;br /&gt;        var message = false;&lt;br /&gt;        if(Klasses[self.klass][selectorName]) {&lt;br /&gt;            message = Klasses[self.klass][selectorName];&lt;br /&gt;        }&lt;br /&gt;        else if(Klasses['*'][selectorName]) {&lt;br /&gt;            message = Klasses['*'][selectorName];&lt;br /&gt;        }            &lt;br /&gt;        &lt;br /&gt;        if(message) {&lt;br /&gt;            return message.apply(self, args);&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;}&lt;br /&gt;    &lt;br /&gt;var guy = obj({klass: 'Person', name: 'peter'});&lt;br /&gt;guy({selectorPart1: 'apple', selectorPart2: 'candy'})&lt;br /&gt;   ({subSelector: 'rotten'})&lt;br /&gt;&lt;br /&gt;var otherGuy = obj({klass: 'Person', name: 'samuel'})({subSelector: 'cotton'})&lt;br /&gt;console.log(otherGuy({get: 'name'}))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To see it live: &lt;a href="http://jsfiddle.net/LG7En/3/"&gt;jsfiddle running the above&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-1365484117728991826?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/1365484117728991826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=1365484117728991826' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1365484117728991826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1365484117728991826'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/05/simple-keyword-message-selectors-for.html' title='simple keyword message selectors for javascript'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-3255036700480222480</id><published>2011-05-20T09:26:00.000-07:00</published><updated>2011-05-20T10:14:40.448-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='phmop'/><category scheme='http://www.blogger.com/atom/ns#' term='smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='phutility'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='metaobject protocol'/><title type='text'>On Phutility</title><content type='html'>Phutility is a collection of tools which I utilize in many of my other projects. For example the Node class is utilized by both covenants (sql builder) and also phmop (meta object protocol). Today though I am going to be discussing some of the work that I have been doing in Func to lay the framework for "higher order object oriented programming" with phmop. To give you an idea of what I am driving at, consider:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defineClass('Person', &lt;br /&gt;    slot('someMethod', function($self) {&lt;br /&gt;        $args = func_get_args();&lt;br /&gt;        $self = array_shift($args);&lt;br /&gt;        $options = appos($args);&lt;br /&gt;        if($self-&gt;{$options[ifField]} == $options[isValue]) {&lt;br /&gt;            $self-&gt;call($options[callMethod], $options[withValues]);&lt;br /&gt;        }&lt;br /&gt;    })-&gt;accessor('someMethod'));&lt;br /&gt;&lt;br /&gt;$person = new Person;&lt;br /&gt;$person-&gt;someMethod(&lt;br /&gt;    ifField, 'age',&lt;br /&gt;    isValue, 30, &lt;br /&gt;    callMethod, 'someMethod2', &lt;br /&gt;    withValues, array(300));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There are a few things we can cleanup. Firstly lets create a function "method" which wraps up simple functions which utilize an accessor which is the same as their internal name. Then lets utilize a higher order function "Func\options" which returns a function which has the last param defined as an options hash to clean things up: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defineClass('Person', &lt;br /&gt;    method('someMethod', Func\options(function($self, $options) {&lt;br /&gt;        if($self-&gt;{$options[ifField]} == $options[isValue]) {&lt;br /&gt;            $self-&gt;call($options[callMethod], $options[withValues]);}})));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But we can go further by creation an optionsMethod which wraps up the need for the explicit Func\options call. Also we can have it pass a param which gives us back a std class for options rather than an array. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defineClass('Person', &lt;br /&gt;    optionsMethod('someMethod', function($self, $options) {&lt;br /&gt;        if($self-&gt;{$options-&gt;ifField} == $options-&gt;isValue) {&lt;br /&gt;            $self-&gt;call($options-&gt;callMethod, $options-&gt;withValues);}}));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For the sake of completeness let me show off another way this could be defined more explicitly taking advantage of Func\keyword which evaluates a closure and then returns a function which responds to an appositive style call:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$keywordFunc = Func\keyword(function($age, $name, $color) {&lt;br /&gt;    return array('age' =&gt; $age, 'name' =&gt; $name, 'color' =&gt; $color);&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;print_r($keywordFunc(&lt;br /&gt;    age, 30, &lt;br /&gt;    color, 'blue', &lt;br /&gt;    name, 'peter'));&lt;br /&gt;&lt;br /&gt;array(&lt;br /&gt;    'age' =&gt; 30,&lt;br /&gt;    'name' =&gt; 'peter',&lt;br /&gt;    'color' =&gt; 'blue');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see this allows us to pass the params in any order we please (which to be fair our Func\options implementation does as well but packaged into an $options var). So now we will skip to step 3 of what a keywordMethod would look like in use:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defineClass('Person', &lt;br /&gt;    keywordMethod('someMethod', &lt;br /&gt;        function($self, $ifField, $isValue, $callMethod, $withValues) {&lt;br /&gt;            if($self-&gt;$ifField == $isValue) {&lt;br /&gt;                $self-&gt;call($callMethod, $withValues);}}));&lt;br /&gt;&lt;br /&gt;$person = new Person;&lt;br /&gt;$person-&gt;someMethod(&lt;br /&gt;    ifField, 'age',&lt;br /&gt;    isValue, 30, &lt;br /&gt;    callMethod, 'someMethod2', &lt;br /&gt;    withValues, array(300));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I think this makes clear why both a meta object protocol and higher order functions are so awesome when they can play together. Rather than having only inheritence, interfaces, or even mixins, as the tool for making things more elegant we can easily add new features to our language with simple function composition.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-3255036700480222480?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/3255036700480222480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=3255036700480222480' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3255036700480222480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3255036700480222480'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/05/on-phutility.html' title='On Phutility'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-3019585641919665178</id><published>2011-05-18T08:09:00.000-07:00</published><updated>2011-05-20T08:22:09.350-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='portofcall'/><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='mop'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='metaobject protocol'/><title type='text'>Considering a MetaObject Protocol for PHP</title><content type='html'>The purpose of a "MetaObject Protocol" is to allow for defining the very nature of how an object system functions. This means the ability to add traits/mixins, aspects, multiple inheritance, "Generics" etc. w/o requiring compilation or low level tinkering. One major advantage is that this means not having to wait for a revision of your language to express certain design patterns.&lt;br /&gt;&lt;br /&gt;As usual php is so close, yet so far away. However ab/utiliz/ing the magic methods you can actually get pretty close to something resembling the &lt;a href="http://en.wikipedia.org/wiki/Common_Lisp_Object_System"&gt;CLOS&lt;/a&gt; system. To accomplish this it requires a few building blocks which I have abstracted into my &lt;a href="https://github.com/shaunxcode/phutility"&gt;Phutility&lt;/a&gt; library. Primarily the MetaArg and Node which provide the building blocks for composing declarative domain specific languages.&lt;br /&gt;&lt;br /&gt;The majority of the magic occurs via macro expansion in CLOS. We are going to make up for that via declaring an &lt;a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree"&gt;abstract syntax tree (AST)&lt;/a&gt; which we will expand and weave into our method dispatch mechanism. &lt;br /&gt;&lt;br /&gt;Enough talk, let's code. First our goal is be able to declare classes and methods. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defineClass('Shape',&lt;br /&gt;    slot('width'),&lt;br /&gt;    slot('height'),&lt;br /&gt;    method('getHeight', function($self) {&lt;br /&gt;        return $self-&gt;height;&lt;br /&gt;    }), &lt;br /&gt;    method('getArea', function($self) {&lt;br /&gt;        return $self-&gt;width * $self-&gt;height;&lt;br /&gt;    })&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;$shape = new Shape(&lt;br /&gt;    width, 20, &lt;br /&gt;    height, 50&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;echo $shape-&gt;getHeight();&lt;br /&gt;echo $shape-&gt;getArea();&lt;br /&gt;&lt;br /&gt;defineGeneric('beforeGetArea', &lt;br /&gt;    before(getArea),&lt;br /&gt;    arity(Shape), &lt;br /&gt;    function($self) {&lt;br /&gt;        echo "Called before get area!\n";&lt;br /&gt;    }&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;echo $shape-&gt;getArea(); //outputs "Called before get area!" and then area&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Looks like a class and acts like a class. But most definitely not a raw class. How does this work? Principally we keep the meta information about each class in a Registry. Each class defined results in a simple declaration of "class X extends \phmop\StandardClass{}" which allows the usual "new Class" syntax. It writes this to a cache directory and does a require_once on it so as to avoid eval. &lt;br /&gt;&lt;br /&gt;The base Obj class looks something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class StandardClass {&lt;br /&gt;    public $slots = array();&lt;br /&gt;&lt;br /&gt;    public function __call($slot, $args) {&lt;br /&gt;        return Registry::dispatchMethod($this, $slot, $args);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function &amp;__get($slot) {&lt;br /&gt;        return Registry::getSlot($this, $slot);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function __set($slot, $value) {&lt;br /&gt;        Registry::setSlot($this, $slot, $value);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public function __construct() {&lt;br /&gt;        foreach(Appos(func_get_args()) as $key =&gt; $val) { &lt;br /&gt;            $this-&gt;$key = $val;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So pretty clearly the real magic is taking place in the way that defineClass, defineGeneric, and friends interoperate with the Registry.&lt;br /&gt;&lt;br /&gt;I am going to end things here for now as I need to make a few posts about some of the inner workings of phutility to really get into the thick of things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-3019585641919665178?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/3019585641919665178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=3019585641919665178' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3019585641919665178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3019585641919665178'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/05/considering-metaobject-protocol-for-php.html' title='Considering a MetaObject Protocol for PHP'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-2985447045087982102</id><published>2011-04-23T21:34:00.000-07:00</published><updated>2011-04-23T22:45:27.676-07:00</updated><title type='text'>a look at the chet "appositive expression" orm dsl</title><content type='html'>Chet is a lightweight, minimal, php framework intended to make writing php not feel like a giant pile of array('a' =&gt; array('b' =&gt; array('c', 'd')). This is accomplished mainly by declaring appropriate constants and using what I am calling "appositive expressions". e.g. Person(name, 'shaun', age, 28); &lt;br /&gt;&lt;br /&gt;While this started out as a joke it has actually begun to have merit and today I am going to demonstrate the latest portion of the project which is the sql dsl which in a nut shell looks like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;TodoItem::with(&lt;br /&gt;    creationDate, between($start, $end), &lt;br /&gt;    either(&lt;br /&gt;        owner, eq(25),&lt;br /&gt;        status, in('active', 'pending')));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;SCS: 26&lt;br /&gt;&lt;small&gt;When I am messing with snytax ideas I have come up with a system for scoring their visual complexity which comes down to counting any piece of non-word character i.e. parens, colons, commas, quotes etc. For the above example the SCS (syntactic-complexity-score) is 26.&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;The above in a raw php + sql approach would be: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;safe_mysql_query("select * &lt;br /&gt;  from TodoItem&lt;br /&gt; where creationDate between(?, ?)&lt;br /&gt;   and (owner = ?&lt;br /&gt;        or status in(?, ?))", array($start, $end, 25, 'active', 'pending'));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;SCS: 33&lt;br /&gt;&lt;br /&gt;The equivalent in something like cake php would be (from with in a controller abusing the concept of $this to access a model... ugh) &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$this-&gt;TodoItem-&gt;find('all', array('conditions' =&gt; array(&lt;br /&gt;    'creationDate between ? and ?' =&gt; array($start, $end), &lt;br /&gt;    'OR' =&gt; array(&lt;br /&gt;         'owner' =&gt; 25, &lt;br /&gt;         'status in(?, ?)' =&gt; array('active', 'pending')))));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;SCS: 58&lt;br /&gt;&lt;br /&gt;I am pretty sure that the above describes what I am trying to get at: if your "abstraction" is messier/harder to read than that which you are meant to be abstracting yourself "from" it is time to go back to the drawing board. While Chet started out as a joke &lt;small&gt;(a reference to Sinatra for ruby but more fitting as Chet Baker was a horrible drug addict yet an incredible musician - thus php is a terrible language yet still capable of doing marvelous things in a non-classy manner even)&lt;/small&gt;, I am slowly actually wanting to use it for real projects. &lt;br /&gt;&lt;br /&gt;One of the design choices was to either bit the bullet and have methods called _and, _or etc. or find alternatives for them. For "and" I have chosen "with". For "or" I have chosen "either". For all of the other sql operators I have chosen the perl approach: "=" is "eq", "&gt;" is "gt", "&gt;=" is "gte" etc. between and in are now both just methods. The beauty is that because all of this is just sugar you can just as easily express the above as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;TodoItem::with(array(&lt;br /&gt;    'creationDate' =&gt; array('between' =&gt; array($start, $end)), &lt;br /&gt;    'or' =&gt; array(&lt;br /&gt;        'owner' =&gt; array('=', 25),&lt;br /&gt;        'status' =&gt; array('in', array('active', 'pending')))));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;SCS: 56&lt;br /&gt;&lt;br /&gt;Still not as gnarly as the cake php but clearly noisier than the "real chet" approach. My point is that you can drop the sugar in favor of the array noise if one is so inclined. &lt;br /&gt;&lt;br /&gt;I am using this same approach for the html/css which yields some very similar gains in readability and "self-similarity" across the entire application. &lt;br /&gt;&lt;br /&gt;All of the above being said this is purely an exercise in "how far" I can push php to gain something that resembles a non-array/class-abusing DSL with a small amount of code generation and utilization of everything php 5.3 has to offer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-2985447045087982102?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/2985447045087982102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=2985447045087982102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2985447045087982102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2985447045087982102'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2011/04/look-at-chet-appositive-expression-orm.html' title='a look at the chet &quot;appositive expression&quot; orm dsl'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-8671875422291996208</id><published>2010-12-03T08:39:00.000-08:00</published><updated>2010-12-12T16:09:19.576-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='tco'/><category scheme='http://www.blogger.com/atom/ns#' term='tail call optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='factorial'/><category scheme='http://www.blogger.com/atom/ns#' term='phlisp'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>Revision to php TCO trampoline</title><content type='html'>&lt;a href="https://github.com/shaunxcode/php-trampoline"&gt;github.com/shaunxcode/php-trampoline&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sometimes I wake up at 6am with the frightful knowledge that there is an edge case to something I wrote somewhere which is incorrect. The only thing worse than knowing someone on the internet is wrong (&lt;a href="http://xkcd.com/386/"&gt;http://xkcd.com/386/&lt;/a&gt;) is knowing you were wrong on the internet. &lt;br /&gt;&lt;br /&gt;I realized in a dream that my trampoline would not work with higher order functions as it currently stands because the while loop is based on is_callable, obviously if your function is meant to return a function you would not want it to be executed immediately (particularly because it probably expects arguments etc.). All of a sudden the whole throwing an exception approach made sense - however thanks to php5.3s __invoke method I can handle this cleanly by wrapping each tail call in an instance of TrampolineBounce and then check "$return instanceof TrampolineBounce". &lt;br /&gt;&lt;br /&gt;I figured if I am going to need a Trampoline class I may as well leverage __callStatic to allow for easier invocation of trampolined functions. With out further ado: &lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;namespace Trampoline;&lt;br /&gt;&lt;br /&gt;class Bounce {&lt;br /&gt;        private $func;&lt;br /&gt;        public function __construct($func) {&lt;br /&gt;                $this-&gt;func = $func;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        function __invoke() {&lt;br /&gt;                return call_user_func_array($this-&gt;func, array());&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Trampoline {&lt;br /&gt;        public static function Bounce($func) {&lt;br /&gt;                return new Bounce($func);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static function __callStatic($func, $args) {&lt;br /&gt;                $return = call_user_func_array($func, $args);&lt;br /&gt;                while($return instanceof Bounce) {&lt;br /&gt;                        $return = $return();&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                return $return;&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function even($n) {&lt;br /&gt;        return $n == 0 ? true : Trampoline::Bounce(function() use($n) { return odd($n - 1);});&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function odd($n) {&lt;br /&gt;        return $n == 0 ? false : Trampoline::Bounce(function() use($n) { return even($n - 1);});&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;echo Trampoline::even(1500) ? 'Yep' : 'Nope';&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-8671875422291996208?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/8671875422291996208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=8671875422291996208' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8671875422291996208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8671875422291996208'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/12/revision-to-php-tco-trampoline.html' title='Revision to php TCO trampoline'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-5426487467892978830</id><published>2010-12-01T15:52:00.000-08:00</published><updated>2010-12-03T08:49:13.285-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='tco'/><category scheme='http://www.blogger.com/atom/ns#' term='tail call optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='factorial'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='scheme'/><title type='text'>tail call optimization in php 5.3</title><content type='html'>&lt;span style="font-weight:bold;"&gt;*note this has been revised: (&lt;a href="http://commonphp.blogspot.com/2010/12/revision-to-php-tco-trampoline.html"&gt;http://commonphp.blogspot.com/2010/12/revision-to-php-tco-trampoline.html&lt;/a&gt;) *&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So I have been holding off on releasing my php lisp for the past couple of months for a few reasons. The first was I wanted to get quasiquotes/macros working correctly and the other was I wanted to get TCO working correctly. I checked quasiquotation and macro expansion off a few weeks ago and have been wrestling with TCO since. There are many work arounds such as only using higher order functions like map etc. which "underneath" use php foreach/while etc. but this always felt like a hack. Today I will show how I am accomplishing TCO. It is actually "pretty" enough that I would even use this technique in "normal" php if the need arose i.e. when implementing an algorithm where mutual recursion is the cleanest way of dealing with a given problem. &lt;br /&gt;&lt;br /&gt;I had heard "tail" of a magical device called a "trampoline" but had yet to see one implemented in php. First lets set the scene for why such a thing is necessary.&lt;br /&gt;&lt;br /&gt;Regular mutually recursive functions:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;function even($n) { &lt;br /&gt;    return $n == 0 ? true : odd($n - 1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function odd($n) { &lt;br /&gt;    return $n == 0 ? false: even($n - 1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo even(15000000) ? 'Yep' : 'Nope'; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Result? &lt;br /&gt;Fatal error: Allowed memory size of 335544320 bytes exhausted (tried to allocate 261900 bytes)&lt;br /&gt;&lt;br /&gt;As you can imagine this would blow the stack pretty quickly. The solution is to return closures which close over the next function to be executed by the trampoline:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;function trampoline($func, $args) { &lt;br /&gt;    $return = call_user_func_array($func, $args);&lt;br /&gt;    while(is_callable($return)) {&lt;br /&gt;        $return = $return();&lt;br /&gt;    }&lt;br /&gt;    return $return;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ready for trampoline version of functions, notice the closures being returned:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;function even($n) { &lt;br /&gt;    return $n == 0 ? true : function() use($n) { return odd($n - 1); };&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function odd($n) { &lt;br /&gt;    return $n == 0 ? false : function() use($n) { return even($n - 1); };&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo trampoline('even', array(15000000)) ? 'Yep' : 'Nope';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;No more blowing the stack!&lt;br /&gt;&lt;br /&gt;For another example here's a tail call version of factorial:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;function fact($n) {&lt;br /&gt;    $product = function($min, $max) use($n, &amp;$product) { &lt;br /&gt;    return $min == $n ? &lt;br /&gt;        $max : &lt;br /&gt;        function() use(&amp;$product, $min, $max) {&lt;br /&gt;            return $product(bcadd($min, 1), bcmul($min, $max));&lt;br /&gt;        };&lt;br /&gt;    };&lt;br /&gt;    return $product(1, $n);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo trampoline('fact', array(5050));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Result?&lt;br /&gt;48424893876442346868149955534231630311152316586879831768663469768542209496025625521335165836597244986775871359731653944863304801472363186993340977071916545094098397335673370033050095301846673812319519184368943848940208083286841710046697935471447379350531958006231636490517114754236601801475241025829782559539886360417931118962453657701734674670226076209971728976092053885317753609072349073735823517244188123450674446015646408575152721563438720528695200000950089076496921144117143216432888312645825602479454709341393797835166357888263581672355452853869124012486552503932416596193377435247315025743200744002301394585228500268455104719958806656594340592125681513366273489623936710098205543483870278942617415439360839831622538877203695372405175195820803498878614463408507559071691975942963055323977023975579962356660525443011519924497192606177308403911494610046020125224506026847906849303464211582255596044461695809931170735992902861015153948973924760246045409447614027579732580231716105662183345892311470363765765619375852044952237375592745997667408717094345683918382540158972633294341661753292428842087402347931146455707829443369742629955406096433554614672210416043568566713315721328986242009438119615170550083892805000693555351590233960368408610557369747063249171375287938142229602269575258888078115537273321885243640816116313033760859934727694805934472650247398590268106132632051710011975357435411073973400518009267243861234604382480972044372345571394804592046625365990943593155118312928026092849203020843936635478814979107242813498013904401479307173527813374488927846868388843629960975688405420793866362748625568963809336537735196635482323869611480442317616213118017936592673957745954854119905353862738630397953491904711075413351939493239103430359228666385849114266162025489907918597974910444817388693635468572983832473160429177887474388606642754513228627277514269543214565586593047881932646980529181738704933529003783674019143726269073240250043051103116046759758599556492457493255007087656022414606222859948126380313826837273496022239059049197478197470692778763575742323649675518937743998020384086092356484327490394949151360442183700474945898304321062066355143800014715430781407860862440970162255814321544952627961522489938257459652704978558232366966762259286202122152536234765500508950380085381022529769410646695981455932497274422145956223070614311782386939393660505071468075609946312266961804079078124972138751570252042991908322662337184841517195535818561858155408260788044667462475133702274158651640293943156955741104099223849587202623924618562507307459878359309762592535803298228381823574279830281362305301068394370171580376856819398786773168976316243886413852653396055497826310062540076987247412010421678922894559582379982459315131410353844686814801084428315428961052501286596189198414322404856396902069457672137306587727429077418184644185029820725981473585275798688633870939149445242039540994144936753560145261967645980942905198036844963065770953567278843744815101688364553167567561127581285151504170857163788476814410430818485342212602471021116122232536945437600193563274350613219002205135771961855617387540043201574995936521078443417355808962389471634447182986942493573328833479027327904592963332830948909056606878114712587614797355021919494836468834407159424831076501904939674180550971070685974826026825572462514492992573071756584471446779582538562871889253777491503761958039422843336111308820256625552392100765429247159402181090198939792727134760027285582388085697688779314720476653237742989447851866203189262136310101262960823946227816914290542573075004229606139191853412465867836753036378462157616915664130017838805074756547841197620513628237540972492294319305705734478032962949128924196666202655682340324787692515590130551301935088659828410687356942341790891345277677382788831208787364801395111486357308798265828146035781558094135067110230536901270297547242166950881473214274739101845553727897045531119954725288893493225046788944932736466460550726919323972814208640861318915500012832311138673106892856437774916302054198800992266101283582978474791023088963610289841529824634218025633260218581419143652195694797922926870213605428040752771533690783079334348985159752481190866305108822791928707079718613729022578623134006395058165941963834815415900225540158365512962747234118295298072392721688699472738462833608355509413369430747483292086244416854740060940250464784905488189338770945263660330117646978971876652613557429461658723058825915031208985735140615497693407650641375234834094995218262573623896322220855235269130698919365626682758374382064483940359436309642974808514506879129036989811006578121058886468214783989745311306991381502598738427646690529026148074559926029141700545754931041231062108024348298640252182862477489626497023992723452959298403206063199087668949604632790351230972033067574210447769545912131839504735995523543564698434762288745349217285435045940022877153117114056361355516568793184887831573689961226955484323093901470710251285589637162339096014594590326637778408537708815313301255641448290264509028416236493070536691277554818638552346553208672413541183818357851114016689498361821413896379525442756652690413158967535936279206144987763854912793024225936394940295690129089121120860291418297457810220526616453514910819323035995322046111221378283408895173068084562318564077990588079762019973028279392634257796579680892376694383912153702257752771918240121360797334802574067759177201695444664008395141273331798769390706217716413944484444589448011804566872918201233352031246374079426621952856774873141762004642963805009605909976650733467147648933063451549234764105261843727285344810237038664893806272788248667617929188856335934471876757762121375528223069436338430636550586312429972101590001624825194534053466559441823558494047711923047787608650174147236583346033499704371720807668032648824335082469921765890357796559326553963051584575314243179379693972869819018936515241128344111174643025352717517264399068943122072909168503889489366305203869840440783566583673872512529607991028619785374051069353232798743538451929474739656942294561359950279354484262386048300967384230958861468226703153885216880543889184923233329346644468452757677009730774828691754812914301660783522852525684240191438648246859144805142924667100195015093959485990061146668886559862309819174810279322086728633972728154606053167707643070032164693171224226003284900895506902979108769760815523818908193387378633599962338329201288673602475038425763910335696933668401126584246627457560953522086694366649469599705521441640238122010959682479428036962415722220141394447107341640961359500927881874233095198411689068446492958685137714321262410692218565491447540332778657853504520774359829079460075117251206648241533763048331739049003142679483361884913145518268997761626564746070642120683866637049087132932456214339322178452985208536699837965699909310064620090804584888468392476355755579270080782553655541381943286896134122662506174668761696780529727626382334663869879097172088652428923258543798284963386781746966688860322027736021528016691959550581844902683467447609407368122794497183432069868909471472548153656903880703201644425109624545859826873667750937614607390493457875484953740767611339667576173714034455565432308153130757930008532562324042807264432614157844822751708067421611502291046796482944889562484299548170367202226348895651943485134487355907416500408163581341989736946778288899701341554759826542507320619287649549795982662920054235475749643320872348617927891303979446402061121132359483927554056402873178493913139966737132973717633632447161627037227392256332565547672908601616412069162541656417328547927835344764379080034006834438837309816235465641185216815046674945763955984713681604516254849662824411306353793798089671114185280187265849418052077836852589180241592723184733541106406465656205948358954948142025233991272905001141355021729920577475479281289486806270011744359500435621608814756150544407957227147107089215203809044297767994104686800618204519792063487603872622575538947815450619856182485749773834231277713725309254568969583149073554526597574846552798676406462337998787339779028992439990039978154586413759133622409437489561164656777421746380264056302768613928564315667912312952457404411495519474886250396579083072312029449210229223734219955586387114225996549617982828293430386694221527613218115999731321291884322073808127116054283436992190175171603278221120478118125795564192351195970923490210310910133096302509169175624548014311817872937471722034686941769631047594296358186560148127293467958839434265463971529119297056567953684958757245231554391244311041212876924918500484087772698403206170331941238143489798776660534676579046337828982028986348099030601184836047434217855703008400176583770452171688793096489449429186708279868381214066539707277515059120768682704305155217982248302399219666594196559372775947145581773723282195411033360764337292946984272715506254608876131243628417716054202032599008485959729298011133493587411121592451061195248871236550219323568794733198388938084043968597320732717910476328327887684545483577062955807065986440317073048021931109482880059179684697878805723379654977018391836443141027833877379573134035147846614695719532905855359486154082235216657769559165736626734582602844219961653790266071295624034376769110677927593476162673165371870321528606055962225071216770606048742973083597090117219781320947530791012971233612874212167300949205392589536160373120473483108568345225335577313624485693021092445510802644688591070751584819925697407862940653022261735482476498456623897965943740384974312102003102503405987723190936549669116934059002978404863724434029651459171929972224636473192846126682034744452198659199773243765555394223202793062777093231567712374298614503785227247044790390230170449231471025389935822203023342537851424261619334224815629159006888149337227458290876318073016643545061947091539741062518116457909282507014366747914604640619597780018271697736234489832448906487488167612194968404133122879631080718761096322629749242740599130685431498769606882708624503872378150881580793787863737584355460103940532518865937858605854476146840248883570271489049276259843458637015215238959285845598888570553863679704803156416650276687716857598414761640580833928733883633835389587148355501394145096219531824605734660342901357825854824533481203519236387571460898657123958733206267932786756738047919023782881760608578646872699523991805943926237776113774398337350917182253520526962590153838195949497674171793321672290838421458771652486169401420831215559578522629914795737160039551091814038045014141164820901176264063896563274263280283566146499227688707995123583313957488864707245532192866843267707404232105194327568792851170384048440120280104065824324895974735080562974987135989427850162706790819742752770673925751139449717572950066181333226422371275841399550790779378722199692256665985844973214290417466996736463656592057379723789125163155964154625281239640046452862780603936207280664294883639688906345127219732436103075763451035422059632678374543779848932298460317103368289281025974169671272176383711807597354081467243350813365849007681882657888031711208469929623879339045017847389034606030926200455252399928369014924250363511229402299134698234156077158889592184980239170939501976466282865503049323617696621577333707865541600453933439576081214463590926434086384747290541542956399056962056229808127723780675081863094174281718420041021021738137563902621285687570410794757069128146157463269445164824140810572619018262027820086204868288731570345974912460949952968977302815206146117344553964793868988818958005020677285939064713111149888845649122939779041112120103892513478651508392217974531543376928740368199784888020421470272916459151814416040117267729799572111113430173741099889364201242246402948747813374749761369635840602934801976235850307624671917843079911771168517196726786713522653929181501433771224598604194250156742985226389799732276295274717715643984526333979308207645737104136935577625600314512836136271115660651134990573752618766965589069059676285129729732662084619078729162659020226938244891662847624627441891710694949940459227354409221979111240807882850754281611301674487520083457930422881455622420345738892296143055690156793547311809505543345371574649444927866169060334457904017188783393683115952245289189776402314456755190701764830857379904237952920537930837101480626961392776308489600995416134740406176538114983299708968857197075820121096069101496947802184680898394989647393102640058875148772532514830965041682985531620318115129285743608361213991132382738975462458617395619613187809486070987315723381903277922746195238195752905633836870278707046586517135634008007513341884363874996422486463455702922902696818946264796634960559597402803593333400937678136319820912555570462398816832063531837359091080659789751716369244408831250173156802380436362475465330236414904123853473096649894512457823362094181780912054103436914017980019455398250827412935061689262299438765336556444028008141319555636511769936177287956920799719676548107901075208403027364066932296087105441105308233895669378571717426107611042700373090786826809357637920085583810333407384012506569539408308629504276425574350546071484766182755577320350092810707004993335303482992232100488260296389559828488542505497559354326474562253495080783576216166234312096015413769488264005498554434439616686883956930058964562125319715331423528773748137428825047204186186648001874137240953303168262859474441442364125373820078661928648678801874400337808524510807407292324770665786283834004819341447708739358303385371869359181326822754638005614357757088482815667552921043175589353835686768950622306463118223568914503995372430337670295660500254935570486455145607978192630525671852896912768541854734619733961476555472299897874821466782568991296975858100442257963419860785714800116609046347135848549904523395244469912871910348036936480662845699967192884116216409488999878911387634858801666284371199007716171100287801287860307049091775742741060304901180847344576070072887286804106341674016729286661940027108142630650637758836422914341360842554401092646434224130444935704965676057926041362775924786583432602640154170852804440351577248486945824032635382183769612125595063262772078130555155831993351782956959696608968709544714953809612896233163746852346991803469348501042522744077168092081901244451643409807267936512732460961147488822964796202735500820301014818688579847672354195891890954086978215346979986227790640259391170662626734729071467762656777507642626883458780766449547354683123105196509097488881829974869470326766694168376589702024017800739547467144404227676674351665468804862538125870908797276169065403720549323187458536526037850524207766074436322836938304257311371902601828532364832899357200542907831617866643720527906804105301881269555094766929366731873712163397632411978533831454925115992025126122572575243124108927948251985272760453761040442900279614459490962271192658777575358243219372257723044331255857441455137934349703756882320673204480286229329737047565154624737913976783040219275254317566702293970510158407465954045780946698855495818114759070368009209396367465717100483910841200597758805510253615045052314093062210028464178602712271706991877647528837796369531833743493455280297995225803903076950864895339985477756937031227397457811500378614493909582380416368640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So in other words PHLISP should be officially released by christmas eve.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-5426487467892978830?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/5426487467892978830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=5426487467892978830' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5426487467892978830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5426487467892978830'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/12/tail-call-optimization-in-php-53.html' title='tail call optimization in php 5.3'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-1200656733477778038</id><published>2010-11-18T19:01:00.000-08:00</published><updated>2010-11-18T19:42:14.513-08:00</updated><title type='text'>ruby gem like system for php</title><content type='html'>With the advent of phar I feel the time is nigh for a ruby gem/perl cpan-esque system for distributing packages/sharing code. I know pear exists but honestly how does one distribute a package via pear? proposals? cvs? I am imagining something where you point it to a github project and it generates a phar, increments the version number, when ever you tell it a release is viable.&lt;br /&gt;&lt;br /&gt;It would also be slick to be able to do something like:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;    rock::require('somePackage');&lt;br /&gt;    namespace somePackage;&lt;br /&gt;&lt;br /&gt;    funcDefinedInSomePackage(); &lt;br /&gt;    $x = new ClassFromSomePackage;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Where rock::require at dev time would check for the latest version of "somePackage" on the server, if it is newer than what is there (or it is not there at all) it will download the phar, put it in the library and then load the phar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-1200656733477778038?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/1200656733477778038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=1200656733477778038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1200656733477778038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1200656733477778038'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/11/ruby-gem-like-system-for-php.html' title='ruby gem like system for php'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-5472561113536490211</id><published>2010-09-30T11:48:00.000-07:00</published><updated>2010-10-01T17:54:54.038-07:00</updated><title type='text'>mock table data</title><content type='html'>I got tired for looking at multidimensional arrays when writing lots of mock table data. &lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$orders = array(&lt;br /&gt;    array('email' =&gt; 'shaunxcode@gmail.com', 'firstname' =&gt; 'shaun', 'lastname' =&gt; 'gilchrist', 'street' =&gt; '555 north 800 east', 'city' =&gt; 'Orem', 'state' =&gt; 'UT', 'zip' =&gt; '84097', 'country' =&gt; 'USA', 'phone' =&gt; '801-222-5555'),&lt;br /&gt;    array('email' =&gt; 'peter@gmail.com', 'firstname' =&gt; 'peter', 'lastname' =&gt; 'jensen', 'street' =&gt; '5555 windsor street', 'city' =&gt; 'Salt Lake City', 'state' =&gt; 'UT', 'zip' =&gt; '84105', 'country' =&gt; 'USA', 'phone' =&gt; '801-555-0445'));&lt;br /&gt;&lt;br /&gt;$orders = Voltron_Test::MockTable("&lt;br /&gt; email                | firstname | lastname  | street              | city           | state | zip   | country | phone&lt;br /&gt; shaunxcode@gmail.com | shaun     | gilchrist | 555 north 800 east  | Orem           | UT    | 84097 | USA     | 801-222-5555&lt;br /&gt; peter@gmail.com      | peter     | jensen    | 5555 windsor street | Salt Lake City | UT    | 84105 | USA     | 801-555-0445&lt;br /&gt;");&lt;br /&gt;&lt;br /&gt;#relevant Volron_Test::MockTable method&lt;br /&gt;&lt;br /&gt;public static function MockTable($data) &lt;br /&gt;{&lt;br /&gt; $rows = array();&lt;br /&gt; foreach(explode("\n", $data) as $row) {&lt;br /&gt;  if(empty($row)) {&lt;br /&gt;   continue;&lt;br /&gt;  }&lt;br /&gt;  $row = array_map('trim', explode('|', $row));&lt;br /&gt;  if(!isset($cols)) {&lt;br /&gt;   $cols = $row; &lt;br /&gt;   continue;&lt;br /&gt;  }&lt;br /&gt;  $rows[] = array_combine($cols, $row);&lt;br /&gt; }&lt;br /&gt; return $rows;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-5472561113536490211?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/5472561113536490211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=5472561113536490211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5472561113536490211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5472561113536490211'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/09/mock-table-data.html' title='mock table data'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-8878007321540581745</id><published>2010-09-23T20:46:00.000-07:00</published><updated>2010-09-23T20:50:40.756-07:00</updated><title type='text'>instantiating object inline via __callStatic</title><content type='html'>This is a nice hack for instantiating objects inline via php 5.3 __callStatic. What I dig about it v.s. the newObject('ClassName') is that a) You can pass in arbitrary constructors, w/ newObject it only supported the case of there being a single param to constructor i.e. newObject('ClassName', $x)-&gt;otherFunc($y) can now be N::ClassName($x)-&gt;otherFunc($y). I think I like the fact the class can be a "bare word" and that any number of constructors can be passed thus legacy classes etc. which may require arbitrary arguments can also be used. &lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class Test {&lt;br /&gt;        public function __construct($name, $age)&lt;br /&gt;        {&lt;br /&gt;                echo "Name: $name and Age: $age passed to constructor\n";&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class N {&lt;br /&gt;        public static function __callStatic($className, $args)&lt;br /&gt;        {&lt;br /&gt;                $class = new ReflectionClass($className);&lt;br /&gt;                return $class-&gt;newInstanceArgs($args);&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;N::Test('some name', 300);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-8878007321540581745?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/8878007321540581745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=8878007321540581745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8878007321540581745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8878007321540581745'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/09/instantiating-object-inline-via.html' title='instantiating object inline via __callStatic'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-746399772685497131</id><published>2010-08-24T09:11:00.000-07:00</published><updated>2010-08-24T22:12:54.189-07:00</updated><title type='text'>transmogrified function composition</title><content type='html'>Using the transmogrifier something like function composition such as: &lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;(define (compose . fs)&lt;br /&gt;  (if (null? fs) (lambda (x) x)&lt;br /&gt;      (lambda (x) ((car fs) ((apply compose (cdr fs)) x)))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Becomes possible like:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$compose = [$funcs | &lt;br /&gt;  empty($funcs) ? [$_] : &lt;br /&gt;       [car($funcs)($compose(cdr($funcs))($_))]];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Which becomes: &lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$compose = function($funcs) use(&amp;$compose) {&lt;br /&gt;  return empty($funcs) ? function($x) { return $x; } : &lt;br /&gt;         function($_ = false) use(&amp;$funcs, &amp;$compose) { &lt;br /&gt;             return apply(car($funcs), array(apply($compose(cdr($funcs)), array($_))));};};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I am not doing an exact copy here because I am not using ". rest" args as I would probably call this function like: &lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;echo $compose({square negate cube})(500); &lt;br /&gt;//shorter than&lt;br /&gt;echo $compose('square', 'negate', 'cube')(500);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I think the above illustrates that really php IS capable of these sorts of things it's just that in it's incredibly gnarly. With a few syntax tweaks (square bracket closures w/ lexical scope, squiggly bracket arrays w/ barewords as strings, ability to use return value as function) - it's almost livable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-746399772685497131?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/746399772685497131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=746399772685497131' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/746399772685497131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/746399772685497131'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/08/transmogrified-function-composition.html' title='transmogrified function composition'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-3856746777115323637</id><published>2010-08-13T22:58:00.001-07:00</published><updated>2010-08-13T23:00:28.444-07:00</updated><title type='text'>php quasiquote preprocessor</title><content type='html'>Sometimes itches must be scratched. Last nights musing leads to tonights finished quasiquote for php: &lt;a href="http://github.com/shaunxcode/php-quasiquote-preprocessor"&gt;http://github.com/shaunxcode/php-quasiquote-preprocessor&lt;/a&gt;. It was nice to implement just quasiquote ignoring the rest of the lisp reader as before I had tried to "Add" quasiquote to my nearly complete lisp. As I discovered this was a mistake. In the future I am going to start the reader with quasiquote and build as much of the system with macros as possible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-3856746777115323637?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/3856746777115323637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=3856746777115323637' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3856746777115323637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3856746777115323637'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/08/php-quasiquote-preprocessor.html' title='php quasiquote preprocessor'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-2245181576595970886</id><published>2010-08-12T18:05:00.000-07:00</published><updated>2010-08-12T22:06:27.283-07:00</updated><title type='text'>Refactoring Voltron query DSL</title><content type='html'>This is an area of the framework I have not had a need to look at in a while and from this latest inspection it was blatantly not very well thought out. Admitting your own fallibility, I think, is probably the first step to being able to refactor your own code. Previously I had decided I really wanted to avoid seeing stuff like: &lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$UserModel-&gt;getWhere(array('type' =&gt; 'and', value' =&gt; array(&lt;br /&gt;    array('type' =&gt; '=', 'field' =&gt; 'name', 'value' =&gt; 'shaun'), &lt;br /&gt;    array('type' =&gt; 'or', 'value' =&gt; array(&lt;br /&gt;        array('type' =&gt; 'between', 'field' =&gt; 'age', 'value' =&gt; array(69, 100)), &lt;br /&gt;        array('type' =&gt; 'like', 'field' =&gt; 'l_name', 'value' =&gt; '%name%')))))); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So I went with a half baked dsl&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$UserModel-&gt;getWhere(Q::andWhere(&lt;br /&gt;    Q::is('name', 'shaun'), &lt;br /&gt;    Q::orWhere(&lt;br /&gt;        Q::is('age', Q::between(array(69, 100))), &lt;br /&gt;        Q::is('l_name', Q::like('%name%')))));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;On first inspection that is not too bad but it rapidly gets out of control if you need to actually do something more in depth (nested or statements etc.). Not only that but all of the :: is pretty ugly as is the fact I can't use words like 'and', 'or' '=' etc. as method names. I also had this idea that "is" should be used for all operators. I have now abandoned that in the name of consistency and to reduce the complexity of the code which actually generates the sql. &lt;br /&gt;&lt;br /&gt;Taking a prefix notation approach and refactoring W (for where instead of Q for query, leaving room for say F for the from stuff for defining joins and S for select) to merely be a global function which returns arrays like in the first example:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$UserModel-&gt;getWhere(W('and', &lt;br /&gt;    W('=', 'name', 'shaun'),&lt;br /&gt;    W('or', &lt;br /&gt;        W('between', 'age', 69, 100), &lt;br /&gt;        W('like', 'l_name', '%name%'))));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I pine for quasiquote:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$userModel-&gt;getWhere(&lt;br /&gt;    `(and&lt;br /&gt;         (= name shaun)&lt;br /&gt;         (or&lt;br /&gt;             (between age 69 100)&lt;br /&gt;             (like l_name %name%))));&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-2245181576595970886?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/2245181576595970886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=2245181576595970886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2245181576595970886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2245181576595970886'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/08/refactoring-voltron-query-dsl.html' title='Refactoring Voltron query DSL'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-3222011587894637908</id><published>2010-07-27T13:54:00.000-07:00</published><updated>2010-07-27T14:19:47.063-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>quasiquote for primitive lisp</title><content type='html'>I was searching for a basic quasiquote implementation in lisp which mentioned a paper by Alan Bawden. Anyway it was difficult to find via google so I figured I would type it up here for posterity. The original paper can be found: &lt;a href="http://www.google.com/url?sa=t&amp;source=web&amp;cd=3&amp;ved=0CCEQFjAC&amp;url=http%3A%2F%2Fpeople.csail.mit.edu%2Falan%2Fftp%2Fquasiquote-v59.ps.gz&amp;ei=OU1PTIDvB4q8sQPDrfyYBw&amp;usg=AFQjCNGOzmDytfGGyjX1-dTD4lrFxcdLwA"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;(define (qq-expand x)&lt;br /&gt;  (cond ((tag-comma? x)&lt;br /&gt;         (tag-data x))&lt;br /&gt;        ((tag-comma-atsign? x)&lt;br /&gt;         (error "Illegal"))&lt;br /&gt;        ((tag-backquote? x)&lt;br /&gt;         (qq-expand (qq-expand (tag-data x))))&lt;br /&gt;        ((pair? x)&lt;br /&gt;         `(append ,(qq-expand-list (car x))&lt;br /&gt;                  ,(qq-expand (cdr x))))&lt;br /&gt;        (else '', x)))&lt;br /&gt;&lt;br /&gt;(define (qq-expand-list x)&lt;br /&gt;  (cond ((tag-comma? x)&lt;br /&gt;         `(list ,(tag-data x)))&lt;br /&gt;        ((tag-comma-atsign? x)&lt;br /&gt;         (tag-data x))&lt;br /&gt;        ((tag-backquote? x)&lt;br /&gt;         (qq-expand-list (qq-expand (tag-data x))))&lt;br /&gt;        ((pair? x)&lt;br /&gt;         `(list (append ,(qq-expand-list (car x))&lt;br /&gt;                        ,(qq-expand (cdr x)))))&lt;br /&gt;        (else ''(,x))))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-3222011587894637908?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/3222011587894637908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=3222011587894637908' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3222011587894637908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3222011587894637908'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/07/quasiquote-for-primitive-lisp.html' title='quasiquote for primitive lisp'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-4654274801558738359</id><published>2010-07-19T17:48:00.001-07:00</published><updated>2010-07-20T11:26:57.274-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='fluent expressions'/><title type='text'>PHP to javascript fluent expressions</title><content type='html'>There are many times in Voltron views where I need to make a jquery/javascript call, initially I compromised and created the UI::ScriptSnippet in which I would put the typical "$(document).ready(function(){})" type deal in place. This was becoming increasingly more obnoxious particularly when the rest of the view code was so clean. So I give you the JSCallBuilder: &lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;    UI::JSCall('object')-&gt;method(array('a' =&gt; 'b')); &lt;br /&gt;    // renders to object.method({'a': 'b'}); &lt;br /&gt;&lt;br /&gt;    UI::JSReady('object')-&gt;method(array('a' =&gt; 'b')); &lt;br /&gt;    //renders to &lt;\script type="text/javascript"&gt;$(document).ready(function(){ object.method({'a', 'b'}) });&lt;\/script&gt; &lt;br /&gt;*/note the escaped script tags for bloggers sake? */&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The source to make this happens is relatively trivial: &lt;a href="http://code.google.com/p/phpviewadapter/source/browse/trunk/UI/JSCallBuilder.php"&gt;http://code.google.com/p/phpviewadapter/source/browse/trunk/UI/JSCallBuilder.php&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-4654274801558738359?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/4654274801558738359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=4654274801558738359' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/4654274801558738359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/4654274801558738359'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/07/php-to-javascript-fluent-expressions.html' title='PHP to javascript fluent expressions'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-1669549373425077537</id><published>2010-07-17T21:18:00.001-07:00</published><updated>2010-07-18T00:19:46.978-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='voltron'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>solving the word cube in voltron</title><content type='html'>In response to: http://programmingpraxis.com/2010/07/13/word-cube/&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;/* returns array of words found in the 9 letters provided */&lt;br /&gt;function solveCube($letters) {&lt;br /&gt;    $words = newType(TFile, 'words.txt')-&gt;splitBy("\n");&lt;br /&gt;&lt;br /&gt;    return newType(TString, $letters)&lt;br /&gt;        -&gt;asArray&lt;br /&gt;        -&gt;powerSet('contains', $letters[4])&lt;br /&gt;        -&gt;map('permutations', I('asString')-&gt;in($words))&lt;br /&gt;        -&gt;map('join');&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo solveCube('ncbciune');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;Next post I will delve into iterative permutation and powerset internals on Array as that is obviously where the meat of that solution lies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-1669549373425077537?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/1669549373425077537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=1669549373425077537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1669549373425077537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1669549373425077537'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/07/solving-word-cube-in-voltron.html' title='solving the word cube in voltron'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-4074705736733202428</id><published>2010-07-05T14:47:00.000-07:00</published><updated>2010-07-05T14:51:29.771-07:00</updated><title type='text'>voltron model calculated fields</title><content type='html'>In the field definition of a voltron model you usually specify the field and the type as a key =&gt; val associative array. In the case that you have a calculated field the current practice is to specify field =&gt; array(Type::Calculated, 'methodNameOnRecord'). With fluent lambdas I have added a short cut:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class TimeRecord extends Voltron_Model&lt;br /&gt;{&lt;br /&gt;    protected $table = 'time_record';&lt;br /&gt;&lt;br /&gt;    protected $fields = array(&lt;br /&gt;        'id' =&gt; Type::Primary,&lt;br /&gt;        'created' =&gt; Type::Timestamp,&lt;br /&gt;        'created_hour' =&gt; Type::Calculated('created')-&gt;asDateTime-&gt;formatAs('H'));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The magic lies with in the created_hour type definition which can also be written as Type::Calculated(I()-&gt;created-&gt;asDateTime-&gt;formatAs('H')). &lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-4074705736733202428?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/4074705736733202428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=4074705736733202428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/4074705736733202428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/4074705736733202428'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/07/voltron-model-calculated-fields.html' title='voltron model calculated fields'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-2657092224736363522</id><published>2010-06-30T16:07:00.001-07:00</published><updated>2010-07-02T15:56:54.161-07:00</updated><title type='text'>voltron and "fluent lambdas"</title><content type='html'>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)-&gt;add(1)&lt;br /&gt;&lt;br /&gt;Lets say you have a list of names and you want to reverse them, uppercase them and then join them by an &amp; symbol. Currently in raw php you have a few options but the cleanest is probably something to the effect of either:&lt;br /&gt;&lt;br /&gt;Idiomatic php:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$names = array('peter', 'paul', 'mary');&lt;br /&gt;foreach($names as $key =&gt; $val) {&lt;br /&gt;    $names[$key] = strtoupper(strrev($val));&lt;br /&gt;}&lt;br /&gt;echo join('&amp;', $names); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Functional php:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$names = array('peter', 'paul', 'mary');&lt;br /&gt;echo join('&amp;', array_map(create_function('$val', 'return strtoupper(strrev($val));'), $names)); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Functional php 5.3:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$names = array('peter', 'paul', 'mary');&lt;br /&gt;echo join('&amp;', array_map(function($val) { return strtoupper(strrev($val)); }, $names)) &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Voltron:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$names = newArray(VString, 'peter', 'paul', 'mary');&lt;br /&gt;echo $names-&gt;map(L(val)-&gt;reverse-&gt;upper)-&gt;join('&amp;');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;functional php:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$listOfList = array(&lt;br /&gt;   array('a', 'b', 'c'), &lt;br /&gt;   array('d', 'e', 'f'));&lt;br /&gt;&lt;br /&gt;echo join('&amp;lt;hr&gt;', array_map(create_function('$val', 'return join(\',\', array_map(create_function(\'$val\', \'return strtoupper($val);\'), $val));'), $listOfList));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Voltron:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$listOfList = newArray(VArray, &lt;br /&gt;    newArray(VString, 'a', 'b', 'c'), &lt;br /&gt;    newArray(VString, 'd', 'e', 'f'));&lt;br /&gt;&lt;br /&gt;echo $listOfList-&gt;map(L(val)-&gt;map(L(val)-&gt;upper)-&gt;join(','))-&gt;join('&amp;lt;hr&gt;');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Basically I am trying to get at the idea that oneliners don't have to be made of gnarleston heston.&lt;br /&gt;&lt;br /&gt;perl:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;@p=(0,1);until($#p&gt;20){print"$p[-2]\n";push @p,$p[-2]+$p[-1]}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Voltron: &lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;echo newRange(0, 1)-&gt;expand(L(x)-&gt;add(y), 20)-&gt;join("\n");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here is an example of finding primes.&lt;br /&gt;&lt;br /&gt;Python:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]&lt;br /&gt;primes = [x for x in range(2, 50) if x not in noprimes]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Voltron:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$noprimes = newRange(2, 8)-&gt;map(N(VRange, L(y)-&gt;times(2), 50, y))-&gt;flatten;&lt;br /&gt;$primes = newRange(2, 50)-&gt;diff($noprimes);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-2657092224736363522?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/2657092224736363522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=2657092224736363522' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2657092224736363522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2657092224736363522'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2010/06/voltron-and-fluent-lambdas.html' title='voltron and &quot;fluent lambdas&quot;'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-194716690365916375</id><published>2009-09-30T21:35:00.001-07:00</published><updated>2009-09-30T21:41:12.031-07:00</updated><title type='text'>APL jot dot in scheme and php</title><content type='html'>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:&lt;br /&gt;&lt;br /&gt;PHP:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function jotDot($fun, $v1, $v2) {&lt;br /&gt;    $result = array();&lt;br /&gt;    foreach($v1 as $x) {&lt;br /&gt;        $result[$x] = array();&lt;br /&gt;        foreach($v2 as $y) $result[$x][$y] = $fun($x, $y);&lt;br /&gt;    }&lt;br /&gt;    return $result;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Scheme:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(define (mapcar func list)&lt;br /&gt;  (if (null? list) '()&lt;br /&gt;      (cons (func (car list)) (mapcar func (cdr list)))))&lt;br /&gt;&lt;br /&gt;(define (jotDot func v1 v2)&lt;br /&gt;  (mapcar (lambda (x) (mapcar (lambda (y) (func x y)) v2)) v1))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;The eventual "fluent expression" APL-&gt;php interpreted code to do something like calculating a times table up to 12 would look like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$V = APL()-&gt;indexGenerator(12);&lt;br /&gt;$V-&gt;jotDot('times', $V);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-194716690365916375?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/194716690365916375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=194716690365916375' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/194716690365916375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/194716690365916375'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2009/09/apl-jot-dot-in-scheme-and-php.html' title='APL jot dot in scheme and php'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-7314190837098982042</id><published>2009-07-27T15:45:00.001-07:00</published><updated>2009-07-27T15:48:45.064-07:00</updated><title type='text'>more php5 musing</title><content type='html'>Whilst in normal php-land another livable library for me is going to be my phparrayplus leveraging anon functions. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$results = StaticClass::methodReturnsArray($arg)-&gt;eachPair(function($i, $x){&lt;br /&gt;  return $x-&gt;lookMaNoTmpVars($i + 1);&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In my opinion so much prettier than&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$results = StaticClass::methodReturnsArray($arg);&lt;br /&gt;foreach($results as $i=&gt;$x){&lt;br /&gt;  $results[$i] = $x-&gt;lookMoCrappTastic($i + 1);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-7314190837098982042?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/7314190837098982042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=7314190837098982042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/7314190837098982042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/7314190837098982042'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2009/07/more-php5-musing.html' title='more php5 musing'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-5605256127538251069</id><published>2009-07-20T12:45:00.000-07:00</published><updated>2009-07-20T12:46:27.058-07:00</updated><title type='text'>curry in php 5.3</title><content type='html'>Here is curry in php 5.3&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; function curry(){&lt;br /&gt;   $args = func_get_args();&lt;br /&gt;   $fn = array_shift($args);&lt;br /&gt;   return function() use(&amp;amp;$fn, &amp;amp;$args) {&lt;br /&gt;       $nargs = func_get_args();&lt;br /&gt;       foreach($nargs as $narg) $args[] = $narg;&lt;br /&gt;       return call_user_func_array($fn, $args);&lt;br /&gt;   };&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; $add20 = curry(function($a, $b){return $a + $b;}, 20);&lt;br /&gt; echo $add20(5); #25&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-5605256127538251069?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/5605256127538251069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=5605256127538251069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5605256127538251069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5605256127538251069'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2009/07/curry-in-php-53.html' title='curry in php 5.3'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-8618792374291367932</id><published>2009-07-03T11:09:00.000-07:00</published><updated>2009-07-03T11:46:48.957-07:00</updated><title type='text'>php 5.3 y combinator and other musings</title><content type='html'>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/&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function apply(){&lt;br /&gt;  $args = func_get_args();&lt;br /&gt;  return call_user_func_array(array_shift($args), $args);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function Y($f) {&lt;br /&gt;    $recur = function($r) use($f) {&lt;br /&gt;        return function($n) use ($f, $r) {&lt;br /&gt;            return apply($f($r($r)), $n);&lt;br /&gt;        };&lt;br /&gt;    };&lt;br /&gt;    return $recur($recur);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$fibo = Y(function($f) {&lt;br /&gt;    return function($n) use ($f) {&lt;br /&gt;        if($n &lt;= 2) {&lt;br /&gt;            return 1;&lt;br /&gt;        } else {&lt;br /&gt;            return $f($n - 1) + $f($n - 2);&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;echo $fibo(15); #610&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;Here is another example taken from the first chapter of SICP:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;define('tolerance', 0.00001);&lt;br /&gt;&lt;br /&gt;function fixed_point($f, $first_guess){&lt;br /&gt;    $close_enough = function($v1, $v2){&lt;br /&gt;        return (abs($v1 - $v2) &lt; tolerance);&lt;br /&gt;    };&lt;br /&gt;  &lt;br /&gt;    $try = function($guess) use(&amp;$try, $f, $close_enough){&lt;br /&gt;        $next = $f($guess);&lt;br /&gt;        return $close_enough($guess, $next) ? $next : $try($next);&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    return $try($first_guess);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo fixed_point('cos', 1.0); #0.7390822985224&lt;br /&gt;echo fixed_point(function($y){return sin($y) + cos($y);}, 1.0); #1.2587315962971&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;The only trick in this example is "use(&amp;$try, ..." clause which passes a ref to $try so the function can call itself.&lt;br /&gt;&lt;br /&gt;Here are some more cool scheme tricks. Creating cons, car, cdr, lst etc. from closures:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function cons($x, $y){&lt;br /&gt;    return function($m) use(&amp;$x, &amp;$y){&lt;br /&gt;        return $m ? $x : $y;&lt;br /&gt;    };&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function car($z){ return $z(true); }&lt;br /&gt;&lt;br /&gt;function cdr($z){ return $z(false); }&lt;br /&gt;&lt;br /&gt;define('nil', null);&lt;br /&gt;&lt;br /&gt;function lst(){&lt;br /&gt;    $args = func_get_args();&lt;br /&gt;    return cons(&lt;br /&gt;        array_shift($args),&lt;br /&gt;        empty($args) ? nil : call_user_func_array('lst', $args));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function length($items){&lt;br /&gt;    return $items == nil ?&lt;br /&gt;        0 :&lt;br /&gt;        1 + length(cdr($items));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function append($list1, $list2){&lt;br /&gt;    return $list1 == nil ?&lt;br /&gt;        $list2 :&lt;br /&gt;        cons(car($list1), append(cdr($list1), $list2));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Obviously the performance implications here have not been explored - it's purely academic but interesting to see what is now possible. &lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function person($age){&lt;br /&gt;    $self = array(&lt;br /&gt;        'get_age' =&gt; function() use(&amp;$age){&lt;br /&gt;            return $age;&lt;br /&gt;        },&lt;br /&gt;        'set_age' =&gt; function($new_age) use(&amp;$self, &amp;$age){&lt;br /&gt;            $age = $new_age;&lt;br /&gt;            return $self['get_age']();&lt;br /&gt;        }&lt;br /&gt;    );&lt;br /&gt;    return $self;&lt;br /&gt;}&lt;br /&gt;$peter = person(20);&lt;br /&gt;echo $peter['get_age'](); #20&lt;br /&gt;echo $peter['set_age'](50); #50&lt;br /&gt;echo $peter['get_age']() #50&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function many_methods($name, $x){&lt;br /&gt;    $GLOBALS['get_'.$name] = function() use(&amp;$x){&lt;br /&gt;        return puts($x);&lt;br /&gt;    };&lt;br /&gt;  &lt;br /&gt;    $GLOBALS['set_'.$name] = function($y) use(&amp;$x){&lt;br /&gt;        $x = $y;&lt;br /&gt;    };&lt;br /&gt;}&lt;br /&gt;many_methods('tony', 20);&lt;br /&gt;$get_tony(); #20&lt;br /&gt;$set_tony(500); #500&lt;br /&gt;$get_tony(); #500&lt;br /&gt;&lt;br /&gt;function clean_many($name, $x){&lt;br /&gt;    return array(&lt;br /&gt;        'get_'.$name =&gt; function() use(&amp;$x){&lt;br /&gt;            return puts($x);&lt;br /&gt;        },&lt;br /&gt;        'set_'.$name =&gt; function($y) use(&amp;$x){&lt;br /&gt;            $x = $y;&lt;br /&gt;        });&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function inner_scope(){&lt;br /&gt;    extract(clean_many('walter', 400));&lt;br /&gt;    $get_walter();&lt;br /&gt;    $set_walter(500);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;etc. etc. etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-8618792374291367932?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/8618792374291367932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=8618792374291367932' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8618792374291367932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8618792374291367932'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2009/07/y-combinator-in-php-53.html' title='php 5.3 y combinator and other musings'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-4335390078625502227</id><published>2009-06-24T10:34:00.000-07:00</published><updated>2009-06-24T10:47:47.792-07:00</updated><title type='text'>recess framework and metacircularity</title><content type='html'>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. &lt;br /&gt;&lt;br /&gt;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).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-4335390078625502227?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/4335390078625502227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=4335390078625502227' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/4335390078625502227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/4335390078625502227'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2009/06/recess-framework-and-metacircularity.html' title='recess framework and metacircularity'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-630239543596611385</id><published>2008-12-19T10:17:00.000-08:00</published><updated>2008-12-20T16:43:20.959-08:00</updated><title type='text'>templating dsl</title><content type='html'>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. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#PHP&lt;br /&gt;$layout = Array('border_layout',   &lt;br /&gt;  'center' =&gt; 'this is the center',&lt;br /&gt;  'south' =&gt; Array('border_layout',&lt;br /&gt;    'north' =&gt; 'this is the north of the south',&lt;br /&gt;    'south' =&gt; 'this is the south of the south'),&lt;br /&gt;  'north' =&gt; Array('form', 'method'=&gt;'POST', 'with'=&gt;Array(&lt;br /&gt;    Array('input', 'name'=&gt;'first_name', 'label'=&gt;'First Name'), &lt;br /&gt;    Array('submit', 'value'=&gt;'Save')));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;One nice thing about the php approach is that I can combine integer indexed with associative indexed arrays thus Array('submit', 'value' =&gt; 'Save') becomes possible as opposed to Array('type' =&gt; 'submit', 'value' =&gt; 'Save'). Clearly the adapter has to know that [0] is the type and thus shift that off before rendering the rest of the component.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#LET&lt;br /&gt;$layout = [border_layout&lt;br /&gt;  center:'this is the center'&lt;br /&gt;  south:[border_layout&lt;br /&gt;    north:'this is the north of the south'&lt;br /&gt;    south:'this is the south of the south']&lt;br /&gt;  north:[form method:post with:[&lt;br /&gt;    [input name:first_name label:'First Name]&lt;br /&gt;    [submit value:Save]]];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As let sits atop php the same combination of integer indexed and associative indexes applies here too. Clearly replacing =&gt; 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.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#S-EXPR&lt;br /&gt;$layout = (border_layout&lt;br /&gt;  (center 'this is the center')&lt;br /&gt;  (south (border_layout&lt;br /&gt;    (north 'this is the north of the south')&lt;br /&gt;    (south 'this is the south of the south'))&lt;br /&gt;  (north (form method:post with:(&lt;br /&gt;    (input name:first_name label:'First Name')&lt;br /&gt;    (submit value:Save))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#JSON&lt;br /&gt;$layout = {border_layout:{&lt;br /&gt;  center: 'this is the center', &lt;br /&gt;  south: {border_layout:{&lt;br /&gt;    north: 'this is the north of the south', &lt;br /&gt;    south: 'this is the south of the south'}},&lt;br /&gt;  north: {type:'form', method:'post', with:{&lt;br /&gt;    {type:'input', name:'first_name', label:'First Name'}, &lt;br /&gt;    {type:'submit', value:'Save'}}};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-630239543596611385?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/630239543596611385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=630239543596611385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/630239543596611385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/630239543596611385'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/templating-dsl.html' title='templating dsl'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-1586889190865798138</id><published>2008-12-13T23:41:00.000-08:00</published><updated>2008-12-14T01:46:51.084-08:00</updated><title type='text'>nodes relating to nodes to relate to nodes</title><content type='html'>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 &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;apple pie (recipe)&lt;br /&gt;  -&gt; (recipe ingredient) -&gt; apple (fruit)&lt;br /&gt;                         -&gt; 1/2 cup (measurement)&lt;br /&gt;&lt;br /&gt;  -&gt; (recipe ingredient) -&gt; margarine (food)&lt;br /&gt;                         -&gt; 1 pound (weight)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(recipe) -&gt; (recipe ingredient) -&gt; ((food) (measurement))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Another example would be a "record" &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(record) -&gt; (pressing) -&gt; ((format) (color) (pressing number) (number pressed))&lt;br /&gt;         -&gt; (relased by) -&gt; (band)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-1586889190865798138?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/1586889190865798138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=1586889190865798138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1586889190865798138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1586889190865798138'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/nodes-relating-to-nodes-to-relate-to.html' title='nodes relating to nodes to relate to nodes'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-1250272355144921672</id><published>2008-12-13T21:30:00.001-08:00</published><updated>2008-12-14T01:49:26.005-08:00</updated><title type='text'>collections of collections and relations of relations</title><content type='html'>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. &lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;node&lt;br /&gt;  &lt;ul&gt; &lt;br /&gt;   &lt;li&gt;person&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;place&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;thing&lt;br /&gt;    &lt;ul&gt;&lt;br /&gt;      &lt;li&gt;record&lt;/li&gt;&lt;br /&gt;      &lt;li&gt;shirt&lt;/li&gt;&lt;br /&gt;      &lt;li&gt;book&lt;/li&gt;&lt;br /&gt;    &lt;/ul&gt;&lt;br /&gt;   &lt;li&gt;concept&lt;br /&gt;    &lt;ul&gt;&lt;br /&gt;     &lt;li&gt;belief&lt;/li&gt;&lt;br /&gt;     &lt;li&gt;date&lt;/li&gt;&lt;br /&gt;     &lt;li&gt;number&lt;/li&gt;&lt;br /&gt;     &lt;li&gt;measurement&lt;br /&gt;      &lt;ul&gt;&lt;br /&gt;       &lt;li&gt;mass&lt;/li&gt;&lt;br /&gt;       &lt;li&gt;weight&lt;/li&gt;&lt;br /&gt;       &lt;li&gt;volume&lt;/li&gt;&lt;br /&gt;       &lt;li&gt;pressure&lt;/li&gt;&lt;br /&gt;       &lt;li&gt;force&lt;/li&gt;      &lt;br /&gt;       &lt;li&gt;distance&lt;/li&gt;&lt;br /&gt;       &lt;li&gt;time&lt;/li&gt;&lt;br /&gt;      &lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;     &lt;li&gt;color&lt;/li&gt;&lt;br /&gt;    &lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;collection&lt;br /&gt;    &lt;ul&gt;&lt;br /&gt;     &lt;li&gt;group of people&lt;br /&gt;      &lt;ul&gt;&lt;li&gt;band&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;     &lt;li&gt;group of things&lt;br /&gt;       &lt;ul&gt;&lt;li&gt;want list&lt;/li&gt;&lt;li&gt;have list&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;    &lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;   &lt;/ul&gt;&lt;/li&gt;&lt;br /&gt; &lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I feel this is a good start&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-1250272355144921672?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/1250272355144921672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=1250272355144921672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1250272355144921672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1250272355144921672'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/collections-of-collections.html' title='collections of collections and relations of relations'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-2602283932576337360</id><published>2008-12-10T20:05:00.000-08:00</published><updated>2008-12-10T20:35:20.620-08:00</updated><title type='text'>On Authors and Hackers</title><content type='html'>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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-2602283932576337360?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/2602283932576337360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=2602283932576337360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2602283932576337360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2602283932576337360'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/on-authors-and-hackers.html' title='On Authors and Hackers'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-6232695074522635472</id><published>2008-12-09T19:13:00.000-08:00</published><updated>2008-12-09T19:21:10.724-08:00</updated><title type='text'>initial impressions of seaside</title><content type='html'>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. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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! &lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-6232695074522635472?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/6232695074522635472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=6232695074522635472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/6232695074522635472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/6232695074522635472'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/initial-impressions-of-seaside.html' title='initial impressions of seaside'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-7581729357634336795</id><published>2008-12-09T15:44:00.000-08:00</published><updated>2008-12-09T15:48:41.087-08:00</updated><title type='text'>trying to put my finger on it</title><content type='html'>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. &lt;br /&gt;&lt;br /&gt;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). &lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;My new framework/language/paradigm is going to tackle these problems absolutely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-7581729357634336795?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/7581729357634336795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=7581729357634336795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/7581729357634336795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/7581729357634336795'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/trying-to-put-my-finger-on-it.html' title='trying to put my finger on it'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-6905139981159256627</id><published>2008-12-08T17:05:00.001-08:00</published><updated>2008-12-08T17:58:10.428-08:00</updated><title type='text'>lisp+smalltalk+php ?</title><content type='html'>So I am closing on a a complete set of rules for my syntax: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#use . to denote end of statement&lt;br /&gt;#list&lt;br /&gt;:(1 2 3 4).&lt;br /&gt;&lt;br /&gt;#boolean&lt;br /&gt;($this == $that).&lt;br /&gt;&lt;br /&gt;#block&lt;br /&gt;{$x $y | $x*$y}.&lt;br /&gt;&lt;br /&gt;#message&lt;br /&gt;[$object method_call: $arg with:[object method:$sub]].&lt;br /&gt;&lt;br /&gt;#use ; to denote "with" &lt;br /&gt;[$object methoda;&lt;br /&gt;         methodb;&lt;br /&gt;         methodc].&lt;br /&gt;&lt;br /&gt;#to emulate int objects anytime a square bracket encounters an int&lt;br /&gt;#it will "cast" as intobject thus:&lt;br /&gt;[1 to: 20 do: {$n | echo $n}].&lt;br /&gt;&lt;br /&gt;#transmogrifies to &lt;br /&gt;$intObject(1)-&gt;to(20)-&gt;apply('lambda_block_n');&lt;br /&gt;&lt;br /&gt;#it may be the case that the int methods could be factored into more&lt;br /&gt;#procedural form even such as for loops etc. It all depends on performance.&lt;br /&gt;#but pre-optimization is definitely NOT what I am going for here&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;[:(1 2 3 4 5) / :(2 4 7)]. #yields (1 3 5 7)&lt;br /&gt;&lt;br /&gt;#transmogrified to &lt;br /&gt;arrayObj(1,2,3,4,5)-&gt;__SYMB_DIV(arrayObj(1,2,3,4,5));&lt;br /&gt;&lt;br /&gt;#hmm may get ugly with nested hash&lt;br /&gt;$hash = :(a:(b:(c:true))).&lt;br /&gt;&lt;br /&gt;#it feels unbalanced but &lt;br /&gt;$hash = :(a::(b::(c:true))). #is far worse&lt;br /&gt;&lt;br /&gt;#or I could stop being an idiot and use #&lt;br /&gt;[#(1 2 3 4) each {$n | echo $n}].&lt;br /&gt;&lt;br /&gt;#my only hesitation is as illustrated here, # is used for comments in c-alikes.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-6905139981159256627?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/6905139981159256627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=6905139981159256627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/6905139981159256627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/6905139981159256627'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/another-idea.html' title='lisp+smalltalk+php ?'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-3496595680303499179</id><published>2008-12-08T10:28:00.000-08:00</published><updated>2008-12-08T13:30:59.016-08:00</updated><title type='text'>more on syntax</title><content type='html'>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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$list = (1 2 3);&lt;br /&gt;$list.each {$x | echo $x}; &lt;br /&gt;&lt;br /&gt;$number = let ($x = 10){&lt;br /&gt;  (add:{$y | $x += $y}&lt;br /&gt;   sub:{$y | $x -= $y});&lt;br /&gt;  #note if we wanted the method to be named add: we would do 'add:':{$y | $x += $y}&lt;br /&gt;}&lt;br /&gt;$number.add 10; #20&lt;br /&gt;$number.sub 5;  #15&lt;br /&gt;&lt;br /&gt;#And from last time:&lt;br /&gt;$decide = {$char | $char == a ? sum : mul};&lt;br /&gt;&lt;br /&gt;$num = 10;&lt;br /&gt;$letter = a;&lt;br /&gt;$result = [$decide char:$letter] 6 6 ($num + 50);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$range = (1..5); &lt;br /&gt;[$list reverse each {echo _}]&lt;br /&gt;#becomes&lt;br /&gt;function block_name($arg0){echo $arg0;}&lt;br /&gt;$list-&gt;reverse-&gt;each('block_name'); &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-3496595680303499179?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/3496595680303499179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=3496595680303499179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3496595680303499179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3496595680303499179'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/more-on-syntax.html' title='more on syntax'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-8191061263538518971</id><published>2008-12-07T11:35:00.001-08:00</published><updated>2008-12-07T11:51:04.977-08:00</updated><title type='text'>philosophy of duality of syntax</title><content type='html'>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? &lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#LET&lt;br /&gt;$x = func arg:val arg1:val2 arg2:(func1 arga:vara); &lt;br /&gt; &lt;br /&gt;#s-expr&lt;br /&gt;(setf x (func arg:val arg1:var arg2:(func1 arga:vara))); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;Something I have been toying with is the idea of how to transmogrify dynamic function calls in s-expressions:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$decide = [$char | $char == a ? sum : mul];&lt;br /&gt;&lt;br /&gt;$num = 10;&lt;br /&gt;$letter = a;&lt;br /&gt;$result = ($decide char:$letter) 6 6 ($num + 50);&lt;br /&gt;&lt;br /&gt;#should become&lt;br /&gt;$result = sum 6 6 ($num + 50); &lt;br /&gt;&lt;br /&gt;#which becomes&lt;br /&gt;$result = sum(6,6,($num + 50));&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-8191061263538518971?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/8191061263538518971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=8191061263538518971' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8191061263538518971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8191061263538518971'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/philosophy-of-duality-of-syntax.html' title='philosophy of duality of syntax'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-2337467576781271343</id><published>2008-12-07T10:56:00.000-08:00</published><updated>2008-12-07T11:29:12.316-08:00</updated><title type='text'>duality of syntax</title><content type='html'>So I have hit a bit of a conondrum with my current approach to introducing a new syntax for lambdas in LET/php. &lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$array = (a b c d);&lt;br /&gt;$array [0]; #a&lt;br /&gt;&lt;br /&gt;#the function expecting the yield block is passed a block which returns 0&lt;br /&gt;$expecting_yield [0];&lt;br /&gt;&lt;br /&gt;#one solution as we have dropped ( and ) for calling functions would be using &lt;br /&gt;#that for array indexes, this would sort of fit with the fact that it is used &lt;br /&gt;#for defining arrays. &lt;br /&gt;&lt;br /&gt;$array = (a b c d); &lt;br /&gt;$array(0); #a&lt;br /&gt;&lt;br /&gt;$array (a:(b:(c:cat))); &lt;br /&gt;$array(a)(b)(c); #cat&lt;br /&gt;&lt;br /&gt;#what about methods stored in arrays?&lt;br /&gt;$number = let($num = 5){&lt;br /&gt;  (mul:[$x | $x * $num]&lt;br /&gt;   div:[$num/_])&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#note that _ is for anon vars and _1 _2 is if there are many&lt;br /&gt;&lt;br /&gt;$number (mul) 10; #50 &lt;br /&gt;#that feels odd. &lt;br /&gt;&lt;br /&gt;#using magic __get and keyword param&lt;br /&gt;$number.mul x:10;&lt;br /&gt;&lt;br /&gt;#that works well for keys which are strings but what of numeric index?&lt;br /&gt;$array = (1 2 3 4);&lt;br /&gt;$array.0 #1 &lt;br /&gt;&lt;br /&gt;#perhaps we could be clever enough to turn numeric dots into&lt;br /&gt;$array[0] &lt;br /&gt;&lt;br /&gt;#if all arrays are objects then why would you not use an accessor method?&lt;br /&gt;$array = (1 2 cat 4); &lt;br /&gt;&lt;br /&gt;#or using an accessor method - thats only one extra char (the .)&lt;br /&gt;$array.at 2; #cat &lt;br /&gt;&lt;br /&gt;#maybe removing the [ ] notation will encourage functional programming&lt;br /&gt;#instead of iterating over for loops anyway? &lt;br /&gt;&lt;br /&gt;#but what about look ups in a hash table?&lt;br /&gt;$actions = (cat:walks rat:crawls bat:flies);&lt;br /&gt;(cat rat bat).each [$creature | &lt;br /&gt;  echo "the $creature {$actions.$creature}";&lt;br /&gt;];&lt;br /&gt;&lt;br /&gt;#normal php &lt;br /&gt;$actions = Array('cat'=&gt;'walks', 'rat'=&gt;'crawls', 'bat'=&gt;'flies'); &lt;br /&gt;foreach(Array('cat','rat','bat') as $creature){&lt;br /&gt;  echo "the $creature {$actions[$creature]}";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-2337467576781271343?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/2337467576781271343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=2337467576781271343' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2337467576781271343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/2337467576781271343'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/duality-of-syntax.html' title='duality of syntax'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-3762192093926261371</id><published>2008-12-05T10:42:00.000-08:00</published><updated>2008-12-07T11:32:39.778-08:00</updated><title type='text'>more on let blocks</title><content type='html'>So as an aside the two are equivalent:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$func = let($x = 10){&lt;br /&gt;  [$y | $x = $x*$y];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$func = [$x | [$y | $x = $x*$y]] x:10; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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). &lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-3762192093926261371?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/3762192093926261371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=3762192093926261371' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3762192093926261371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3762192093926261371'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/more-on-let-blocks.html' title='more on let blocks'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-7719309939519362717</id><published>2008-12-02T17:08:00.000-08:00</published><updated>2008-12-02T17:32:24.457-08:00</updated><title type='text'>closures in php</title><content type='html'>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:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$func = let($x = 10){[$y | $x = $x*$y]};&lt;br /&gt;echo $func y:2; #20&lt;br /&gt;echo $func y:2; #40 (as x is now 20 having been modified by prior call to closure)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;First the simple class for handling closures&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class __Closure{&lt;br /&gt;        private $method;&lt;br /&gt;        private $env;&lt;br /&gt;        function __construct($method, $env){&lt;br /&gt;                $this-&gt;method = $method;&lt;br /&gt;                $this-&gt;env = $env;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        function call(){&lt;br /&gt;                $args = func_get_args();&lt;br /&gt;                $args[] = $this-&gt;env;&lt;br /&gt;                return call_user_func_array($this-&gt;method,$args);&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And now the transmogrified version of the let statement:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function lambda_closure_0($y,$env){&lt;br /&gt;        return $env['x'] * $y;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function lambda_func_0($y){&lt;br /&gt;        return $GLOBALS['lambda_closure_0']-&gt;call($y);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function lambda_let_block_0($x){&lt;br /&gt;        $GLOBALS['lambda_closure_0'] = new __Closure('lambda_func_0',Array('x'=&gt;&amp;$x));&lt;br /&gt;        return 'lambda_func_0';&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$func = lambda_let_block_0(10);&lt;br /&gt;echo $func(2); #20&lt;br /&gt;echo $func(2); #40&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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' =&gt; &amp;$x)).&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-7719309939519362717?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/7719309939519362717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=7719309939519362717' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/7719309939519362717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/7719309939519362717'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/12/closures-in-php.html' title='closures in php'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-110906504542131293</id><published>2008-11-30T18:44:00.000-08:00</published><updated>2008-11-30T20:21:41.181-08:00</updated><title type='text'>on the road to lisp</title><content type='html'>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:&lt;br /&gt;&lt;br /&gt;#So we start with a function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function filter($array, $field, $pattern=false, $limit=0, $above=0){&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#first we make an array of users&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$users = Array(Array('name'=&gt;'shaun','age'=&gt;26),Array('name'=&gt;'peter','age'=&gt;60));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#now we can filter it  &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$newusers = filter($users, 'age', false, false, 25); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#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. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$newusers = filter(array:$users, field:'age', above:25); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#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.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$newusers = filter array:$users, field:'age', above:10; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#now we're getting somewhere but why not drop the comas and just infer from the whitespace that there are seperations? &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$newusers = filter array:$users field:'age' above:25; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#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"&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$newusers = filter the array:$users where field:'age' is above:25; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#that would end up getting parsed into:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$newusers = filter($users,'age',false,false,25); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#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.&lt;br /&gt;&lt;br /&gt;#now what about the array declaration? using our concept of dropping the un-necessary lets use key:value pairs and no commas &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$users = ((name:'shaun' age:25) (name:'peter' age:60)); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#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? &lt;br /&gt;&lt;br /&gt;#the next question is probably: what about inline expressions and or method calls i.e. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function get_users($group,$limit){}&lt;br /&gt;&lt;br /&gt;$users = filter array:getusers group: 10 limit: 10 field:'name' pattern:'/[a-z]*/i'; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#cleary we have some issues how can the parser group the arguments? well:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$users = filter array:(getusers group:10 limit:10) field:'name' pattern:'/[a-z]*/i';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;#holy s-expressions batman!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-110906504542131293?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/110906504542131293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=110906504542131293' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/110906504542131293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/110906504542131293'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/11/on-road-to-lisp.html' title='on the road to lisp'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-988161038957184138</id><published>2008-11-26T10:26:00.000-08:00</published><updated>2008-11-26T10:27:47.764-08:00</updated><title type='text'>bootstrapping the bootstrap</title><content type='html'>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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-988161038957184138?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/988161038957184138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=988161038957184138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/988161038957184138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/988161038957184138'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/11/bootstrapping-bootstrap.html' title='bootstrapping the bootstrap'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-5125759283687699677</id><published>2008-11-26T09:19:00.000-08:00</published><updated>2008-11-26T09:26:58.362-08:00</updated><title type='text'>getting emotional over lisp</title><content type='html'>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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-5125759283687699677?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/5125759283687699677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=5125759283687699677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5125759283687699677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5125759283687699677'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/11/getting-emotional-over-lisp.html' title='getting emotional over lisp'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-6705044513052618274</id><published>2008-11-25T00:05:00.000-08:00</published><updated>2008-11-25T00:09:55.022-08:00</updated><title type='text'>compilers, transmogrifiers and dragons oh my</title><content type='html'>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:&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;the collection space is going to be written using the transmogrifier. &lt;br /&gt;&lt;br /&gt;Once we are done with the ruby/python/perl type constructs I am going to be using the lbirary to implement lisphp.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-6705044513052618274?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/6705044513052618274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=6705044513052618274' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/6705044513052618274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/6705044513052618274'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/11/compilers-transmogrifiers-and-dragons.html' title='compilers, transmogrifiers and dragons oh my'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-925296830087431264</id><published>2008-11-21T08:05:00.000-08:00</published><updated>2008-11-21T08:09:19.578-08:00</updated><title type='text'>a tasty tidbit to scratch an itch</title><content type='html'>One of my favorite perl constructs is the ability to put an if statement after a print statement:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;print 'test' if($x == 2);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In php that becomes&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if($x == 2) echo 'test';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not strictly longer but the &lt;i&gt;phrasing&lt;/i&gt; feels wrong. &lt;br /&gt;&lt;br /&gt;Extending the chain class like so I can do this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Puts extends Chain{&lt;br /&gt;  var $val;&lt;br /&gt;  function __construct($val){&lt;br /&gt;    parent::__construct();&lt;br /&gt;    $this-&gt;val = $val;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function __if($condition){&lt;br /&gt;    if($condition) echo $this-&gt;val."\n";&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function puts($string){&lt;br /&gt;  $new = new Puts($string);&lt;br /&gt;  return $new;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$x = 2;&lt;br /&gt;puts('this is an assertion')-&gt;if($x == 2);&lt;br /&gt;&lt;br /&gt;#this would be nice for debugging&lt;br /&gt;puts('this is a debug message')-&gt;if(DEBUG);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-925296830087431264?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/925296830087431264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=925296830087431264' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/925296830087431264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/925296830087431264'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/11/tasty-tidbit-to-scratch-itch.html' title='a tasty tidbit to scratch an itch'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-320762357110166226</id><published>2008-11-20T17:47:00.000-08:00</published><updated>2008-11-21T07:52:52.510-08:00</updated><title type='text'>fluent expressions and conditionals</title><content type='html'>One problem I have encountered when designing "dsl" fluent expressions in php is conditionals. &lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Chain{&lt;br /&gt;  var $valid;&lt;br /&gt;  var $__methods;&lt;br /&gt;  var $__class_name;&lt;br /&gt;&lt;br /&gt;  function __construct(){&lt;br /&gt;    $this-&gt;valid = true;&lt;br /&gt;    $this-&gt;__class_name = get_class($this);&lt;br /&gt;    $this-&gt;__methods = get_class_methods($this-&gt;__class_name);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function __get($arg){&lt;br /&gt;    if(in_array($arg,$this-&gt;__methods)){&lt;br /&gt;      return $this-&gt;$arg();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function __call($arg,$data){&lt;br /&gt;    if(!$this-&gt;valid){&lt;br /&gt;      return $this;&lt;br /&gt;    }&lt;br /&gt;    $arg = '__'.$arg;&lt;br /&gt;    if(in_array($arg,$this-&gt;__methods)){&lt;br /&gt;      return call_user_func_array(Array($this,$arg),$data);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function __if($arg){&lt;br /&gt;    $this-&gt;valid = $arg;&lt;br /&gt;    return $this;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function __method1($value){&lt;br /&gt;    echo $value."\n";&lt;br /&gt;    return $this;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function start(){&lt;br /&gt;    $this-&gt;valid = true;&lt;br /&gt;    return $this;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function stop(){&lt;br /&gt;    $this-&gt;valid = false;&lt;br /&gt;    return $this;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function chain(){&lt;br /&gt;  $new = new Chain();&lt;br /&gt;  return $new;&lt;br /&gt;}&lt;br /&gt;chain()-&gt;if(false)-&gt;method1('will not display');&lt;br /&gt;&lt;br /&gt;$x = 10;&lt;br /&gt;chain()-&gt;if($x == 10)&lt;br /&gt;       -&gt;stop&lt;br /&gt;       -&gt;method1('wont work')&lt;br /&gt;       -&gt;if(false)&lt;br /&gt;       -&gt;start&lt;br /&gt;       -&gt;method1('will not work - will now')&lt;br /&gt;       -&gt;if(false)&lt;br /&gt;       -&gt;method1('will not work either');&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-320762357110166226?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/320762357110166226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=320762357110166226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/320762357110166226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/320762357110166226'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/11/fluent-expressions-and-conditionals.html' title='fluent expressions and conditionals'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-5665226800800190372</id><published>2008-10-29T20:18:00.001-07:00</published><updated>2008-11-21T07:30:34.160-08:00</updated><title type='text'>Ideas for php extension/mod</title><content type='html'>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. &lt;br /&gt;&lt;br /&gt;xR(1,100)-&gt;reduce({$x,$y | $x*$y}); &lt;br /&gt;&lt;br /&gt;xR(1,100)-&gt;reduce([$x,$y | $x*$y]);&lt;br /&gt;&lt;br /&gt;funcname($arg1)[$x | echo $x]; &lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;[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. &lt;br /&gt;&lt;br /&gt;xR(1,100)-&gt;reduce(($x, $y | $x*$y));&lt;br /&gt;&lt;br /&gt;Another nice thing would be having keyword paramaters but with json that become easy with an object i.e.&lt;br /&gt;&lt;br /&gt;functionName({parama:$a,paramb:$b});&lt;br /&gt;&lt;br /&gt;but wouldnt: &lt;br /&gt;&lt;br /&gt;functionName(parama:$a, paramb:$b); &lt;br /&gt;&lt;br /&gt;I guess thats more python esque. &lt;br /&gt;&lt;br /&gt;I mean shit while we're at it lets get rid of -&gt; notation and use. instead so now we have and allow an "implicit code block" to be passed in..:&lt;br /&gt;&lt;br /&gt;xR(1,100).reduce($x,$y | $x*$y);&lt;br /&gt;&lt;br /&gt;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&lt;br /&gt;&lt;br /&gt;[1,2,3,4,5].reduce($x,$y | $x*$y);  is applicable as is 'this is a string   '.trim().replace('a','b').split(' '); etc. &lt;br /&gt;&lt;br /&gt;Numbers could be objects too &lt;br /&gt;1.times(2);&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-5665226800800190372?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/5665226800800190372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=5665226800800190372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5665226800800190372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5665226800800190372'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/10/ideas-for-php-extensionmod.html' title='Ideas for php extension/mod'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-5568399929905781527</id><published>2008-06-22T20:21:00.001-07:00</published><updated>2008-06-22T20:41:06.011-07:00</updated><title type='text'>array to object</title><content type='html'>So I really get sick of:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if($promotion['req']['min'] &gt; 10)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if($promotion-&gt;req-&gt;min &gt; 10)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;The code is simple/hackish:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  class oArray{&lt;br /&gt;    /*class to turn a keyed array to object&lt;br /&gt;      IF a key is numeric it will be prepended with a letter n i.e. key 2 becomes n2&lt;br /&gt;      Really though this is meant for meaningful key=&gt;val relationships&lt;br /&gt;    */&lt;br /&gt;    function __construct($array){&lt;br /&gt;      foreach($array as $key=&gt;$val){&lt;br /&gt;        $key = is_numeric($key) ? 'n'.$key : $key;&lt;br /&gt;        $this-&gt;$key = is_array($val) ? new oArray($val) : $val;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  function oArray($array){&lt;br /&gt;    return new oArray($array);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//instantiation&lt;br /&gt;$promotion = oArray(Array(&lt;br /&gt;  'req'=&gt;Array(&lt;br /&gt;    'min'=&gt;50,&lt;br /&gt;    'max'=&gt;100),&lt;br /&gt;  'grants'=&gt;Array(&lt;br /&gt;    'limit'=&gt;50,&lt;br /&gt;    'type'=&gt;504))));&lt;br /&gt;&lt;br /&gt;//access&lt;br /&gt;if($promotion-&gt;req-&gt;min &lt;= $promotion-&gt;grants-&gt;limit); &lt;br /&gt;v.s.&lt;br /&gt;if($promotion['req']['min'] &lt;= $promotion['grants']['limit']); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-5568399929905781527?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/5568399929905781527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=5568399929905781527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5568399929905781527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5568399929905781527'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/06/array-to-object.html' title='array to object'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-8763643136527653767</id><published>2008-06-01T19:44:00.001-07:00</published><updated>2008-06-22T20:39:51.945-07:00</updated><title type='text'>All is not quiet</title><content type='html'>So I have been working through &lt;a href="http://projecteuler.net"&gt;project euler&lt;/a&gt; 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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-8763643136527653767?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/8763643136527653767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=8763643136527653767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8763643136527653767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/8763643136527653767'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/06/all-is-not-quite.html' title='All is not quiet'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-1321425257836534477</id><published>2008-05-20T11:49:00.000-07:00</published><updated>2008-05-20T12:43:00.041-07:00</updated><title type='text'></title><content type='html'>Added diff and intersect to the Hash object making the primes example even smaller.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  /*python version*/&lt;br /&gt;  noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]&lt;br /&gt;  primes = [x for x in range(2, 50) if x not in noprimes]&lt;br /&gt;&lt;br /&gt;  /*common php version*/&lt;br /&gt;  $noprimes = xR(2,8)-&gt;mapf('xR($x*2,50,$x)-&gt;out()')-&gt;flatten();&lt;br /&gt;  $primes = xR(2,50)-&gt;diff($noprimes);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or as a lovely one liner&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  $primes = xR(2,50)-&gt;diff(xR(2,8)-&gt;mapf('xR($x*2,50,$x)-&gt;out()')-&gt;flatten());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-1321425257836534477?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/1321425257836534477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=1321425257836534477' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1321425257836534477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/1321425257836534477'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/05/added-diff-and-intersect-to-has-object.html' title=''/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-3383191891925421643</id><published>2008-05-17T23:34:00.000-07:00</published><updated>2008-05-17T23:52:05.434-07:00</updated><title type='text'>inline lambda with out a wrapper function</title><content type='html'>So here is my implementation to allow for inline lambda functions:&lt;br /&gt;&lt;br /&gt;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). &lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;echo $_[sfnx('$x')]('hello world');&lt;br /&gt;&lt;br /&gt;You can use this how ever you would normally use a function (nested, in function calls etc.)&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;echo inline('$x','return $x;','hello world'); &lt;br /&gt;&lt;br /&gt;As you can see it's doable but I guess I like the "feel" of the first one.&lt;br /&gt;&lt;br /&gt;I should mention I was inspired by Peter Goodmans i/o reader blog post on a similar tip here: &lt;a href="http://ioreader.com/2007/06/18/hacking-variable-composition-another-approach-to-php-lambdas/"&gt;Hacking variable composition - another approach to php lambdas&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-3383191891925421643?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/3383191891925421643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=3383191891925421643' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3383191891925421643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/3383191891925421643'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/05/inline-lambda-with-out-wrapper-function.html' title='inline lambda with out a wrapper function'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-5178828250688430867</id><published>2008-05-17T11:26:00.001-07:00</published><updated>2008-05-17T11:33:44.308-07:00</updated><title type='text'>anonymous function caching</title><content type='html'>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. &lt;br /&gt;&lt;br /&gt;Define a directory where your anonymous methods will sit. I call mine 'defun'.&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-5178828250688430867?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/5178828250688430867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=5178828250688430867' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5178828250688430867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5178828250688430867'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/05/anonymous-function-caching.html' title='anonymous function caching'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-5587531935964881208</id><published>2008-05-16T23:53:00.000-07:00</published><updated>2008-05-17T11:01:00.818-07:00</updated><title type='text'>Prime numbers in PHP</title><content type='html'>More fluent interface goodness.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  // PRIME NUMBERS IN PYTHON&lt;br /&gt;   noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]&lt;br /&gt;   primes = [x for x in range(2, 50) if x not in noprimes]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  //PHP&lt;br /&gt;  $noprimes = xR(2,8)-&gt;for_each('xR($x*2,50,$x)-&gt;out()')-&gt;flatten();&lt;br /&gt;  $primes = xR(2,50)-&gt;if_only('!xH('.$noprimes-&gt;implode().')-&gt;in($x)');  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-5587531935964881208?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/5587531935964881208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=5587531935964881208' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5587531935964881208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/5587531935964881208'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/05/prime-numbers-in-php.html' title='Prime numbers in PHP'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8582403812843601208.post-6319304733587316516</id><published>2008-05-16T23:03:00.000-07:00</published><updated>2008-05-17T11:05:47.882-07:00</updated><title type='text'>Purpose</title><content type='html'>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).&lt;br /&gt;&lt;br /&gt;For now here are some examples of my Fluent Hash class in action with some list comprehension comparisons to python and lisp.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Note that xH and xR are shortcuts for creating a "new Hash" or creating a new hash &lt;br /&gt;and immediately calling it's range method i.e &lt;br /&gt;$new = new Hash(); &lt;br /&gt;$new-&gt;range(10);&lt;br /&gt;&lt;br /&gt;  /* python versions&lt;br /&gt;   S = [x**2 for x in range(10)]&lt;br /&gt;   V = [2**i for i in range(13)]&lt;br /&gt;   M = [x for x in S if x % 2 == 0]&lt;br /&gt;   P = [str(round(355/113.0, i)) for i in range(1,6)]&lt;br /&gt;   F = [x.strip() for x in ['  banana', '  loganberry ']]&lt;br /&gt;   VEC = [2, 4, 6]&lt;br /&gt;   X = [3*x for x in vec if x &gt; 3]&lt;br /&gt;   X1 = [[x,x**2] for x in vec]&lt;br /&gt;  */&lt;br /&gt;  &lt;br /&gt;  //PHP&lt;br /&gt;  $S = xR(10)-&gt;for_each('pow($x,2)');&lt;br /&gt;  $V = xR(13)-&gt;for_each('pow(2,$x)');&lt;br /&gt;  $M = xH($S)-&gt;if_only('$x % 2 == 0');&lt;br /&gt;  $P = xR(1,6)-&gt;for_each('round(355/113.0,$x)');&lt;br /&gt;  $F = xH('  banana', '  loganberry ')-&gt;map('trim');&lt;br /&gt;  $VEC = xH(2,4,6);&lt;br /&gt;  $X = xH($VEC)-&gt;if_only('$x &gt; 3')-&gt;for_each('3*$x');&lt;br /&gt;  $X1 = xH($VEC)-&gt;for_each('Array($x,pow($x,2))');&lt;br /&gt;&lt;br /&gt;  /*common lisp&lt;br /&gt;   (loop for x from 0 to 100 if (&gt; (* x x) 3) collect (* 2 x))&lt;br /&gt;  */&lt;br /&gt;&lt;br /&gt;  //PHP&lt;br /&gt;  $C = xR(100)-&gt;if_only('($x*$x) &gt; 3')-&gt;for_each('2*$x');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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!?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8582403812843601208-6319304733587316516?l=commonphp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://commonphp.blogspot.com/feeds/6319304733587316516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8582403812843601208&amp;postID=6319304733587316516' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/6319304733587316516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8582403812843601208/posts/default/6319304733587316516'/><link rel='alternate' type='text/html' href='http://commonphp.blogspot.com/2008/05/purpose.html' title='Purpose'/><author><name>shaunxcode</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
