<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>My name is Mitchell Hashimoto. I’m passionate about open source software, DevOps, and programming languages (with a focus on functional programming).</description><title>Mitchell Hashimoto</title><generator>Tumblr (3.0; @mitchellhashimoto)</generator><link>http://mitchellhashimoto.com/</link><item><title>Lessons Learned Building Open Source Software</title><description>&lt;p&gt;Having spent a significant amount of time conceptualizing and growing Vagrant into a decently successful open source project, I&amp;#8217;ve come away learning quite a bit. I haven&amp;#8217;t seen many blog posts about open source maintainers commenting on their lessons learned, so I&amp;#8217;d like to share them here. These are not only engineering lessons, but lessons involving being an open source maintainer, promoting your project, etc.&lt;/p&gt;

&lt;h1&gt;Open Source Lessons&lt;/h1&gt;

&lt;p&gt;These are lessons that are generally applicable to open source projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be friendly.&lt;/strong&gt; This is the &lt;em&gt;most&lt;/em&gt; important thing. You&amp;#8217;re going to get bad ideas sent to you, people are going to get angry when something doesn&amp;#8217;t work despite you providing your project for free, and you&amp;#8217;re going to get terrible pull requests. Just remember that despite all this: these people are using your project, so be respectful, even if they may not be. I&amp;#8217;ve only had &lt;a href="https://github.com/mitchellh/vagrant/pull/333"&gt;one issue&lt;/a&gt; where I was starting to become clearly agitated, but I&amp;#8217;m pretty proud to say that despite all that I think I remained friendly. It is important to remain friendly because as long as you are friendly you are approachable, and open source simply doesn&amp;#8217;t work if people can&amp;#8217;t approach you for help or contributions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don&amp;#8217;t have crazy rules for contributions.&lt;/strong&gt; Don&amp;#8217;t worry about style, whitespace, proper indentation, etc. Unless your project is &lt;em&gt;huge&lt;/em&gt;, complex rules for contributing only serves to hinder those people who want to contribute. Style, indentation, etc. is very quick to hand-fix. You should instead be grateful and accepting of the changes which are actually coming in, rather than any superficial attributes of it. So how do you contribute to Vagrant? Just fork the code, make your change, and pull request. I don&amp;#8217;t care about style, tests, etc. I&amp;#8217;m just happy to see contributions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation is key.&lt;/strong&gt; I can&amp;#8217;t show evidence for this, but I&amp;#8217;m not exaggerating when I say that &lt;em&gt;100%&lt;/em&gt; of the first users of Vagrant who talked to me said they did so because it was so well documented. And at conferences I&amp;#8217;ve heard more of the same. Another important thing is that writing documentation is probably the most boring thing in the world. If you put it off until the end and write in all in one go you risk becoming horribly depressed. So just slowly build up the documentation. Also, make your &lt;a href="https://github.com/mitchellh/vagrant/tree/docs"&gt;documentation forkable for easy contributions.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have a clear method of communication.&lt;/strong&gt; IRC, mailing lists, forums. It doesn&amp;#8217;t matter what it is, but you need to have a clear way for users to get support or voice their opinions in a place that they can expect a response reasonably quickly (within 48 hours would be nice). For Vagrant, I&amp;#8217;ve always had an IRC channel and mailing list. This has worked well. And if your users interface with you more, they gain a stronger trust for the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You don&amp;#8217;t know everything.&lt;/strong&gt; At some point, inevitably, you&amp;#8217;ll get a feature request where you&amp;#8217;ll say &amp;#8220;this is useless&amp;#8221; to yourself. The major responsibility of the project maintainer is to guide the &lt;em&gt;vision&lt;/em&gt; of the project, not to micromanage specific features. Does the feature fit in with the vision? Is it useful for at least a couple people, even if it isn&amp;#8217;t for yourself? Merge it. Guide the vision, be open minded, your users know what they want to see more than you do. But you know whether it fits in with the overall goal of the project better than anyone.&lt;/p&gt;

&lt;h1&gt;Marketing Lessons&lt;/h1&gt;

&lt;p&gt;So how do you get people to use your project? Here are some things I&amp;#8217;ve learned in this space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hacker News.&lt;/strong&gt; The &lt;a href="http://news.ycombinator.com/"&gt;hacker news&lt;/a&gt; community likes trying new things, and there are a lot of developers on there (hackers, if you would). So submit your project there, and comment in the thread saying you&amp;#8217;re ready to answer any questions. Be friendly, because you will be criticized! Also, just some good tips: avoid submitting news when something crazy happens, submit around 1030 AM GMT-8 which is when HN is most active, don&amp;#8217;t link your HN entry directly because upvotes won&amp;#8217;t count, don&amp;#8217;t try to game the system with fake accounts because you&amp;#8217;ll get caught. When Vagrant was first released, it was #1 on Hacker News for most of the day. I received 11,000 unique page views that day (although some of that was from Reddit as well).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reach out to popular niche blogs.&lt;/strong&gt; In every community, especially in the Ruby community, there are niche blogs that are popular and like to report on cool projects in a specific language or field. Find these blogs, reach out to them, and get them to write about your project. This will result in two things: If they write about it, your project not only gets more eyeballs to look at it but your idea is better validated! This is the best way to get your early adopters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speak at meetups (&lt;em&gt;before&lt;/em&gt; conferences).&lt;/strong&gt; Find local meetups that would find your project interesting, and speak there. Practice speaking if you&amp;#8217;re new to it. Don&amp;#8217;t give a tutorial on your project, instead sell the crowd on the &lt;em&gt;vision&lt;/em&gt; of the project, since they&amp;#8217;re probably smart enough to do the tutorial you have with your amazing documentation (right?!). If you&amp;#8217;re new to speaking, do not try to speak at conferences right away, because you &lt;em&gt;will&lt;/em&gt; be bad, people will remember, and it will be that much harder for you to to ever speak again. Also, meetups give you a place to hone your vision and get important feedback from real people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speak at conferences. Start with regional conferences.&lt;/strong&gt; Next, speak at regional conferences. These conferences are generally smaller but filled with good content, and people will be more forgiving if your talk doesn&amp;#8217;t go so well. Also, the bigger conferences are unlikely to accept a talk about a project that is brand new. Now, you&amp;#8217;re going to be in front of around 100 to 200 people and have 40 minutes. Also, you&amp;#8217;re going to be recorded, so make sure you&amp;#8217;re well prepared. Deliver your vision, smile, and take note of the feedback you receive. Use this to further hone your idea and stabilize your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speak at big conferences.&lt;/strong&gt; Now, I&amp;#8217;m talking about conferences like &lt;a href="http://velocityconf.com/"&gt;VelocityConf&lt;/a&gt; or &lt;a href="http://qconlondon.com/"&gt;QCon&lt;/a&gt;. These guys will get you in front of a huge crowd of people (500+), and the audience will be extremely intelligent. Give a deeply technical talk that will challenge these folks, and again, sell your vision. Also, if your project is still relatively new, you should have examples of it being used successfully in the wild by people other than you in order to validate the whole thing. These big conferences attract generally important attendees (CIOs, VPs of Engineering, etc.) who will have a big say in getting your project in use at their big companies!&lt;/p&gt;

&lt;h1&gt;Engineering Lessons&lt;/h1&gt;

