SlideShare a Scribd company logo
1 of 69
Download to read offline
Cleanliness is Next to
Domain-Specificity
Ben Scofield
Senior Developer
Viget Labs




4 November 2007
© Copyright 2007 Viget Labs, LLC – www.viget.com
Part 1: Linguistics
Part 2: Refactoring
The Ruby
Community
http://www.flickr.com/photos/jesper/1395418767/




Interdisciplinary
Linguistics
Categories
Regional Dialects
(more)

Regional
Dialects
Jargons   Cants
Pidgins and Creoles
Vocabulary
 Grammar
Real DSLs




Ruby Domain-Specific Code
ActiveRecord
RSpec
Same Grammar,
Different Vocabulary
Who Cares?
DSLs
                                                 DSL




                                                       Intimidate
                                                           and
                                                        Frighten
http://www.flickr.com/photos/cwsteeds/58514985/
Write a Parser?
 No, Thanks.



            http://www.flickr.com/photos/rooreynolds/243810988/
http://www.flickr.com/photos/jonosd/498162310/
Change the Vocabulary
  Change the World

               Heroes on NBC - Mondays at 9 PM
API vs. Dialect
Why DSanything?
Who Are We?
http://www.oreillynet.com/onlamp/blog/2006/05/
sapirwhorf_is_not_a_klingon.html
http://tech.puredanger.com/2006/11/08/does-your-programming-
language-affect-how-you-think/
http://snakesgemscoffee.blogspot.com/2006_11_01_archive.html
http://talklikeaduck.denhaven2.com/articles/2007/06/11/sapir-
whorf
http://adams.id.au/blog/2007/10/what-is-behaviour-driven-
development/
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/75914
http://www.weiqigao.com/blog/2007/09/10/
an_interesting_experiment_sapir_whorf_hypothesis.html
http://www.ibm.com/developerworks/blogs/page/pmuellr?
tag=ruby
http://intertwingly.net/blog/2007/10/05/NOC
http://brooders.net/category/perl/
http://gilesbowkett.blogspot.com/2007/02/sapir-worf-in-
action_19.html
http://blogs.msdn.com/daveremy/archive/2005/04/06/
sapirwhorfs.aspx
http://erlangish.blogspot.com/2007/05/shape-of-your-mind.html
http://www.oreillynet.com/onlamp/blog/2006/06/
how_does_a_programming_languag.html
Linguistic Determinism
The Hopi
Linguistic Relativism
http://www.flickr.com/photos/maxhunter/79993854/




                                                   Snow
                                 qanuk                    avalanche
                                 kaneq                    blizzard
                                 kanevvluk                dusting
                                 natquik                  flurry
                                 nevluk                   frost
                                 aniu                     hail
                                 qanikcaq                 hardpack
                                 muruaneq                 igloo
                                 nutaryuk                 pingo
                                 qanisqineq               powder
                                 qengaruk                 sleet
                                 utvak                    slush
                                 navcaq                   snow
                                 pirta                    snowflake
                                 pirtuk                   snowstorm
                                 ...                      ...
Color
Perception

             http://www.flickr.com/photos/thedeplorableword/140856437/
Direction of Causality
Degree of Influence
RSpec
     
Sapir-Whorf
Testing is Too Late
Specifications
 Come First
RSpec Leads You in
the Right Direction
DSDs are Built on
Linguistic Relativism
Keep Your Head in
   the Domain
Refactoring
Tastes Vary
?
Finding a Ticket
kayak.com
What Does This Do?
Ruby? Awesome!
exit 0

  @@results.each do |r|
    if searchtype == 'h'
      puts quot;#{r.price} url=#{r.url}quot;
      puts quot;#{r.stars} #{r.name} $#{r.loprice} - $#{r.hiprice}quot;
    elsif searchtype == 'f'
      puts quot;#{r.price} url=#{r.url}quot;
      r.legs.each do |leg|
        puts quot; #{leg}quot;
      end
    end
  end

  exit(0)
  more = poll_results_file(searchtype)
  @@results.each do |r|
    puts quot;#{r.price} #{r.url}quot;
    r.legs.each do |leg|
      puts quot; #{leg}quot;
    end
  end
