Categories
Uncategorized

Tucows (Re)Introduces OpenSRS

I’m always happy to point out cool things that my former employer, Tucows, is up to (from 2003 to 2007, I was their Tech Evangelist). The latest one is one I’ve long supported: pulling their reseller services under a single, well-known and trusted name, OpenSRS, and a gorgeous new brand identity:

OpenSRS\' new brand identity

OpenSRS now refers to a whole slew of services: domain name registration, SSL certificates, email and “personal names” (white label access to their portfolio of common North American and European surname domains), all of which are accessible via control panel or API.

Here’s what they have to say:

Don’t mistake this for a simple re-brand. Yes, we have a new logo, and a snazzy new website, but there’s a lot more to what we’re doing here than a fresh coat of paint and some new pictures on the wall.

Back in 1999 when Tucows first started selling domain names as one of the original ICANN accredited registrars, we wanted to bring Internet service providers something they hadn’t been accustomed to getting when it came to domain names: customer service. We launched back then with a real customer focus that extended throughout everything we did.

The logo also proudly proclaims that OpenSRS is “Reseller Friendly.” That is more than just a slogan, or a tag line – it’s a promise. Like the customer focused wholesale domain name business that launched in 1999 as OpenSRS, today we remain dedicated to providing the best possible experience for our resellers.

That means resellers can expect easily accessible customer support with knowledgeable people on the other end of the phone line. And it means products and services that are created and implemented with the specific needs of the reseller in mind. That Reseller Friendly attitude and approach extends throughout every aspect of our business.

We’re putting that Reseller Friendly promise prominently on display, right in our logo. We’re not only rebranding our wholesale Internet Services business as OpenSRS, but we’re re-dedicating ourselves to the approach that, with your help, made us so successful over the past nine years and will continue it into the future.

For more, including a video interview featuring my old boss Ken Schafer (VP Marketing and Product Management), check out this entry in the Tucows Reseller Blog.

Categories
Uncategorized

Enumerating Enumerable: Enumerable#each_cons

Enumerating Enumerable

Welcome to the ninth installment of Enumerating Enumerable, the series of articles where I attempt to do a better job at documenting Ruby’s Enumerable module than Ruby-Doc.org does.

I’m going through the Enumerable‘s methods in alphabetical order, and we’ve reached the methods that are variations on each In this article, I’m going to cover each_cons, which got introduced in Ruby 1.9.

If you missed any of the earlier articles, I’ve listed them all below:

  1. all?
  2. any?
  3. collect / map
  4. count
  5. cycle
  6. detect / find
  7. drop
  8. drop_while

Enumerable#each_cons Quick Summary

Graphic representation of the \"each_cons\" method in Ruby\'s \"Enumerable\" module

In the simplest possible terms Think of each_cons as an each that takes a number n and spits out n elements at a time.
Ruby version 1.9 only
Expects A number n describing the number of elements to be fed to the block.
Returns
  • nil if used with a block
  • An Enumerator object that outputs n-sized consecutive array slices of the collection if used without a block.
RubyDoc.org’s entry Enumerable#each+cons

Enumerable#each_cons and Arrays

When used on an array and given a block and a number n as an argument, each_cons is like an each that goes through each element in the array and outputs an n-sized array slice of the original array starting at the current element.

each_cons is one of those methods that’s really tough to describe. This is one of those cases where a demonstrating trumps describing…

justice_league = ["Aquaman", "Batman", "Black Canary", \
                  "Flash", "Green Arrow", "Green Lantern", \
                  "Martian Manhunter", "Superman", \
                  "Vixen", "Wonder Woman"]
=> justice_league = ["Aquaman", "Batman", "Black Canary", "Flash", "Green Arrow",
"Green Lantern", "Martian Manhunter", "Superman", "Vixen", "Wonder Woman"]

justice_league.each_cons(3) {|team| p team}
=> ["Aquaman", "Batman", "Black Canary"]
["Batman", "Black Canary", "Flash"]
["Black Canary", "Flash", "Green Arrow"]
["Flash", "Green Arrow", "Green Lantern"]
["Green Arrow", "Green Lantern", "Martian Manhunter"]
["Green Lantern", "Martian Manhunter", "Superman"]
["Martian Manhunter", "Superman", "Vixen"]
["Superman", "Vixen", "Wonder Woman"]
=> nil