&lt;p&gt;Here are the handful of things I&amp;#8217;ve learned about the programming side of things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test.&lt;/strong&gt; I don&amp;#8217;t think this has to be said, but since it is so important, I will include it. Tests are not something you can just bolt on to a project later. You &lt;em&gt;must&lt;/em&gt; test early and test often. Also, don&amp;#8217;t forget integration tests. I added integration tests to Vagrant much later, and they are by far the most valuable tests prior to release. Unit tests will catch my basic errors quickly, but integration tests will find major issues prior to a release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Support Windows ASAP.&lt;/strong&gt; Vagrant began supporting Windows pretty early, with &lt;a href="http://nickelcode.com"&gt;John Bender&lt;/a&gt; doing much of the initial work. Despite Vagrant not being very feature-rich at the time, it was an absolute nightmare, since many of our dependencies didn&amp;#8217;t work on Windows, and because there were many places in the code which expected Linux or simply called methods that didn&amp;#8217;t work on Windows. I couldn&amp;#8217;t imagine trying to bolt on Windows support later in the product cycle, since it can possibly require huge overhauls in your code base. Additionally, there are a significant number of Windows developers who want to use Linux-style tools. Instead of responding &amp;#8220;Why don&amp;#8217;t you switch to Linux?&amp;#8221; I think its important to accommodate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid FFI.&lt;/strong&gt; This is more of a Ruby thing. The &lt;a href="https://github.com/ffi/ffi"&gt;Ruby FFI library&lt;/a&gt; is just not good for anything more than the simplest C libraries. I spent over 18 months working heavily with FFI. I&amp;#8217;d even venture to guess I was one of &lt;a href="https://github.com/mitchellh/virtualbox"&gt;the heaviest users of FFI&lt;/a&gt;. The issue is that the FFI library would routinely update and break, even in patch releases. More than a handful of times I awoke to find that Vagrant simply no longer worked on Windows due to FFI compilation issues, due to a &lt;em&gt;patch&lt;/em&gt; release of FFI. Additionally, I found it extremely difficult to work with callbacks and dealing with memory management with FFI. Vagrant was one big memory leak until version 0.9. In the end, I ditched FFI until a better library exists, and now support C extensions again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Become friends with the maintainers of your dependencies.&lt;/strong&gt; Any heavy user of a library will find a bug in that library. Throughout the life of Vagrant, I&amp;#8217;ve found a bug in every dependency. At this point, I&amp;#8217;m reasonably good friends with the maintainers of all my dependencies, so I&amp;#8217;m able to quickly ask &amp;#8220;is this your bug? how long until its fixed? can you release a fix?&amp;#8221; The &lt;em&gt;worst&lt;/em&gt; possible output is that there is a bug in a dependency and the maintainer either won&amp;#8217;t fix it or won&amp;#8217;t push a release containing the fix.&lt;/p&gt;

&lt;p&gt;In the end, I still have a lot to learn, but hopefully these tidbits will help some people out there when working on open source.&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/20106073460</link><guid>http://mitchellhashimoto.com/post/20106073460</guid><pubDate>Wed, 28 Mar 2012 22:41:00 -0700</pubDate><category>open source</category><category>ruby</category><category>vagrant</category><category>lessons</category></item><item><title>The Hardest, Most Rewarding Job I've Ever Had.</title><description>&lt;p&gt;I just released &lt;a href="http://vagrantup.com"&gt;Vagrant 1.0&lt;/a&gt;, exactly two years since I showed Vagrant to the world for &lt;a href="http://news.ycombinator.com/item?id=1175901"&gt;the first time&lt;/a&gt;. I&amp;#8217;ve made an &lt;a href="https://groups.google.com/forum/?fromgroups#!topic/vagrant-up/F7mG_R8uIoQ"&gt;official announcement&lt;/a&gt; but I think it is only appropriate to share a deeper, more personal story of the road travelled to reach this milestone, and what I&amp;#8217;ve learned throughout the process. My goal in sharing is to give others an inside look at the guts of a successful open source project and perhaps offer a different point of view of the open source world.&lt;/p&gt;

&lt;p&gt;Today is one of the proudest days of my life. I&amp;#8217;ve released the first stable version of &lt;a href="http://vagrantup.com"&gt;Vagrant&lt;/a&gt;, the software project I started with &lt;a href="http://johnbender.us/"&gt;John Bender&lt;/a&gt; over two years ago while I was still in college. Vagrant is currently used by &lt;a href="http://mozilla.org"&gt;Mozilla&lt;/a&gt;, &lt;a href="http:/rackspace.com"&gt;RackSpace&lt;/a&gt;, &lt;a href="http://livingsocial.com"&gt;LivingSocial&lt;/a&gt;, &lt;a href="http://shopify.com"&gt;Shopify&lt;/a&gt;, &lt;a href="http://openstack.org/"&gt;OpenStack&lt;/a&gt;, &lt;a href="http://eventbrite.com"&gt;EventBrite&lt;/a&gt;, and many, many more. Both the project and the ideas behind the project have been far more successful than I could&amp;#8217;ve ever dreamed of. But the road to this point is an interesting one, filled with highs and lows, and I&amp;#8217;d like to share it with you.&lt;/p&gt;

&lt;p&gt;The original idea for Vagrant came in 2009, when both John Bender and I were employed by &lt;a href="http://ruby-lang.org"&gt;Ruby&lt;/a&gt; development shops where it was routine to see a new project every 6 to 8 weeks. It was becoming increasingly frustrating to setup our development environments for every new project, which would be &lt;em&gt;slightly&lt;/em&gt; different from previous projects. And it was absolutely infuriating when we had to go back to do maintenance on an old project since it was always a nightmare to get the environment back to that state. In the winter of 2009, I was frustrated enough to try to come up with a solution to this problem.&lt;/p&gt;

&lt;p&gt;At this point in my life (and even still today), I viewed open source very romantically. People like &lt;a href="http://yehudakatz.com/"&gt;Yehuda Katz&lt;/a&gt; and &lt;a href="http://ejohn.org/"&gt;John Resig&lt;/a&gt; were my idols, because they did their work in the open passionately and successfully. I wanted nothing more than to find my own &amp;#8220;jQuery&amp;#8221; or &amp;#8220;Ruby on Rails.&amp;#8221; Basically: I was eager to start something which I thought would change the landscape of some field, just as jQuery and Rails did theirs. I don&amp;#8217;t actually believe that Vagrant is as influential as jQuery or Ruby on Rails, but this gives you an idea of how I was thinking at the time.&lt;/p&gt;

&lt;p&gt;In Janurary, 2010, I approached John Bender with some initial thoughts for what would eventually become Vagrant. John immediately saw value in the idea and offered to join in on the project, which I gladly accepted. We got started working immediately. It was January 21, 2010.&lt;/p&gt;

&lt;p&gt;We both worked furiously, and within a week we had a working prototype that could bring up virtual machines we could SSH into. Below, you can see a screenshot from January 31, 2010, about a week after we started hacking, showing a functional version. Yes, Vagrant started life named &amp;#8220;hobo.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://img.skitch.com/20100201-riu3dcnj46y8er43g8g28bxrdd.jpg"&gt;&lt;img src="http://img.skitch.com/20100201-riu3dcnj46y8er43g8g28bxrdd.jpg" alt="First Working Version"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The initial development went fairly smoothly. Much of the essence of what Vagrant is today was molded during those initial weeks, and I&amp;#8217;m happy to see that the ideas John and I had have been validated worldwide. Some are starting to show their age, but the fact that so many early decisions have lasted this long I think shows we had the right idea.&lt;/p&gt;

