Wednesday, April 29, 2009

Vim Sugar

Chris Sutter writes:

I have a script and mapping in my ~/.vimrc:


function! CheckForShebang()

   if (match( getline(1) , '^\#!') == 0)

       map <F5> :!./%<CR>

   else

       unmap <F%>

   end

endfunction

map <F5> :call CheckForShebang()



This way, if i'm editing a script with a shebang at the top and i hit <F5>, it maps <F5> to run the script (if not, <F5> is unmapped, so that it doesn't keep checking if I hit it again). I always found myself mapping <F5> by hand to run the current script while i was editting/debugging and I'd frequently lose track of whether I had mapped it or not. You could, of course, replace <F5> with your favorite run/compile/debug/etc key, it just happens to be my standard (from my QBasic days hehe).

Thanks for the tip Chris!

Wednesday, April 15, 2009

i_Ctrl-O

Derek Wyatt shared this in a recent comment, and I thought it deserved it's own tip.

If you're in insert mode, and you hit ctrl-o, Vim will accept one normal mode command and then return you to insert mode. Two examples given showed some typical usage:

<C-o>ma - Mark the current position and then keep typing.

<C-o>gql - Format the current line and keep typing

A final blurb from the comment:

"The next type you do <Esc>(thing)a you might remember that you could have done that with <C-o>".

Thanks Derek!

Tuesday, April 14, 2009

Set Hidden

If you've ever tried to type :only and had Vim refuse to hide existing buffers because they contain changes, you can use :set hidden to override this behavior. Just remember to keep the possibility of hidden modified buffers in mind when you're doing a :q!.

Monday, April 13, 2009

Yank S-Exp

If you're hacking a Lisp dialect in Vim, you can do type ya( to yank the current s-exp into the default buffer.

Friday, April 10, 2009

Pull Into Ex

If you position your cursor over a given word and type :<ctrl-r><ctrl-w> it will pull the value into your current ex mode command line. This is great for yanking long values into substitutions among other things.

Thanks to Nate for the tip!

Wednesday, April 8, 2009

bashreduce

I stumbled across this project recently. It's a program that allows you to apply standard shell tools in a map reduce style fashion. Large memory hungry tasks like sorting can be distributed across machines to maximize throughput. As a bonus, it's written in bash, so it's highly portable and works with a combination of vanilla shell utilities and ssh shared-key authentication.

The bashreduce project.

Insert Mode Shortcuts

Here are some handy shortcuts that you can utilize while you're in insert mode.

ctrl-t - adjust current line one indent right
ctrl-d - adjust current line one indent left
ctrl-w - backspace over a word
ctrl-u - delete to beginning of indent

Monday, April 6, 2009

Why Functional Programming Matters

I'm always trying to sharpen my skills as a programmer. One approach I've been using to become a better programmer is to learn as many development methodologies as possible. In the past few years, I've become a big fan of functional programming. The basic idea behind functional programming is to compose your programs using functions that return a single value and avoid side effects whenever possible. A side effect is an action that is not required for a function to do it's work. An example of a function with a side effect would be:

function sum(a, b) {
    print "a + b = " + (a + b)
    return a + b
}

In this case, the print statement wouldn't be required to accurately calculate the sum, so it would be considered a side effect. A pure functional language prohibits side effects altogether; although, most functional languages allow some level of impurity for convenience.

Another common feature of functional programming is the use of higher order functions. Higher order functions are functions that take functions as their arguments; thereby, providing an additional level of abstraction. An example of a higher order function included in most modern languages would be the map function.

function square(x) { return x * x }
numbers = [1, 2, 3, 4, 5]
squares = map(square, numbers)
print squares
[1, 4, 9, 16, 25]

Higher order functions can typically take anonymous functions as their arguments as well leading to increased flexibility.

I can already hear you groaning as you read this article and saying, "yeah yeah, my language can do all that too... what's the point?" Well, in the typical zen fashion of functional languages, it's not always what you can do that matters; rather it's what you can't do. A striking difference between a number of functional languages and their imperative counterparts is how mutability is handled.

A number of functional languages such as Haskell, Erlang, and Clojure address the majority of their built-in types as immutable. This means that once a value is assigned to a local variable, it cannot be changed. At face value, this may seem like a huge disadvantage and might even lead one to believe that certain types of programs might be impossible to write. The truth is that any imperative program can be rewritten in a functional style but doing so requires the adoption of a new set of tools. Specifically, recursion must be adopted in lieu of traditional iteration. Things like closures can be used to simulate state, and objects are generally thrown by the wayside.

At this point, the resounding question in your mind is probably, "why bother?" Well, fortunately there's a very strong reason behind all this shifting of methodology, and that's concurrency. Anybody that's written a non-trivial multi-threaded program in an imperative language has dealt with the difficult issues of synchronization, locking, and sharing of state. The larger and more complex the program, the more difficult it becomes to avoid subtle errors and race conditions. For most programmers writing traditional multi-threaded applications, there are more things that can go wrong than right.

