Z830 uses an mSATA SSD (to save space), and the largest available mSATA SSD in the market is 128GB (source). So, if you’d need more than 128GB storage, don’t buy the Z830 (or anything that uses mSATA) yet.
21 Dec 2011
You cannot upgrade Toshiba Z830’s SSD (yet)
Z830 uses an mSATA SSD (to save space), and the largest available mSATA SSD in the market is 128GB (source). So, if you’d need more than 128GB storage, don’t buy the Z830 (or anything that uses mSATA) yet.
Your thoughts betray you
I know all this negative feeling is because I am just tired and sleepy. Nevertheless it makes me hate Java uncontrollably!
18 Dec 2011
Life has to go on
Rest in peace
When someone dies, everyone — people who follow “conventional” religions (e.g. Christianity) as well as those that follow the “science religion” — uses the phrase “rest in peace”. Isn’t that “incorrect” for a science believer to use that phrase? I mean, what’s left of the dead person to rest in peace?
12 Dec 2011
Reading code
10 Dec 2011
Blissful ignorance
4 Dec 2011
Wavy waters
I had married Janaki the previous week. I wasn’t very excited about the marriage itself, and even less excited about my new wife. My mind was preoccupied with lost dreams. I had always thought IS and I would be living like the young couples they show in movies... the couples that are so happy that you want to be like them. I’d dream that I would be driving my car in a highway with IS sitting next to me and we’ll be talking, singing aloud, stopping to take pictures, staying in random hotels, and having fun travelling around. For two days after the wedding I didn’t feel anything, but as relatives left and the reality set in, I felt more and more miserable.
I don’t even remember what I told Janaki then at the temple. Probably it didn’t matter what I said; maybe she was just making an attempt to start a conversation. When two people new to each other are sitting together, silence can be intimidating. Once they have remained silent for a while, breaking that silence can be even more intimidating. But Janaki was willing to break the silence; she took the first step to make our relationship work, when I was actively resisting every minute of my new life.
Once we started living by ourselves in Madurai, I had to face the reality, and being resigned to everything was not a practical option anymore. Slowly we defined our relationship and defined our own unwritten protocols. I learned to ask her to help me with things. If I felt like coffee, I’d ask her to make one. I’d have preferred to make it myself, but she’d feel bad for reasons I couldn’t comprehend. After a while, asking her to make coffee was not only convenient, but it even started feeling natural.
The real change happened on our first vacation after I had just bought my car. We took the car and visited my father and her parents, and went to Periya Kovil. That was the first temple Janaki and I had gone to by ourselves, so she was sentimentally attached to it. Her face when we were sitting in the temple — content with the life she was living — is still in my eyes. While walking back to our car she held my hand tightly and walked along like a kid with her father... entirely positive about life... or maybe thinking nothing about life and just happy to be holding my hand. I didn’t feel as happy as she did, but I was at peace nonetheless.
Next year I wanted to drive down to Visakhapatnam, which Janaki wasn’t very keen of. She didn’t really enjoy sitting in a car all day and staring at roads. I had always loved roads, and I was always dreaming of being on the road driving my own car with someone I really, really like. Neither of us wanted to compromise on our plans for the vacation, so we had no vacation that year. Janaki was disappointed, but she truly believed that it was all my fault. That was the first blow our marriage sustained. What was lost in that bitterness was lost forever... like a fallen tooth that never grew again.
Next year I planned the vacation entirely based on Janaki’s preferences. The places we went to and the things we did were sure fun, but I couldn’t be genuinely happy about being there and doing them. When you’re faking a smile, when you’re pretending to be happy, it shows, and it hardly ever makes the people around you happy. My dissatisfaction ruined Janaki’s happiness, and that year’s vacation ended up even more bitter than the one that didn’t happen the previous year.
Life went on like a vessel on wavy water. Eventually I realised life is so volatile that judging your future based on your present is always wrong. But I learned that way too late, after our relationship was irreparably broken and we had to separate. Janaki had become too adamant and unyielding and all my attempts to reconnect failed.
I haven’t taken a vacation this year, but I don’t want to travel alone anymore. I sometimes want to start my life all over again... but I don’t have the energy or courage for that. Marriage has turned my life upside down. But certain things never change. Not a day goes by without me thinking that life would have been joyous if only I had married IS.
--
Thanks to Sumitra for inspiration. Thanks to Nags for inspiration as well as for proofreading the draft of this post.
Android’s “sticky row” of icons
Sticky row sure sounds useful in theory—because “important” apps can be accessed from all pages of the home screen, but I have never found it useful myself. Once I am familiar with the icon layout, I hardly ever look for an icon in the home screen—I simply navigate to it instead.
Let’s say I am on 2nd page of the home screen of my phone and I want to open the browser. Although the browser icon is present on the second page as well, I’d swipe over to the center page (which is the “main” page where I am mostly on) and then launch the browser from there1. My brain has associated the main page with browser so it’s faster to launch it from there vs. looking for it on the 2nd page.
I believe this how it is for many people: this is why programs in Start menu are easier to find when they are in alphabetic order, but the icons on the desktop when in a familiar order. Only this spatial familiarity makes us walk towards the kitchen without thinking when we are thirsty. Walking to the kitchen first and then figuring out what we want from there is more efficient than doing it the other way around.
Most people won’t look so deep into this, and they don’t have to; it’s the job of UX/interaction designers to evaluate these ideas. Which means, even if the Android team knows by now that the sticky row is useless, they cannot take it away lest upsetting users who think it’s a useful feature. If I were to control whether the bottom row of my Android is sticky or not, I’d make it non-sticky2.
Notes:
1. If memory serves right, Android 2.0 (Eclair) was the first version of Android to have a sticky row. I have been using Android from version 1.5 (Cupcake). I got the sticky row feature when I upgraded to a Nexus One a year later. I don’t know how much of an influence this has over my usage patterns. Also, I am still using Android 2.3 (Gingerbread), so I cannot customise the icons in the sticky row. My usage pattern may change when I upgrade to Android 4.0 (Ice Cream Sandwich).
2. I know Android is open source, so I can control if the bottom row on my phone is sticky or not. But this annoyance is not reason enough for me to hack the home screen app. Not yet.
30 Nov 2011
27 Nov 2011
Influence
Pinch of salt
I am no big writer, nor a serious reader... so take this all with a pinch of salt.I read this again today and I am embarrassed by these words. Did I honestly believe that my observations can be off the mark? No, I didn’t. But I almost always downplay my own views and come across less assertive. Pretend I don’t know what I am talking about. What for, I have no idea! One thing I do know is I do this subconsciously. Maybe this is the next thing I should start being conscious about.
22 Nov 2011
Chrome’s Duplicate Tab feature
- I am on Page A.
- I click on a link. Now I am in Page B.
- I have to do something that requires looking at both Pages A and B.
Now I can duplicate the current tab, which would give me two tabs with Page B. I can press Back in any of the two tabs to get back to Page A.
I stumbled upon an easier way to use this feature today. Instead of duplicating the tab first and then clicking Back on the new tab, I can Ctrl+click on the Back button to open a duplicate tab and go back in history one step. Works with Shift+click as well, but as you may expect it opens the duplicate tab in a new window.
18 Nov 2011
Change
13 Nov 2011
Real world
Literature
9 Nov 2011
Launch and iterate
7 Nov 2011
Acceptance
Borderless Chrome windows in Linux
I prefer to use KDE’s window borders for two reasons:
- I have customised my window title bar to add an “Always on top” button to it. It’s handy once in a while.
- When using system window border, I can see the full title of the current tab. This particularly useful when there is a nontrivial number of tabs open—which is like always.
Chrome windows that are opened after the change, however, are rendered correctly with border, title, minimise/maximise/close buttons, etc. If you are stuck with a few ‘naked’ windows like this, you can force KDE to draw borders by closing and recreating those windows. To avoid losing state in the process, use Chrome’s “undo close tab” feature.
Press Alt+F4 and close a whole window—close all tabs in that window at one go. (You cannot close that window otherwise because it doesn’t have a close button.) Now, from a different Chrome window press Ctrl+Shift+T for Undo Close Tab. This will restore the window you just closed with all tabs that were present in it. Since it’s a newly created window, KDE would paint all borders correctly.
5 Nov 2011
Corner cases
Whenever fire alarm goes off, people’s reaction is not “oh my god, fire!”... it’s “oh dear not again”. What’s intended as a life-saver lives on as a nuisance. I lived vast majority of my life in a developing nation where finding buildings with proper fire protection is hard. Not because we cannot afford to install fire detectors everywhere, but because we don’t feel the need for it.
Heard of corner cases? In the software world a corner case is when a user uses a software in a way not many people would normally use. Using Excel to create UI mocks for a new product is an extreme example. (No, I am not making this up; a PM I worked with really did this, and we were all like this.) Fire protection seems like a corner case in physical world.
I mean, how often something burns at home? Not very often, but once in a while a fire strong enough to trigger the alarm. Okay, how often are these fire incidents really serious? Occasionally. Most of the time you can just put off the fire by yourself before it can cause any trouble. Yet, first world countries all have this
Number of corner cases covered by a software is a metric of how complete (or complex) the software is. Maybe the number of physical corner cases a country has covered is a measurement of how developed/rich the country is. (It’s like they are so rich they can afford to spend resources on something that gives very little in return.)
Expectations
I guess the issue is just that: Shankar’s movies have some quality. Perarasu’s movies are plain trash from start to end. Shankar, because he’s better at his craft than Perarasu, makes me subconsciously expect more from his movies. And I get annoyed when the movie doesn’t really meet the expectation. Perarasu’s movies are so bad, 30 minutes into the movie I have no expectation whatsoever... so whatever he does gets accepted.
You can think of it this way. Not having sex can be depressing. But having to stop in the middle can be even more so.
2 Nov 2011
More quotes from Star Wars
3PO being funny and lame is quite likeable too. I have only one quote of 3PO’s in the list, but I liked several of his dialogues. Not quotable though, since they don’t make much sense without the context.
(Spoiler alert!) Another nice touch was not forgetting the original prophecy when the movie ends. Anakin is the one who’s supposed to end the war, but he turns to the dark side. Obi-Wan is shocked, but Yoda with his wisdom stays calm. Eventually it’s Anakin who ends the war and brings peace to the galaxy.
- All mentors have a way of seeing more of our faults than we would like. It’s the only way we grow.
- Life seems so much simpler when you’re fixing [broken] things.
- To be angry is to be human.
- The fear of loss is a path to the dark side.
- Attachment leads to jealousy. The shadow of greed that is.
- Train yourself to let go of everything you fear to lose.
- Good is a point of view, Anakin.
- [3PO to R2-D2] I don’t know what this trouble is about, but I’m sure it must be your fault.
- Your eyes can deceive you, don’t trust them.
- In my experience, there’s no such thing as luck.
- If money is all that you love, then that’s what you’ll receive.
- “Great warrior! Wars not make one great.”
- Many of the truths we cling to depend greatly on our own point of view.
- Your thoughts betray you.
29 Oct 2011
Fear of loss
(Spoiler alert!) Anakin (good guy) finds out that his wife is going to die in childbirth. Lord Sidious (evil guy) lures Anakin to join his side (the dark side) by promising to teach him powers to stop people from dying. Anakin changes sides, and before even he could start learning the powers, his wife dies. Anakin continues to stay with Lord Sidious, however.
Now, if Anakin really only wanted to save his wife and if he didn’t really have the ‘power lust’, he should have left the dark side and gone back to where he belongs—to the Jedis. But he decides to stay on the dark side. Maybe saving his wife was just an excuse he had for himself... he was fooling himself thinking that he’s doing it out of love while in fact he was only after power. It can be argued that he didn’t go back because the Jedis wouldn’t accept him again after all he had done. That again goes back to the fear of losing his position.
Master Yoda would say in a scene, “The fear of loss is a path to the dark side”. Anakin proves that by transforming into Darth Vader.
27 Oct 2011
Success is relative
Vast majority of the people either didn’t like Google Buzz or they weren’t as excited about it as Google would have wanted them to be. But there are people who like Buzz. And many of them are upset that Buzz is being killed. If you look only at those users, Buzz is a success. Same with Google Wave. Wave is still up and running, and those who’ve seen the possibilities of Wave are still using it. If you look only at those users, Wave is a success, and there’s point in working on improving it.
But Google decided to dump both Buzz and Wave because they want a different kind of success. Success is relative. Do you know what kind of success you are after? Do you know what kind of success will make you feel good about yourself? Discover that first—achieving it won’t be too hard.
23 Oct 2011
Star Wars
- Concentrate on the moment. Feel, don’t think. Use your instincts.
- May the Force be with you.
- Whenever you gamble, my friend, eventually you’ll lose.
- The choice is yours alone.
- You can’t stop the change, any more than stop the suns from setting.
- Hard to see, the dark side is.
- Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
- Your focus determines your reality.
21 Oct 2011
Processes
16 Oct 2011
Very high level programming
The C standard says a bunch of stuff leads to undefined behavior. Real compilers take advantage of that to optimize away code, sometimes with surprising results.Essentially compilers understand the intent of our statements and can rewrite the program for us if they can prove that the rewrite does not change the program’s behaviour. Compilers understand a lot of “low level” operations so they are smart enough to rewrite them for us.
What assembly has undefined behavior on that scale?mov al, [3483h] ;(Intel syntax)
is going to try to copy the byte at 3483h into the al register, period.
One thing you would have noticed if you’re a programmer is that formidable amount of coding time is spent on handling corner cases. Most of this corner case complexity is caused by the lack of understanding our tools (compilers, runtimes, etc.) have of the program’s intent. Let’s take an example code snippet:
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; ++i) {
list.add(300 * 2);
}
Compilers of today can rewrite this code as:List<Integer> list = new ArrayList<Integer>();
int __tmp = 300 * 2;
for (int i = 0; i < 10; ++i) {
list.add(__tmp);
}
This is a very simple optimization that saves CPU time. This is possible only because our compilers know that a loop repeats the execution of its body over and over again, and that the value of 300 * 2
cannot change over time.All the languages and other tools we have today are only aware of low level constructs, or code blocks. They don’t understand, for instance, connection between two functions in a program. What I think future holds for us are tools that understand very high level semantics. Tools that can detect if you have two conflicting features in your product.
Another example. If a Blogger blog uses a classic template, that blog should not have Layouts tab in the UI. Because Layouts tab is only for manipulating a Layouts template. Currently this idea is beyond the scope of tools, so we implement this manually: there’s a block of code that determines if the Layouts tab can be shown for a specific blog or not.
If a code change accidentally makes the Layout tab available to classic template blogs, no tool can find it today. The only way we can detect such an error is by having tests. Awesome as they are, tests are just band-aids. Some day there will be tools that would know that classic templates and Layout tab are in conflict. Those tools will flag an error if we link to the Layout tab of a classic template blog. (In other words, a few more levels of indirection is due.)
14 Oct 2011
You are that
From the way the movie is shot, and from my own way of thinking, I interpreted the quote to mean “what you’re praying for is probably not what you actually want”. Today, more than 5 years later, I happened to come across this quote again. I am seeing it now in a completely different way. St Teresa could have possibly meant that the more you yearn for something—the more you cry for it—the more it’s likely to happen. If you didn’t want something so badly, maybe you won’t get it.
What’s my takeaway from this? “When your eyes are blue the whole world looks blue.” I used to have a negative attitude towards everything, filled with negative thoughts. It was only natural that I saw the quote the way I did back then. But I am becoming progressively positive. Now I see the quote in a different, positive way.
Whoever said we create our own world is very right. Our world is as wide or narrow as we want it to be.
10 Oct 2011
Thinking about thinking
A few things I am wondering about:
- Thinking is not just talking to oneself. It can also be reading an imaginary book... or watching an imaginary movie.
- What are the other ways people think? (Please leave a comment if you have any insight into this.)
- How and when did I acquire these thinking methods? How did I think before I could read and write? As a kid I must have thought a lot more than I do now.
3 Oct 2011
Reasons
Orchestra of a million things,
Happening over an eternity.
30 Sept 2011
Teaching and learning
Since I liked teaching so much, I decided to teach at a local computer institute. I taught things like BASIC, C, MS Office, etc. It was all very interesting for a while. And then suddenly one day it all started to be boring. Unsurprisingly my students didn't seem to understand the lessons either.
Today, after about 11 years, I think I have an insight into it. When I had just started working, I had to learn what I was teaching. Everyday I'd learn something, and then explain the same to the students. Very soon there wasn't anything new I had to learn to do my job. My work was to simply repeat what I already knew.
Most of my teachers in college were hoplessly bad. I think it was because they faced the same issue that I did: they weren't really learning anything new. That gave the students a terrible learning experience, and probably made the teachers' jobs suck too. An educational institution should employ as teachers only those who are themselves learning. Because, like Steve Yegge said, the most important thing you learn in college is how to learn on your own, and you can't teach a kid to ride a bicycle at a seminar.
Asking right questions
If you take a bunch of good developers and put them in a team without a good leader, you will end up with something like Opera. But if you add a few good leaders to the same team, they will produce a Chrome. A leader isn't necessary to make a few people's lives better or to get loyal fans who'd keep praising your work. But you need leaders if you want to change the world.
Recently I have been catching myself ask irrelevant questions in meetings. The coder in me has to understand all implementation details as we talk. The impatient enthusiast in me has to immediately convey all cool ideas I can think of. I think I am just a coder who can create Opera. (FotoBlogr is one recent example. My friend who uses it likes it a lot, but I have no clue how to make it useful for others.)
But... we learn most things by seeing others do them. I now realise my questions are stupid mainly because I see others around me ask better questions. I'm in the right place; I just have to learn from them. This is my opportunity to learn the skill of asking good questions. And eventually figure out how to build an app that's useful for more than one person.
25 Sept 2011
Quotes: The Madman
- Those who understand us enslave something in us.
- Even a Thief in a jail is safe from another thief.
- And I love my Hell too well to have thee visit it. I would be in Hell alone.
- “The joy of scaring is a deep and lasting one, and I never tire of it.”
- And what comfort is there for controlled desire and unspent passion?
- But memory is an autumn leaf that murmurs a while in the wind and then is heard no more.
22 Sept 2011
Words
If a picture is worth 1000 words, a piece of literature -- like a poem -- is worth several hours of video.
Self-confidence
15 Sept 2011
I blog because
8 Sept 2011
Good weather, bad weather
First response my mind gave to that thought was something very common: if all days were like this, there won't be nothing "pleasant" about this weather. And then came another (not-so-new to me) revelation. I start to want this weather for everyday precisely when I am not thinking about the weather I am oh-so-happy about! I reckon the thought process goes like this:
- Nice weather. Happy about it for a few moments. (Ain't it weird to be happy or unhappy about something like weather?)
- Mind goes "I like this weather. Remember that bright sunny day that came in the middle of last week? I hated it. I'm glad the good weather is back now."
- "That bad weather last week... it's so bad I don't want it again. I know it's gonna be here in another month when summer starts. But I don't want it. I want it to remain like this forever."
4 Sept 2011
The courage to wander
That day wasn't notable for anything that happened then. That place wasn't notable for anything that happened there. Yet, it's been etched in my memory and I keep thinking about it every now and then for more than a year. And several other "ordinary" places too that I'd been to in some trip or other. This is what travelling gives you.
When I was planning my Pilgrimage 2010, I heard other people's travel stories and thought maybe I am not the travelling kind because I don't do anything other people seemed to do. I don't talk to the locals, unless they make an effort to talk to me. I don't try a lot of local food. I don't go to touristy places and take pictures. I don't do anything adventurous. But now, more than a year after my first ever long travel, I think travel is very personal and you do it in your own way. Like a firang rolling dosas into burritos and still enjoying it. There's nothing wrong or right.
I came to Australia wanting to travel. It's been months and I am doing everything but leaving home. Slowly I'm starting to get claustrophobic... I want to see the skies; I want to see the roads; I want to see the waters; I want winds all over me; I just want to get lost in this huge world. Maybe I should just leave on a Saturday morning and just go to some place with no planning whatsoever. The worst that can happen is, I might completely forget that trip in a few weeks. But who knows, I might as well find my next Manali road that stays with me forever. I just have to gather the courage to walk aimlessly on some random path. I hope I do.
3 Sept 2011
The cooking saga begins
I woke up late today, as it's usual for a Saturday, and made myself an instant coffee using the microwave. Was wasting time on the web till 11.30 when I actually felt like some food. With eggs and a microwave at my disposal, I decided to use the simple recipe I found on wikihow.
With almost nothing to add to eggs (apart from salt, which I remembered to buy yesterday) the eggs were a bit bland. Well, actually it was too salty, but it'd have been nicer and better-looking if I had had some onions and green chillies.
Cooking is sure some work, but it's a lot easier than going out only to eat. I guess I'll cook my breakfast over weekends going forward, mainly because it's simpler and I don't enjoy starving anyway :)
Now that the hunger god is pacified, I should go buy some essentials to make future cooking experience better :)
[*] I always have candies, ice creams, and some Indian snacks at home, but I don't eat them when I am hungry. They are to eat when I am bored :)
30 Aug 2011
Story of a failed software project
Another thing TM was particular about, apart from using Access, was that we shouldn't be using any modern reporting solution. All reporting tools used Windows' GDI to print the report on paper. "We must do the DOS-style printing so that printing is really really fast", he said, though he wasn't sure if that was even possible. I knew in theory how that could be done from a Win32 program, and this was a good opportunity to verify if my guess was correct. So I agreed happily.
I defined my own reporting language and wrote a simple reporting system in Visual Basic. The reporting system would generate plain text reports, which I'd just write to PRN file. Worked like a charm. (Later, this reporting language grew to include bold text, right-, center-, and left-aligned text, page breaks, cumulative totals, and all such funky features. Even today, thinking about that system makes me feel good about myself.)
When it was mostly done, I showed him the working program and the reports. He was happy with the way report was generated and printed. He asked me how I'd done that. I showed him the report definition .rpt files and the report generator code. He didn't bother to see the code. Only feedback he had was that having individual .rpt files was bad because you lose one file and your program stops working. I had a solution for that too. I baked in all .rpt files into the .exe as resources so the program effectively needed only one .exe file to run. Again, he only wanted to know if I had fixed the problem; he didn't care how I fixed it.
He took a few days to use the app and see how it worked. He called me and set up a meeting. He showed a few bugs he had found. Then he gave the big news: the customer wanted to be able to keep some records "hidden" so that they don't have to pay taxes for all the money they were making. But having anything in the UI that suggests that some records might be hidden was not acceptable. Plus, the entire app needed to understand hidden records. Search, reports, etc. should or should not include hidden records depending on which mode the system was in. Effectively, there'd be two reports: one for the customer and one for the government. Requirement itself was fair, but the timing was not. I had to change the entire app to understand "white" records and "black" records.
It took a while, but I changed the app throughout to make it work. After a few more days of testing, the customer test drove the app for a few hours. That uncovered a number of flaws in the system that invalidated some fundamental assumptions the app was built on. TM asked me to make changes again. Without those changes there was no way the customer could use it, so we had no way other than changing the app to fit the new requirements. It went on like this for a while, with random changes suggested to every part of the system.
With all these ad hoc changes, the code was becoming worse day by day and the number of bugs kept increasing. What we thought would be a 2 weeks project was not complete after 3 months. I love coding so much, so I don't usually fix my price before starting the work. I hadn't talked about money to TM either. One day I asked him how much he'd pay me. He agreed to pay some 20% of what I had in mind. (He even paid me a part of it then, I think.) I told him that the actual work had been several times more than what we initially thought and demanded more. His response was that he can't get a penny from the customer before the program goes live and he can only charge what he'd agreed to before starting the work.
I wasn't happy. I told him that I can't work anymore and I came off. I really don't think TM could have understood the code and fixed bugs. The project might have been abandoned soon after I had left. He probably didn't get any money from the customer either.
Thinking about it now, I think TM's fault was that he didn't know what PM-ing was, and did a sloppy job of it. My fault, as a coder, was to trust the PM too much. Even when I hesitated to do certain things -- like coding some mother of all hacks -- TM encouraged me to do it. I think it was because he didn't understand the risks involved. I never bothered to make him understand either. (There's a reason for that: most people like TM look at how polite I am and conclude that I don't know what I'm doing. Even when I say doing something may not be right, they'll "encourage" me like "oh not a problem, don't worry, go ahead". One other person I have worked with knew I was good and he always respected my judgement. Not coincidentally, all projects I worked with him made it to production.)
29 Aug 2011
What will I be remembered for?
That made me think – what would I be remembered for, if I were to die tomorrow? I can think of a few. The programs I wrote for a family friend's hospital. FotoBlogr. Maybe some post from one of my blogs, if a friend cared to look for it again. Maybe two or three sessions I gave in my college, if it inspired at least one person to question their way of learning. Maybe the Ladder magazine, if anyone still remembered it (even I don't think of it often). Maybe the inventory program I wrote for Loyal Mills, though I am not sure if it's still in use.
I love Dido's line "you who loved to love, and believed we can never give enough", and I once wanted a friend to associate me with that line. But now, I guess it'd be more appropriate if I was remembered for the code I write; for the few minutes my code saves for people. Because, I think I put more of myself in my code than the love I have for people.
28 Aug 2011
Dog Day Afternoon
Today I was thinking about it again. I tried to visualize how long 20 years in my life has been. If the sentence was to start when I had just entered Madurai Kamaraj University for my masters -- before I had completed the course, before I had moved to Bangalore, before I had moved to Hyderabad, and before I had moved out of Hyderabad -- the sentence would have been almost half over by now. If the sentence were to end now, it should have started when I was in my 4th standard. 20 years in prison pretty much means you rob the convicted of his life. Well, a huge part of it. If someone commits a "crime" when he's 30, we deny him his life until he's 50. And we expect him to lead a "normal life" after that.
Looking at these laws, I can't decide if we're cruel or dumb. Maybe both.
Yellow everywhere
One advice from the book is to train your eyes to see things on streets. Thomas advises you to pick one colour -- any colour -- and try to see that colour throughout a day. I tried that today. I randomly chose red. Suddenly it was red everywhere all around me! I could see so much red that I thought I should pick a different colour. So I told myself that I would see yellow. Now I started seeing yellow everywhere, as much as there was red. It's amazing how I don't see any of these colours when I don't want to see.
This exercise gave me a new experience, but my mind said this was just another variant of two different ideas I already have. I could rationalise and see this experience as a proof to those ideas. But I suspect that it's just my mind playing games with me and making me see only what I already know. Maybe knowledge is, like everything else, both an asset and a liability.
26 Aug 2011
Remote debugging client side code
When I learned Java, I tried to use jdb for some debugging but couldn't get my head around debugging from the "command line". I never managed to learn that. 8+ years later, even today, I cannot connect the context from a jdb- or gdb-style debugger with code in an editor.
But I learned another way of debugging: System.err.println
. Just add a few print statements in the places you think are interesting and rerun your code. (Some people are surprised when I say I find using print statements faster than using an interactive debugger.) One thing I like about print statements is that it's so universal: I never have to learn how to use a new debugger. It works the same way in all kinds of enviroments including Python, C++, and JavaScript.
The latest toy I've built, FotoBloger, has a mysterious bug that kicks in only when a friend of mine uses the app. I have been trying to reproduce the bug from my account for a few weeks, but with no success. Yesterday, I decided I had no way but to do some "remote debugging" when my friend is using the app. My universal "print what's interesting" approach works really well in this bizarre remote debugging scenario as well :)
I added a /debug
URI to the app which won't do anything apart from sending a 204 (no content) response back. Next time the app is being used, it will make a bunch of /debug requests with the data I want to inspect in its query string. The server logs all incoming requests, so I can look at the logs to see what those values were and maybe I can discover the bug. (Can your interactive debugger do this? ;-)
22 Aug 2011
The importance of URLs
Try this: go to icanread.tumblr.com and click on "next" link at the bottom. You'll be taken to http://icanread.tumblr.com/page/2
. Go to blog.fatema.in and click on "previous entries" at the bottom. You'll be taken to http://blog.fatema.in/page/2
. Go to thewayialwayswas.blogspot.com and click on "older posts" at the bottom. You'll be taken to http://thewayialwayswas.blogspot.com/search?updated-max=2011-08-12T09%3A00%3A00%2B08%3A00&max-results=3
.
Now, the designer kind might think that Blogger URLs are ugly while WordPress and Tumblr URLs are neat. But there's more than what meets our eyes.
Let's say you find the content in one of these links interesting, and you share it with some of your friends. Naturally you'd just grab the URL from the address bar and share it. If your friend happens to open your link only a few weeks later, they might be seeing content that is completely different from what you intended to share.
Why? Because both Tumblr and WordPress "page" URLs are not unique identifiers to content. The same /page/2
URL will be showing different content based on how many new posts are added after you copied the URL. Blogger's URL, on the other hand, fixes on published date, so the content is much more likely to stay the same over time.
PS: It might be possible to configure WordPress to generate good URLs like Blogger; I don't know for sure.
16 Aug 2011
Guru appears when the disciple is ready
- We learn what we want to learn.
- We like to take our learnings from someone else. We want at least one person (or entity) to preapprove our learning.
7 Aug 2011
AJAX fie upload
enctype='multipart/form-data'
attribute on your form. Form submissions require a page refresh. If your app is AJAX-heavy you probably wouldn't want to refresh the page just for uploading files.Here's what you need to do to submit a form with file inputs without refreshing the page:
- Add an invisible iframe to your page. Give the iframe a name. For example, your iframe might look like:
<iframe name='submit-iframe' style='display: none;'></iframe>
. - Set the target of your form so that the form submission goes to the hidden iframe:
<form method='POST' action='/upload' enctype='multipart/form-data' target='submit-iframe'>
. - Add an onload event handler for your iframe. This event handler will be called every time the form is submitted. You can then read the response from the iframe's body. A JQuery app might do it like:
$(myIFrame).load(function() { var responseText = this.contentDocument.body.innerText; // Do something with response text. });
$(myIFrame).load(function() { var responseText = this.contentDocument.body.innerText; if (!responseText) { return; } // Clear the content of the iframe. this.contentDocument.location.href = '/img/logo.png'; // Do something with response text. });
FotoBlogr
- use Blogger for your blog,
- use Flickr for your photos, and
- want better integration between Blogger and Flickr?
Try FotoBlogr. It's still a work in progress. It has been functional only since this morning! Try it out and let me know how it goes.
You can comment here, or you can comment on my Google+ post if Google+ is your thing.
UPDATE: This is how the main UI of the app looks:
See the picture in Flickr; I have added some annotations to mark different parts of the UI.
29 Jul 2011
Walking on water
But what I did like was that I was walking on water. Not literally, of course. There was a really long platform floating on water for us to walk on. There's a subtle difference in the way once balances oneself walking on a float like that compared to walking on the ground. The difference is mild, but it's kinda fun. The few minutes I was on water renewed my desire to go on a cruise -- basically to be on water for a few days. Hope I get to do that sometime this year!
23 Jul 2011
Mysskin and me
I saw his third movie Nandhalala this morning. The movie had almost no songs. He had apparently asked Ilaiyaraja to compose 5 or 6 songs and later decided not to use most of them in the movie because he thought songs were not appropriate in his story. So, it looks like he did manage to try his approach to movie making. Personally, I hated the movie because it was full of extremely unlikely incidents and characters.
Then I saw Yudhdham Sey, his fourth movie. This movie was kinda liked by some of my friends. "It's mostly like Anjaadhey (his second movie). It's not a great movie, but don't miss it" was the advice I got. While the movie was tolerable, it had its own share of stupid characters and very unlikely incidents. I hear the movie managed to make some money for the producers, but I wonder if Mysskin himself is happy with the way the movie has turned out to be.
Being the egotist I am, I could see myself in Mysskin. He looked at other people's work and said they were all doing it wrong. He rose to make a few movies in the "right way" to show to the world what movie making is, but ended up making movies that are arguably worse.
Same with me. Every time I look at legacy code I scream. Everything is in one humongous class? I scream that one component does too many things. There are quite a few classes? I scream that the code is overengineered. And I know the code I write myself is not any better either. I am trying to make it better, but I know it's not there yet.
I guess the real lesson for me is this: it's easy to mock legacy. It's easy to call all our predecesors stupid. Wise it is to understand that the world is not, and probably never will be, ideal, and do what best we can do. Life is too short for negative thoughts and feelings.
18 Jul 2011
Feeling sad for no reason
Only a few weeks ago I found out that I don't know the reason for my worries because there's no real reason. Because I was never worried. I was only feeling tired and/or sleepy. Just letting myself relax and rest would bring my happiness back. Mind is a wretched thing that rejoices in its own tears!
15 Jul 2011
Mistakes
Having grown up with people like that, I took the liberty to correct people when I thought they were wrong. Not many people took it well, especially when they were not close friends with me. I learned from my experiences and now I don't always say it when I find something wrong. I mostly assume that they don't care if they are right or wrong; they just want to say what they think/feel.
But I really wish everyone were like my brother. I also wish everyone told me when they thought I was wrong.
Conditionals and code complexity
- The user might misspell the city name. The function will use a spell checker to correct any spelling errors we may find.
- Even with spell correction, we may not find the city. We will throw an exception if we can't find any city.
- There can be multiple cities with the same name. For example there is a Hyderabad in India, and one in Pakistan. In such cases, we will arbitrarily pick one. If we get the wrong city, user has to refine the query.
- We may not be able to get weather data. If the weather service we are relying on fails, we return
null
. (You would probably throw an exception here as well, but this is just a fabricated example.) - You don't always want real weather data. Most of the time, you are working on different parts of the app; you don't care if the weather you get is accurate or not. You want to use fake weather data if you are running the app for development/testing.
Weather getWeatherFor(String cityName, boolean mayCorrect) throws CityNotFoundException {
if (AppConfig.useFakeWeather()) {
return AppConfig.getFakeWeather();
} else {
try {
List<Location> locations = locationService.findCity(cityName);
if (locations.size() > 0) {
Location locn = locations.get(0);
return weatherService.getCurrentWeather(locn);
} else {
if (mayCorrect) {
for (String name : spellCheckService.getCorrectionsFor(cityName)) {
Weather weather = getWeatherFor(name, false);
if (weather != null) {
return weather;
}
}
throw new CityNotFoundException(cityName);
} else {
throw new CityNotFoundException(cityName);
}
}
} catch (WeatherException e) {
return null;
}
}
}
Sure, you can read this code and understand what's going on. But how easy is it to find a bug in this? And how easy it would be to fix that bug?The problem with this code is that it uses way too much branching. An if-else is essentially one statement. What I mean by that is, when you change something in the middle of an if-else, you should keep the entire if-else in mind. The condition
(weather != null)
, for example, is 3 levels down a decision tree. Before you can touch that part of this function, you should have worked out all 3 paths of the decision tree in your mind; otherwise your change might introduce a bug.Now, the same code written in a way I like:
In this version, the decision tree is only one level deep at any given point. (Weather getWeatherFor(String cityName, boolean mayCorrect) throws CityNotFoundException { if (appConfig.useFakeWeather()) { return appConfig.getFakeWeather(); } List<String> candidates = new ArrayList<String>(); if (mayCorrect) { candidates = spellCheckService.getCorrectionsFor(cityName); } // Actual input must be the first search we do; insert it // as the first item in the list. candidates.add(0, cityName); Location locn = findCity(candidates); try { return weatherService.getCurrentWeather(locn); } catch (WeatherException e) { return null; } } Location findCity(List<String> nameCandidates)
throws CityNotFoundException
{ for (String candidate : nameCandidates) { List<Location> locations = locationService.findCity(cityName); if (locations.size() > 0) { return locations.get(0); } } return new CityNotFoundException(nameCandidates.get(0)); }
for
and try
are not necessarily "conditionals", but even if you include them, nesting is only two levels deep. Which of these two versions would you change confidently?If you have been writing code for a while, you will know that what starts like the second version would eventually end up like the first version over time: by changes that happen one line at a time. As you make code changes, check how deep your decision trees get; if it's anything more than two, it's time to restructure the code to simplify it.
12 Jul 2011
Parking cars
Because I don't think much about the fundamentals anymore, now my brain can focus on other things. Now I am learning to park. Parking straight, I found in the first few days (of this Mountain View trip) that I can do much easier than before. Now I am learning to park in reverse.
Well, I am not the kind that would try those things just like that. I am too scared to experiment with cars or bikes :) One day I missed the only parking space available and went past it. Instead of going back all the way and returning to the same place again to park, I tried to park in reverse. I was surprised how easy it was, and I called my brother Saravanan to ask if I was doing something wrong. Apparently parking in revers is easy. He gave me a tip as well: instead of using the rear-view mirrors or looking through the windows, looking through the rear wind shield gives you a better idea of where the car is going.
So I tried that today. First time I parked the car fairly decently; second time was terrible. But the point is I am now consciously experimenting. That's a progress. I'm happy :)
10 Jul 2011
8 Jul 2011
T-Mobile and me
Annoyed, but left with no other option, I buy a new SIM with $10 credit for voice calls. When I put the SIM on the phone, it won't connect to the Internet. The storekeeper had said that I can get a "day pass" data connectivity by paying around a dollar and a half. I have already paid $10, so they should deduct from that credit for the day pass, right? Turns out they won't do that either. I have to buy it separately.
So I open T-Mobile's web site, and there's no link or option that would let me buy that damned day pass. I would have to go to the shop again tomorrow to buy it.
I'm glad I don't live in the US.
23 Jun 2011
Woody Allen
Manhattan was made in 1979. VCB in 2008. 29 years is a long time. When the core of the movies of resemble each other, it only leads me to believe that Woody Allen hasn't found a convincing answer for his questions in these 29 years. This kind of repetition is probably unavoidable when you are an honest artist struggling with an impossible puzzle.
(I realise there's another possible explanation. VCB does have some solution for the puzzle, only I fail to see it.)
19 Jun 2011
Go: first impressions
Things I like
- Static typing done really well. Lightweight interfaces (see Rotting Cats section of Go tutorial), type inference, closures, etc. make the language fun like a dynamic language.
- Clean standard library. The interfaces are well thought out, and names are picked well. Effective Go, the document that describes the design/style ideas used by the Go project says "long names don't automatically make things more readable" and I can't agree more.
- Google App Engine support for Go. This is the deciding factor for writing my current app in Go.
- Object oriented programming without fetters. There are no classes. There is no type hierarchy. You can define methods for any type, even those defined by a third party library you don't have source code for.
There are certain things that are not entirely new to me, but I have almost forgotten because I have been coding mostly in Python and Java.
- Values are different from pointers. I can define a method on a type like this:
func (o MyObject) Increment() { o.count++ }
o
's type is not*MyObject
. So when I callmyo.Increment()
,myo
is passed by value, i.e., a copy ofmyo
is passed toIncrement
, not a reference. - Crashes and core dumps. Because the code compiles to native code, you can easily crash your program by dereferencing a null pointer or accessing a nonexistent index in an array.
- Errors are returned, not thrown. In most modern languages your code is mostly free of error-handling because either you want to propagate it to the caller or you can handle them all in one place (with a try-catch). Go doesn't have exceptions. So you have to check for errors after calling every function that may return an error. If you forget to do that, too bad, the error is silently ignored.
16 Jun 2011
What I miss in Sydney
- Lunch time, random coffee breaks, random dine outs, etc. with Ajay. Now, if I am bored I cannot walk over to his desk for a random chat or go with him to get something chocolaty to eat. The fact that he and I share similar taste in several things make our conversations lively. I miss all those conversations and occasional silent lunches with him.
- Tea breaks and occasional lunch with Jhinuk. We have different philosophies, our views of life are very different. Yet, we get along very well. She's one of the few people I respect a lot.
- After he moved to Bangalore, I don't get to meet Bharat often. But when we do meet, it's always a pleasant experience. He is the only one who understands my unclear frenzied ramblings. He is the one I ask when I have any science question. He is the one I have gone for aimless walks with. Only when I think about him now I realise how rich our years together have been.
- Rice and dal. And parathas. And coconut chutney.
- The freedom of having my own transportation. I realise that I am not the kind that can use public transport for travelling. Should buy a bike soon... maybe next year.
Deteriorating relationships
What I was thinking so far: I get to know a lot of people. With some of them I become kinda like a friend. Most such "friendships" deteriorate over time; I don't remain friends with most people for a long time. For some unknown reason the relationship doesn't work out.
What I think I have found today: When communicating with a person becomes hard, I stop talking to them. Suddenly one day I decide I won't discuss serious issues with them. That's pretty much the end of that relationship.
Takeaway: Keep talking to your spouse. Even if you think/know that you would only annoy them.
11 Jun 2011
Life - 4
(Originally tweeted a few months ago.)
Writing
I'm learning UX
I wrote a simple program that lets my friend Nags post pictures to her photo blog. Yesterday I made two tiny little changes to the UI. She probably noticed one of them, but I doubt if she would care enough. (Now that I have talked about it, she might go looking for it and she'll find it.) When I make such changes I deliberately don't tell her about it: she doesn't have to know. People notice it immediately when the experience gets slightly worse, but when it gets better, even if they notice, they soon forget about it.
I wrote the first version of this program about 5 months ago. She has posted probably around 130 pictures to her blog using the program. If the program saved her 2 minutes for each post, it's a saving of 2 hours over 5 months. That number doesn't look great[**], but not everything is quantifiable. I don't know about her, but I get demotivated easily with repeated manual work. If I had a similar blog, I would have soon stopped posting without a helper tool. I'm sure my program makes her photo blogging experience a bit more pleasant, and that's a lot more valuable.
PS: I started writing this post with the intention of writing about what I have learned about UX, but apparently I have failed in that. Maybe it would take some time before I can think clearly about them.
* Unless it annoys them. I had an iPod for a long time. If I want music, I'd press the play button; I didn't have to think about what all it did internally. We had a Creative player that would eat up all its battery in 3 hours because it would keep the screen on when it's playing. My brother found a workaround to turn the screen off, and thus improve battery life. The Creative player forced him to think/care about how it functions.
** I spent maybe around 20 hours on getting the program to the state it is now. Spending 20 hours to save 2 hours is not the wisest thing to do, obviously.
7 Jun 2011
Life - 3
6 Jun 2011
Match point
- The man who said "I'd rather be lucky than good" saw deeply into life.
- Some people just don't have any luck.
- You never know who your neighbours are till there's a crisis.
- You can learn to push the guilt under the rug and go on. You have to. Otherwise it overwhelms you.
- "The innocent are sometimes slain to make way for a grander scheme. You were collateral damage."
"So was your own child."
"Sophocles said, 'To never have been born may be the greatest boon of all'."
5 Jun 2011
Saving for tomorrow
Saving up for tomorrow is probably the worst thing you can do with your time. Just sleeping off is far better than that.
4 Jun 2011
Results of two unscientific observations
- I was kicked to find out that the Atom chip my puny laptop has is a 64-bit processor. I wiped out the 32-bit Ubuntu I was running and installed 64-bit version of it. I don't know the internals of Linux, but it looked like the 64-bit kernel was swapping too much. My machine has 2GB RAM. Even when half of the physical RAM is free, the machine would be using around 0.5 to 1 GB of swap space. It was unusably slow, I reverted to 32-bit Kubuntu. It doesn't swap stupidly any more. (On the other hand, 64-bit kernel runs fine on my machines that have 8 or 12GB RAM. Maybe 64-bit works well on machines that have a lot of RAM.)
- I was cribbing about bad wireless performance of my Galaxy Tab, and someone suggested that I use the n channel of 802.11 on my home wireless router. I made the switch and the experience just got worse. Maybe it was the router's 802.11n implementation that sucked. After reverting to 802.11g, it's better now.
How I became so conceited
I just remembered something that happened 5 years ago. Someone was asking for some technical help on a mailing list of the Madurai Kamaraj University alumnus. Someone gave a blatantly wrong answer (that's what I thought back then) and I responded with a message that started with a "WTF". A senior of mine posted this response:
It does not behave well for any member of the group to use such unparliamentary terms in the mails sent to the group.I didn't like that at all and I stopped being active on the list. I was simply reading mails and when I wanted to help people, I mailed them privately. (I have always hated the "I am elder, respect me" attitude of many of my seniors. It badly hurt my ego to think that they scrutinise and criticise the mails I wrote.)
This is not a motley group of friends chit chatting amongst themselves through mails.It has members who are quite senior, having more than 10 years of experience in the Industry. So let the decorum of such an August group be preserved.
Fast forward a few years. The mailing list had become a place exclusively for "job openings" spam. It's not like people who are looking for a job have nowhere to find openings. It's not like recruiting is done only a few times a year. All companies are recruiting all the time, so I didn't find those "Company X is hiring" mails useful. I sent a mail to the list proposing that either people don't send such mails or they send them to a different mailing list. It wasn't very well received. A few weeks went and I unsubscribed from the mailing list. I am completely disconnected from the MKU community now.
All of these happened after I had joined Google. Madurai Kamaraj University is not one of those elite institutions where Google visits for campus recruitment, so one of the questions I frequently get asked by my juniors is "how can I get a job at Google?" In that regard, I am more privileged than most others from MKU. I am like those "rich people" SRK describes... I stay away from the rest of the crowd because I work at Google.
But the reality, at least my version of it, is different. People who have worked with me or studied with me would know this: even in schools and colleges I was like this. Two similar-looking girls were my classmates in MCA; it took me two or three semesters to get their names right. A big percentage of my class has never spoken to me (apart from maybe a hi when we happen to see on the hallway). It's very easy now to paint me "conceited Google employee" and add me to a "rich, so won't laugh at our jokes" bucket. But the reality is people are just different. Infinitely more different than we can define categories to put them in.
2 Jun 2011
Why is it so hot in humid weather?
Why do we sweat?
Normal human body temperature is 98.6 °F. When the external temperature drops or increases, it changes our body temperature too (obviously), but our body works to bring it back to the normal temperature. When it's cold, our body shivers to generate heat; when it's hot, our body sweats to cool itself down.
How exactly does sweating help?
You need to know the physics of evaporation to understand that. Take a very hot metal plate and pour water on it. You'd see water boiling, and soon all of the poured water would disappear. If you measure the temperature of the plate now, you can see that it's become colder than before pouring water. What's really happened is, water took the heat energy from the plate and used it to become water vapour (which then mixed with air in the atmosphere).
Sweating is pretty much the same. Our body becomes hot because of the weather. As a response to it, we secrete sweat all over our body. Sweat then uses the heat from our body to evaporate. Since some body heat is expended on sweat evaporation, our body cools down. (In a way, we return the unwanted heat back to the environment.)
Humid weather
What happens in hot-humid weather? Because it's hot, our body secretes sweat to cool itself down. Now we get all sweaty, but nothing happens after that. Why? When a liquid becomes gaseous vapour, it needs someplace to go to: usually it mixes with the air in the atmosphere. But there's only so much air around us and only so much water vapour can mix with it. In dry weather, the air can take in a lot of water vapour because it doesn't have much in it already... it's dry. But in humid weather air is pretty much "full" so the vapour intake will be much less. The sweat stays on our body until we wipe it off. And our bodies remain hot.
In dry weather we probably sweat the same amount, but we don't notice it because the sweat evaporates pretty much immediately. Our bodies don't get too hot either.
Add +1 buttons to your blog manually
- Configure your +1 button and get the code from Google.
- Remove
href
attribute of<g:plusone>
starting tag; insertexpr:href='data:post.canonicalUrl'
in its place. For example, the code on my blog is:<g:plusone expr:href="data:post.canonicalUrl" size="medium"/>
- Insert the code in your blog’s template.
- Open Blogger > your blog > Design > Edit HTML.
- Check “Expand Widget Templates”.
- Look for
<div class="post-footer">
if you want to place the +1 button at the bottom of each post; look for<div class="post-header">
if you want it at the top of each post. - Paste the +1 button’s code. View your blog to see if the button appears at the right place, and adjust the placing accordingly.
31 May 2011
That Medak ride
We decided one of us would chase and and stop them. I took the bullet and was pushing it like I never usually do... going at around 85 or 90 when a bus and a truck are very close by. This was after the bullet's breakdown incident, so I knew riding it fast wasn't the safest thing to do, especially with a pillion rider with me. At one point I stopped the bike and asked Jhinuk (who was on the pillion with me) to send them a text message asking them to return. She sent a message and then called them too, so that they notice the vibration of the call.
In a few minutes we got a call from Aditya saying they were turning back. Even now, when I think about it, I am happy that I didn't do anything stupid like pushing the bike to 100+ kmph. Speed kills. Especially on a lousy bike like the bullet.
29 May 2011
A thousand splendid suns
Then the story of her marriage. The kid who gave such a bold speech goes on to the street and guess what? She's scared of everyone on the street. Like, really? What for? First day she gets scared and runs back in. That's okay, maybe that's normal. But after that she never goes out. All the women who were curious to talk to her make no further attempts to befriend her and she simply remains friendless. Even as a kid she had about half a dozen friends in her tiny village, but as a housewife who spends all day alone at home she gets no new friends.
And the marriage. It keeps getting worse over time. The author does capture the way the relationship deteriorates, but making it look like there were no good moments whatsoever is just not natural. I mean, how can a guy be always angry with his wife? Won't he act like a good guy now and then, at least to sleep with her?! Would he always come home in a bad mood after work?
I was irritated by all these oddities and decided to stop reading. Long time ago, I decided that I won't decide on watching or skipping a Tamil movie based on other people's review. Now, I think I shouldn't buy a book based on Amazon readers' reviews.
Here are some quotes from the book up to the point I read:
- She did not know what this word harami--bastard--meant. Nor was she old enough to appreciate the injustice, to see that it is the creators of the harami who are culpable, not the harami, whose only sin is being born.
- Like a compass needle that points to north, a man's accusing finger always finds a woman. Always.
- Mullah Faizullah admitted to Mariam that, at times, he did not understand the meaning of the Koran's words. But he said he liked the enchanting sounds the Arabic words made as they rolled off his tongue. He said they comforted him, eased his heart. "They'll comfort you too, Mariam jo," he said. "You can summon them in your time of need, and they won't fail you. God's words will never betray you, my girl."
- God, in His wisdom, has given us each weaknesses.
- A man's heart is a wretched, wretched thing, Mariam. It isn't like a mother's womb. It won't bleed, it won't stretch to make room for you.
- Could she fault him for being the way God had created him?
- She laid down her prayer rug and did namaz. When she was done, she cupped her hands before her face and asked God not to let all this fortune slip away from her.