&lt;p&gt;Fun fact: John came up with the entire idea of the &amp;#8220;box&amp;#8221; system about a week before the public release. Prior to that, I had planned to release Vagrant 0.1 only supporting a single Ubuntu image. The &amp;#8220;box&amp;#8221; system has been one of the most critical pieces in making Vagrant as successful as it is today, so my hat is off to John here.&lt;/p&gt;

&lt;p&gt;While Vagrant was ready for release around mid-February, I was concerned that an open source project coming from two unknown/unproven developers would hurt our initial adoption. I decided that to be as successful as we could, we&amp;#8217;d have to have amazing documentation and a mascot. Yes, a mascot was &lt;em&gt;critical&lt;/em&gt;. I don&amp;#8217;t know why, but I just find projects that have mascots to be more trustworthy. So, Vince was born (shown below), and I spent a week only working on documentation. I can&amp;#8217;t stress how important this week was.&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;a href="http://vagrantup.com/static/images/vagrant_chilling.png"&gt;&lt;img src="http://vagrantup.com/static/images/vagrant_chilling.png" alt="Vince, Chilling"/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Vagrant 0.1.0 was released on &lt;a href="http://rubygems.org/gems/vagrant/versions/0.1.0"&gt;March 7, 2010&lt;/a&gt; with a mostly &lt;a href="http://news.ycombinator.com/item?id=1175901"&gt;positive response&lt;/a&gt;. There were a handful of individuals who immediately grasped onto the idea and began using Vagrant with their projects right away. Most of these individuals still use it today, and deserve recognition for being so brave to adopt a new technology so early. Some of these early adopters even border on fanatical, creating things like Vagrant pins they distribute anywhere they go. I love this:&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://media.tumblr.com/tumblr_m0gcgfhKhe1qfb135.jpg"/&gt;&lt;/div&gt;

&lt;p&gt;The first few months of Vagrant were reasonably uneventful. Besides the initial rush of early adopters, growth mostly stagnated, and each release of Vagrant was getting averaging around 100 downloads. While I loved the project and still whole-heartedly believed in it, seeing very little growth was hugely discouraging. At this point, I actually started to view Vagrant as a potential &amp;#8220;failure.&amp;#8221; Despite this, John and I and our respective companies used Vagrant every day and saw the value first hand. And I was still passionate about the project, so I decided to just keep going, believing that if this were truly a good idea, something good would happen.&lt;/p&gt;

&lt;p&gt;And something good did happen, something &lt;em&gt;great&lt;/em&gt;: &lt;a href="https://github.com/carllerche"&gt;Carl Lerche&lt;/a&gt; discovered Vagrant. At the time, Carl Lerche worked at &lt;a href="http://www.engineyard.com/"&gt;Engine Yard&lt;/a&gt; and was a &lt;a href="http://rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt; core developer. He also specifically pair programmed with &lt;a href="https://github.com/wycats"&gt;Yehuda Katz&lt;/a&gt;. Carl popped in and out of the Vagrant IRC channel for a few weeks, asking for help and offering ideas here and there, and even contributed a few times. After a few weeks, he private messaged me. I don&amp;#8217;t remember the exact words he used, but it was something along the lines of &amp;#8220;How would you feel if Engine Yard sponsored Vagrant?&amp;#8221; I vividly remember shaking with excitement at this point, despite the uncertainty. &lt;a href="http://www.engineyard.com/"&gt;Engine Yard&lt;/a&gt; had long been known for being huge supporters of open source in the Ruby community, and backed important projects such as &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, &lt;a href="http://jruby.org"&gt;JRuby&lt;/a&gt;, &lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt;, and a few more. I saw this potential sponsorship opportunity as huge idea validation as well as an outlet to better spread the word about Vagrant.&lt;/p&gt;

&lt;p&gt;On October 14, 2010, Engine Yard &lt;a href="http://www.engineyard.com/blog/2010/mitchell-hashimoto-joins-engine-yard-oss-community-grant-program/"&gt;announced that I had joined their OSS grant program&lt;/a&gt;. The specifics of the deal are private, but the basic idea is that they would help me in any way possible, as long as it was reasonable. This was a really exciting day because it was the first time with Vagrant that I could say &amp;#8220;Mom and Dad, look! See! I told you I&amp;#8217;m not just playing on my computer.&amp;#8221; At this point I was still in college, as well, just to put things in perspective.&lt;/p&gt;

&lt;p&gt;The Engine Yard sponsorship changed everything. Just having Engine Yard supporting me spurred a huge interest in Vagrant, and blasted Vagrant into &amp;#8220;small-time popularity:&amp;#8221;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://img.skitch.com/20120217-mk6g24kicnn6jj1xey8c3iqxad.png"&gt;&lt;img src="https://img.skitch.com/20120217-mk6g24kicnn6jj1xey8c3iqxad.png" alt="Engine Yard Effect"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The personal horsepower I put behind Vagrant went up to over 9000 at this point. Since I was still in college, I was spending 8 or more hours per day on Vagrant. At the same time, I was sending speaking proposals &lt;em&gt;everywhere&lt;/em&gt; I could to educate people about Vagrant and try to gain some more interest in the project. I spoke at a handful of conferences, pushed many releases, and by March, 2011, the average page views per day on vagrantup.com had gone from around 200 to over 500. Success!&lt;/p&gt;

&lt;p&gt;Unfortunately, this success came at a price: burnout. By March, although I refused to admit it for many more months to come, I was completely and utterly burnt out. This is clear to see from the release dates of various Vagrant versions: It took 6 months to release Vagrant 0.7.0 from Vagrant 0.6.0 (although there were various bug fix releases between). This was the lowest point in my personal involvement with the project. During these times, I would let bugs pile up to around 20 or 30 before triaging them all in one go. I&amp;#8217;m not proud of this, but it was an important part of the history of Vagrant.&lt;/p&gt;

&lt;p&gt;While I was burnt out and busy feeling sorry for myself, Vagrant only grew more and more popular. A great community built around Vagrant, a healthy set of plugins, and I gained a small fan club. It is the community that brought me back. I simply started getting more and more tweets, emails, etc. telling me how Vagrant had changed people&amp;#8217;s lives, how they couldn&amp;#8217;t imagine working before Vagrant, etc. I was flattered, and the praise was highly motivational. By the fall of 2011, I was working on Vagrant again, though not as much since I was out of college at that point and had a &lt;a href="http://kiip.me"&gt;full time job&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In October, 2011, I travelled halfway around the world to Sweden for &lt;a href="http://devopsdays.org/events/2011-goteborg/"&gt;DevOpsDays&lt;/a&gt;, where I &lt;a href="https://vimeo.com/31367609"&gt;gave a talk on DevOps&lt;/a&gt;. It was here that something &lt;strong&gt;big&lt;/strong&gt; happened: About 15 seconds into the talk, I introduced myself as the creator of Vagrant, in case anyone would recognize me that way. I thought maybe a handful would care, but instead the entire room, filled with around 200 people, erupted in applause, which you can hear in the video. This single act of kindness, again by the community, showed me just how much people cared about what I was doing, and motivated me even further. I consider this an extremely important moment in Vagrant history, and would be the first of many amazing events I&amp;#8217;d witness in the following months.&lt;/p&gt;

