Wednesday, 31 December 2014

CljOS - Objectifying Clojure

The venerable master Qc Na was walking with his student, Anton. 
Hoping to prompt the master into a discussion, Anton said 
"Master, I have heard that objects are a very good thing - is this true?" 
Qc Na looked pityingly at his student and replied, 
"Foolish pupil - objects are merely a poor man's closures."

Chastised, Anton took his leave from his master and returned to his cell, 
intent on studying closures. He carefully read the entire 
"Lambda: The Ultimate..." series of papers and its cousins, 
and implemented a small Scheme interpreter with a closure-based object system. 
He learned much, and looked forward to informing his master of his progress.

On his next walk with Qc Na, Anton attempted to impress his master by saying 
"Master, I have diligently studied the matter, and now understand that 
objects are truly a poor man's closures." 
Qc Na responded by hitting Anton with his stick, saying 
"When will you learn? Closures are a poor man's object."

At that moment, Anton became enlightened.

~ * ~
When I first started learning Clojure (and Lisp in general), I was extremely skeptical, and the primary source of skepticism was what I had been reading about functions. 

Functions in Lisp were described as beings of great power and flexibility, especially if they could "close over" their environment. Having been exposed only to what are called functions in C and static-methods in Java, I could not even begin to imagine how they could possibly be as powerful as objects.

The first step to realizing the awesomeness of Lisp functions was using higher-order functions. The whole concept of Java Interfaces that I had loved so much flew right out the window. This approach was simpler, more intuitive, and actually easier to write/read/modify. Just compare examples of sort-by to how you would do something similar in Java.

Now, I had written a game engine in Java (Kilvish), and was thinking of porting it to Clojure. I had originally intended to write idiomatic Clojure, but that would require a complete redesign of my Java code. This is when I had a scary idea.
~*~
"Lisp has jokingly been called "the most intelligent way to misuse a computer". I think that description is a great compliment because it transmits the full flavor of liberation: it has assisted a number of our most gifted fellow humans in thinking previously impossible thoughts."

(Edsger Dijkstra, CACM, 15:10)
~*~
I realized that I could add an Object System to Clojure, and reuse the same structure as my Java code. And though this sounds like a big project in itself, I was able to achieve this in less than a hundred lines of idiomatic, documented code! The result was CljOS.

After this, it was business as usual, and I ended up with a small game engine that I call Bakait.

CljOS is NOT a re-implementation of the Java OOP system, by the way. Much like the rest of Clojure, it is closer to what Python provides. CljOS does not 'hide' any data, for example. Being written in Clojure, it is also thread-safe.

Another *BIG* difference from traditional OO is the inheriting of class-variables as well as methods.  This is not a problem because just entering a class name at the REPL shows the entire structure of the class- every property, method, and the entire class hierarchy that it is a part of.

Anyways, Rich Hickey (the creator and BDFL of Clojure) hates objects and has good reasons for it. I don't use CljOS myself when writing Clojure, and generally wouldn't recommend anyone else to use it. But its existence reminds me of the power I wield being a Lisp programmer. Although Rich has (good) opinions on how Clojure should be used, the language itself is extremely malleable.

In short- Clojure doesn't tell me how to write my code, I tell it how to execute it.

Thursday, 30 October 2014

The Curious Case of Terrance McElroy

Sally:
There is something wrong with Terry, don't you know? The elder Miss DeWitt told me. They are saying he's gone mad, lost all touch with reality. Of course, I always knew there was something wrong with him and the way he behaved at times. I found him sitting in the lobby late one night, mumbling something about why pies deserved more credit than they got, and aliens were right for not letting us in on the secrets of space travel.
I asked him if he was alright, but he told me not to worry because the universe was a mistake, anyway! I didn't know how to respond, so I left. I think that was the night he started floating around the house. We had to turn off all the fans in the middle of summer, just so he could demonstrate his denial of the existence of reality. He even refused to take off his shoes! It is pretty unnerving to see the dirt stuck on the bottom of shoes hovering above your head, ready to give in to gravity at any instant.
Yes, of course! I heard about that incident from Gregory. He would not shut up about it. Last fall, they had gone hiking, out on the Old George, and set camp about a kilometer from the top. Terry had been picking all kinds of stuff along the way- pebbles, leaves, beetles, and shoving them into a pouch. Later by the fire, Greg took the pouch from him to take a look. Inside, he saw the two of them sitting around the fire- Terry sipping soup, and he looking into the pouch. Creeped him out. Not the first time he's done this, either.
Ah, no! I didn't know about this! Are you sure? Of course you are. Not unlike him to disrupt peace. Bringing vultures to a hospital! What was he thinking? I wonder if he thinks at all. I could bet his head was hollow. I've even thought of knocking to check- more than once- but then I'd be as mad as him, and we certainly don't want that.
Yes, I remember! He had wasps in his pockets. A bunch of them, alive. Roamed freely on his hands when he took them out, what a horrible thing to do! I really don't like those evil cratures around me.
Here comes Hector! Hello! Could you tell us what happened?