Note that in this case, each_cons returns nil.

each_cons can also be used without providing a block. In this case, you’re using it to create an Enumerator object that you can then use to spit out array slices when you call its next method:

# Let's create an enumerator that we can use to give us three-person
# superhero teams
teams_of_3 = justice_league.each_cons(3)
=> #

# Let's get the first team of 3
teams_of_3.next
=> ["Aquaman", "Batman", "Black Canary"]

# Now the next one...
teams_of_3.next
=> ["Batman", "Black Canary", "Flash"]

teams_of_3.next
=> ["Black Canary", "Flash", "Green Arrow"]

teams_of_3.next
=> ["Flash", "Green Arrow", "Green Lantern"]

# Let's go back to the first team of 3
teams_of_3.rewind
=> #

teams_of_3.next
=> ["Aquaman", "Batman", "Black Canary"]

Enumerable#each_cons and Hashes

When used on a hash and given a block and a number n as an argument, each_cons is like an each that goes through each element in the array and outputs an n-sized array slice of the hash starting at the current element. Note that in the process, hash elements are converted into two-element arrays where the first element contains the key and the second element contains the corresponding value.

Again, examples speak louder than descriptions:

enterprise_crew = {:captain => "Picard",
                   :first_officer => "Riker",
                   :science_officer => "Data",
                   :tactical_officer => "Worf",
                   :chief_engineer => "LaForge",
                   :chief_medical_officer => "Crusher",
                   :ships_counselor => "Troi",
                   :annoying_ensign => "Crusher",
                   :attractive_ensign => "Ro",
                   :expendable_crew_member => "Smith"}
=> {:captain=>"Picard", :first_officer=>"Riker", :science_officer=>"Data", :tact
ical_officer=>"Worf", :chief_engineer=>"LaForge", :chief_medical_officer=>"Crush
er", :ships_counselor=>"Troi", :annoying_ensign=>"Crusher", :attractive_ensign=>
"Ro", :expendable_crew_member=>"Smith"}

enterprise_crew.each_cons(3) {|team| p team}
=> [[:captain, "Picard"], [:first_officer, "Riker"], [:science_officer, "Data"]]
[[:first_officer, "Riker"], [:science_officer, "Data"], [:tactical_officer, "Worf"]]
[[:science_officer, "Data"], [:tactical_officer, "Worf"], [:chief_engineer, "LaForge"]]
[[:tactical_officer, "Worf"], [:chief_engineer, "LaForge"], [:chief_medical_officer, "Crusher"]]
[[:chief_engineer, "LaForge"], [:chief_medical_officer, "Crusher"], [:ships_counselor, "Troi"]]
[[:chief_medical_officer, "Crusher"], [:ships_counselor, "Troi"], [:annoying_ensign, "Crusher"]]
[[:ships_counselor, "Troi"], [:annoying_ensign, "Crusher"], [:attractive_ensign, "Ro"]]
[[:annoying_ensign, "Crusher"], [:attractive_ensign, "Ro"], [:expendable_crew_member, "Smith"]]
=> nil

As with arrays, each_cons, when used on a hash, returns nil.

Again, as with arrays, each_cons can also be used without providing a block to create an Enumerator:

# Starfleet has decided to let the ship's computer determine
# the away teams, which are groups of 3
away_teams_of_3 = enterprise_crew.each_cons(3)
=> #

# Okay, who's the first away team?
away_teams_of_3.next
=> [[:captain, "Picard"], [:first_officer, "Riker"], [:science_officer, "Data"]]

# Let's get the next one
away_teams_of_3.next
=> [[:first_officer, "Riker"], [:science_officer, "Data"],
[:tactical_officer, "Worf"]]

away_teams_of_3.next
=> [[:science_officer, "Data"], [:tactical_officer, "Worf"],
[:chief_engineer, "LaForge"]]

# Let's go back to the first away team
away_teams_of_3.rewind
=> #