&lt;p&gt;Vagrant has been a full time job for the past 2 years. I work 8 hours at work &lt;em&gt;not&lt;/em&gt; on Vagrant, and then spend at least 4 hours at home working on Vagrant, and typically also work on it on the weekends. I&amp;#8217;m incredibly proud to finally ship a 1.0, and I&amp;#8217;m proud of what the project has taught me and the community that has grown around it. I hope my story shows how much work, luck, and passion has gone into Vagrant. If I could go back in time, I wouldn&amp;#8217;t change a thing, since as they say, &amp;#8220;it&amp;#8217;s all about the journey!&amp;#8221;&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m looking forward to see where this journey continues to take me.&lt;/p&gt;

&lt;p&gt;And finally, last but not least, &lt;strong&gt;thank you so, so much&lt;/strong&gt; to the Vagrant community and early supporters. Patrick Debois, Christian Trabold, Kieran Pilkington, and so, so many more: You make it a joy for me to work on Vagrant every day. Open source is all about the community. And, of course, thank you to Engine Yard for all their support, which continues to be critical in educating the world about Vagrant.&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/18870472135</link><guid>http://mitchellhashimoto.com/post/18870472135</guid><pubDate>Tue, 06 Mar 2012 15:46:00 -0800</pubDate><category>vagrant</category><category>open source</category></item><item><title>"New" Purely Functional Data Structures</title><description>&lt;a href="http://cstheory.stackexchange.com/questions/1539/whats-new-in-purely-functional-data-structures-since-okasaki/1550"&gt;"New" Purely Functional Data Structures&lt;/a&gt;: &lt;p&gt;This StackOverflow post covers “new” purely functional data structures created since &lt;a href="http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504"&gt;Okasaki’s book “Purely Functional Data Structures”&lt;/a&gt; published in 1998.&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/8871026043</link><guid>http://mitchellhashimoto.com/post/8871026043</guid><pubDate>Sat, 13 Aug 2011 10:38:28 -0700</pubDate></item><item><title>"The Essence of Functional Programming" Part 1: The Identity Monad</title><description>&lt;p&gt;This is the first of a new series of posts that will take papers that I read and will explain them and attempt to make them more concrete (and less theoretical) by showing real world examples using more industry-standard languages. These papers will be tagged with &lt;a href="http://mitchellhashimoto.com/tagged/theory-in-practice"&gt;theory-in-practice&lt;/a&gt;. For more information on the &amp;#8220;Theory in Practice&amp;#8221; series, read the &lt;a href="http://mitchellhashimoto.com/post/7080543745/theory-in-practice"&gt;introductory post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Today&amp;#8217;s paper is &lt;a href="http://homepages.inf.ed.ac.uk/wadler/topics/monads.html#essence"&gt;&amp;#8220;The essence of functional programming&amp;#8221;&lt;/a&gt; by Philip Wadler. This paper is widely known as the paper which popularized monads, and introduces them in a relatively elementary context with a focus on practical programming use.&lt;/p&gt;

&lt;p&gt;This is part 1 of a multi-part series. In order to allow the information to soak in and to not consume too much of your time, I&amp;#8217;ve decided to split this into multiple parts which I will publish over the coming weeks. These will all be tagged with &lt;a href="http://mitchellhashimoto.com/tagged/essence-of-functional-programming"&gt;essence-of-functional-programming&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Part 1 will cover the inspiration for monads as well as introduce the trivial monad.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prior knowledge required:&lt;/strong&gt; Basic programming experience with basic experience in functional programming (in any language, whether it be Ruby, Python, C, etc.). The examples will be given in Haskell and Scala.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h1&gt;Inspiration: Purity vs. Impurity&lt;/h1&gt;

&lt;p&gt;The inspiration for monads comes from the desire to program in a purely functional environment, but to ease program modification in cases where it appears impure languages have the upper hand.&lt;/p&gt;

&lt;h3&gt;What is &amp;#8220;purity?&amp;#8221; What is &amp;#8220;impurity?&amp;#8221;&lt;/h3&gt;

&lt;p&gt;While a conceptual &amp;#8220;pure vs. impure&amp;#8221; discussion is out of the scope of this post and the definition of purity was not covered in the paper, I&amp;#8217;ll quickly define the terms. A function is &lt;strong&gt;pure&lt;/strong&gt; if it generates it&amp;#8217;s result using nothing but the parameters given to it, whereas a function is &lt;strong&gt;impure&lt;/strong&gt; if it uses or modifies some outside state. A quick example of a pure function:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
def add(x: Int, y: Int) = x + y
&lt;/pre&gt;

&lt;p&gt;And that same function becoming impure, since we&amp;#8217;re modifying global state by outputting text to the world:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
def add(x: Int, y: Int) = {
  println("Adding!")
  x + y
}
&lt;/pre&gt;

&lt;p&gt;Additionally, the benefits of purity are:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Increased modularity&lt;/strong&gt; - A pure function can be used anywhere and it will be have the same way. Therefore pure functions are ideal for libraries among programs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Concurrency safe&lt;/strong&gt; - Since a pure function modifies no outside state, it can be easily (theoretically) parallelized. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simplified testing&lt;/strong&gt; - Once you test all input conditions and edge cases, you can be certain the function behaves correctly.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Of course, there are also benefits to impurity:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;strong&gt;State&lt;/strong&gt; - Its very easy to maintain state in impure situations, since you just add a global variable to the mix, and every function can use it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quick edits&lt;/strong&gt; - You can just throw in a &lt;code&gt;println&lt;/code&gt; wherever you see fit to assist in debugging.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;A pure pain point&lt;/h3&gt;

&lt;p&gt;As an example for comparing purity vs impurity, let&amp;#8217;s use a basic interpreter which takes as input a program, evaluates it, and returns the result. This is surely a simple venture in both pure and impure settings.&lt;/p&gt;

&lt;p&gt;Now, what if we wanted to add error handling to this interpreter? With impurity, we could simply throw exceptions with the error message. But in a pure environment, we would have to modify the result type to also include errors at each recursive point, and each function would have to check for errors prior to running. Holy smokes batman, that&amp;#8217;s annoying.&lt;/p&gt;

&lt;p&gt;Okay, what about adding an execution count? With impurity, all that needs to be done is to add a global variable that is incremented with each operation. Again, though, for a pure language, we would have to modify the result type to include execution count everywhere.&lt;/p&gt;

&lt;p&gt;Based on these examples, it looks like impurity wins completely! But, there is another option: &lt;em&gt;Monads&lt;/em&gt;. Wadler argues that monads can be used to structure an interpreter so that the above changes can be made just as easily as with an impure language, while maintaining the purity of the computations.&lt;/p&gt;

&lt;h1&gt;The Monad&lt;/h1&gt;

&lt;p&gt;A monad consists of three parts. In Haskell, it is defined like so:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
class Monad m where
  unitM :: a -&amp;gt; m a
  bindM :: m a -&amp;gt; (a -&amp;gt; m b) -&amp;gt; m b