Hector:
Madness, I tell you- severe, acute, utter, total madness. That is what has happened. Terry has been at it again, and this time he's gone too far. I have never sought to interfere in the matters of others, but in his case- I think I should have.
I didn't say anything when he decided to chop off the one good guava tree in the yard, or when he yanked off the hose that time the Browns were shifting out- but teleporting all over the neighborhood? Putting cats in trees? Spiders in showers? Squids in pools? What does he think he is doing? Does he think this is a game?
Oh, yes- I did. I asked him when he appeared at the table- "Do you think this is a game?" He looked at me as if I was mad, and said- "Who zee do", grabbed my drink, and disappeared. I don't know what to do with him.
He doesn't believe in the existence of reality, you say? That has to be it. I think we must prove to him that we are real, and so is he, and that he can't get away with these frivolities all the time, just because he doesn't believe all this is real. I think Ralph could help. I can meet him in an hour.

Ralph:
He thinks I'm not real? What? Neither of us? He doesn't believe in 'reality'? What does that even mean? I know I'm real.
POP! (Terry appears) "No, you're not."
Hey!
Grabs cigar out of his hand
What do you think you're doing?
POP! (Terry disappears)
Fool!
What are you laughing at?

Lomas:
I heard he was teleporting everywhere last week? Or was it the one before last? He's been doing it the whole month?
I think I remember seeing a man disappear right in front of me near Lake Orin when I was around six. I think he looked like Terry. I think he's been doing it the whole time. I think he's been jumping around in time as well. (sigh)...
I don't know what he wants from life. He used to be such a good kid. I wonder what's gotten into him.