away_teams_of_3.next
=> [[:captain, "Picard"], [:first_officer, "Riker"], [:science_officer, "Data"]]

Categories
Uncategorized

Notes from Damian Conway’s Presentation

Damian Conway - July 16, 2008

Here are my notes on Damian Conway’s presentation, Temporally Quaquaversal Virtual Nanomachine Programming in Multiple Topologically Connected Quantum-Relativistic Parallel Timespaces…Made Easy, which he gave on Wednesday, July 16th at the University of Toronto’s Bahen Centre. This presentation was a dry run for the presentation he made on Tuesday at the O’Reilly Open Source Conference (OSCON) 2008. The talk ran for about two hours, and the time allotted for it at OSCON 2008 was one hour. He incorporated parts of earlier talks into this one, so I suspect that he condensed those parts.

Damian was in fine form and it was good to catch another one of his funny, off-the-wall presentations; it was a good warm-up for RubyFringe.

- I'd just celebrated my 42nd birthday was doing some reflection
- I thought maybe now it was time to get serious [yeah, right]

- The original title for this presentation was going to be something
  like "The lies we tell ourselves"
- Consider the myths that we in the F/OSS world tell ourselves:
    - Consider ESR's line, "Given enought eyeballs, all bugs are shallow"
    - Speaking from experience, that's not true.
      What *is* true is: "Given eniugh eyeballs, all *bug reports*
      are shallow"
    - Then there's the line "Fast, cheap, good: pick any two."
    - What closer to reality? "Fast, cheap, good: pick at most one."
    - The biggest lie is probably "Information wants to be free"
    - You might as well be saying
        - "Beer wants to be drunk"
        - "Virginity wants to be lost"
        - or...

Slide from Damian Conway\'s presentation: \"An iPhone data plan wants to be vastly more expensive in Canada\"

        - An iPhone data plan wants to be vastly more expensive
          in Canada

- The bad angel on my shoulder has been telling me lies: "Damian, you're not
  just an amazing hacker, you're a deep thinker as well!"
- The truth is that I'm not good at analyzing reality -- I'm good at
  *manipulating reality via language*

- That's a popular lie we tell ourselves: that "Smart is distributive"
- In other words, we think that if we do well in one area, perhaps we
  can do well in others
- Genius is a *vector*, not a *field*
- Convincing ourselves that genius is distributive is a sign of aging

[ Damian launches into funny photo essay showing his hair greying
  after joining the world of Perl programming. He then shows Larry
  Wall over the same time period, noting that he looks pretty much
  the same. He hypothesizes that Larry doesn't age, and as proof,
  shows an amusing series of Photoshopped photos of Larry through
  the ages, ending with ancient Egypt. ]
- You can derive two bits of knowledge from all this:
    - Perl 5 isn't line noise, it's *hieroglyphics*!
    - As for when Perl 6 is coming out, keep in mind that
      Larry has all the time in  the world

\"Larry Wall does not age\" slide from Damian Conway\'s presentation

- Back in 2000, I decided to introduce superpositions (the ones from
  quantum physics) into Perl.
- There's the "any" function, which is not so rigid, which is why
  I call it the "Canadian superposition"
- There's the "all" function, which is quite rigid, which is why
  I call it the "American superposition" (which will come to liberate
  you with its troops!)
- Superposition functions are constant-time operations
- You can ue them now with "use Quantum::Superpositions"
- They're part of Perl 6
- Other junction functions:
    - none
    - one

[ He goes into a discussion about relativity, light cones, quantum
  physics and the whole "Brief History of Time" ball of wax,
  a condensed version of his "Time::Space::Continuum talk.
  I now look at gravitational lensing in a different way! ]

- I'm always chasing after new mental models of programming
- While doing that, I keep this motto in mind: Progressio defectum postulat
  ("Progress requires failure")

- There's something I call Rod Logic: that's computation via levers,
  gears and cams
- Doesn't "Rod Logic" sound like a 1950's science fiction hero
  written for boys?

\"Rod Logic book covers\" slide from Damian Conway\'s presentation

