Tuesday, December 04, 2012

setq / custom.el changes up

I made the changes corresponding to yesterday's post on setting variables to my emacs configuration.  If you are interested, you can look at the diff to see what kind of cleanup is the result of taking the advice I gave in the last post.

In the progress, I realized that the code I gave yesterday for loading custom files could be improved, and I've edited the post to reflect that.

Also, I've actually seen a live example of using the package-loading capabilities of custom-set-variables. Evidently, this is used to set global modes to true. For modes, using setq doesn't work, you either have to use a function or change it through the customization interface. When you set this variable, you really want to load the package you are setting the variable on. The resulting bit of code looks something like:

(custom-set-variables
  ...
  '(foo-global-mode t nil (foo))
  ...)

This will load the package foo and set its global mode to true.

For these kinds of things, I prefer to use the method instead in setup, so that enabling the global mode can be grouped with any other customization for the feature.  So instead of using customize to set the variable, instead we'd just call:

;; Turn on foo everywhere.
(foo-global-mode 1)

Monday, December 03, 2012

Variable customization

There are a few major kinds of customization you can perform:
  1. Change the variables for already existing code.
  2. Create new keybindings (or erase ones that were there already).
  3. Create new functions to add new interactive capabilities.
  4. Load new packages that alter the behavior of emacs, and call functions that setup the initial state of those packages.
I'm going to focus on changing the variables in this post.

There are two main ways to change variables: by using setq directly, or by using customize. Looking at my init file, my first line setting a variable directly is this:

;; This only gets set for real when cc mode is enabled
(setq c-buffer-is-cc-mode nil)

This is an example of using setq. If you are new to elisp, you may wonder why it is called setq instead of set. The answer is pretty simple: setq stands for "set quoted", and there already is a set. Here's the same thing with set:

(set 'c-buffer-is-cc-mode nil)

The difference here is we have to quote the variable we are setting, c-buffer-if-cc-mode, whereas in setq it is done for you. At any rate, setq is more idiomatic in elisp, so let's use that.

The other main way to set variables in using customize. To set the same variable with customize, we can type M-x customize-variable and then enter c-buffer-is-cc-mode. However, if you try this, you'll see that c-buffer-is-cc-mode doesn't work; it has no customization option. That's probably because it isn't intended to be customized, and indeed if you look at it, you'll see that it is buffer-local, which means that it isn't a global variable, it is one that has a potentially different meaning in every buffer. To such variables, there isn't much need for global customization.

As you can see, you can't customize everything. For many things, though, customization is pretty nice. You can also do M-x customize-group and then put the name of some package, such as ido. You'll see a list of variables printed as phrases: the first letter capitalized and the dashes replaced with spaces. For example, the variable ido-before-fallback-functions is referred to as "Ido Before Fallback Functions". For variables with a freeform value, you can edit the value in a small textbox. For lists, you can insert an element at a time.  For things that can be one of a few values, you get a selection widget.  It's all very nice and easy to use.  The documentation is also right there. After making a modification, you can save for the current emacs session, or permanently. Permanently saving puts the customization in your initialization file in a stanza that looks like:

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(ido-auto-merge-delay-time 1.5))

There is a choice to make for customizing options, then. Use plain-old setq, or use the snazzy built-in customization?  I think each has it's uses, but my current configuration isn't a good example of this. Let's fix it.

Generally, I think it's best to use customization for machine-specific things, and setq for everything else. setq has some nice advantages to it, but also a few drawbacks. The advantages are that you can group the setq statements with similar customization (for example, keybindings). Also, you can comment on the variable settings. This is very important. Looking at my setting of c-buffer-is-cc-mode, my only comment is "This only gets set for real when cc mode is enabled". This comment sucks. Looking at this, I don't recall why I felt the need to set it, and this comment does not help at all. Ideally, I'd like to know what horrible fate will befall me if I fail to set this variable. I'm going to remove this from my config. When I figure out why I needed it, I should remember to leave a better comment. Maybe I'll never figure it out, which is fine, since my config will be just that much cleaner.

The drawbacks to setq are that the UI for changing the settings is not nearly so nice as the built-in customize. That's about it.

A variable can be set with setq before the variable is even defined, and the value set with setq will still take effect. For example:

(setq foo 10)
(defvar foo 3 "An example variable")
(princ foo)  

--
10