Rose:
Ha ha! What do you mean he's messing with space-time? Like, really popping up in different places at different times? That's gotta be fun! Wait. I just realized I remember him standing outside my window, smiling. So many times! He's been messing around!
Where are you, Terry? Show me your face right now, I swear I won't punch you instantly. You could've talked to me like a sane person.
POP! (Terry's face appears) Define 'sane'. POP! (disappears)
Did that really happen? Yeah, I know. Should have punched.

Sally:
Did you get the news? They found him! They found Terry! I've heard they started regretting it immediately. He was chasing the bats down in one of the caves. Said he couldn't believe the busters tried to imitate both rats and butterflies, and failed at both. He said he would rather have pandas flying around, breathing fire, than rats who tried to look like butterflies but didn't.
Yes, it's true! He told the officers they shouldn't have come so deep in, and gave them some hot pancakes and beer. What a scene! With him missing for two weeks, and the media gathered outside. That man finds a way to strike every nerve he can!
Oh, yes! They were surprised to see him calm and normal- more than he's been this whole year, in fact. He even managed to arrange a feast out of two fish and six loaves of bread. Some Vietnamese delicacy, I can't pronounce the name. I just hope they don't all get diarrhea.

Roger:
Do you remember the guy they 'rescued' from the Caves? All the people he treated to fish later stopped ageing. No, really! Read the news. One driver guy from a news channel was due to retire next week, but since they figured he wasn't ageing, he has basically been enslaved. He's suing that guy for a Billion Dollars, what's his name- Terry Something. Such madness!

Terry:
What a sad bunch of crybabies.

Saturday, 6 September 2014

Kilvish Game Engine - Getting Started

Prerequisites:
  • Java Development Kit - the Java language and runtime system
  • Eclipse - a development environment for Java. (you can use another IDE if you like, but this tutorial assumes an Eclipse environ)
Setting up the environment
(make sure you have Java and Eclipse installed before continuing)
    A game-engine is a framework for writing games. Kilvish Game Engine is such a system that is simple to learn, use, and modify. We'll start with setting up a Kilvish project in Eclipse.
  • Download the zipped version of the engine from the project's site (top-right)
  • In eclipse, go to File -> Import -> General -> Existing Projects into Workspace
  • Choose select archive file and click Browse
  • Select the downloaded zip file, and click Finish
You should now see the Kilvish project in your Package Explorer (on the left).

Let's start!
    Go to KILVISH -> examples -> clouddemo -> CloudDemo.java.
This should be what you see
    Now click the Run button. (green play-button on the top panel)
The cloud demo

    The cloud looks pretty still and boring, doesn't it? Let's animate it!
    Note: The setFPS(60) method call tells Kilvish to update the game 60 times every second.
    Modify the constructor to look like this:
CloudDemo(){
 super(600, 400);
 this.setFPS(60);
  
 cloud = new Sprite("cloud");
 cloud.addImage(cloudImg1, 10);
 cloud.addImage(cloudImg2, 10);
 this.add(cloud);
}
 
    What this will do is display the two added images in a loop, with each image being displayed for 10 frames at a time. Save the file, and hit Run again. Easy, right?

    But what if we want the cloud to move? Add this method above main:
public void update(){
 cloud.moveBy(1, 0);
}

    This method is called by Kilvish every time the game is updated, and we have overridden it to move the cloud one pixel to the right. Save and Run again. Pretty neat!

    Now add this line to the constructor:
new DragAdapter(cloud);

    You should now be able to drag the cloud around the screen!

What Now?
    Believe me, this covers most of what you need to know to make a game. Now that you know the absolute basics, it would be a good time to check out the other examples that come bundled with the engine. The code is as simple as this for the most part.
    If there is anything at all that you have trouble understanding, you can leave a comment and I'll be happy to explain. Happy coding!

Friday, 8 August 2014

System Six

How can you challenge a perfect, immortal machine?

These words rang in Kito Kiyomoto's head as he lay on the hard plastic puller, headset lodged carefully around his ears and winding down the back of his head. He had been working on this for a long time now – over eight years, and maybe (of course) it was getting to his head.

DUMMY had started as a simple reply-bot in his senior year at school, that would give randomized sassy answers to how/why/where/when/what questions, the most complex piece of software he had yet written. It had been a lot of fun, too – forwarding to it questions that he did not want to answer himself, and getting back silly (and sometimes a bit profane) answers that only irritated the asker. Friends laughed at first, but then they claimed he was overdoing it. He didn't mind. He kept giving them those same tired answers until they realized it was his own, personal way of telling them to fuck off.

Kito tilted the stick in his left hand forward, and felt the slight hum of hydraulics as the puller started retreating into the elliptical groove of the drawing shaft. He could hear the gentle, rhythmic whisper of his breath inside his head that was cut off from the world by the locking headset. Over time, he had expanded the list of answers in Dummy's database, initially by adding them in manually - whenever he came upon a phrase or sentence that made him snicker or at least grin, he would re-frame it as an answer and feed it to him.

In second year of college, while studying for his Data Mining exam, he had written a small script to find and categorize replies from large bodies of text. It was not that tough, actually – sentences occuring right after a question mark turned out to be valid candidates almost all the time, and there were some other obvious patterns. After running it on soft-copies of all the Jeeves stories and then on all the transcripts of Monty Python sketches that he could find, he had spent the better of four hours reading the results, laughing (sometimes hysterically), and rephrasing them. He had barely passed the exam (totally worth it).

Are you pleased with yourself?” Prof. Hamlin had asked.
Ni.” he had said, and that had been the end of it.

Sometime during final year at college, Kito had realized he could make a questioning system that could keep firing random questions. NAGGY, he had called it, and installed it on three computers at the library. Within a month, he had a brand new collection of sassy answers that unwitting Naggy users had written, that he had then fed back to Dummy. It was while he was doing this that it had hit him – could dummy be made to answer naggy?

He had then spent an hour getting the systems to interact, and months refining the interactions. Naggy would ask a bitchy question to which Dummy would give a sassy answer, and the process would repeat with Naggy trying its best to ask a question contextually close to Dummy's last response. After a point, it was quite a rush to watch them talking. Holding a conversation. A silly one, perhaps, but a conversation none-the-less.

He had repackaged them together, and presented it has his major project under the name of System One – a framework for generating (silly) conversations – the first of its kind. He had received a bold A+, and an invitation to work at Dome Labs (NASA finds this interesting?).

'Dome' read the spidery blue letters on the front of the groove, a line starting from the center-left of the D, curving up to the right, and coming back down to the center-right of the elongated e, forming a dome. Kito looked away from it as the puller fit into position, and into the terminal on the roof of the unit. Dome was responsible for building the central computer of Hoplon-1, the first manned shuttle to Mars, and Kito was in charge of hacking the primary (conversational) interface – System Six.

Give me the processor stats, Sissy.”
Sure, Kit.” she said in her slightly distorted electronic voice, modeled to be relaxing and reassuring to the listener.

The console in front of him came to life, with all the bars green and way below their respective stress-points. Things were definitely better. They had to be – the launch was scheduled two months from now, and the time for major changes had gone. 

“Polish. Refine. Don't change.” he had been told.

Over a month back, during the first emergency simulation over at NASA, the computer had pinpointed a spark dangerously close to an O2 valve on one of the burners.

Shut down all O2 valves on burner-3, Sissy.”
Warning: shutting down all valves on burner might disrupt navigation.”
Noted. Now shut them down, Sissy!”
Shutting all O2 valves on burner-3.”

Then all hell had broken loose. The ship was spinning out of control and navigation systems had failed as warned. But when most others had left to fix whatever problems there had been with the navsys and the valves, and Kito had been left alone with his headset on, smiling at the brilliant performance of his system, Sissy had said almost in a whisper -

How can you challenge a perfect, immortal machine?”

Kito had looked around, shocked and dumbfounded – had she really said that?
Two others had their headsets on, but they hadn't seemed to notice. Were they paying attention? Cool it Kit, you're stressing yourself. She works fine – hell, she works beautifully. She was right, after all. But did she really say that? I should really get a beer.

He had spent the last month telling Sissy to do stuff that was generally dangerous, trying to corner her into another outburst, if there really had been one, but it had never come.

What were you expecting, Kit? She's fine.
She's GOOD, man!
Your brain child is going to Mars as an active member of the crew.
Let her be.

That last thought stressed him again. It was almost as if it hadn't originated from inside his own mind, but was resonating with it. I should really leave her alone, or I'll go mad.

System Six was up, and running well. It had passed all tests, and would be leaving for Mars as the spokesperson for Hoplon-1 in two months. Nothing would change that now.

Wednesday, 30 July 2014

System Shock 2 - Old is Nanites

So I started playing System Shock 2... and boy, does it rock!

The intro was enough to get me hooked. Check it out:
Watch this, insect.

The game takes place aboard a spaceship 67 trillion miles away from Earth that has been taken over by strange forces - the central computer has been hacked and gone rogue, and the inhabitants are either dead or in hiding, or have (obviously) become zombies who hiss a sardonic 'sorry' before charging at you with whatever they are armed with.

Unlike games like Halo, SS2 isn't about running and firing incessantly. It is more like Thief or Hitman in that it is always better to catch your enemy off-guard. Even the normal, low-level enemies can knock you out easily in head-on combat, which makes the game very challenging and rewarding.
"Your fleshh betrayss yoou..."
The hybrid FPS/RPG engine makes it possible to micro-manage your resources which really puts you into the skin of your character. The atmosphere is very immersive and does a fantastic job of sucking you out of this world and into this other, twisted one - just the sound of a zombie dragging its feet somewhere in the distance can send adrenaline rushing through your system.

Also, you're on free-roam all the time! You get to know the plot by collecting flight logs and such, and advance the game by unlocking different areas, but once a new area has been unlocked, you can go back to it anytime you want. This makes the feeling of being trapped in a doomed ship even stronger. You get to know the ship, and really feel like you're part of its dying crew.

Now, I might get a bashing for this, but I think I would have been able to enjoy Knights of the Old Repblic more if it had a similar FPS-like gameplay (I don't really dig the turn-based format). I'm done ranting, time to go back on-board.

Thursday, 12 June 2014

Clojure:Lisp :: LSD:Meditation

When I got back to my room last night, I found my roommate watching Scorsese's documentary on George Harrison, and immediately joined in.

The film suggests that the main motivation behind Harrison's foray into eastern mysticism and spirituality came out of a desire to tap into the mind-altering effects of LSD while steering free of chemical dependency. Today, the impact that the counterculture revolution has had on western society is very apparent, and much of it rose out of these same reasons. Many of the things that they now take for granted were born out of the same wants and needs, with Yoga being an obvious example.

Timothy Leary, in his version of the Tibetan Bardo Thodol, the 'Tibetan Book of the Dead' compares the phases that the soul passes through after death to good and bad trips, corresponding to Nirvana and rebirth respectively.

I have heard of the effects of Sudarshan Kriya from some of my college friends who had signed up for a summer course with the Art of Living and their experiences were very much like what we have come to know about the effects of external mind altering substances.

Anyway, my point is that experimenting with psychedelics led many to rediscover many spiritual aspects that were previously unknown to the vast majority, and brought them into the mainstream. Hoffman called his invention 'medicine for the soul', and wanted it to be regarded with awe rather than distrust, though it never really came to be. Acid led to the understanding of the the structure of DNA, a major revolution in thought, a dislike and deglamorization of war and things that lead to it, and to a whole lot of absolutely brilliant music.

Coding in Lisp seems to have infused many brilliant hackers (Alan Kay, Dijkstra, Stallman, etc.) with similar revelatory experiences.

It's been a long time since Common Lisp was standardized, and it has proven its worth time and again, and due to the largely orthogonal nature of the language, there have been little to no changes to its core, which some people see as a sign of 'death', and which couldn't be farther from the truth. Lisp embodies ideas that are timeless, and CL stuck to them and flourished, but didn't 'grow' in the sense other languages grow, because entirely new paradigms could be introduced in it without even touching the core. There was not a need to grow, only to embrace apparently new ideas.

But the language was dead to people who had not grown up with it, and lived in entirely foreign environments. Lispers tried time and again to reintroduce the power of their language through new implementations, but failed to grasp their attention. It was only with the addition of Lispy features to the now-mainstream languages, and the complexity that it exposed in them, that their followers regained that dying interest.

I would like to highlight this with some examples.
List comprehensions, for example, are an awesome feature, and Python supports them with the following syntax:
squares = [i*i for i in range(100)]

Clojure has a for macro to achieve the same thing, and it looks like this:
(def squares
  (for [i (range 100)])
    (* i i))

The Python example looks simple at first, but becomes increasingly complex when you try to do something useful.
Take this function (from Conway's Game of Life) for example, that returns a list of neighboring cells.
;Clojure
(defn neighbors [[x y]]
  (for [dx [-1 0 1]
        dy [-1 0 1]
        :when (not= 0 dx dy)]
    [(+ x dx) (+ y dy)]))

#Python
def neighbors(cell):
  [x, y] = cell
  ds = (-1, 0, 1)
  return [((x+dx, y+dy) for dy in ds if (dx!=0 and dy!=0)) for dx in ds]

Clojure's for scales gracefully to address the problem, whereas Python's list comprehension starts getting ugly. GvR wouldn't even let me break it into separate lines (which also results in a broken lambda, but I digress).

Then there's the issue of metaprogramming. One of the best Python frameworks I've ever come across is Django. And one of its best features is the Model-based database creation and interaction. Turns out it's written using metaclasses, which are (in Python) largely undocumented, really complex and nothing short of black magic. The best documentation on the subject is this answer on stackoverflow. Metaclass programming is easier in Ruby, and Ruby is more like Lisp, but as Paul Graham says - "If [Python hackers] don't want to wait for Python to evolve the rest of the way into Lisp, they could always just..."

In fact, this is exactly what prompted me to start learning Lisp.
I turned to Clojure because of these reasons:
1. It embraces the JVM, which I'm very comfortable with,
2. It has more novel ideas (STM, immutability-as-default, laziness, etc.) built-in than CL,
3. Rich Hickey is an awesome person, and his talks have made me a big fan (especially this one)

Yes, the current Clojure environment is not nearly as good as CL's, and ugly stack-traces litter the scene. Yes, there is no TCO happening automagically. Yes, there are no custom reader-macros.

But then, the community is working on a pure Clojure compiler, which will bring with itself a better environment, the recur keyword makes it absolutely clear that my code runs in constant space, and lesser diversity of reader-syntax makes the code easier to read.

This survey showed that 29% of Clojurians would switch to CL if Clojure disappeared, when only 5% of them were coming from it.

Clojure is re-introducing Lisp to a lot of people, much like Acid re-introduced spirituality, and for some reason, some Lispers (*cough* Pascal *cough* Costanza), instead of being happy about it, are bitching in public. There might be some truth to the myth of the SmugLispWeenie after all.

Monday, 9 June 2014

Queens

I finally got around to reading SICP, which is absolutely brilliant.
I love the way programming is treated as an extension of cognitive concepts that lie at the very core of our being. Here is a quote from the first chapter:

The acts of the mind, wherein it exerts its power over simple ideas, are chiefly these three:
  1. Combining several simple ideas into one compound one, and thus all complex ideas are made. 
  2. The second is bringing two ideas, whether simple or complex, together, and setting them by one another so as to take a view of them at once, without uniting them into one, by which it gets all its ideas of relations.
  3. The third is separating them from all other ideas that accompany them in their real existence: this is called abstraction, and thus all its general ideas are made.
- John Locke, An Essay Concerning Human Understanding (1690)

The book then goes on to describe the 3 important features of a programming language as follows:
  1. Primitive expressions, which represent the simplest entities the language is concerned with
  2. Means of combination, by which compound elements are built from simpler ones
  3. Means of abstraction, by which compound elements can be named and manipulated as units

Needless to say, I'm having a blast.

The book then explains these concepts with the help of various exercises, one of which is the N-Queens Problem. Here is a solution in Clojure that produces all possible configurations:

(ns queens)

(defn attacking? [[r1 c1] [r2 c2]]
  (or (= r1 r2)
      (= c1 c2)
      (= (+ r1 c1) (+ r2 c2))
      (= (- r1 c1) (- r2 c2))))

(defn safe? [board pos]
  (not (some #(attacking? % pos) board)))

(defn safe-poses [board n c]
  (for [r (range n)
        :let [pos [r c]]
        :when (safe? board pos)]
    pos))

(defn poss-boards [board n c]
  (for [pos (safe-poses board n c)]
    (conj board pos)))

(defn solutions [n]
  (loop [c 0, boards [[]]]
    (if (>= c n) boards
      (recur (inc c) (mapcat #(poss-boards % n c) boards)))))

Concise and expressive.
In fact, I was pretty surprised when i realized I was done, as my last attempt (in Java, around 3 years back) had been pretty complicated and unwieldy, and produced only one of the possible configurations.

Anyways, did I mention I'm having a blast?
Because I really am.

Sunday, 25 May 2014

A Measure of Learning

How do you know if someone is learning?

For a long time, the mainstream opinion seems to be that you should have answers.
That is, if you know answers to certain questions in your field, you are considered to be learned in that field.

In machine learning, a similar conventional measure is used where the agent is supposed to produce the closest answers to specific problems.

But do we work this way?
"I think, therefore I am."

I have personally observed that people who ask the right questions are the ones who are really learning, especially amongst coders.

To build a measure that determines the ability of an agent to question stuff around it, and by extension, its own existence, could be seen as one that was truly measuring learning in the absolute sense - developing conscience.

I'm working on an algorithm along these lines.
Open to ideas.

Phew.

Thursday, 1 May 2014

(and Infinity Beyond)

So I came across this paradox called Thomson's Lamp, and immediately thought- "Well, isn't this what quantum theory is all about?"

Niels Bohr had once said-
"If quantum mechanics hasn't profoundly shocked you, you haven't understood it yet."

Let's try and simulate the phenomenon that creates this paradox.

(defn thomsons-lamp []
  (iterate (fn [[onoff dur]]
             [(not onoff) (/ dur 2)])
           [true 1]))

This Clojure function returns an infinite list of (on/off, duration)pairs where every successive on/off value is toggled (between true/false) and duration is halved.

NOTE: You can follow along on an awesome live REPL here.

So now when I call:
(take 10 (thomsons-lamp))

I get:
([true 1] 
 [false 0.5] 
 [true 0.25] 
 [false 0.125] 
 [true 0.0625] 
 [false 0.03125] 
 [true 0.015625] 
 [false 0.0078125] 
 [true 0.00390625] 
 [false 0.001953125])

...which is precisely what I wanted. Time to have some fun.

(nth (thomsons-lamp) 100) ;=> [true 7.888609052210118e-31]
(nth (thomsons-lamp) 1000) ;=> [true 9.332636185032189e-302]
(nth (thomsons-lamp) 10000) ;=>  [true 0]

Wait, what?

(nth (thomsons-lamp) 10001) ;=>  [false 0]
(nth (thomsons-lamp) 10002) ;=>  [true 0]

So it is on for 0 seconds, then turns off for the next 0 seconds, and keeps toggling every 0 seconds?

Basically, after some point, we don't know whether the lamp is on or off. In fact, it can be thought to be in both the states at the same time. We can know only if we observe or measure its state at a particular moment.

The problem is: we know that every even position (starting from 0) will return true, and every odd position will return false.

Measuring the state changes the outcome.

This has deep parallels with quantum theory, where electrons travelling at high velocities can either be observed as physical matter, or as waves of energy, depending on how we observe them (more).

Coming back to Thomson's problem, I define:

(defn state [t]
  (let [t-vals (map second (thomsons-lamp))]
    (loop [i 1]
      (if (<= t (apply + (take i t-vals)))
        ((comp first last) (take i (thomsons-lamp)))
        (recur (inc i))))))

which returns the state of the lamp at time = t seconds.

(state 1)    ;=> true
(state 1.5)  ;=> false
(state 1.51) ;=> true
(state 2)    ;=> false
(state 2.1)  ;=> ...(stuck)

Just as the paradox says, we will never know what the status of the lamp is after around 2 seconds.

PS: I got the idea after reading this list. You might like it too.

Saturday, 19 April 2014

Metanoia

"What did you see?"

The world assembled itself in bits and pieces around a smoldering ego that took to flame in a final, desperate attempt to make sense of what it had been subjected to.

"Pa?" Lawley mumbled, guarding his eyes against the harsh bright moonlight.
"What did you see?" Mani the fish merchant repeated in a firm voice.
A pair of hands put a bowl of milk to his chaffed, quivering lips, that he took a few gulps from.
"I saw - I saw a mountain of fire, it was a sea of calm, I could feel others around me. And that word- it kept -" He then turned to look at Mani with ridicule on his face. "How do you know?"

Lawley scrambled to his feet, his thighs barely supporting his weight, to gather his bearings. It was then that he saw the white marble dome of the temple shining from the mainland, across a narrow channel, about two kilometers wide. Thirty or so natives stood behind him bearing short, flaming torches, despite the ample light. "What is this? Where am I?"

---

I was born and raised, m'child,
In Karkid, that snakes fear.

I saw and heard them all, m'child,
But only He is truly there.

I have seen the shadows rise, m'child,
Deep inside the center of the sun.

Faith will keep you sane, m'child,
Shock will make you go insane.

---

Wednesday, 19 March 2014

Mrinalini

A Stranger Arrives

The bombs had just been dropped, and the war was coming to an awkward end. Atrocities of the most inhuman nature had been committed by all sides, and only the naive or the ignorant thought anyone had won.

Many had died in numerous names. Most of them had not lived at all.
Some had tried to escape the chaos and ended up in the remotest corners of the Earth.

Madari walked down the forest path, glancing now and then at the half-moon that lay low above the valley. The woods were dense, and home to bears and big cats, and looking at the wilderness below him made him conscious of the one he was about to enter. 

He paused for a bit when he reached the paghdandi that led in, took a deep breath, then resumed walking his normal pace. Shadows engulfed him instantly as he entered the narrow alley down the bosom of Mother Nature in her prime.

Madari laughed a bit. Indeed, it was Madari whose short, deep guffaws echoed in the dark silence, not the man he had been before. There was a life he had left behind, a life that he had loved and lived. A life that had ended in cinders, and irons, and pain, and misery, and bloodshed.

It had been a remote village on the Karnatic coast in 1938 where it had all changed. The fresh young Lieutenant Fredrick Lawley had been posted there to receive two unidentified guests, who were driving all the way from Simla.

Lawley had to be there two months in advance, with no clear orders on what had to be done. In fact, he had been summoned by the Governor himself, and subtly told to maintain discretion. "We don't want," he had said so many times in so many words, "We don't want this one to spread or stagnate, young man."

Madari's guffaws gave way to a sob, with a  sudden burst of thick tears that stuck to the glass on his spectacles. He stopped, and took a deep breath.

When the young and confident but not naive Lt. Frederick had arrived in the remote town of Karkid on the 13th of March, 1938, it was early evening. The town was silent, almost desolate, and cool sea breeze whispered above the warm tropical summer sand.

His arrangement had initially been the servants-quarters of a fish merchant's house. The white-skinned were of the lowest caste in this part of the world, and the young soldier did not mind  This was one land that no foreigner had dared touch. The villagers lived in neutral solitude, and it dawned on him that he was among some of the oldest peoples of this Earth.

He had a dinner of boiled rice and pomfret-curry after unpacking in the small thatched hut in the backyard. His bed that night was a small roped cot out under the open sky, by a clear beach washed by the Arabian Sea, under a black sky adorned with dots and blots and patches of every imaginable color.

While he slept like a child, a strange word in an unknown language kept throbbing over and over in his mind. It sounded gentle and peaceful, and induced in him a euphoria that he would never trade for any thing in the world.

Mrinalini.

It might have been a lamp of extraordinary proportions,
or an exquisite volcano on a distant planet.

It radiated euphoria and calm from deep within its flaming core.
It seduced, it overwhelmed, it entranced, it freed, it enslaved all Conscience with its beauty.

Bells clanked and conches bellowed at the ancient town-temple with the spreading of dawn, and shook young Lt. Lawley out of his hallucinatory sleep. Resonating peace and calm gave way to paranoia and confusion. Frederick jumped out of bed, flailing like a fish in this teleology of death. He stumbled to his legs, now white with sand, and ran awkwardly towards the Arabian Sea.

Mrinalini! His mind said.
Mrinalini! It yelled in agony.

He did not know what that meant. He had never heard the word before, but he ran as the water tickled his feet, he ran as his thighs struggled, he ran while his shoulders failed and his eyes were full of the sultry water, and he drifted till he saw that thing again.
---

Sunday, 2 February 2014

On The Art of Programming

Foreword

This article is meant to guide the reader through the process of writing a program.
More importantly, it is intended to introduce the non-initiated hackers to the powerful world of functional programming and Lisp.


Introduction to Clojure

. Clojure is a dialect of Lisp, which is a family of programming languages.
. Lisp stands for list processing, and that is the core of the idea - everything is a list.
. Unless specified otherwise, lists are (eventually) evaluated, and are called forms.
. Clojure is built around the idea of immutability of state, which is pretty new and exciting.
. Many things in Clojure are lazy, ie, they are evaluated when and only if they are absolutely needed.

In Lisp, a form looks like this: (form-name x y z ...)
form-name can be one of 3 things: function-name, special-form-name, or macro-name.
The form (+ 1 2) evaluates to 3. + is a function, 1 and 2 are its arguments.


Aim

Our aim is to create a function infer-seq that takes a sequence as input and returns an infinite list created by extrapolating the input sequence using the Method of Differences.

Basically, we are implementing Babbage's Difference Engine in code. Awesome.

Use cases:

    (infer-seq [1 2])    ;=> (1 2 3 4 ...)    
    (infer-seq [10 8])   ;=> (10 8 6 4 ...)   
    (infer-seq [1 4 9])  ;=> (1 4 9 16 25 ...)

Code

Step 1
We first define a function diffs to get the list of differences for a pattern.

Use Case:
    (diffs [1 4 9]) ;=> (3 5)

Implementation:

    (defn diffs [pattern]
         (map - (rest pattern) pattern))

Working:
    (diffs [1 4 9])

  => (map - 
          (rest [1 4 9])
          [1 4 9])

  => (map - 
          [4 9]
          [1 4 9])

  => [(- 4 1) (- 9 4)]

  => [3 5]

Note:
    . As map iterates till the end of the smaller list, the 9 in the second list is simply ignored.

Step 2
We then define get-triangle as per the method of differences.

Use Case:
    (get-triangle [1 4 9]) ;=> ((1 4 9) (3 5) (2))

Implementation:

    (defn get-triangle [pattern]
         (take (count pattern) (iterate diffs pattern)))

Working:
    (get-triangle [1 4 9])

  => (take (count [1 4 9])
           (iterate diffs [1 4 9]))

  => (take 3
           [[1 4 9] [3 5] [2] [] [] [] ...])

  => [[1 4 9] [3 5] [2]]

Note:
     . As Clojure is lazy, the empty lists after [2] would never even exist.

Step 3
Finally, we define infer-seq.

Use Case:
    (infer-seq [1 4 9]) ;=>  (1 4 9 16 25 ...)

Implementation:

    (defn infer-seq [pattern]
         (->> (get-triangle pattern)
              (map last)
              reverse
              (iterate #(reductions + %))
              (map last)
              rest
              (concat pattern)))

Working:
    (infer-seq [1 4 9])

    => (->> (get-triangle [1 4 9])
          ...)
    
    => (->> [[1 4 9] [3 5] [2]]
          ...)

      => (map last [[1 4 9] [3 5] [2]])
      => [9 5 2]

      => (reverse [9 5 2])
      => [2 5 9]

      => (iterate #(reductions + %) [2 5 9])
      => [[2 5 9] [2 7 16] [2 9 25] ...]

      => (map last [[2 5 9] [2 7 16] [2 9 25] ...])
      => [9 16 25 ...]

      => (rest [9 16 25 ...])
      => [16 25 ...]

      => (concat [1 4 9] [16 25 ...])
      => [1 4 9 16 25 ...]

Note:
     . This example will help you understand how the ->> macro works.
     . #( ... ) is a reader-macro for writing anonymous functions in Clojure.
       Its arguments are: % %2 %3 ...
       Example: (map #(+ % 5) [1 2 3]) ;=> (6 7 8)
     . (reductions + [...]) returns the cumulative sums of a sequence.
       Example: (reductions + [1 2 3 4 5]) ;=> (1 3 6 10 15)


Complete Code

(defn diffs [pattern]
     (map - (rest pattern) pattern))

(defn get-triangle [pattern]
     (take (count pattern) (iterate diffs pattern)))

(defn infer-seq [pattern]
     (->> (get-triangle pattern)
          (map last)
          reverse
          (iterate #(reductions + %))
          (map last)
          rest
          (concat pattern)))

Conclusion

I had an awesome time writing this post.
Hope it encourages more people to check Lisp out.

Note

My original implementation was pretty memory intensive.
This version was suggested to me on StackOverflow.

Edit 1: Here's an equivalent in Python.