end




                                   Whoa.
Start at the End
I Want to:
find flights from CLT to RDU leaving today
         and returning in one week
I Want to:
find :flights, :from => :CLT, :to => :RDU,
  :leaving => Date.today, :returning => Date.today + 7
48
                                                                                               40




                      The Old Way
sid = getsession(@@token)
searchid = start_flight_search(sid, ‘n’, ‘CLT’, ‘RDU’, Date.today, nil, 1)

more = poll_results('f', sid, searchid, nil)
while more == 'true' do
  more = poll_results('f', sid, searchid, nil)
  sleep(3)
end

def poll_results(searchtype, sid, searchid, count)
  url = quot;/s#{@@sparkleinstance}/apibasic/flight?searchid=#{searchid}&apimode=1&_sid_=#{sid}quot;

  more = nil
  Net::HTTP.start(@@hostname, @@port)   do |http|
    if count
      url += quot;&c=#{count}quot;
    end
    response = http.get(url)
    body = response.body
    File.open(quot;ksearchbody.xmlquot;, quot;wquot;)   do |f|
      f.puts(body)
    end
    more = handle_results(searchtype,   body)
    if more != 'true'
      # save the body, so we can test   without doin
      # an actual search
      File.open(quot;ksearchresults.xmlquot;,   quot;wquot;) do |f|
        f.puts(body)
      end
    end
  end
  return more
end
48
                                                                                      40




   The Old Way, cont.
def handle_results(searchtype, body)
  xml = REXML::Document.new(body)
  more = xml.elements['/searchresult/morepending']
  @@lastcount = xml.elements['/searchresult/count'].text
  @@sparkleinstance = xml.elements['/searchresult/searchinstance'].text
  if more
    more = more.text
  end
  if more != 'true'
    @@results = []
    #puts quot;count=#{@@lastcount}quot;
    xml.elements.each(quot;/searchresult/trips/tripquot;) do |e|
      trip = Trip.new()
      e.each_element(quot;pricequot;) do |t|
        trip.price = t.text
        trip.url = t.attribute(quot;urlquot;)
      end
      e.each_element(quot;legsquot;) do |legs|
        legs.each_element(quot;legquot;) do |l|
          leg = Leg.new
          l.each_element do |ld|
            # extract the detail from each leg
            case
            when ld.name == 'airline': leg.airlinecode = ld.text
            #...
            end
          end
          trip.legs << leg
        end # leg in legs loop
      end # legs in trip loop
      #e.each_element(quot;/searchresult/trips/trip/pricequot;) { |p| trip.price = p.text }
      #puts quot;trip: #{trip.price}quot;
      @@results << trip
    end # each trip
  end
  return more
end
40




                       Output
session_url = quot;/k/ident/apisession?token=#{token}quot;



search_url = quot;/s/apisearch?basicmode=true&oneway=n&origin=#{origin}
&destination=#{destination}&destcode=&depart_date=#{dep_date}
&depart_time=a&return_date=#{ret_date}&return_time=a&travelers=#
{travelers}&cabin=e&action=doflights&apimode=1&_sid_=#{sid}quot;



results_url = quot;/s#{@@sparkleinstance}/apibasic/flight?searchid=#
{searchid}&apimode=1&_sid_=#{sid}quot;
40




              Expectations
