Final Year Undergraduate Student
Department of Computer Science & Engineering
”Nuggets from my .emacs” is a series wherein I will occasionally put up small but nevertheless quite useful functions in Emacs Lisp that help enhance daily productivity. This post here is Part I.
You can also get my entire Emacs config on Github.
NOTE: “Windows” in Emacs are different from “windows” in the conventional
sense used today. When you split a screen into 2 “panes” using C-x 3, the 2
panes are called “windows”. Conventional windows, created using C-x 5 2, are
called “frames” in the Emacs world.
I never really got the hang of C-x { (shrink-window-horizontally), C-x }
(enlarge-window-horizontally), and C-x ^ (enlarge-window) for resizing
windows. When I split my screen vertically and I want to change the window
sizes, I’m usually thinking of how I should move the border between the 2
windows, rather than whether I want to enlarge or shrink the current window.
Fortunately I found the following nugget on the Internet (credits to the
original author; I have long since lost the source link):
;; intuitive window resizing
(defun xor (b1 b2)
(or (and b1 b2)
(and (not b1) (not b2))))
(defun move-border-left-or-right (arg dir)
"General function covering move-border-left and move-border-right. If DIR is
t, then move left, otherwise move right."
(interactive)
(if (null arg) (setq arg 3))
(let ((left-edge (nth 0 (window-edges))))
(if (xor (= left-edge 0) dir)
(shrink-window arg t)
(enlarge-window arg t))))
(defun move-border-up-or-down (arg dir)
"General function covering move-border-up and move-border-down. If DIR is
t, then move up, otherwise move down."
(interactive)
(if (null arg) (setq arg 3))
(let ((top-edge (nth 1 (window-edges))))
(if (xor (= top-edge 0) dir)
(shrink-window arg nil)
(enlarge-window arg nil))))
(defun move-border-left (arg)
(interactive "P")
(move-border-left-or-right arg t))
(defun move-border-right (arg)
(interactive "P")
(move-border-left-or-right arg nil))
(defun move-border-up (arg)
(interactive "P")
(move-border-up-or-down arg t))
(defun move-border-down (arg)
(interactive "P")
(move-border-up-or-down arg nil))
I have the following keybindings corresponding to these functions:
;; keybindings for window resizing
(global-set-key (kbd "M-S-<left>") 'move-border-left)
(global-set-key (kbd "M-S-<right>") 'move-border-right)
(global-set-key (kbd "M-S-<up>") 'move-border-up)
(global-set-key (kbd "M-S-<down>") 'move-border-down)
I find this pretty handy when I’m writing CSS or customizing my Emacs theme, notwithstanding the fact that I’m colourblind.
;; CSS color values colored by themselves
;; http://news.ycombinator.com/item?id=873541
(defvar hexcolor-keywords
'(("#[abcdef[:digit:]]+"
(0 (put-text-property
(match-beginning 0)
(match-end 0)
'face (list :background
(match-string-no-properties 0)))))))
(defun hexcolor-add-to-font-lock ()
(font-lock-add-keywords nil hexcolor-keywords))
Then all you need to do is add some major mode hooks:
(add-hook 'css-mode-hook 'hexcolor-add-to-font-lock)
(add-hook 'emacs-lisp-mode-hook 'hexcolor-add-to-font-lock)
(add-hook 'less-css-mode-hook 'hexcolor-add-to-font-lock)
and see your hex colors light up right there in front of you :)
This a no-nonsense function that does exactly what it says on the tin:
(defun comment-or-uncomment-region-or-line ()
"Like comment-or-uncomment-region, but if there's no mark \(that means no
region\) apply comment-or-uncomment to the current line"
(interactive)
(if (not mark-active)
(comment-or-uncomment-region
(line-beginning-position) (line-end-position))
(if (< (point) (mark))
(comment-or-uncomment-region (point) (mark))
(comment-or-uncomment-region (mark) (point)))))
Immensely useful; I have it bound to C-c C-r.
This one takes the boring old Home key and puts it on steroids. The new and improved Home key toggles between the first non-whitespace character on the current line, and the very first column on the line.
;; "smart" home, i.e., home toggles b/w 1st non-blank character and 1st column
(defun smart-beginning-of-line ()
"Move point to first non-whitespace character or beginning-of-line."
(interactive "^") ; Use (interactive "^") in Emacs 23 to make shift-select work
(let ((oldpos (point)))
(back-to-indentation)
(and (= oldpos (point))
(beginning-of-line))))
I use it all the time, so I’ve replaced the default Home and C-a keys with
this:
(global-set-key [home] 'smart-beginning-of-line)
(global-set-key (kbd "C-a") 'smart-beginning-of-line)
That’s all for Part I.
NOTE: I mostly use single application instances with tabbed UIs or similar (Firefox, Emacs + escreen.el, Terminator, Zathura PDF viewer + Tabbed, SpaceFM), so this method works flawlessly for me. If you like having separate windows inside every program and hate tabbed interfaces, this won’t work so well. But you can still use it for things like your browser, which only runs a single instance.
The thing that’s always ticked me off about the standard desktop metaphor is the
inefficiency of Alt-tab (at any point of time, you cannot be sure of
where a particular application is, in the most-recently-used order). For so
fundamental an operation as switching applications, which users perform many
hundreds of times a day, making them tediously scan a (constantly-changing) list
sorted by recently-used order seems like an awful idea to me, in many cases.
Sure, toggling between two windows is dead simple, but when you have to switch
to some other task, you’re left with no choice but to go window-hunting.
And I’m not the only one who feels Alt-tab sucks.
The problem is especially chronic, for example, when I’m working on some web
development stuff. I have 3 or more applications open (editor, browser, command
line: at the very least, often with another browser for looking up
documentation), and I have to switch among them very often. In such a situation,
Alt-tab is plain frustrating.
Turns out there is a 100x better solution, called run-or-raise. But
first…
I always end up forgetting that I do in fact have the desired application running, only it’s not on the current workspace.
I have to make sure applications are always running on their designated workspaces, otherwise the strategy breaks down.
Consider what happens when I have more than one application on a workspace. I’ve to switch to the correct workspace, and then switch to the target application if it’s not already on top.
run-or-raise does better than workspaces on all counts.
The idea is to have each frequently-used application one key combination away at all times, irrespective of which workspace it is on, or how recently it has been used, or even whether it’s running or not. That way you can get down to actually using it in a jiffy.
run-or-raise is borrowed from my very brief experience with
Awesome Window Manager (it used to be a Lua customization
there, but recently an implementation has been added to Awesome’s master
branch by Anurag Priyam). Its concept is very intuitive. Calling
run-or-raise on an application does the following:
“run”: if the application is not running, launch it, and focus on it, or
“raise”: if the application is already running, just switch to its workspace and raise it.
It may not sound like much, but it’s been hugely productive for me. There’s a
strange satisfaction in knowing that Super+E will always take me straight to
my Emacs :)
Now with all that out of the way, let’s look at how to get a crude but effective
implementation working in pretty much any window manager (the only requirement
is that the WM must be compatible with the EWMH specification). Turns
out a one-liner shell script will suffice (make sure you have wmctrl
installed, it should be in your distro’s default repositories):
#!/bin/bash
wmctrl -x -a "$1" || $2
For reference, here are some extracts from wmctrl --help:
-a <WIN> Activate the window <WIN> by switching to its desktop
and raising it.
-x Include WM_CLASS in the window list or
interpret <WIN> as the WM_CLASS name.
How does this work? The part before the || checks if a running application’s
class name (or any case-insensitive substring of it) matches the string
given by $1; if yes, it raises that application. If not, it simply runs the
command given by $2, so we’ll pass in a command that runs our application.
Pretty straightforward.
However, if you have multiple windows for an application open, then this will only be able to switch to one of the windows; there is no way to cycle between them, like the Awesome WM implementation.
Now, in most cases, the first and second arguments ($1 and $2) will be the
same. In the rare case when it does not work, you need to find out what class
name to pass as $1. Run your application and check the output of wmctrl -l
-x. The third column should give you the application class (it’s always of the
form *.*). Here’s wmctrl --help on the -l switch:
-l List windows managed by the window manager.
Let’s see how to use it. Save the script as /usr/local/bin/run-or-raise, then
make it executable:
$ sudo chmod a+x /usr/local/bin/run-or-raise
Finally, bind keyboard shortcuts to specific invocations of run-or-raise for
your favourite applications. Sample invocations:
$ run-or-raise firefox firefox
$ run-or-raise emacs "emacsclient -a '' -c"
Note how, in the first invocation, even though the WM_CLASS for Firefox is “Navigator.Firefox”, we can pass a case-insensitive substring of it.
On my setup I have the following keys set to run or raise specific applications:
Super+F => FirefoxSuper+C => ChromiumSuper+E => EmacsSuper+T => TerminatorSuper+G => PDF viewerSuper+S => File ManagerThere’s another, easily scalable alternative to Alt-tab:
incremental filtering on a window list. No matter how
many windows you have open, it should work reasonably well. It essentially
changes the behaviour of Alt-tab from sequential access through a
most-recently-used stack to random access in a list of applications. Hence the
easy scalability. I know of only 2 pieces of software that do this: the
“Scale Window Title Filter” plugin in Compiz, and
“Switcher” for Windows, of which I have used the former.
This is similar to the searchable user interface concept from an earlier post. But it’s still not in wide use. Guess I’ll just have to wait for the future to arrive.
Thoughts, comments, questions?
The function pointer in C is, in my opinion, one of the most ignored gems of the language. It’s the kind of feature you rarely need, and then suddenly, one day, you find yourself in dire need of it, as evidenced by the use-case below.
If you don’t know what a function pointer is in the first place, here’s the meat of it: it gives you the ability to pass a function around like a normal variable. If you know Python / Ruby / Lisp, you might know it by the name ‘lambda’, or if you come from a JavaScript background, you might’ve used it under the name ‘anonymous function’. (UPDATE: a lot of people have pointed out that function pointers are not the same as closures, and they are correct. But the point here is to establish some semblance of familiarity for those who are new to function pointers in C).
Say we’re writing a library for linked list manipulation, as part of another application. Being the kind of programmers who see beauty in reusable code, we want the library to be completely generic and independent from the other modules in our application, so we can re-use it in other projects. To that end, first we define some basic structures for the list and its nodes:
struct list_entry_t {
void * data;
struct list_entry_t * next;
};
struct list_t {
struct list_entry_t * head;
unsigned int length;
};
Now let’s assume that, in our application, the data field in our linked list entries is meant to store a pointer to a structure of the following type:
struct mem_block {
void * addr;
unsigned int size;
};
Now if we want to search for a specific struct mem_block in our list, given the value of it’s addr field, how would we do it? (I encountered this exact same use-case when I had to write a memory manager for my last Operating Systems assignment).
We ideally shouldn’t make a public function in our generic linked list library (that’s meant to store any type of data), hard-wired just for this specific case (searching by the addr field of the struct mem_block), since that would make our library, well, not generic. Argh, the reusability-seeker within itches for a better solution! If you’ve so much as read the title of this post, you already know the answer: function pointers!
Now let’s see how function pointers can help us here. First, we declare a public function in our linked list library with the following prototype:
/* get the data of the first element of list @l which passes the
* comparison test implemented by the function @compar.
*
* @param l the linked list to search
* @param compar the comparison function. The two parameters passed to
* it are the element data, and @key, respectively. Must
* return 1 for a success, else 0.
* @param key the search key passed as the second parameter to
* @compar */
void * list_get_by_condition(struct list_t * l,
int (* compar) (void *, void *),
void * key);
void * list_get_by_condition(struct list_t * l, int (* compar) (void *, void *), void * key) {
struct list_entry_t * entry;
for (entry = l->head; entry; entry = entry->next) {
if (compar(entry->data, key)) {
return entry->data;
}
}
return NULL;
}
And our comparison function, in the application program:
/* comparison function to compare a block and an address; intended to be passed
* to list_get_by_condition() */
int compar_addr(void * block, void * addr) {
return (((struct mem_block *) block)->addr == addr);
}
Now let’s see how this helps us. We call list_get_by_condition() with our linked list, it traverses the list, and for each list entry, it passes the data (the struct mem_block) and the search key key to our comparison function compar_addr(). The comparison function in turn checks if its parameters satisfy our search criterion, and returns 1 or 0 to list_get_by_condition(), as appropriate. As soon as a match is found, the matching struct mem_block is returned, otherwise NULL is returned.
Notice how we separate the common parts from the use-case-specific parts using the function pointer compar. We put the common parts into our linked list library, and the small application-specific parts into our application. Now we can have several comparison functions testing various conditions, for different search criteria, and the sanctity of our linked list library remains preserved :)
TL;DR: Mammoth software with tons of features are not uncommon nowadays. However, the interfaces for these software have not matured. They are not scalable enough to support efficient usage of the program’s features. The traditional menu UI metaphor becomes very cluttered in this case. The solution: searchable user interfaces.
The above picture should make amply clear the scalability problem with menu-driven user interfaces. It’s a waste of the user’s time if you make them manually look through the menus (or make them remember arcane keyboard shortcuts) for actions they want to perform, especially if your application can do a lot of things. The purpose of the interface is to make life easy for the user, and the GIMP’s UI doesn’t really make much of an effort in that direction. Sure, it organizes the gazillion “Filters” into neat categories, but the categorization could be subjective, or an action could belong under more than one category. We need a scalable interface. Fortunately, we do have a practical solution to menu-spaghetti.
Wouldn’t it be amazing if, alongwith menus, your application gave you functionality to search through them, all the way down to individual items buried deep? That way you wouldn’t have to go feature-hunting through the menus (or tax your brain with a key combination); you could merely search for what you wanted. And the icing on the cake would be if the search did fuzzy matching and took into account synonyms, various word forms, etc.
There are actually some well-known existing software which implement these “searchable user interfaces”, or SUIs, as I like to call them.
First up, we have Google’s zippy web browser, Google Chrome / Chromium.
Chrome has always been somewhat of a leader in modern UIs, and their carefully crafted preferences interface is testimony to that fact. Notice how, when you search for “ser”, Chrome searches even inside the Content Settings box. This is what user interfaces should aspire to be: clean, functional, and efficient. Hats off to the Chrome team for a job splendidly executed.
Next we have our friendly neighbourhood operating system, Ubuntu.
Ubuntu, come April, will sport an SUI on every single application in the OS. They call it the HUD. The HUD will allow you to search through menu options in a jiffy, so you can say bye-bye to the GIMP’s messy menus, and instead search for what you want to do. Of course, the HUD cannot substitute menus, because SUIs have terrible discoverability (i.e., you cannot browse through available actions, you must know what you’re looking for); the best solution would be to have both, traditional menus and the HUD.
Do you know of any other SUIs? What is your opinion of them? Let me know in the comments.
Today I had the opportunity to use an amazing feature in GDB — “reverse debugging”. Actually, ‘amazing’ is probably an understatement.
Think of the following scenarios in a GDB debugging session (and forgive the dramatic prose):
You’re battling against an elusive little bug, the kind that appears only some times when you’re running your code, crashes it, and goes its merry way, only to strike again a few compile-run cycles later. So how do you get rid of that bug? The usual answer: you pain-stakingly go through session upon GDB session, hoping to catch that bug in action and find out what’s causing it. Isn’t there supposed to be an easier way?
You’re in a middle of a particularly time-consuming debugging session, having set up the perfect combination of breakpoints and watchpoints after hunting around to find the approximate location of the bug’s origin. So you run the code, and then carefully start issuing continue and next commands, navigating the code, examining variables along the way. Then you realize, somehow, that you’ve let the code run just a little too far and missed your chance. What now, you start over?
Reverse debugging in GDB could be a neat solution to the problems above. By allowing you to re-simulate a particular instance of execution of your program any number of times, it gives you the ability to catch bugs easily and test them to your heart’s content. Here’s how you can handle problems #1 and #2 described above using this technique:
Instead of carefully setting up and plodding through multiple GDB sessions in the hope that the bug will appear, you can simply set a few important breakpoints in the suspicious area of code, and keep issuing continue, and if Mr. Bug doesn’t show up, run it again. Keep doing this until the bug rears its ugly head, at which point you issue a reverse-continue, which takes you back to the last breakpoint hit. This reversal restores everything to the state it was in before you’d issued your last continue – but now you know the bug is going to appear shortly, so you set more breakpoints before the next one and narrow down your problem to a smaller area. Things don’t look so good for the cornered prick.
The answer to this should be pretty obvious now. Whenever you realize you’ve come too far in the code, you can go back using reverse-continue (or some other reverse command). Just make sure you set “recording” on (using record) at the point till which you want to able to reverse execution, preferrably right at the start of the program (it’s pretty easy, take a look).
You can even do set exec-direction reverse to make all commands like continue, next, and step go backwards. To get back to normal, forward running code, use set exec-direction forward.
In Part I, we saw how to open up the Magit status buffer, view unstaged changes and untracked files, stage changes and commit them. The next thing you should learn is how to view the git log.
To view a terse history of your repository (à la git log --graph --oneline --abbrev-commit, which I’ve aliased to git pretty), press l l in any magit buffer. To view the log in verbose form, use l L instead. Initially, only the last 100 commits are shown (to see 100 more, press e, and to see all commits, press C-u e).
Press RET to view any commit in the log.
Pressing a on a commit will apply it to your current branch (a “cherry pick”, in git-speak), although the changes won’t be automatically committed (use A instead to apply and commit in one go).
On the other hand, v will revert the commit at point (again, you need to commit the changes yourself).
You can compare any 2 commits or the working tree and a commit right from Magit. Let’s see how.
Let’s say you want to compare 2 commits in the log. Mark the first commit by navigating to it and pressing .. Then go to the second and press =, and your diff will come up in a new buffer. Similar to the previous section, you can selectively apply parts of the diff to your current branch by using a and A, and reverse-apply them using v.
To compare your working directory with a specific commit, use d. To compare any 2 arbitrary commits, use D. As usual, you can use a and v to apply and reverse diffs / chunks of diffs.
You can reset to a previous commit in the branch by typing x and entering a commit name (this will not affect your working tree or staging area in any way). This does a soft reset, meaning that the changes from the discarded commits are put back in your working tree, and you can commit them again. Be forewarned that rewriting history in this way is not preferable if you have already published it (instead do a normal revert using v on the defective commits from the log).
To discard only the changes in your working tree and staging area (i.e., to reset to the state of the most recent commit), press X. This will get rid of all uncommited changes, but will not affect the commit log.
Remember the Magit status buffer we talked about in Part I, which you get by running M-x magit-status? After you’ve made your commit with C-c C-c, Magit will thoughtfully display an Unpushed Commits section in the status buffer, meaning that you haven’t yet published those commits to a remote repository. There’s not much point in committing from Magit if you can’t do your git push from it too. So, to push the current branch to a remote, type P P. If you have no default origin repository configured, you will be prompted for it. If you want to push to a different remote, give a prefix argument to P P.
If you want to run a git pull, press F F. If the current branch is not configured to pull from some remote branch, you will be prompted for one. Magit, again very thoughfully, displays an Unpulled Changes section in the status buffer.
This is the end of Part II. Look out for Part III, which will cover the intermediate to advanced stuff, like branching and merging.
This is a tip showing a clever little use-case for macros in C. How many times have you typed
char *s = (char *) malloc(x*sizeof(char));
in C and not thought about it twice? Think: that statement violates a fundamental principle of programming: the DRY (Don’t Repeat Yourself) principle – that too twice over – by repeating the data type char 3 times. If you had to change the data type of s, you’d have to change it in 3 places. Surely that’s something a machine should take care of, not a human. Using C macros we can get that redundancy count down to 2 times, in the process getting a sweet abstraction out for simple memory allocation.
The macro is as follows:
#define ALLOC(t,n) (t *) malloc((n)*sizeof(t))
The effect of this macro is that it allocates memory for n units of data of type t, and returns a pointer to the newly allocated memory. It works by replacing any code of the form ALLOC(t,n) with (t *) malloc((n)*sizeof(t)), where t is any data type and n is any arithmetic expression involving only integers (in a valid use scenario).
A side note on macros: they are blind replace operations, meaning that the replacement occurs exactly as specified. That is why we need the parentheses around n in the replacement text, otherwise ALLOC(int,3+4) would translate to (int *) malloc(3+4*sizeof(int)), but we probably intended (int *) malloc((3+4) * sizeof(int)) (if you’re new to macros in C, you should read a bit about macro functions and macros in general before trying to use them in some critical part of your code, because they can bite back in subtle ways).
So we can replace our initial un-DRY statement with char *s = ALLOC(char,x). Short and sweet, eh?
I love Emacs. I only started using it a few months ago, but I’m already hopelessly in love with its (unapparent) simplicity and crazy extensibility. Perhaps my custom hand-crafted .emacs, – yes, I call it hand-crafted – alongwith the fact that this very blog post has been written in Emacs, is proof enough.
I recently came across Magit for Emacs, and I was amazed at how much it could do. It’s basically a cool interface to git, inside Emacs. This post here is the first in a 3 part series that aims to be a reasonably comprehensive tutorial to using Magit (make sure you have it installed first, as per the instructions in the README here). However, it assumes prior familiarity with both Git and Emacs, so if you’re not comfortable with either, this guide probably won’t help you much. I have, however, listed some excellent git resources at the bottom of this article, so you can skip along to that part if you don’t want to read the whole thing.
The first command you need to know is M-x magit-status. So to see the status of a git repository using Magit, open a file in Emacs that is a part of that repository, and then run the above command. That is usually how I initiate interaction with Magit, so I’ve bound magit-status to M-xgs. This opens up a buffer with a name like *magit: blog* or something similar. This buffer is in magit-mode, with convenient keybindings for common git operations like staging and committing.
Each Magit buffer is divided into tree-like sections, and each section can be hidden or shown individually. The <Tab> key toggles the visibility of a section. You can also use M-S (show all) and M-H (hide all). M-H collapses all diffs, so you can see at a glance the list of files involved, and M-S expands everything, so you can see full diffs of all the files. Sweet!
The Magit status buffer is divided into sections as described above. The top header gives general information about the repository’s current state (the current branch, the repository’s location, and so on). The first section is Untracked Files, followed by sections for the staging area.
The Untracked Files section lists all untracked files (duh). You can add an untracked file to the staging area using s (which will move it to the Staged Changes section), ignore it with i, or delete it permanently with k. If point is on the Untracked Files section header, pressing s or k will stage or delete all untracked files, respectively. Typing C-u S anywhere will stage all untracked files, alongwith all changes to already tracked files.
In the Unstaged Changes section, s will stage the change point is in, and S will stage all changes, regardless of the position of point. Similarly, in the Staged Changes section, u will unstage the change point is in, and U will unstage all changes, regardless of the position of point.
Oh, and you can even stage parts of changes individually! All you have to do is expand everything (M-S), navigate to the part of the file diff you want to stage (the region will get highlighted as you move into it), press s, and BAM! It doesn’t get any cooler than that.
When you’re done deciding which changes to stage, type c to open up a buffer to write your commit message in, and when you’re done doing that, press C-c C-c to commit your changes. Congratulations, you’ve successfully performed your first commit in Magit! (Interestingly, Magit was used for the publication of this very blog post!)
That’s it for the first part. Part II will pick up with how to view the git log in Magit and continue further from there.
I was tempted to title this post “Hello, World”, but decided it was too much of a cliché to attract anyone’s attention. Hence the TV show-inspired “Pilot” (also, I’d already used the same title for the first post on my other blog).
This blog is meant to help me improve my programming skills (and hopefully others’ too), because I’ve noticed that writing makes me understand and remember things better. Many a times I read about some important programming guideline, or some obscure – but occasionally extremely useful – Emacs command, or some new technology. But sooner or later I end up forgetting it. And when I need it, I have to go scrambling all over the Web again. I’ve decided it’s just better to write down the good stuff instead. There’s a psychological reason too: I gain confidence at a topic when I note it down and successfully explain it to others.
Perhaps you’d like to know more about me?
... the Total Perspective Vortex can annihilate a man's soul! ... When you are put into the Vortex you are given just one momentary glimpse of the entire unimaginable infinity of creation, and somewhere in it a tiny little mark, a microscopic dot on a microscopic dot, which says, "You are here."
- Douglas Adams, The Hitchhiker's Guide to the Galaxy.Whenever I'm outside on a clear night, I have a tendency to look up at the sky in wonder, every now and then. Seeing this, a friend once asked me, in all seriousness, "Why are you so fascinated by the night sky?"
"The mind is its own place, and in itself, can make a Heaven of Hell, a Hell of Heaven."
- John Milton
"Universities and research labs force hackers to be scientists, and companies force them to be engineers."(here, me = "hacker" = "programmer"). Basically the only good place for people like me is in tech startups, or in big companies with a relatively larger percentage of "hackers" and less office politics, like Google. Since I'm caught up in "science" and "engineering", it's an obstacle in my path.
| See something? |
| Which one's the mango milkshake? |
| Truer than the word of God. |
| It's not totally pathetic. |
One of the most idiotic ideas ever, right up there with Vanilla Coke and giving Phil Spector a gun permit. Deceit makes our world go round. Without lies, marriages would crumble, workers would be fired, egos would be shattered, governments would collapse.