Functional programs that operate on immutable data don't have to deal with any of these issues. Since nothing is shared, there's no potential for race conditions, multiple threads stomping on one another's data, or any of the other trappings one might traditionally succumb to. Freeing the programmer from worrying about such things allows focus to be shifted to solving the actual problem at hand instead of dealing with the fine grained details of threading semantics.

Why should you care about threading? I believe the introduction to Java Concurrency in Practice puts it well when they say, "For the past 30 years, computer performance has been driven by Moore's Law; from now on, it will be driven by Amdahl's Law." Basically, processors aren't getting any faster. For many years, programmers have written code under the assumption that performance wasn't an issue because the next generation of processors would pick up the slack. We've reached the point where we'll never be able to assume this again. From this point on, things will become increasingly parallel, which means that learning to work with multi-core machines will become an increasingly marketable skill.

Traditionally relegated to academia, theorem proving, and compiler writing, functional languages are finally becoming mainstream by filling the multi-core niche. Even if you don't adopt a functional language for your day job, taking the time to learn a different method of problem solving will make you a better programmer and provide valuable techniques you can use in your day to day work.

This being said, there are some really nice languages out there to play around with. I will briefly highlight a handful of them for your perusal. Please take note, that not all of these adhere explicitly to the immutable state share nothing model previously mentioned; although, most provide exceptional facilities for multi-core programming.

Clojure - A modern Lisp running on the JVM. Clojure throws out all the cruft of old world Lisp and provides a lean and mean core with immutable data structures. One of Clojure's core features is excellent concurrency performance, and it also provides seamless access to Java libraries whenever desired.

Scala - Adpoted by Twitter to solve their initial concurrency issues that Ruby could not handle, Scala runs on the JVM, which makes deployment a breeze and provides a multi-paradigm approach to development.

Erlang - Initially developed as a proprietary language by Ericcson, Erlang was open sourced some years back. Erlang makes use of immutable state and sends data back and forth between managed processes using a built-in messaging system. The process model allows code to be seamlessly distributed across several cores, servers, or networks. Ericcson has successfully used Erlang to manage their telco switching on massive networks for many years.

Haskell - A purely functional language with an advanced type system. Haskell provides a robust feature set and an extremely advanced compiler. The ability to introduce arbitrary operators and a non-standard syntax can make Haskell intimidating at first glance, but it's concurrency peformance rivals any other language. Notable projects written in Haskell include the Xmonad window manager and Pugs, a Perl 6 compiler.

OCaml - Numerous wins in the ICFP helped OCaml gain initial notoriety. Native code compilers allow OCaml programs to run at blazing speeds, and a sophisticated type system provides both safety and flexibility.

F# - Developed by Microsoft Research, F# is a variant of ML with a core that is similar to OCaml. It runs on .Net and will be a fully supported language in the .NET Framework and Visual Studio ecosystem as part of Visual Studio 2010.

PLT Scheme - A functional language with a history in academia. The ubiquitious MIT book, how to design programs, uses PLT as it's host language. Excellent documentation makes PLT a great way to cut your teeth on functional programming, and it's concurrency features are actually pretty good as well. Threading in PLT is based on the mechanism used in Concurrent ML.

New Lisp - Although including the word "New" in the name of any product might not be the best idea, New Lisp fills a nice niche in the scripted functional language domain. It seems to be at least partially inspired by Paul Graham's Arc, and it provides a good number of modern features out of the box.

SBCL - One of the de-facto standard Common Lisp implementations. I haven't done any concurrency stuff in Lisp, but I do know that SBCL provides a high quality Lisp implementation for your general Lisp-ing needs. If SBCL doesn't meet your needs, Clisp is another very solid Lisp distribution.

Javascript - The ubiquitous Javascript language now has a JVM port and runs everywhere. It's one of the most widely deployed programming languages on earth and allows the application of higher order functions, lambdas, closures, currying, etc. Who would've thought there was a functional language right under your nose?

Wednesday, April 1, 2009

Goodbye Daily Vim, Hello Emacs

After some careful consideration, I've come to realize that it's time to switch editors. Vim has been a good friend, but like an old horse with a broken leg, it's time to put it down. A few days ago, a strange thing happened. Richard Stallman caught wind of this blog and sent me a DMCA takedown notice for documenting patented proprietary Emacs features (copy and paste). I tried to explain that these features were part of Vim as well, but he insisted that Emacs had prior art (implemented in 1953) and that the blog must be taken down at once. Determined to fight back, I decided to take a hard look at the Emacs internals to find some hidden weakness. After days of wanding through the Elisp forest, it happened... I fell in LOVE! Who would've thought that I could send email, surf the web, and play tetris all inside of my text editor? ZOMFG! I'm sorry folks, but if I would've realized what we've been missing, I wouldn't have wasted your time with all these silly Vim tips. This being said, I'll be shutting down this blog in the next 24 hours and dedicating my life to the Church of Emacs. I feel so seriously about this that I'm quitting my job here at Grooveshark and focusing my professional career on writing Emacs kernel modules and improving Emacs boot time. To any earthings that might be reading this, I've enjoyed my time on your planet, but the spaceship has landed, and I must return home. Farewell.