class KayakTest < Test::Unit::TestCase
  def test_find_should_call_out_to_session_endpoint
    setup_mocks_for_find
    Kayak.find :flights
  end

  private
  def setup_mocks_for_find
    response = mock(:body => '<?xml version=quot;1.0quot;?>
    <ident>
      <uid>uid</uid>
      <sid>0123456789</sid>
      <token>12345</token>
      <error></error>
    </ident>')
    success = mock()
    success.expects(:get).with('/k/ident/apisession?token=12345').returns
      (response)
    Net::HTTP.expects(:start).at_least_once.yields(success)
  end
end
40




   Parsing Responses
class KayakTest < Test::Unit::TestCase
  def test_session_response_should_be_parsed_for_session_id
    setup_mocks_for_find
    Kayak.find :flights
    assert_equal '0123456789', Kayak.session_id
  end

  private
  def setup_mocks_for_find
    response = mock(:body => '<?xml version=quot;1.0quot;?>
    <ident>
      <uid>uid</uid>
      <sid>0123456789</sid>
      <token>12345</token>
      <error></error>
    </ident>')
    success = mock()
    success.expects(:get).with('/k/ident/apisession?token=12345').returns
      (response)
    Net::HTTP.expects(:start).at_least_once.yields(success)
  end
end
class Kayak




                                      First Cut
  @@session_id = nil
  @@search_id = nil
  @@search_options = {}

  TOKEN    = '12345'
  HOSTNAME = 'www.kayak.com'
  PORT     = 80

  class << self
    def session_id
      @@session_id
    end

    def method_missing(name, *args)
      @@search_options[name]
    end

    def find(type, conditions = {})
      session_id ||= initialize_session
      @@search_options[:origin]      = conditions[:from]
      @@search_options[:destination] = conditions[:to]
      @@search_options[:depart_date] = conditions[:leaving].strftime('%m/%d/%Y')  if conditions[:leaving]
      @@search_options[:leave_date] = conditions[:returning].strftime('%m/%d/%Y') if conditions[:returning]

      search_id ||= initialize_search
      self
    end

    def initialize_search
      Net::HTTP.start(HOSTNAME, PORT) do |http|
        response = http.get(quot;/s/apisearch?basicmode=true&oneway=n&destcode=&depart_time=a&...
        if body = response.body
          xml = REXML::Document.new(body)
          @@search_id = xml.elements['//searchid'].text
        end
      end
    end

    def initialize_session
      Net::HTTP.start(HOSTNAME, PORT) do |http|
        response = http.get(quot;/k/ident/apisession?token=#{TOKEN}quot;)
        if body = response.body
          xml = REXML::Document.new(body)
          @@session_id = xml.elements['//sid'].text
        end
      end
    end
  end
end
module Kayak




                          Second Cut
  TOKEN    = '12345'
  HOSTNAME = 'www.kayak.com'
  PORT     = 80

  class Flight
    attr_accessor :session, :search_id, :search_options

    def method_missing(name, *args)
      search_options[name]
    end

    def initialize(conditions = {})
      session ||= Kayak::Session.new
      self.search_options = {}
      self.search_options[:origin]        =   conditions[:from]
      self.search_options[:destination]   =   conditions[:to]
      self.search_options[:depart_date]   =   conditions[:leaving].strftime('%m/%d/%Y')   if conditions[:leaving]
      self.search_options[:return_date]   =   conditions[:returning].strftime('%m/%d/%Y') if conditions[:returning]

      Net::HTTP.start(HOSTNAME, PORT) do |http|
        response = http.get(quot;/s/apisearch?basicmode=true&oneway=n&destcode=&depart_time=a&return_date=...
        self.search_id = Kayak.retrieve(response, '//searchid')
      end
    end

    def self.find(args)
      self.new(args)
    end
  end

  class Session
    attr_accessor :session_id

    def initialize
      Net::HTTP.start(Kayak::HOSTNAME, Kayak::PORT) do |http|
        response = http.get(quot;/k/ident/apisession?token=#{Kayak::TOKEN}quot;)
        self.session_id ||= Kayak.retrieve(response, '//sid')
      end
    end
  end

  def self.find(type, *args)
    case type
      when :flights
        Kayak::Flight.find(*args)
    end
  end

  ...
I Want to:
find :flights, :from => :CLT, :to => :RDU,
  :leaving => Date.today, :returning => Date.today + 7
Third Cut


  ?
Always Room for
  Improvement
Tips
:symbol
ignore the colon
I Want to:
find :flights, :from => :CLT, :to => :RDU,
  :leaving => Date.today, :returning => Date.today + 7
Optional Parentheses
   looks like a sentence
I Want to:
find :flights, :from => :CLT, :to => :RDU,
  :leaving => Date.today, :returning => Date.today + 7
Blocks for All
In other languages, you have to specify
explicitly that a function can accept another
function as an argument. But in Ruby, any
method can be called with a block as an
implicit argument.
                                 Matz, 2003
*
arrays from anything
Optional Braces
 not that common
I Want to:
find :flights, :from => :CLT, :to => :RDU,
  :leaving => Date.today, :returning => Date.today + 7
• Start Modestly
• Stay in the Domain
• Get Better
56




That’s It
travel safely
Ben Scofield
   ben.scofield@viget.com
http://www.extendviget.com/
   http://www.culann.com/

 4 November 2007
 © Copyright 2007 Viget Labs, LLC – www.viget.com

More Related Content

What's hot

RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteDr Nic Williams
 
Bringing Characters to Life for Immersive Storytelling - Dioselin Gonzalez
Bringing Characters to Life for Immersive Storytelling - Dioselin GonzalezBringing Characters to Life for Immersive Storytelling - Dioselin Gonzalez
Bringing Characters to Life for Immersive Storytelling - Dioselin GonzalezWithTheBest
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 
Writing Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdWriting Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdRicardo Signes
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and ProfitOlaf Alders
 
"The worst code I ever wrote"
"The worst code I ever wrote""The worst code I ever wrote"
"The worst code I ever wrote"Tomas Doran
 
Malli: inside data-driven schemas
Malli: inside data-driven schemasMalli: inside data-driven schemas
Malli: inside data-driven schemasMetosin Oy
 
Moose Best Practices
Moose Best PracticesMoose Best Practices
Moose Best PracticesAran Deltac
 
Designing with malli
Designing with malliDesigning with malli
Designing with malliMetosin Oy
 
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!Guilherme Carreiro
 
Moose (Perl 5)
Moose (Perl 5)Moose (Perl 5)
Moose (Perl 5)xSawyer
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With ClojureMetosin Oy
 
Reitit - Clojure/North 2019
Reitit - Clojure/North 2019Reitit - Clojure/North 2019
Reitit - Clojure/North 2019Metosin Oy
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with MooseDave Cross
 
Moose talk at FOSDEM 2011 (Perl devroom)
Moose talk at FOSDEM 2011 (Perl devroom)Moose talk at FOSDEM 2011 (Perl devroom)
Moose talk at FOSDEM 2011 (Perl devroom)xSawyer
 

What's hot (18)

RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
Bringing Characters to Life for Immersive Storytelling - Dioselin Gonzalez
Bringing Characters to Life for Immersive Storytelling - Dioselin GonzalezBringing Characters to Life for Immersive Storytelling - Dioselin Gonzalez
Bringing Characters to Life for Immersive Storytelling - Dioselin Gonzalez
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 
Writing Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdWriting Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::Cmd
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit
 
Ruby Robots
Ruby RobotsRuby Robots
Ruby Robots
 
"The worst code I ever wrote"
"The worst code I ever wrote""The worst code I ever wrote"
"The worst code I ever wrote"
 
Malli: inside data-driven schemas
Malli: inside data-driven schemasMalli: inside data-driven schemas
Malli: inside data-driven schemas
 
Moose Best Practices
Moose Best PracticesMoose Best Practices
Moose Best Practices
 
Designing with malli
Designing with malliDesigning with malli
Designing with malli
 
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
TDC 2014 - JavaScript de qualidade: hoje, amanhã e sempre!
 
Moose (Perl 5)
Moose (Perl 5)Moose (Perl 5)
Moose (Perl 5)
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With Clojure
 
Reitit - Clojure/North 2019
Reitit - Clojure/North 2019Reitit - Clojure/North 2019
Reitit - Clojure/North 2019
 
Command
CommandCommand
Command
 
Your code is not a string
Your code is not a stringYour code is not a string
Your code is not a string
 
Evolving Software with Moose
Evolving Software with MooseEvolving Software with Moose
Evolving Software with Moose
 
Moose talk at FOSDEM 2011 (Perl devroom)
Moose talk at FOSDEM 2011 (Perl devroom)Moose talk at FOSDEM 2011 (Perl devroom)
Moose talk at FOSDEM 2011 (Perl devroom)
 

Viewers also liked

Resourceful Plugins
Resourceful PluginsResourceful Plugins
Resourceful PluginsBen Scofield
 
Building Cloud Castles - LRUG
Building Cloud Castles - LRUGBuilding Cloud Castles - LRUG
Building Cloud Castles - LRUGBen Scofield
 
How to Be Awesome in 2.5 Steps
How to Be Awesome in 2.5 StepsHow to Be Awesome in 2.5 Steps
How to Be Awesome in 2.5 StepsBen Scofield
 
Page Caching Resurrected
Page Caching ResurrectedPage Caching Resurrected
Page Caching ResurrectedBen Scofield
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful RailsBen Scofield
 
Open Source: A Call to Arms
Open Source: A Call to ArmsOpen Source: A Call to Arms
Open Source: A Call to ArmsBen Scofield
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers StealBen Scofield
 

Viewers also liked (10)

Resourceful Plugins
Resourceful PluginsResourceful Plugins
Resourceful Plugins
 
Building Cloud Castles - LRUG
Building Cloud Castles - LRUGBuilding Cloud Castles - LRUG
Building Cloud Castles - LRUG
 
How to Be Awesome in 2.5 Steps
How to Be Awesome in 2.5 StepsHow to Be Awesome in 2.5 Steps
How to Be Awesome in 2.5 Steps
 
Ciclo 13
Ciclo 13Ciclo 13
Ciclo 13
 
Page Caching Resurrected
Page Caching ResurrectedPage Caching Resurrected
Page Caching Resurrected
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful Rails
 
Open Source: A Call to Arms
Open Source: A Call to ArmsOpen Source: A Call to Arms
Open Source: A Call to Arms
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
Thinking Small
Thinking SmallThinking Small
Thinking Small
 
Ship It
Ship ItShip It
Ship It
 

Similar to Cleanliness is Next to Domain-Specificity

Juggling Chainsaws: Perl and MongoDB
Juggling Chainsaws: Perl and MongoDBJuggling Chainsaws: Perl and MongoDB
Juggling Chainsaws: Perl and MongoDBDavid Golden
 
R57php 1231677414471772-2
R57php 1231677414471772-2R57php 1231677414471772-2
R57php 1231677414471772-2ady36
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of RubyTom Crinson
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applicationselliando dias
 
Security Challenges in Node.js
Security Challenges in Node.jsSecurity Challenges in Node.js
Security Challenges in Node.jsWebsecurify
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!Boy Baukema
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Masahiro Nagano
 
SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)wqchen
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applicationselliando dias
 
CoffeeScript Design Patterns
CoffeeScript Design PatternsCoffeeScript Design Patterns
CoffeeScript Design PatternsTrevorBurnham
 
Interface de Voz con Rails
Interface de Voz con RailsInterface de Voz con Rails
Interface de Voz con RailsSvet Ivantchev
 
Let's play a game with blackfire player
Let's play a game with blackfire playerLet's play a game with blackfire player
Let's play a game with blackfire playerMarcin Czarnecki
 
Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottO'Reilly Media
 
I put on my mink and wizard behat (tutorial)
I put on my mink and wizard behat (tutorial)I put on my mink and wizard behat (tutorial)
I put on my mink and wizard behat (tutorial)xsist10
 
React PHP: the NodeJS challenger
React PHP: the NodeJS challengerReact PHP: the NodeJS challenger
React PHP: the NodeJS challengervanphp
 

Similar to Cleanliness is Next to Domain-Specificity (20)

Juggling Chainsaws: Perl and MongoDB
Juggling Chainsaws: Perl and MongoDBJuggling Chainsaws: Perl and MongoDB
Juggling Chainsaws: Perl and MongoDB
 
R57php 1231677414471772-2
R57php 1231677414471772-2R57php 1231677414471772-2
R57php 1231677414471772-2
 
Postman On Steroids
Postman On SteroidsPostman On Steroids
Postman On Steroids
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Sphinx on Rails
Sphinx on RailsSphinx on Rails
Sphinx on Rails
 
Security Challenges in Node.js
Security Challenges in Node.jsSecurity Challenges in Node.js
Security Challenges in Node.js
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!
 
Perl basics for Pentesters
Perl basics for PentestersPerl basics for Pentesters
Perl basics for Pentesters
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)SparkR - Play Spark Using R (20160909 HadoopCon)
SparkR - Play Spark Using R (20160909 HadoopCon)
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
CoffeeScript Design Patterns
CoffeeScript Design PatternsCoffeeScript Design Patterns
CoffeeScript Design Patterns
 
Interface de Voz con Rails
Interface de Voz con RailsInterface de Voz con Rails
Interface de Voz con Rails
 
Apache Spark Workshop
Apache Spark WorkshopApache Spark Workshop
Apache Spark Workshop
 
Let's play a game with blackfire player
Let's play a game with blackfire playerLet's play a game with blackfire player
Let's play a game with blackfire player
 
Dealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter ScottDealing with Legacy Perl Code - Peter Scott
Dealing with Legacy Perl Code - Peter Scott
 
I put on my mink and wizard behat (tutorial)
I put on my mink and wizard behat (tutorial)I put on my mink and wizard behat (tutorial)
I put on my mink and wizard behat (tutorial)
 
React PHP: the NodeJS challenger
React PHP: the NodeJS challengerReact PHP: the NodeJS challenger
React PHP: the NodeJS challenger
 

More from Ben Scofield

Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud CastlesBen Scofield
 
Intentionality: Choice and Mastery
Intentionality: Choice and MasteryIntentionality: Choice and Mastery
Intentionality: Choice and MasteryBen Scofield
 
Mastery or Mediocrity
Mastery or MediocrityMastery or Mediocrity
Mastery or MediocrityBen Scofield
 
With a Mighty Hammer
With a Mighty HammerWith a Mighty Hammer
With a Mighty HammerBen Scofield
 
Mind Control - DevNation Atlanta
Mind Control - DevNation AtlantaMind Control - DevNation Atlanta
Mind Control - DevNation AtlantaBen Scofield
 
Understanding Mastery
Understanding MasteryUnderstanding Mastery
Understanding MasteryBen Scofield
 
Mind Control: Psychology for the Web
Mind Control: Psychology for the WebMind Control: Psychology for the Web
Mind Control: Psychology for the WebBen Scofield
 
The State of NoSQL
The State of NoSQLThe State of NoSQL
The State of NoSQLBen Scofield
 
NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010Ben Scofield
 
NoSQL: Death to Relational Databases(?)
NoSQL: Death to Relational Databases(?)NoSQL: Death to Relational Databases(?)
NoSQL: Death to Relational Databases(?)Ben Scofield
 
Charlotte.rb - "Comics" Is Hard
Charlotte.rb - "Comics" Is HardCharlotte.rb - "Comics" Is Hard
Charlotte.rb - "Comics" Is HardBen Scofield
 
The Future of Data
The Future of DataThe Future of Data
The Future of DataBen Scofield
 
WindyCityRails - "Comics" Is Hard
WindyCityRails - "Comics" Is HardWindyCityRails - "Comics" Is Hard
WindyCityRails - "Comics" Is HardBen Scofield
 
"Comics" Is Hard: Alternative Databases
"Comics" Is Hard: Alternative Databases"Comics" Is Hard: Alternative Databases
"Comics" Is Hard: Alternative DatabasesBen Scofield
 
Mind Control on the Web
Mind Control on the WebMind Control on the Web
Mind Control on the WebBen Scofield
 
How the Geeks Inherited the Earth
How the Geeks Inherited the EarthHow the Geeks Inherited the Earth
How the Geeks Inherited the EarthBen Scofield
 
And the Greatest of These Is ... Space
And the Greatest of These Is ... SpaceAnd the Greatest of These Is ... Space
And the Greatest of These Is ... SpaceBen Scofield
 
"Comics" Is Hard: Domain Modeling Challenges
"Comics" Is Hard: Domain Modeling Challenges"Comics" Is Hard: Domain Modeling Challenges
"Comics" Is Hard: Domain Modeling ChallengesBen Scofield
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportBen Scofield
 
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy TalePage Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy TaleBen Scofield
 

More from Ben Scofield (20)

Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud Castles
 
Intentionality: Choice and Mastery
Intentionality: Choice and MasteryIntentionality: Choice and Mastery
Intentionality: Choice and Mastery
 
Mastery or Mediocrity
Mastery or MediocrityMastery or Mediocrity
Mastery or Mediocrity
 
With a Mighty Hammer
With a Mighty HammerWith a Mighty Hammer
With a Mighty Hammer
 
Mind Control - DevNation Atlanta
Mind Control - DevNation AtlantaMind Control - DevNation Atlanta
Mind Control - DevNation Atlanta
 
Understanding Mastery
Understanding MasteryUnderstanding Mastery
Understanding Mastery
 
Mind Control: Psychology for the Web
Mind Control: Psychology for the WebMind Control: Psychology for the Web
Mind Control: Psychology for the Web
 
The State of NoSQL
The State of NoSQLThe State of NoSQL
The State of NoSQL
 
NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010NoSQL @ CodeMash 2010
NoSQL @ CodeMash 2010
 
NoSQL: Death to Relational Databases(?)
NoSQL: Death to Relational Databases(?)NoSQL: Death to Relational Databases(?)
NoSQL: Death to Relational Databases(?)
 
Charlotte.rb - "Comics" Is Hard
Charlotte.rb - "Comics" Is HardCharlotte.rb - "Comics" Is Hard
Charlotte.rb - "Comics" Is Hard
 
The Future of Data
The Future of DataThe Future of Data
The Future of Data
 
WindyCityRails - "Comics" Is Hard
WindyCityRails - "Comics" Is HardWindyCityRails - "Comics" Is Hard
WindyCityRails - "Comics" Is Hard
 
"Comics" Is Hard: Alternative Databases
"Comics" Is Hard: Alternative Databases"Comics" Is Hard: Alternative Databases
"Comics" Is Hard: Alternative Databases
 
Mind Control on the Web
Mind Control on the WebMind Control on the Web
Mind Control on the Web
 
How the Geeks Inherited the Earth
How the Geeks Inherited the EarthHow the Geeks Inherited the Earth
How the Geeks Inherited the Earth
 
And the Greatest of These Is ... Space
And the Greatest of These Is ... SpaceAnd the Greatest of These Is ... Space
And the Greatest of These Is ... Space
 
"Comics" Is Hard: Domain Modeling Challenges
"Comics" Is Hard: Domain Modeling Challenges"Comics" Is Hard: Domain Modeling Challenges
"Comics" Is Hard: Domain Modeling Challenges
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack Support
 
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy TalePage Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
 

Recently uploaded

"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 

Recently uploaded (20)

"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 

Cleanliness is Next to Domain-Specificity