- Think of Babbage's engines
- Eric Drexler has shrunk rod logic: using carbon nanotubes as
  nano-sized levers, he's made mechanical logic gates
- Can't I use rod logic for Perl?
- I created a straight line language that could charitably be described
  as "Readability suboptimal"

[ He demonstrates a language that's made of nothing but straight-line
  characters -- _, -, [, ], <, >, \, |, /. It makes Perl look like
  a storybook for first grade readers in comparison. ]

[ Discussion of positrons -- electrons with positive charge -- and
  Feynman diagrams. One of the consequences of drawing the release
  of a positron on a Feynman diagram is that they are travelling
  leftwards on the "time" axis. They are going backwards in time!

  He then showed an application that takes the idea of particles
  travelling backwards in time and applied them to variables.
  The end result? Positronic variables! ]

- use Positronic::Variables
- They come into existence at end of block, and travel backwards
  in runtime
- With a positronic variable, you can declare a variable that
  holds values you'll need later, and they'll travel back in time
  where your program "catches up" with them later
- Makes the square root finding algorithm so much easier!
- The trick is that positronic variable programs get run through
  a preprocessor that repeatedly runs through the app
- This will works only on programs with convergent algorithms
- "I will eventually develop a positronic debugger,
  and I have been using it."

- And finally, if you look at everything I talked about this evening,
  you have the title of this talk explained: "Temporally Quaquaversal
  Virtual Nanomachine Programming in Multiple Topologically Connected
  Quantum-Relativistic Parallel Timespaces…Made Easy.

===

Q & A

- Earlier at lunch with Richard Dice, I told him: "There's no crowd like
  a Toronto crowd." You're wonderful, thank you!

- What's up with Perl 6?
    - For the past few years, there have been on average hundreds
      of doc changes committed
    - This year, there are fewer than 100
    - What does it mean? That we got it right
    - And yes, Larry's implementing
    - Which means that we are in a new phase in the development
      of Perl 6: the end phase"
    - This is going to be an awesome language
    - I've been working with early releases of Perl 6, and I've noticed
      how irritating it is to go back to Perl 5

- Now let me talk about Perl 5.10
    - There are many improvements that are largely about making life easier
      and programming less annoying.
    - Consider the say function -- simple, but not having to add a newline
        and the end of print strings makes a lot of difference
    - That's the whole point -- they looked at the really basic stuff
      that we do all the time and made it simpler
    - Another example, the "//" operator, called "defined or". It
      returns the left argument if it's defined, otherwise
      it returns the returns the right argument
    - At long last, Perl has a switch statement!

- Does any of this stuff lend itself to multicore?
    - Junctions and superpositions are a natural fit for multiprocessors
    - With languages that have junctions, it should at least be possible
      to automatically farm junction operations to parallel processors

- How hard was it to write your modules based on quantum physics?
    - Easier than you think
    - What helped what that I had the quantum physics metaphor to guide me
    - The trick is to understand the metaphor,
      and implement it consistently
    - Remember: quantum mechanics is one of the most rigorously
      tested systems we've ever conceived

- Are positronic variables another way of implementing
  constraint-based programming?
    - YES!
    - In fact, this is a good time to explain why I do all this
      odd stuff, taking concepts from quantum physics and then applying
      them to Perl
    - I use odd metaphors to think up new programming paradigms
Categories
Uncategorized

Enumerating Enumerable: Enumerable#drop_while

After the wackiness of the past couple of weeks — some travel to see family, followed by a busy week of tech events including DemoCamp 18, Damian Conway’s presentation, FAILCamp and RubyFringe — I’m happy to return to Enumerating Enumerable, the article series in which I attempt to do a better job at documenting Ruby’s Enumerable module than Ruby-Doc.org does.

In this article, the eighth in the series, I’m going to cover a method introduced in Ruby 1.9: drop_while.

I’m going through the Enumerable‘s methods in alphabetical order. If you missed any of the earlier articles, I’ve listed them all below:

  1. all?
  2. any?
  3. collect / map
  4. count
  5. cycle
  6. detect / find
  7. drop

Enumerable#drop_while Quick Summary

Graphic representation of the \"drop_while\" method in Ruby\'s \"Enumerable\" module