It's also worth noting that you can have one setq to set many variables, like so:

(setq foo 1
      bar 2)

As I mentioned above, customization may be useful for per-machine settings, such as the location of binaries. This is because we can separate out the customization to another file. The docs to custom-file explain this nicely, but the basic idea is that you setup another file to hold your customization. With things split into another file, you can add this file to your .gitignore, and then just not check it in. There should be no need to.

To do this, first, copy any customizations we have into your new file. If you have an ~/.emacs.d/ directory like I suggest, then ~/.emacs.d/custom.el is a reasonable choice.

(setq custom-file "~/.emacs.d/custom.el")
(load custom-file t t)

Loading in this way will let the file not be there without throwing an error.  That's fine, usually it shouldn't be there when running this config on a new machine.

Just in case you were wondering, customization does not act like setq; it matters where you do it:

(custom-set-variables
 '(bar 10))
(defvar bar 3 "An example variable")
(princ bar)

--
3

This is why customization always happens last.

You can actually change this behavior. And you can add comments.

(custom-set-variables
 '(baz 10 t nil "With the t argument, this will be evaluated explicitly"))
(defvar baz 3 "An example variable")
(princ baz)

--
10

There is one other interesting thing you can do with custom-set-variables, which is to have the customization per-feature.

(custom-set-variables
 '(jabber-keepalive-interval 10 nil (jabber) "Only pertains to feature 'jabber"))

This will load up the feature in question, in this case jabber when customizing. I'm not really sure why this is useful. If anyone knows, please tell me in the comments.

Customization has even more complexity. You can have customization themes that you can change between, or layer on top of each other. It's all very interesting, but to me it's best to just have the separate file, and store machine-specific settings there.

In summary, my suggestions for variable settings are:
  1. Use setq for each variable you want to set.
  2. Unless it is dead obvious, comment on why you are changing the variable.
  3. Keep all similar variables together.
  4. If the variable is something inherintly machine-specific, such as the location of a binary, then customize it, and put your customization in a different file that will not be shared between computers.
  5. Load customization last.
I plan on going through my configuration file and making these changes, and I encourage you to do the same.

Sunday, December 02, 2012

Some people don't customize emacs. If you are one of them, there's no need to read further. However, the more packages you use, and the more you want to optimize, the more customization you require. Furthermore, the more customization you need, the more valuable that customization is, and the more you want to keep it around. With Emacs 24 and ELPA, getting and using packages is incredibly easy, so I anticipate that customization is going to be more important than ever.

I'm planning to write a series of posts on customizing Emacs, sharing tips and developing elisp to make the job easier. This is an introductory post to this series.

My first tip is to store your setup on github. I've done this with my emacs-setup project. I'll be updating this repository as I develop new elisp. Having your setup on github means you can put it on any computer you use, and other people can see and refer to your config. Stealing bits of elisp from other people's setup is a long-held emacs tradition, and github makes this easy.

My second tip is to store your configuration in ~/.emacs.d/init.el, not ~/.emacs. The .emacs.d directory is where all the action happens these days. Configuration files are stored there, as well as ELPA packages (in the elpa subdirectory). So if you are just starting your configuration, put it in ~/.emacs.d/init.el, or else move your existing configuration there.

Finally, all the tips I'll be giving assume Emacs 24. If you haven't upgrade, please consider doing so.

Stay tuned for more tips!

ELPA for App Engine

I've just released on open-source project: ELPA on AppEngine.  This is an implementation of ELPA written in the Go programming language, that runs on AppEngine.  Right now it isn't ready to be a real running system, but it probably won't take too much work to get it the rest of the way there.

It might have the possibility into being a really cool ELPA that is open to all, as opposed to the other ELPAs which are hand-curated.  I'm still thinking about where I want to take this.

Thursday, March 15, 2012

Tips for code interviews

If you are a programmer, then you inevitably spend some time every few years doing a bunch of interviews for a programming job. You probably are going to have to do some code interviews as part of that, which means you'll be doing coding interviews many times throughout your career.  Allow me to help.

Since I previously wrote a post on why I prefer coding interviews, I thought I'd follow up with some tips for doing well at these things.  I suppose it can also double as a list of things to look out for if you do code interviews.

The problem is, coding interviews, done well, are a pretty accurate gauge on your ability to code.  If your coding is rusty, it's hard for that not to show up during an interview. Still, there's a few things you do to help your chances.

  • If you are given a choice in languages, choose the most high-level language you are relatively good at.  So if you code mostly in C++ and sometimes in Python, use Python.  The coding will be faster and easier. If you aren't a regular user of any high-level language, though, better stick with what you know.
  • Know your chosen language well.  Know the standard data structures - sets / hashtables / lists / arrays.  If it's C++ or Java, know how to use Generics.  Know the features of the latest version.  If you tell me you primarily program in Java, but haven't used any version over Java 1.4, I'll feel you just don't care very much about programming.  On the other hand, if you tell me about upcoming features in C++11, I'll be pretty impressed.
  • Know when to use each type of data structure.  In Java, if you don't care about ordering, and items shouldn't have duplicates, don't use a List. Use a Set.  I am supremely annoyed when candidates just use LinkedLists for everything.  In fact, using it for anything is usually a bad sign.  Make sure you understand why.
  • You don't have to necessarily complete the whole program in order.  Feel free to write the main structure of the code, then fill in the more complicated bits later.
  • Go back and refactor code if possible.  Don't leave your code in a messy state if you think you have time to fix it.
  • Test out your code on an example.  I can't stress enough how important this is.
  • Choose meaningful variable names.  Not just good practice stylistically, but you are less likely to trip yourself up.
  • If the algorithm you are coding could be done in several different ways, choose the easiest way to code up first.  Then if you have time you can change it or just explain to the interviewer how to improve it.  It's better to have complete suboptimal code than incomplete optimal code.
  • Make sure you can figure out the running time of simple programs.
  • When physically writing on a whiteboard, leave as much space as possible between consecutive lines.  You often will have to go back and insert things in between lines.  Having to erase or write somewhere else and have an arrow pointing to the insert point will make things look confusing, which is bad for your comprehension.
Now, if you feel you are rusty or just a bit slow at coding, these tips won't help you too much if you can't actually code up the problem in question in time.  What you can do, though, is train this skill by doing coding exercises.  There's a few sites that offer small coding exercises, such as CodeSprint or  Project Euler.  Do these as much as possible before your interviews.  Don't just wait until you are actually about to interview.  Start as soon as possible.  

If you have any other suggestions for doing well in coding interviews, please share in the comments!

Sunday, March 11, 2012

The code interview

I was halfway through the bad interview when I realized that my method of interviewing was fatally flawed.  The candidate I was interviewing just did not make the conceptual leap to come up a way to solve the problem, no matter how many hints I gave.  The problem, which I don't wish to reveal, wasn't a classic a-ha type puzzle type problem, like the three lightbulbs controlled with two switches, but it was a software engineering problem that required some insight.

What worried me was that some candidates got the answer to my question instantaneously.  Almost no thought needed.  Oh, so you want to accomplish X?  How about a scheme that does Y?  Other candidates needed to think about it for some time.  But this one didn't get it even after about 15 minutes.  Are the ones that get it instantaneously really so dramatically better?  I knew from experience that many who came up with the answer fast didn't do well on the next part of the question, or overall in the rest of their interviews.

As the interviewee continued to metaphorically bang his head on the wall of the question, I realized that this part of the question was meaningless. I couldn't say for sure that a great performance on it would indicate a great engineer, or a poor performance would indicate a poor engineer.  Worse, my candidate had to struggle without making progress for quite a while.  He wasn't feeling good about it.

I was ultimately wasting time.  15 minutes spent determining that the interviewee can't answer a specific issue is 15 minutes that only yields a small amount of information.  Either the interviewer realized the answer or not, so I really only got that binary signal.  

At that time I had another question in my repertoire, which was a simple coding exercise, significantly more complicated the FizzBuzz, but less complicated than writing merge sort.  Pretty much the exact opposite of this type of question.  Anyone that can write code could do it.  But it turned out that performance on it was still variable, which was good, and I never got the feeling that performance was random.  Also, I was able to get all sort of signals: how fast the candidate wrote their code, if they remembered details about their language, if they made mistakes, if they remembered to test their code, etc.

After this bad interview, I switched almost exclusively to this simple coding exercise.  After I made the switch, I never had a bad interview again.  Candidates always made progress on this question.  They almost always finished the implementation.  They may have had to think about some parts, but they always left thinking they did a reasonable job.  And I never had to sit through and puzzle out how to drop hints to solve some algorithmic problem that the candidate is just not grasping.

With everyone pretty much able to finish the question, I judge candidates on the following:
  • How quickly were they able to finish the code?  
  • How correct is the code? 
  • After writing the code, did they go through the code to test it against some sample data?
  • How familiar do they seem to be with the language they are writing in?
  • How elegant is the code?
  • Is the code efficient?
Additionally, I'd ask a algorithmic question or two after this, if we have time, to see how they can speed up the code.

Usually, the answers to these are pretty well correlated.  If you can code elegantly, then you can usually code quickly, which them means you will have time to test and correct the code.  At the end, I think I have a good judgement of how decent a coder the person is.  If the candidate is a good coder, I almost always recommend hiring.

If you are thinking of asking a coding question, here are my recommendations, based on an interview time of 45 minutes:
  • Make sure you can write the code from scratch in about 15 minutes.  That doesn't sound like a lot of time, but you already know how to solve it, presumably, or else you wouldn't be asking the question.  All candidates, good or bad, take longer than you may think to code something up.
  • Have follow up questions that are algorithmic in nature.  What is the running time of the code?  How you can make it faster?  Could you parallelize it?  This is all for when the coding is finished.  If the coding never finishes, don't ask these questions.
  • Insist on real code, not psuedocode.  Let the candidate choose the language they are most comfortable in.
  • If you don't have a good coding question, look at the last few bugs you fixed.  Could one of them be an algorithm that could be simplified and turned into a coding exercise?  The existence of a bug is proof that the algorithm isn't too simple.
Judging a candidate can't be done through coding questions alone.  Algorithmic and design questions are necessary too.  But I'd ask coding questions first, since they seem to offer the most solid and reliable feedback.

Saturday, February 18, 2012

Work / life balance advice

Don't let either your personal life or your work life go neglected.


There. That's it. If you are short on time, you can stop reading now, since that's the one most important thing about work / life balance.


Oh, you're still here? I might as well talk about the actual balance part, then. The part before was just about boundaries, but within those boundaries are many possibile ways to allocate your time. I'll try to keep this advice short too: Do you what love, be flexible, and keep learning.


"Do what you love" is pretty standard advice, but most people use it to talk about your career. It applies to your extracurriculur activies too. It means that your time on nights and weekends is best spent pursuing the priorities that are important to you at the moment. For an engineer right out of college, that probably is some combination of working and hobbies. For an engineer with a family, that is mostly going to be family activities and hobbies. That might be family activities and work, but family activities, at least with young children, are a fair bit of effort. I think hobbies balance out better with family life.

Lets assume that you have a family, since that is when people start thinking about the work / life dilemma. I think it is completely reasonable to work just 40 hours a week. However, you have to make sure that those 40 hours are spent wisely. No wasting time at work. In fact, you have to make you are always working on the highest priority task, keeping your focus, and not going to unimportant meetings. If you do those things, you should do well even if others are working 12 hour days.


"Be flexible" is just saying that you shouldn't have any hard rules about work / life balance. Sometimes you do need to take extra time for work, to fight some emergency or to finish off a release. Or sometimes you need to take less time than normal for work, so you can tend to issues that come up at home. If you have an urgent family situation, your work should be flexible and let you take time off. And if you have an urgent work situation, you family or other non-work life should be flexible and allow you to work that extra time. So what I said before about not letting work or personal life go neglected is not necessarily true for short periods of time. It's only true for the long run.

"Keep learning" is about the reality that there is a bit more you need to do away from the office. You need to work to keep your skills fresh. That means not only devoting time to learn new technologies, but also reviewing the fundamentals. The good news is that this doesn't take a lot of effort. I'd guess an hour a week of study or experimentation is sufficient. More is better, of course.

I've seen too many people, both old and young, stagnate because they only did their work. It isn't enough, because change is constant in this industry, and fundamentals are easy to forget. It is good if you can respond to changing technologies, but even better if you can lead some of that change. Keeping your fundaments sharp and keeping up with new technologies will put you in a good position to do either.


Finally, I'll leave you with a piece of concrete advice: Don't check email within three hours of your bedtime. It raises stress levels, and on receiving mail, you are often compelled to act on them or reply to them. Even if you choose to be working in the evening, just work, and skip the email.