Sunday, July 25, 2010

End of Support isn't the End of the World

The PHP development team released PHP 5.2.14 last week and with it comes the end of active support for the 5.2 branch. A bit of dissent rippled throughout the community... but is it really a big deal? Contrary to popular belief, downloads from php.net don't come with an expiration date.

There is a lot of legacy code running mission-critical applications. These apps work and are stable so the time, effort, and expense required to upgrade them put doing so very low on a companies' priority lists. A few years ago I worked as a System Administrator for a credit union turned bank; the core processing system was written in PL/I and the ATM switching system was written in COBOL. There are probably more applications written in non-OOP PHP 3 code with register globals running atop a Linux 2.4 kernel than any of us want to acknowledge.

But version numbers are just mile-markers that reference a snapshot of the project at a given time. The development team is continually improving PHP so there will always be a newer, better version just around the corner. If your application is running stable on whatever version you have installed, and you're not using features or extensions that are subject to security or bug fixes in newer versions, then what's the problem? Use the version that works for you (and that your company's compliance officer will let you use).

With that said, don't expect the development team to support your favorite branch forever. PHP is open-source; people are free to participate in its development and do so for a variety of reasons. Just as the resources you can allot to refactoring legacy code are limited, the resources the development team have are limited as well. If you need a version 5.2.15, .16, or beyond then get involved and make it happen.

Tuesday, July 13, 2010

Learning Prolog

I'm not quite sure exactly I was searching for, but somehow I serendipitously stumbled upon the site learnprolognow.org a few months ago. It's the home for an introductory Prolog programming course. Logic programming offers an interesting way to think about your problems; I've been doing so much procedural and object-oriented programming in the past decade that it really took effort to think at a higher level!

I found the most interesting features to be definite clause grammars (DCG), and unification. Difference lists are very powerful and Prolog's DCG syntax makes it easy to work with them. Specifying a grammar such as:
s(s(NP,VP)) --> np(NP,X,Y,subject), vp(VP,X,Y).

np(np(DET,NBAR,PP),X,Y,_) --> det(DET,X), nbar(NBAR,X,Y),
pp(PP).
np(np(DET,NBAR),X,Y,_) --> det(DET,X), nbar(NBAR,X,Y).
np(np(PRO),X,Y,Z) --> pro(PRO,X,Y,Z).

vp(vp(V),X,Y) --> v(V,X,Y).
vp(vp(V,NP),X,Y) --> v(V,X,Y), np(NP,_,_,object).

nbar(nbar(JP),X,3) --> jp(JP,X).

pp(pp(PREP,NP)) --> prep(PREP), np(NP,_,_,object).

jp(N,X) --> n(N,X).
jp(jp(ADJ,JP),X) --> adj(ADJ), jp(JP,X).

det(det(DET),X) --> [DET], {lex(DET,det,X)}.

pro(pro(PRO),X,Y,Z) --> [PRO], {lex(PRO,pro,X,Y,Z)}.

v(v(V),X,Y) --> [V], {lex(V,v,X,Y)}.

prep(prep(PREP)) --> [PREP], {lex(PREP,prep)}.

n(n(N),X) --> [N], {lex(N,n,X)}.

adj(adj(ADJ)) --> [ADJ], {lex(ADJ,adj)}.
allows me to parse a statement for grammatical correctness, produce a parse tree, and determine where the point of failure is if it isn't grammatical.
?- s(X,[the,man,shoots,he],Y).
X = s(np(det(the), nbar(n(man))), vp(v(shoots))),
Y = [he]
The power of unification is highlighted by the append/3 predicate, a "function" whose primary purpose is to concatenate two lists. By providing partial lists and pattern structures, append can not only be used to concatenate, but also split a list, double it, and even test an element for membership.
is_member(X,Y) :- append(_,[X|_],Y).
?- is_member(4,[1,2,3,4,5]).
Yes
I have to say working through the course has made me a better programmer. It exposed me to new ways of thinking about old problems which broadened my "programmer toolset." I feel more comfortable working with immutable variables and recursion, too-- both concepts which I knew but subconsciously shied away from.

One of the difficulties of self-study though is the lack of teacher and classmates to ask questions and verify solutions. I purchased the printed version of the course to check my work but was dismayed to see it only contains answers for the chapter exercises. I've decided to make my solutions to the practical sections available for other self-learners.

I definitely recommend setting aside some spare time and working your way through the course if you haven't been exposed to Prolog somewhere in your studies or career already.

Tuesday, July 6, 2010

On Unobtrusive JavaScript

Traditionally, unobtrusive JavaScript means the code is kept separate from the page's markup. This separation makes it easier to maintain and reuse the code. However, I view unobtrusive code as more than simple separation. True unobtrusiveness means your JavaScript code will function alongside other code that may be loaded by the browser, and the other code will function alongside yours. Don't pollute the global scope in the execution environment; don't clobber global objects, their properties, or prototypes with your own; and be able to work alongside various frameworks.