In the simplest possible terms Given a collection and a condition, return an array made of the collection’s items, starting the first item that doesn’t meet the condition.
Ruby version 1.9 only
Expects A block containing the condition.
Returns An array made up of the remaining items, if there are any.
RubyDoc.org’s entry Enumerable#drop_while

Enumerable#drop_while and Arrays

When used on an array, drop_while returns a copy of the array created by going through the original array’s items in order, dropping elements until it encounters the an element that does not meet the condition. The resulting array is basically a copy of the original array, starting at the first element that doesn’t meet the condition in the block.

As in many cases, things become clearer with some examples:

# In Canada, and in fact in all but 2 countries in the world,
# the weather report gives temperatures in Celsius!
temperatures = [28, 25, 30, 22, 27]
=> [28, 25, 30, 22, 27]

# The block returns true for the FIRST two elements,
# and false for the third.
# So drop_while returns an array like the original,
# but starting at the third element.
temperatures.drop_while {|temperature| temperature < 30}
=> [30, 22, 27]

# The block returns false for the first element,
# so drop_while returns an array like the original,
# starting at the first element
# (in other words, a copy of the original).
temperatures.drop_while {|temperature| temperature < 28}
=> [28, 25, 30, 22, 27]

Enumerable#drop_while and Hashes

When used on a hash, drop_while effectively:

  • Creates an array based on the hash, with each element in the hash represented as a two-element array where the first element contains the key and the second element containing the corresponding value, then
  • goes through each element in the array, dropping elements until it encounters the first element that doesn’t meet the condition in the block. The resulting array is an array of two-element arrays, starting at the first element that doesn’t meet the condition in the block.

Once again, examples will make this all clear:

# We're basically taking the array from the previous example
# and dressing it up in a hash
city_temperatures = {"New York" => 28, \
                     "Toronto" => 25, \
                     "Washington" => 30, \
                     "Montreal" => 22, \
                     "Boston" => 27}
=> {"New York"=>28, "Toronto"=>25, "Washington"=>30,
"Montreal"=>22, "Boston"=>27}

# The block returns true for the FIRST two elements,
# and false for the third.
# So drop_while returns an array based on the hash,
# but starting at the third element
# (and, of course, the key-value pairs turned into
# two-element arrays).
city_temperatures.drop_while {|city_temperature| city_temperature[1] < 30}
=> [["Washington", 30], ["Montreal", 22], ["Boston", 27]]

# This is a more readable version of the line above
city_temperatures.drop_while {|city, temperature| temperature < 30}
=> [["Washington", 30], ["Montreal", 22], ["Boston", 27]]

# The block returns false for the first element,
# so drop_while returns an array based on the hash,
# starting at the first element
# (in other words, an array based on the original hash,
# with key-value pairs turned into two-element arrays).
city_temperatures.drop_while {|city,temperature| temperature < 28}
=> [["New York", 28], ["Toronto", 25], ["Washington", 30],
["Montreal", 22], ["Boston", 27]]

Enumerable#drop_while’s Evil Twin, Enumerable#take_while

I’ll cover take_while in detail in a later installment, but for now, an example should suffice:

city_temperatures.drop_while {|city_temperature| city_temperature[1] < 30}
=> [["Washington", 30], ["Montreal", 22], ["Boston", 27]]

city_temperatures.take_while {|city_temperature| city_temperature[1] < 30}
=> [["New York", 28], ["Toronto", 25]]

Categories
Uncategorized

Pardon Our Appearance

\"Technical diffculties - Please stand by\" title card from The Simpsons

I’ve had to make some quick changes to the appearance while I investigate how someone managed to hack my blog to include a giant list of invisible porn spam links (apparently, “Fart Porn” really exists and isn’t just something that South Park made up). It was spam-a-riffic enough to make Google send me an email that could be summarized as “Fix this or we’re de-listing you!”

I’d like to spend a special “thank you” to Thomas Hurst, who pointed out that Global Nerdy had been hacked.

Categories
Uncategorized

I Have an Advance Copy of Neal Stephenson’s “Anathem”!