&lt;/pre&gt;

&lt;p&gt;The rough equivalent in Scala would be the following:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
trait Monad[M[_]] {
  def unitM[A](a: A): M[A]
  def bindM[A, B](a: M[A], f: A =&amp;gt; M[B]): M[B]
}
&lt;/pre&gt;

&lt;p&gt;As you can see:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;strong&gt;M&lt;/strong&gt; is a type constructor. That is, its not a complete type on its own, because it requires another type to complete it. An example, &lt;code&gt;List&lt;/code&gt; in Scala is not a type, but &lt;code&gt;List[Int]&lt;/code&gt; is. Therefore, &lt;code&gt;List&lt;/code&gt; is a kind of type constructor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;unitM&lt;/strong&gt; is a function which takes a value and &amp;#8220;lifts&amp;#8221; it into the monad. So if you had a just an int, such as &lt;code&gt;7&lt;/code&gt;, and your monad was a list of ints, then &lt;code&gt;unitM&lt;/code&gt; would make it a list &lt;code&gt;[7]&lt;/code&gt;. In fact, although we won&amp;#8217;t talk about it in this post, &lt;code&gt;List&lt;/code&gt; is a monad!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bindM&lt;/strong&gt;  is a function which allows computations to be done on the value held by the monad. Building on the list example, if you wanted to double each item in the list, you could do &lt;code&gt;bindM([7], (x: Int =&amp;gt; x + x))&lt;/code&gt; and this would return &lt;code&gt;[14]&lt;/code&gt;. Notice the computation was done on the items inside, but the result was still contained in the monad type, which was &lt;code&gt;List&lt;/code&gt; for our short examples here.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So, &lt;code&gt;unitM&lt;/code&gt; can be thought of as bringing a value &lt;em&gt;into&lt;/em&gt; a monad and &lt;code&gt;bindM&lt;/code&gt; can be thought of taking that value, doing some computation, and putting it back into a monad. The question remains: how do I get a value out of a monad? This operation is typically specific to each monad, so it is not generalized. You&amp;#8217;ll see examples later.&lt;/p&gt;

&lt;p&gt;Okay, I realize this was &lt;em&gt;really&lt;/em&gt; abstract. The main takeaway from this section is that a Monad is nothing more than the three parts above. Don&amp;#8217;t worry about understanding the &amp;#8220;why?&amp;#8221; of monads yet, concrete examples are on the way!&lt;/p&gt;

&lt;h2&gt;A basic interpreter&lt;/h2&gt;

&lt;p&gt;Our concrete example is going to be a basic interpreter. The interpreter was originally written in Haskell in Wadler&amp;#8217;s paper. I&amp;#8217;ve converted this to Scala. Both sources are &lt;a href="https://gist.github.com/1079807"&gt;available in this gist&lt;/a&gt;. Please read the interpreter over until you understand what it should do. You don&amp;#8217;t need to understand the monadic parts, of course, but you should be able to get the gist of what it does. As an example, take the following input into the interpreter:&lt;/p&gt;

&lt;pre class="prettyprint lang-scala"&gt;
term = App(Lam("x", Add(Var("x"), Var("x"))), 
           Add(Con(10), Con(11)))
&lt;/pre&gt;

&lt;p&gt;The above is roughly equivalent to the following Scala code:&lt;/p&gt;

&lt;pre class="prettyprint lang-scala"&gt;
term = ((x: Int) =&amp;gt; x + x)(10 + 11)
&lt;/pre&gt;

&lt;p&gt;With that input, running the interpreter should yield &lt;code&gt;42&lt;/code&gt;, since it adds 10 and 11, to make 21, and that is passed as the parameter into the lambda function, which doubles it to 42.&lt;/p&gt;

&lt;p&gt;We will take the above interpreter, extend it in various ways using monads, and compare this approach to what would be necessary in an impure language.&lt;/p&gt;

&lt;h3&gt;Variation zero: Standard Interpreter with the Identity Monad&lt;/h3&gt;

&lt;p&gt;To begin, let&amp;#8217;s create the trivial monad. This monad doesn&amp;#8217;t actually &lt;em&gt;do&lt;/em&gt; anything, it just wraps the value, but its a gentle introduction to monads and their operations:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
case class Id[+A](val value: A)

object IdOps extends Monad[Id] {
  def unitM[A](a: A) = Id(a)
  def bindM[A,B](a: Id[A], f: A =&amp;gt; Id[B]) = f(a.value)
  def showM[A](a: Id[A]) = a.value.toString
}
&lt;/pre&gt;

&lt;p&gt;This monad is called the &amp;#8220;identity monad.&amp;#8221; It is called this because it doesn&amp;#8217;t serve any real purpose except to wrap a value. While it may not be necessary, I will explain each operation for the purpose of being explicit about each monad operation:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;The type constructor &lt;strong&gt;M&lt;/strong&gt; in this case is &lt;strong&gt;Id&lt;/strong&gt;. As you can see, this matches the above definition of a monad by taking a single value of some type.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;unitM&lt;/strong&gt; takes a value and wraps it in &lt;code&gt;Id&lt;/code&gt;. This brings the value into the monad, just as was described earlier.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bindM&lt;/strong&gt; allows computations to be done on the value of the monad. In this case, the function is applied directly to the value. Since this is the identity monad, there is nothing sneaky going on here, just simple function application. If we had an &lt;code&gt;Id(7)&lt;/code&gt; and did &lt;code&gt;bindM(Id(7), (x: Int =&amp;gt; unitM(x * 2)))&lt;/code&gt; then the result would be &lt;code&gt;Id(14)&lt;/code&gt;. Note the symmetry between this and the example given earlier when defining monads.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For the purpose of our interpreter, we&amp;#8217;ve also introduced a &lt;strong&gt;showM&lt;/strong&gt; function. This is not a standard monad function in general, but we&amp;#8217;re requiring all monads implement this so that we have a way to get the value out of the monad as a string.&lt;/p&gt;

&lt;p&gt;Despite its practical uselessness, the identity monad serves a practical purpose for this post since it demonstrates the simplest monad. The result of using this monad with our example is that it constructs a basic, working, interpreter.&lt;/p&gt;

&lt;h2&gt;Testing the Monad&lt;/h2&gt;

&lt;p&gt;In order to test the monads we&amp;#8217;ll be using during this series, I&amp;#8217;ve constructed the interpreter example in such a way that you simply have to subclass the &lt;code&gt;Interpreter&lt;/code&gt; trait and point it to our latest monad to see the changes. Add the identity monad and create the interpreter:&lt;/p&gt;

&lt;pre class="prettyprint lang-scala"&gt;
class StandardInterp extends Interpreter {
  type M[A] = Id[A]
  override val monadOps = IdOps
}
&lt;/pre&gt;

&lt;p&gt;Then create a basic test program and run it:&lt;/p&gt;

&lt;pre class="prettyprint lang-scala"&gt;
val current = new StandardInterp()
import current._

val term: Term = App(Lam("x", Add(Var("x"), Var("x"))),
                     Add(Con(10), Con(11)))

println(current.test(term))
&lt;/pre&gt;

&lt;p&gt;The result should be &amp;#8220;42.&amp;#8221;&lt;/p&gt;

