Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DSLs As Teaching Tools

1472f3638730675f859e980757457d9f?s=47 Ryan Cook
February 22, 2012

DSLs As Teaching Tools

Given at Boulder Ruby Group in February 2012. A presentation examining DSLs, what they might be teaching us or especially new programmers, and some common tactics or methodologies for creating them.


Ryan Cook

February 22, 2012


  1. DSLs Let Them Teach!

  2. WHAT IS A DSL? • DSL = Domain Specific Language

    • A lingual subset dedicated to a particular problem (domain) area • Code that makes it easier to work on specific (types of) problems • A specialized tool
  3. WHAT IS A DSL? (REDUX) talk "DSL" do | topic

    | topic.acronym true , [ "Domain" , "Specific" , "Language" ] topic.definition "A lingual subset dedicated to a particular problem (domain) area" topic.definition "Code that makes it easier to work on specific (types of) problems" topic.definition "A specialized tool" end
  4. WHAT IS THE GOAL OF A DSL? • To provide

    a powerful and declarative abstraction around a specific set of underlying library/code functionality • From @justicefries -- "Provide a means for developers to effectively communicate with each other and domain experts in a domain."
  5. POP CULTURE • Code Academy and Code Year ◦ Founder

    Sims - "Programming is the new literacy" ◦ http://bit.ly/wO7UP3 • "Well understood problems lend themselves to DSLs" ◦ http://bit.ly/wCqFKk • "Human beings, as tool makers, can create things that amplify our ability" ◦ Steve Jobs (1980) re: Scientific American study about inter-species locomotive efficiency ◦ http://bit.ly/wE6HyH
  6. POP CULTURE • "On the contrary, the best way to

    teach someone to code is within a meaningful context, where they are given an existing solution and guided how to alter and customise it to their preferences or requirements, as often required in the “real world”." ◦ Andy Young of Kernel Mag on "Coding For Success" ◦ http://bit.ly/xGxDAn
  7. WHERE OH WHERE • Rake • Sinatra • ActiveRecord

  8. RAKE • A DSL for definining command line interface tasks

    in Ruby • A ruby build tool
  9. RAKE $ cat Rakefile namespace :my_task_group do task :my_task do

    p "hello" end end $ rake my_task_group:my_task hello
  10. RAKE • Understand that it's helpful to name command line

    tasks • Understand that it's helpful to namespace similar command line tasks • Understand that it's helpful to describe command line tasks
  11. SINATRA • A DSL for HTTP application servers built on

  12. SINATRA $ cat app.rb require "sinatra" get "/" { body

    "Hello World!" } $ ruby app.rb &> /dev/null & $ curl Hello World! (Who can spot the syntax error?)
  13. SINATRA $ cat app.rb require "sinatra" get("/") { body "Hello

    World!" } $ ruby app.rb &> /dev/null & $ curl Hello World!
  14. SINATRA • Understand that HTTP servers have a set number

    of methods through which to communicate (GET, POST, etc.) • Understand that you have access to certain things in an HTTP request • Understand that there are specific ways to respond to HTTP requests (response codes) • Understand that there are parts of an HTTP response that you can control to have the desired effect
  15. ACTIVERECORD • ActiveRecord's class methods provide many different DSLs •

    A DSL for object relationships • A DSL for object data validations • A DSL for object callbacks
  16. ACTIVERECORD class MyModel < ActiveRecord::Base belongs_to :my_other_model validates_presence_of :my_important_field after_save

    { p "Saved!" } end
  17. ACTIVERECORD • Understand different ways that data can be related

    • Understand the power behind callbacks and how they can help you manage your data • Understand validations and how they can help you keep your data standardized
  18. OTHERS • What other DSLs do you like?

  19. HOW CAN THEY TEACH • DSLs teach by making it

    easier to understand how to accomplish a problem though programming • They lower the barrier to entry • Help introduce people to programming concepts at a more gradual pace • Provide more output for less input
  20. EASY? • Programming is not easy, but DSLs can make

    it easier • People know problem domains, but they don't always know how to program • DSLs puts programming in a language that people understand inherently
  21. BARRIERS TO ENTRY • There are A LOT of them

    • e.g. Syntax, development environment • Remove some of them and you'll be helping someone
  22. EASE INTO IT • Help make the landing into programming

    a little softer • A little syntax and maybe a little logic and they're off!
  23. MORE FOR LESS • By writing only a tidbit of

    expressive and declarative code, a user can have built something very powerful
  24. THE POINT • DSLs can be teaching tools unintentionally •

    Writing a ton of DSLs around the problems WE solve isn't necessarily helpful • If people can be taught how to use DSLs then they're one step closer to being a programmer
  25. WHAT I REALIZED • DSLs are already a powerful teaching

    tool • They teach programming through use assuming you know, or are willing to learn, the domain • What's hard about them are the barriers to entry
  26. HOW TO DIY • 3 common methodologies ◦ Naked ◦

    Proc passing ◦ Class methods • Think: Object Builder
  27. NAKED DSL • Rake • Add methods globally ◦ http://bit.ly/wk51Xa

  28. NAKED DSL (RAKE) $ cat lib/rake/dsl_definition.rb module Rake module DSL

    ... ALL the code ... end end self.extend Rake::DSL
  29. NAKED DSL • Eval in context • Rackup ◦ Rack::Builder

    ◦ http://bit.ly/ylRd0z • Capistrano ◦ Capistrano::Configuration::Loading ◦ http://bit.ly/xLwveX
  30. NAKED DSL (RACKUP) $ cat lib/rack/builder.rb module Rack class Builder

    def self.parse_file( config , opts = Server::Options.new ) ... other code ... # cfgfile is the result of a File::read app = eval \ "Rack::Builder.new {\n" + cfgfile + "\n}.to_app", TOPLEVEL_BINDING, config ... other code ... end end end
  31. NAKED DSL (CAPISTRANO) $ cat lib/capistrano/configuration/loading.rb module Capistrano; class Configuration

    module Loading; module ClassMethods def load( *params , &block ) ... other code ... # options[ :string ] is the result of a File::read instance_eval options[:string] , options[:name] || "<eval>" ... other code ... end end; end end; end
  32. PROC PASSING DSL • Rails routes ◦ Rails 2.3.X --

    `map` object yielded to block directly ▪ http://bit.ly/yU27AL ◦ Rails 3.X.X -- proc `instance_exec`-ed behind the scenes on to `map` object ▪ http://bit.ly/xGgvVg ▪ http://bit.ly/zJkxd3
  33. PROC PASSING DSL (RAILS 2.3.X) $ cat actionpack/lib/action_controller/routing/route_set.rb module ActionController;

    module Routing class RouteSet class Mapper; ... other code ... end def draw yield Mapper.new( self ) ... other code ... end end end; end
  34. PROC PASSING DSL (RAILS 3.X.X) $ cat actionpack/lib/action_dispatch/routing/route_set.rb module ActionDispatch;

    module Routing class RouteSet def draw( &block ) eval_block block end def eval_block( block ) Mapping.new( self ).instance_exec &block end end end; end
  35. CLASS METHODS • ActiveRecord ◦ http://bit.ly/xr34Qk

  36. CLASS METHODS (AR) $ cat activerecord/lib/active_record/associations.rb module ActiveRecord; module Associations

    module ClassMethods def belongs_to( name , options = {} ) Builder::BelongsTo.new( self , name , options ) end end end; end
  37. TIPS • `Class.new` • `const_get` and `const_set` • `class_variable_get` and

    `class_variable_set` as well as their instance variable counterparts • `Forwardable` and `def_delegators` • Defining things directly on the included class with `Module::included`
  38. PITFALLS • Definition vs. execution scope • What is `self`?

  39. IN CONCLUSION • Create DSLs for non-programmers • Remove barriers

    to entry • When you're writing a DSL, think about building objects
  40. THE END Questions? Thank you! Links: http://bit.ly/cookrn_boulder_ruby_feb_12 Ryan Cook cookrn@gmail.com