I Have an Advance Copy of Neal Stephenson’s “Anathem”! It just arrived at the office, and I’ve written about it here.

Categories
Uncategorized

RubyFringe: Day 2 Notes, Part 3


Photo by Carsten.
Click the photo to see it on its Flickr page.

Pete Forde Break

- When the idea for this first started, it was much simpler:
  "Let's throw a merb conference, it would be awesome!"
- We love you people a lot
- This has exceeded our expectations
- Meghann: I see her every morning when I arrive, and she works late
- Rubyfringe has become like a monolith in space for us
- Meghann did all the heavy lifting
- [standing ovation for Meghann]
- Rubyfringe next year? In Portland, next year, it's going to be awesome!
- But seriously, maybe we'll have one again next year. We'll have to think
  about it.

Ruby.rewrite(Ruby) (Reginald Braithwaite)


Photo by Libin Pan.
Click the photo to see it on its Flickr page.

- I'm happy to be here with the smart people and good people
- Being interested in the same things that smart people are interested in
  is not the same thing as being smart
- I had no idea what Pete was thinking when he came up with the
  "RubyFringe" concept -- did he mean the fringe of the Ruby
  community, or did he mean the fringe of the Ruby language
- The conference seems to be a nice mix of both

- andand
    - Groovy has an andand built in; it's called the Elvis operator
    - The Haskell people said "Reg is just inventing the maybe
      monad in Haskell"

    [shows code]

    - There has to be a better way
    - If returning nil -- method_missing
    - "Yes, I know because I heard the guy who wrote it says it sucks"
    - I'm using it because I'm hardcore

    - Problem: we've opened up the Object class
    - andand is really slow
        - This is not a performance bug
    - A Haskeller will tell you that the problem is solved
        - Haskell has lazy evaluation
        - Haskell never bother evaluating stuff that will always be nil
        - Ruby isn't "turtles all the way down" -- it doesn't give
          you all the tools it has for itself

    - @logger.debug is expensive
    - Make it a block!
    - Or do if defined?

    - This is going to sound smarmy -- you know, the way it sounds smarmy when
      people say "I don't know how to do this" or play dumb to seem more "real",
      but I swear this is true: I'm not good with IDEs
    - I think that when IDEs give you some kind of wizard or other feature
      to simplify some aspect of programming, it's a sign of a defect in the
      language you're using

    - Ruby's open classes and "eager eval-by-default" are problems
    - There are probably a number of ways to get around it -- my way was to
      use macros
    - Using Rewrite gets around the open class problem
    - Yes, it turns your code into this shit [shows slide]
      but better by far to have the code do it than your IDE
    - [shows benchmarks] As you can see, it performance is far better than
      doing it by opening up the Object class
    - Rewrite version of andand doesn't execute the shit

    - Okay, this is tather nichey stuff
    - You know the saying that people don't by drills or drill bits, but they
      buy *holes*? Think of Rewrite as diamond dust that you use to make
      drill bits. Maybe you'll make use of it, but most people won't

- Just a quick note -- in his presentation, Giles [Bowkett] renamed lambda as
  L because he needed to use it a lot.
- Having to do that is a code smell
- Never mind making it shorter -- get rid of it entirely!

[Joey note: Reg corrected himself in a blog entry written after RubyFringe,
 stating that having to rename lambda is *not* a code smell;
 it's a *language smell*. Giles is simply using the best workaround
 available to him.

 See his blog entry at
 http://weblog.raganwald.com/2008/07/l-is-not-code-smell.html
 ]

- Why does Ruby read from left to right?
    - I have a lot of unpaid Demeter speeding tickets
    - thingy.thingy2.thingy3.thingy4
    - Because this OOP paradigm, even Ruby goes from left to right
    - From time to time, people want to go from right to left
    - blitz.not.blank?
    - not is really a adverb
    - There's really no place for adverbs
    - Adverbs modify verbs, and since OOP is in the Kingdom of Nouns,
      they get short shrift. I'd like to see more support for adverbs.