&lt;p&gt;This is what we expected, since our monad does nothing in this case except introduces us to the basic operations and usage of it. It should be clear to see that in the future we&amp;#8217;ll add considerably more logic to the monad, and the interpreter will quite simply be augmented with additional functionality without at all compromising the purity of it&amp;#8217;s functions.&lt;/p&gt;

&lt;p&gt;Look for part 2 in the coming days!&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/7564789784</link><guid>http://mitchellhashimoto.com/post/7564789784</guid><pubDate>Tue, 12 Jul 2011 23:06:00 -0700</pubDate><category>functional-programming</category><category>haskell</category><category>monad</category><category>paper</category><category>scala</category><category>theory-in-practice</category><category>essence-of-functional-programming</category></item><item><title>Theory in Practice</title><description>&lt;p&gt;I&amp;#8217;m starting a series of blog posts, published weekly, called &amp;#8220;Theory in Practice.&amp;#8221; These will take papers I read from the world of academia and attempt to reiterate them in simpler, more practical terms. One way I will do this is to take the examples, often in &lt;a href="http://www.haskell.org/haskellwiki/Haskell"&gt;Haskell&lt;/a&gt;, and rewrite them in a more practical language, such as &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. I&amp;#8217;ll also add more real world applications, if needed.&lt;/p&gt;

&lt;p&gt;Since my interests are currently in the world of programming languages and functional programming, I will start this series with a set of foundational papers in this subject area.&lt;/p&gt;

&lt;p&gt;My goal with this series is to open the world of academic papers to a more general audience, as I&amp;#8217;ve found that reading these papers has helped me in my day-to-day work greatly, and I hope that my blog posts will have a similar effect on others.&lt;/p&gt;

&lt;p&gt;The first part the series will be on &lt;a href="http://homepages.inf.ed.ac.uk/wadler/topics/monads.html#essence"&gt;&amp;#8220;The essence of functional programming&amp;#8221;&lt;/a&gt; by Philip Wadler, and will be published this week.&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/7080543745</link><guid>http://mitchellhashimoto.com/post/7080543745</guid><pubDate>Thu, 30 Jun 2011 06:23:23 -0700</pubDate><category>theory-in-practice</category></item><item><title>Welcome to Ruby. We Have Many Rubies.</title><description>&lt;p&gt;Although I consider myself (and I&amp;#8217;m proud to be) a polyglot, most of my open source code is Ruby. I&amp;#8217;ve been a Rubyist for almost 5 years now and it is still my language of choice for starting projects. Professionally, I&amp;#8217;ve begun to use Python in the work-place, and in the process of learning Python I&amp;#8217;ve had a hard time understanding the various Python implementations. Additionally, I know friends coming to Ruby who have trouble understanding the reasoning behind all the different Ruby implementations.&lt;/p&gt;

&lt;p&gt;As such, I&amp;#8217;m going to give a brief overview of the major Rubies available, their purpose, their development status, and my opinion of them. I&amp;#8217;ll cover &lt;strong&gt;Matz&amp;#8217;s Ruby (MRI or CRuby)&lt;/strong&gt;, &lt;strong&gt;Ruby Enterprise Edition (REE)&lt;/strong&gt;, &lt;strong&gt;JRuby&lt;/strong&gt;, &lt;strong&gt;Rubinius (rbx)&lt;/strong&gt;, &lt;strong&gt;MacRuby&lt;/strong&gt;, &lt;strong&gt;IronRuby&lt;/strong&gt;, and &lt;strong&gt;MagLev&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The world of Rubies is unlike other languages, such as Python, where I would guess 95%+ use CPython exclusively. It is not uncommon for a single Ruby developer to use Rubinius at home, JRuby for production deployment, and MacRuby for desktop development.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2&gt;Matz&amp;#8217;s Ruby Interpreter&lt;/h2&gt;

&lt;p&gt;Matz&amp;#8217;s Ruby interpreter, or more commonly called MRI, is the original Ruby interpreter. This is the one you get by default from the official &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby website&lt;/a&gt; or the one you probably get if you install Ruby via your package manager.&lt;/p&gt;

&lt;p&gt;MRI is also where all the new Ruby features land first, and as such is currently the place where Ruby moves forward. Other implementations strive to reach compatibility with all Ruby that works with MRI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical detail:&lt;/strong&gt; You may see some people reference &amp;#8220;YARV.&amp;#8221; YARV is the Ruby VM powering Ruby 1.9, and stands for &amp;#8220;Yet Another Ruby VM.&amp;#8221; YARV technically replaced MRI (which powered 1.8), although Ruby 1.9 is still known as MRI.&lt;/p&gt;

&lt;p&gt;My opinion: MRI is still the most mainstream Ruby. It is maintained by the Ruby-dev team and when someone is a &amp;#8220;Ruby programmer&amp;#8221; they&amp;#8217;re usually referring to this Ruby. I personally still run this Ruby as my default at home.&lt;/p&gt;

&lt;h2&gt;Ruby Enterprise Edition&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.rubyenterpriseedition.com/"&gt;Ruby Enterprise Edition&lt;/a&gt; (or REE for short) is a fork of MRI (Ruby 1.8) which adds some optimizations which make running Ruby in production more performant. Some of the optimizations it adds:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Copy-on-write friendly garbage collector, which makes forking much less expensive.&lt;/li&gt;
&lt;li&gt;Improved memory allocator&lt;/li&gt;
&lt;li&gt;Tunable GC settings, important for servers!&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;My opinion: I don&amp;#8217;t have a lot of experience with REE. Many people, such as &lt;a href="http://twitter.com"&gt;Twitter&lt;/a&gt;, use it in production with great success. I&amp;#8217;ve heard nothing but good things about it, but prefer JRuby for deployment myself.&lt;/p&gt;

&lt;h2&gt;JRuby&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://jruby.org"&gt;JRuby&lt;/a&gt; is a complete Ruby implementation written in Java on top of the JVM, which provides complete interaction with Java libraries.&lt;/p&gt;

&lt;p&gt;For those new to the concept of additional languages on top of the JVM, this may seem like a huge &amp;#8220;why?&amp;#8221; The JVM is mature, battle-tested, and exceptionally performant. The Java ecosystem is filled with every library imaginable and is the de facto enterprise language. By putting Ruby on top of the JVM you gain numerous benefits:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Portability and speed of the JVM&lt;/li&gt;
&lt;li&gt;Every Java library becomes a Ruby library&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;My opinion: JRuby is amazing. It can even compile most MRI C extensions (think about that for a moment). Also, I&amp;#8217;ve found deploying web applications as &lt;code&gt;war&lt;/code&gt; files the easiest method for deployment available. JRuby also beats MRI in many benchmarks. Its fast!&lt;/p&gt;

&lt;h2&gt;Rubinius&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://rubini.us/"&gt;Rubinius&lt;/a&gt; is a new virtual machine build from the ground up for Ruby. It is written in C++ and can &lt;a href="http://en.wikipedia.org/wiki/Just-in-time_compilation"&gt;JIT&lt;/a&gt; Ruby code to LLVM bytecode. Rubinius can execute Ruby &lt;em&gt;fast&lt;/em&gt;, far faster than MRI. The performance hits to Rubinius come from C extensions, which are slower than MRI.&lt;/p&gt;

