I’ve had lots of readers commenting on Phosphorus Five, and more explicitly Hyperlambda, stating how some of my claims are “impossible”. Particularly when I explain that there is neither any interpretation process, nor any compilation process occurring, at any level in Hyperlambda. Statements like this seems to upset some of my readers. This combined with my statements about how Hyperlambda is still Turing complete, obviously puzzles developers. Of course, the reasons are because they’ve never seen anything quite like this before, so it’s difficult to believe in such statements. Basically, every single programming language they’ve seen before, is either an interpreted language, a compiled language, or some sort of variation of both. I wanted to write this article to clarify this though, such that there (hopefully) won’t be any misunderstandings about this.
For the record, if somebody showed me something without “wheels”, and told me it was a “car”, I’d be suspicious too, which arguably sums up their concerns you might argue …
Short explanation; Hyperlambda is a relational file format, capable of describing “graph objects”. That’s its technical definition. Its structure is “name/value/children”, and you can add “children nodes” to any specific node you wish, by simply adding two CR+LF and 2xSP characters behind another node. This implies that it is arguably similar in “structure” to XML, JSON, HTML, and for that matter Edifact, which are other “file formats” capable of describing “graph objects”. Once the file format has been “parsed”, such graph objects can be “evaluated”. Below is an example.
.data name:John Doe name:Jane Doe for-each:x:/@.data/*?value create-widget innerValue:x:/@_dp?value
The above Hyperlambda would for instance create two “widgets” (Ajaxified HTML elements), and render these back to the client. The above for instance, would create a graph object with one “root node”, having two children [.data] and [for-each]. The [.data] node would have two children itself, being its [name] nodes, etc. The values of any node can be found after its “:”. Now paradoxically, the above could just as easily have been declared with e.g. XML. Below is an example.
<root> <.data> <name value="John Doe" /> <name value="Jane Doe" /> </.data> <for-each value="/@.data/*?value" type="x"> <create-widget> <innerValue value="/@_dp?value" type="x" /> </create-widget> </for-each> </root>
Notice, after the DOM structure of the above XML have been parsed, there is no further “compilation” or “interpretation” occurring as the “graph object” is evaluated. Such graph objects, are simply passed into an “eval” function, which you can find here. Yet again, let me emphasise once more, in case you didn’t “get it”.
No further compilation or interpretation is done after the Hyperlambda has been parsed! It is evaluated “as is”, period!
In fact, the only structural difference between Hyperlambda and XML, is that Hyperlambda have an “implicit root node”. Now each “function” in the above “anti-code” (it’s not technically “code”, since it’s not interpreted or compiled), is created as Active Events. Read more about Active Events here. This allows me to create any Active Event I wish, including events such as the following.
- [!=] (comparison operators)
- [eval] – The most important one of course, being the “CPU” of Hyperlambda
This implies, that I can do anything in Hyperlambda, that I can do in any other programming languages, including creating a “compiler”. For the record, creating a “compiler” in Hyperlambda is a terrible idea, but it is possible. The same way creating a “web app” in CISC x86 Assembly code, is also probably “possible”, but yet again, highly likely a terrible idea …
I have created Active Events, that allows me to create a Turing complete “graph object”, which allows me to “declare” any programming instructions I want to “declare”. And since there is no “interpretation”, or “compilation”, ever occurring – Hyperlambda is no more a “programming language”, than that which XML (or HTML and Edifact) is. So the technical term for describing Hyperlambda, is arguably.
A “non-programming language”, based upon “anti-code”
This again creates some peculiar (and extremely interesting) side-effects. Among other things, if you are able to visualise this “graph object” (I refer to them as “lambda objects”) – You start realising you can modify them, as your “lambda” is executing – Which facilitates for “self modifying code” (among other things), to an extent previously impossible to fathom, using traditional “programming languages”.
So if you declare Hyperlambda to be a programming language, you’ll purely logically have to admit that this implies that XML is also a programming language. If you believe that Hyperlambda is interpreted, or compiled, you’ll purely logically have to admit that also XML is either interpreted, or compiled. Since defining XML as a “programming language”, is ridiculous, so is defining Hyperlambda a programming language also preposterous …
So why didn’t I use XML instead of creating my own file format (Hyperlambda) …?
Count the lines of code (LOC) above, and you’ll probably get it … 😉
What does Paul Graham have to do with this …?
p5.mime.create text:plain content:Foo bar
And it’s an integrated part of my “non programming language”, and becomes a “programming instruction”. 3 lines of code, allows for me to do what would require (literally) thousands of lines of code in any other programming language. Still, there is no semantic difference between how my [eval] function evaluates the above [p5.mime.create] Active Event, and how it evaluates an invocation to [if]. To create an Ajax widget, requires no more than 5 lines of code.
create-widget:foo innerValue:Click me! onclick set-widget-property:foo innerValue:I was clicked ...
The above traits allows me (or you) to create “domain specific Active Events”, in C# or F# for instance, to “extend” Hyperlambda, with your own keywords. Then later “orchestrate” these events together, in an extremely loosely coupled fashion (through Hyperlambda), and facilitates for reuse previously unmatched in other traditional programming languages.
The end of the Rabbit Hole …
I don’t like saying this out loud, because it sounds so preposterous, but in fact, Hyperlambda facilitates for “exponential software productivity growth” – Which of course sounds so ridiculous, that most people tend to believe I am a fruitcake insane quasi conspiracy theorist for stating such a thing. Exponential software productivity growth, for those not understanding its meaning, is the equivalent of proclaiming having found “free energy”, “cold fusion” or having created a “never ending eternity machine, capable of sustaining its own movement, without adding energy to it”. However, the proof is in the pudding, as you can see in the video below …
Every single “app” in the above video, including the actual “operating system” and its “Bazar” was created by one man, in 6 months, and you can verify this by checking up my GitHub repository …
Edit; Some commenter have argued that the lambda structure is in fact “interpreted”, since it creates a mapping between the string of “for-each”, and a method that “interprets” its arguments. This is of course true, and hence arguably turns lambda into an “interpreted structure”. However, since this lambda structure still can be built with XML, this still implies that we’ll have to accept the paradox of that XML is (potentially) a “programming language”, if we exchange the Hyperlambda (file format), with an equivalent XML file/string. Hence, if Hyperlambda is an “interpreted programming language”, then so is XML.
Notice though, that when you have a lambda structure, this can be directly modified by using Active Events such as [add], [insert-before] and [set]. These events acts upon the execution tree directly, and does not in any ways require you to type out “code” to have new “ideas” execute. In addition, any lambda object can also be serialised, during execution, into its associated Hyperlambda (file format), or an XML structure for that matter. Below is an example …
.exe event switch:x:/../*/some-argument?value case:foo set:x:/@.exe/*/event?name src:do-foo case:bar set:x:/@.exe/*/event?name src:do-bar eval:x:/@.exe
The above example illustrates directly modifying the lambda structure, as it is being executed, depending upon a [some-argument]‘s value, expected as input, and will either evaluate an Active Event named [do-foo], or another named [do-bar]. Since there are tons of other really weird examples, with highly interesting use-cases for this – The execution tree is in fact not even “fixed” as execution is initiated, and can be physically changed, according to arguments passed into it. And I don’t mean “passing in a lambda object”, I literally mean “physically changing the execution tree”. Even though lambda objects (obviously) can also be passed into it, of course …
In addition, you can for instance choose to copy and paste “half a lambda object”, and for instance rearrange the order of execution, having a function’s latter half, being executed before its first half, etc, etc, etc …
Regardless, I agree that a “lambda structure is interpreted”, after having given it a lot of thought, in addition to having been flooded with comments about this. Happy …? 😉