- Take a look at ruby2ruby, created by the folks at seattle.rb
- It asks "Hey, interpreter, what are you actually working with?"
- It does a lot of cleaning up of Ruby's s-expressions.
- Lisp's s-exps are like the nice flat-pack furniture you get from IKEA;
  Ruby's are the furniture you find in the dumpster -- and that's the stuff
  left over after a couple of people have been through it first.
- In the end, Ruby is like Lisp. Except you do all this work up front,
  and you do all this work on the back, and it's morepainful.
- But aside from that, it's like Lisp!

- Abstraction solves every problem except for one: the problem you have
  when there are too many layers of abstraction
- If working with the tool is worse than the problem, then the tool is bad
- Maybe you've been taken in by Home Depot -- they sell you on how easy it is to
  do the job. Many tools make the job part easy to do, but often they make
  cleaning up after the job more difficult
- Need to consider this when using or building tools

- I know that I don't have the best solution for this
- I *do* know that we have don't have enough competing solutions
- I don't believe that "open classes" is sustainable

Conceptual Algorithms (Tom Preston-Warner)

- When I was 7 years old, I'd fight with my brother over the TV
- I vividly remember a time I was so frustrated that I ran to the top of the
  stairs, took off my shoe, and threw it at my brother's face.
- Naturally, this led to a "time out" -- we were both sent to our rooms and
  told to think about what we'd done and if there was a better way to
  handle things...
    - What happened?
    - Are there better ways to resolve it that shoe-throwing?

- Problem solving can be broken down into these steps:
    1. Think about the problem
    2. Proposed solutions
    3. Evaluate the benefits and consequences of those proposed solutions
    4. Select the best soltuion

- I wrote chronic, god, fixture scenarios, fuzed, grit
- I work at Powerset -- now Microsoft
- Just realized John Lam and I are colleagues! I'm going to have to catch up
  with him when I get back
- I co-founded GitHub

- Conceptual Algorithm: Scientific Method
    - Geoff covered in his philosophy talk
    - It's one of the most powerful conceptual algorithms ever devised

    1. Define the question
    2. Gather info and resources
    3. Form a hyptothesis
    4. Analyze and interpret the data
    5. Plan
    6. Publish the data

    - How *not* to do science
        - To fix a memory leak in god.rb, I didn't use a reasonable methodology
          at first.
        - I just tried commenting stuff out to see if eliminated the leak
        - It was random and didn't get any real results

    - Then I tried the scientific method
    - Go see "science and god.rb" -- my use of the scientific method
      to fix a bug in god.rb is documented at:
      http://groups.google.com/group/god-rb/browse_thread/thread/01cca2b7c4a581c2

- Conceptual Algorithm: Memory Initialization
    - George Dantzig
        - Imagine a situation where you come late to class and everyone's
          already gone, but there are two math problems on the blackboard.
          You copy them down, take them home, find the solutions and
          hand them in, under the impression that it's just an overdue
          assignment
        - Now imagine that a little while later, you discover that those
          problems were strictly for display because they were considered
          unsolved problems by the mathematics community at large!
        - Everybody wants to be that dude -- and George Dantzig was that
          dude at UC Berkeley

    - The "memory initialization" algorithm works like this:
        - "I have a problem"
        - "I am going to disregard everything I know about a problem"
        - When you don't know about a problem domain, you often bring in a
          new perspective, no limits and no limits
        - Rather than look at existing work when developing chronic,
          a Ruby natural-language date parser, I worked from first principles
        - Sometimes coming in "fresh" and working from first principles
          gets you results!

- Conceptual Algorithm: Iteration
    - In making what is considered to be the best vaccuum cleaner in the world,
      James Dyson -- actually SIR James Dyson -- built 5127 prototypes
    - He said: "Making mistakes is the most important thing you can do"
    - Knighted for his efforts

- Conceptual Algorithm: Vaporset Corollary
    - Hard problems take a long time to solve
    - When harangued about why you haven't got any results yet,
      ignore the wankers
    - In the end, your long, hard work can pay off:
      Powerset sold to Microsoft for $100 million

    - Charles Darwin
        - Took 20 years on his evolution research
        - He published his finding only when his colleague Wallace said
          "Hey! You should publish this!"
        - [shows picture of Darwin] Look at those sideburns! He's awesome!