&lt;p&gt;Brian Ford, one of the developers behind Rubinius, posted a good &lt;a href="http://rubini.us/2011/02/25/why-use-rubinius/"&gt;Why Use Rubinius?&lt;/a&gt; article that is worth reading.&lt;/p&gt;

&lt;p&gt;My opinion: Rubinius is clearly the future of Ruby VMs. The C++ implementation is beautiful and extensible, whereas the MRI code base is a mess of spaghetti C. Rubinius is extremely performant, and there are a lot of forward-thinking ideas within the VM itself. Rubinius runs most Ruby code, but still hasn&amp;#8217;t replaced MRI for me as my default Ruby for edge-case reasons. I recommend giving Rubinius a shot if you havent.&lt;/p&gt;

&lt;h2&gt;MacRuby&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.macruby.org/"&gt;MacRuby&lt;/a&gt; is a fork of Ruby 1.9 made by Apple, Inc. MacRuby compiles to LLVM bytecode and can interface with all of Cocoa. MacRuby can even do things like &lt;a href="http://www.macruby.org/documentation/gcd.html"&gt;Grand Central Dispatch&lt;/a&gt; elegantly.&lt;/p&gt;

&lt;p&gt;The point of MacRuby is to allow building Mac applications with a Ruby that is deeply integrated with Mac, such that performance doesn&amp;#8217;t suffer and resulting applications are truly native.&lt;/p&gt;

&lt;p&gt;Cool use case: &lt;a href="http://twitter.com"&gt;Twitter&lt;/a&gt; uses MacRuby to unit test much of their Cocoa libraries that their iOS and Mac native clients use. This makes sense thanks to Ruby&amp;#8217;s beautiful test libraries.&lt;/p&gt;

&lt;p&gt;My opinion: If you&amp;#8217;re making a Mac app, you should really use MacRuby. You can punt the super high-performance stuff to Objective-C and have MacRuby interface with it. Its a no-brainer if you&amp;#8217;re a Ruby developer looking to make a Mac app.&lt;/p&gt;

&lt;h2&gt;IronRuby&lt;/h2&gt;

&lt;p&gt;This is here for completions sake. IronRuby is Ruby on top of the .NET runtime. This is exactly analogous to JRuby and the JVM.&lt;/p&gt;

&lt;h2&gt;MagLev&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://ruby.gemstone.com/"&gt;MagLev&lt;/a&gt; is built by &lt;a href="http://gemstone.com/"&gt;GemStone&lt;/a&gt; and it is Ruby on top of a smalltalk virtual machine. It has a JIT as well as an impressive built-in persistence system across multiple VMs.&lt;/p&gt;

&lt;p&gt;My opinion: I&amp;#8217;m not aware of any people using MagLev in production personally, but its certainly worth watching.&lt;/p&gt;

&lt;h2&gt;Playing with Rubies&lt;/h2&gt;

&lt;p&gt;Want to play with other Rubies easily? Just use the &lt;a href="http://rvm.beginrescueend.com/"&gt;Ruby Version Manager&lt;/a&gt; (or &lt;code&gt;rvm&lt;/code&gt; for short) which makes it dead simple to install multiple Ruby versions and implementations side by side.&lt;/p&gt;

&lt;p&gt;Now, can someone make one of these posts for Python? Thanks!&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/3849626712</link><guid>http://mitchellhashimoto.com/post/3849626712</guid><pubDate>Sun, 13 Mar 2011 22:13:00 -0700</pubDate><category>ruby,</category><category>rubinius,</category><category>jruby</category><category>ironruby</category><category>maglev</category></item><item><title>CloudFormation: The Big Picture</title><description>&lt;p&gt;Amazon announced &lt;a href="http://aws.amazon.com/cloudformation/"&gt;CloudFormation&lt;/a&gt; to the public yesterday, and while the general opinion I could glean from various sources shows that people are excited about this new technology, many are still unsure what it is and how it fits into their current cloud workflow. I feel as though I have a firm grasp on CloudFormation and will attempt to answer some questions here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I&amp;#8217;m definitely not a representative of Amazon in any way, and anything here is simply my educated opinion on the matter.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2&gt;What is it?&lt;/h2&gt;