- Conceptual Algorithm: Breadth-First Search
    - There are over 2500 programming languages. Why just explore only
      2 or 4?
    - My original title was "Sapir-Whorf for Robots", but I didn't think
      it would catch on
    - For developing Fuzed, I tried using Erlang
    - The most important thing about trying a new language is to
      just accept the syntax. A strange new syntax often turns off
      developers -- tell yourself: "The syntax is okay"

- Conceptual Algorithm: Imagining the Ideal Solution
    - There's an example of this in god's config file
    - If you're creating a language, don't model it after English.
      That's retarded.
    - Config files are just big lists. You can't do loops or other things
      that we take for granted in programming languages
    - god config files are just Ruby

- Conceptual Algorithm: Dedicate Thinking Time
    - You should set aside some time to just think
    - Sometimes the best things come from this
    - One example: Gravatar, the avatar system -- this came up during my
      thinking time, and I did all right selling it to Automattic last year

    - A guy who devoted a lot of time for thinking: Rene Descartes
        - He's fringe to the max! I know Babbage is RubyFringe's mascot,
          but I think Descartes should've been the guy
        - Many accomplishments: a major philosopher and the father of
          analytic geometry
        - He got on the  Pope's list of prohibited books! How cool is that?

- Conceptual Algorithm: Cash Filter
    - There comes a point when you need to build something that makes you money

- Conceptual Algorithm: Deathbed Filter
    - Imagine yourself on your deathbed
    - Think about a decision you have right now
    - Think about yourself in the future -- imagine yourself looking back on
      that decision. Would it be a good memory or a bad memory?

Sinatra (Blake Mizerany)

- Sinatra is a micro-framework
- Less than 2K LOC in GitHub, including blank lines and comments

- Sinatra "hello world" is simple
- Rails was too slow
- Multiple Mongrel handlers getting cumbersome to maintain
- Same reasons as most for starting a new framework

- Camping is awesome, but...nuff said

- Freaks
- Islands on Second Life
- git-wiki by Simon Rozet

- Ultimate REST client
- RESTClient + Sinatra
- No longer have to use curl

7 WTFs of Sinatra
- Why am I falling for Sinatra?

Be Good (Leila Boujnane)

- People have been asking how I've been doing, and I've lately been saying
  "not too good"
- Some kind of aphasia-like symptoms [Get well sooon, Leila!]
- Founder of Idee Inc., which makes image search

- I'm probably the only person at this conference using notes
- Martin: here from Copenhagen
    - Needed a break -- working really really hard
    - Really really tired
- Couple of days, realy tired
- Use giant Post-It notes to think process
- Have been having trouble writing ideas down -- a sort of aphasia

- "If you make enough money in this world, you can smoke pot all day and have
  people killed." -- Patton Oswalt
- I am not one of those interesting individuals
- Here's something that was true when you were growing up and it's true today:
  Let's not have people killed. Let's be good.

- "What does a man need -- really need? A few pounds of food each day, heat and
  shelter, six feet to lie down in -- and some form of working activity that
  will yield a sense of accomplishment." -- "The Wanderer" by Sterling Hayden
- We have been brainwashed into belonging to an economic system that says you
  need more than that. Way more.

- How do we start to make the world a better place?
- I work long hours, seven days a week, and I love my job
- I love my clients
- Every day you walk in and have to make a set of decisions
- These are the early days

- Make something people want
- Paul Graham: "If you make people with money love you, you can probably
  get some of it."
- Idee: Gives people a better way to search for images
- Nothing more gratifying than an inbox full of messages from happy people
  who love what you make
    - It's satisfying -- you feel wanted and desired
- If you are not good at what you do, you end up resorting to being bad
    - You may have to cheat
    - Bully
    - Lie to your customers
- Your adoption rate is not tied to the number of people who you bully
  into adoption!

- Contrary to what a VC will tell you: don't focus on business models first
- Instead, focus on building something useful first.
- *Then* focus on the business model, *after* you've proven your usefulness
- Crappy products plus sales equals unhappy users

- It's all about happiness and being good!