&lt;p&gt;CloudFormation is best described as an &lt;em&gt;infrastructure provisioning tool&lt;/em&gt; based on a declarative language (expressed in JSON, in this case). CloudFormation takes the declarative file (a &amp;#8220;template&amp;#8221;) and uses it to orchestrate the creation of various cloud services and hook them up together (resulting in a &amp;#8220;stack&amp;#8221;).&lt;/p&gt;

&lt;p&gt;The difference between this and Chef or Puppet, is that Chef and Puppet are &lt;em&gt;configuration management tools&lt;/em&gt; and work best with installing and configuring software on new nodes. Some people have used configuration management for launching virtual machines and servers and so on, but this is an exception, and not the norm.&lt;/p&gt;

&lt;p&gt;Chef and Puppet are complementary tools to CloudFormation. CloudFormation starts the server orchestration act and configuration management tools complete it.&lt;/p&gt;

&lt;h2&gt;Where does it fit in my current workflow?&lt;/h2&gt;

&lt;p&gt;It doesn&amp;#8217;t, &lt;em&gt;yet&lt;/em&gt;. CloudFormation is really great at describing the infrastructure of a single application, service, or cluster, and bringing up the entire infrastructure as one atomic operation. However, CloudFormation doesn&amp;#8217;t yet provide any way to incrementally improve and re-provision infrastructure, which is most of the battle when doing any Ops work. There are some &lt;a href="https://forums.aws.amazon.com/thread.jspa?threadID=61219&amp;amp;tstart=0"&gt;hints from Amazon&lt;/a&gt; that they are thinking about this for the future.&lt;/p&gt;

&lt;p&gt;However, if you&amp;#8217;re looking to bring up a new service or application, CloudFormation is far superior to writing manual launch scripts. This is very nice.&lt;/p&gt;

&lt;h2&gt;So, does CloudFormation matter at all?&lt;/h2&gt;

&lt;p&gt;Yes! Infrastructure provisioning is a space which is currently lacking a mainstream tool. CloudFormation is a good step in that direction, and therefore everyone should learn about it, but it is not the end-all-be-all. Certainly if you use AWS exclusively you should pay close attention, since I&amp;#8217;m sure its innovation in the future will be important and useful.&lt;/p&gt;

&lt;p&gt;However, we need an &lt;strong&gt;open source, cloud-agnostic solution&lt;/strong&gt; to this problem. Libraries such as &lt;a href="https://github.com/geemus/fog"&gt;Fog&lt;/a&gt;, &lt;a href="http://boto.cloudhackers.com/"&gt;Boto&lt;/a&gt;, &lt;a href="http://incubator.apache.org/libcloud/"&gt;libcloud&lt;/a&gt;, etc. are not the answer. These libraries are just that&amp;#8230; libraries to cloud APIs.&lt;/p&gt;

&lt;p&gt;Ideally, we would have a declarative language to define infrastructure (incrementally, as well), and tools to consume this language and use the various libraries noted previously to spin up cloud infrastructure, perhaps even across different cloud providers.&lt;/p&gt;

&lt;p&gt;CloudFormation is a brilliant move by AWS and is a technology worth watching, but at this stage its uses are limited, and it leaves space open for an open source alternative, which I hope will come about.&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/3526628232</link><guid>http://mitchellhashimoto.com/post/3526628232</guid><pubDate>Sat, 26 Feb 2011 10:09:00 -0800</pubDate><category>aws</category><category>cloudformation</category><category>ops</category></item><item><title>Flexible Local AWS Credentials Management</title><description>&lt;p&gt;The &lt;a href="http://aws.amazon.com/"&gt;Amazon Web Services&lt;/a&gt;(AWS) command line tools require certain environmental variables to be set up, such as &lt;code&gt;EC2_HOME&lt;/code&gt; for EC2 and &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and so on. Most people throw this in their &lt;code&gt;bashrc&lt;/code&gt; file and call it good, but this quickly becomes inflexible if you have to manage more and more accounts.&lt;/p&gt;

&lt;p&gt;For example, I happen to manage 4 separate AWS accounts (my personal account and 3 other projects).&lt;/p&gt;

&lt;p&gt;This post outlines how I manage my credentials in a DRY (Don&amp;#8217;t-Repeat-Yourself) and flexible way, such that I could easily add more credentials in the future if I needed to.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;h2&gt;Directory Structure&lt;/h2&gt;

&lt;p&gt;I maintain a very specific directory structure for my AWS related files:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/.aws
|- bashrc
|- credentials/
|-- setup/
|---- personal
|-- personal/
|- keys/
|-- personalkey.pem
|- ec2/
|- cloudformation/
|- ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;#8217;ll explain each below:&lt;/p&gt;

&lt;h4&gt;&lt;code&gt;bashrc&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;This file is the main hook that my main &lt;code&gt;bashrc&lt;/code&gt; (at &lt;code&gt;$HOME/.bashrc&lt;/code&gt;) sources. It sets up the various enabled AWS modules and also defines the function for selecting AWS credentials.&lt;/p&gt;

&lt;p&gt;The basic idea is to consolidate all the global and unchanging AWS related environmental variables into a single bash file, so that it is easy to add new services without cluttering my main &lt;code&gt;bashrc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;ll see later that the changing environmental variables (those related to authorization) live in specific credentials files which are enabled using the &lt;code&gt;aws_credentials&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;You can view this file &lt;a href="https://github.com/mitchellh/dotfiles/blob/master/aws/bashrc"&gt;in my dotfiles repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To enable it, add a line like this to your main &lt;code&gt;bashrc&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;test -f "$HOME/.aws/bashrc" &amp;amp;&amp;amp; . "$HOME/.aws/bashrc"
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;&lt;code&gt;credentials/&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;credentials&lt;/code&gt; directory is in charge of holding all files related to site-specific credentials as well as the bash scripts to setup the environmental variables. There is always a &lt;code&gt;setup/&lt;/code&gt; folder within this directory which contains the bash scripts to toggle different site keys. For example, I may have a &lt;code&gt;personal&lt;/code&gt; file in &lt;code&gt;credentials/setup/personal&lt;/code&gt; which looks like the following:&lt;/p&gt;

&lt;script src="https://gist.github.com/844112.js"&gt; &lt;/script&gt;&lt;p&gt;As you can see, it simply sets the required AWS environmental variables. Easy! But how do you enable this? Use the &lt;code&gt;aws_credentials&lt;/code&gt; function in your terminal, anywhere:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;aws_credentials personal
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will find the &lt;code&gt;credentials/setup/personal&lt;/code&gt; file and load it for your current shell.&lt;/p&gt;

&lt;p&gt;Also important to note, I store all the required files such as the certificates for API calls in a special &lt;code&gt;credentials/SITENAME&lt;/code&gt; directory (&lt;code&gt;personal&lt;/code&gt;, in this case).&lt;/p&gt;

&lt;h4&gt;&lt;code&gt;keys/&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;I store all my EC2 private keys in this directory for easy access with SSH. For example, my personal account has a &lt;code&gt;mh_key.pem&lt;/code&gt;. To SSH into one of my instances, I just do the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh -i ~/.aws/keys/mh_key.pem ubuntu@my-ec2-ip.com
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;#8217;m still looking to improve this, but it works fine for me now.&lt;/p&gt;

&lt;h4&gt;&lt;code&gt;ec2/&lt;/code&gt;, &lt;code&gt;cloudformation/&lt;/code&gt;, etc.&lt;/h4&gt;

&lt;p&gt;I extract the command line tools for the various AWS services and place them directly in the &lt;code&gt;.aws&lt;/code&gt; directory. I may pull these out further into a &lt;code&gt;services&lt;/code&gt; directory or something in the future but for now it works fine. You can see how the various services are enabled in my AWS bashrc (linked to above). Each service has its own way of being enabled, so its easiest to just do it manually for each new service.&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;My method of credentials management isn&amp;#8217;t yet perfect, but its much improved from when I started to a point where its very easy to add new services, add new credentials, change existing credentials, switch sites, etc. I plan on further improving this as time goes on, but hopefully this post is enough to get you started with managing your growing number of AWS credentials.&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/3505121069</link><guid>http://mitchellhashimoto.com/post/3505121069</guid><pubDate>Fri, 25 Feb 2011 09:23:00 -0800</pubDate><category>aws</category></item><item><title>Let's Get Back to Business</title><description>&lt;p&gt;Five years ago, and for about two years after that, I was an avid blogger. I maintained a personal blog that focused on PHP (specifically the &lt;a href="http://framework.zend.com"&gt;Zend Framework&lt;/a&gt;) and a year later I launched a successful blog on Erlang, known as &lt;a href="http://spawnlink.com"&gt;spawn_link&lt;/a&gt;. Both blogs had a readership of over 500 people, which, while not trying to brag, I was proud of.&lt;/p&gt;

&lt;p&gt;Though both blogs brought multiple serious job offers, it was my personal blog which got me my first two jobs in the tech industry (note that I was only 17 when I started blogging!). My first job was at &lt;a href="http://zend.com"&gt;Zend&lt;/a&gt; as a contractor doing screencasts for the &lt;a href="http://framework.zend.com"&gt;Zend Framework&lt;/a&gt;, and my second job, and still my current employer, was with &lt;a href="http://citrusbyte.com"&gt;Citrusbyte&lt;/a&gt;, a modern web development shop (which introduced me to the Ruby programming language).&lt;/p&gt;

&lt;p&gt;Both jobs kept me busy, &lt;em&gt;super busy&lt;/em&gt;, and the result was that I stopped blogging!&lt;/p&gt;

&lt;p&gt;The past few years I&amp;#8217;ve worked with some extremely smart people, had some unbelievable experiences, and have grown &amp;#8212; in many ways &amp;#8212; at a rapid speed. There is still so much out there I want to do and things to learn, but I think my experiences the past few years and ongoing deserve to be put down to &amp;#8220;ink&amp;#8221; for others to gain from.&lt;/p&gt;

&lt;p&gt;And that&amp;#8217;s my goal with this blog: Let&amp;#8217;s get back to business, the business of giving back for everything that I&amp;#8217;ve gained.&lt;/p&gt;</description><link>http://mitchellhashimoto.com/post/2869215320</link><guid>http://mitchellhashimoto.com/post/2869215320</guid><pubDate>Fri, 21 Jan 2011 21:53:00 -0800</pubDate></item></channel></rss>

