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

Writing your own Programming Language to understand Ruby better

Writing your own Programming Language to understand Ruby better

@GoGaRuCo 2011

Plataformatec

March 02, 2012
Tweet

More Decks by Plataformatec

Other Decks in Technology

Transcript

  1. blog twitter ID José Valim @josevalim blog.plataformatec.com Writing your own

    Programming Language to Understand Ruby sexta-feira, 2 de março de 12
  2. Erlang VM + Concurrent Processes + Message Based + Hot

    Code Swapping + Runs with low memory sexta-feira, 2 de março de 12
  3. Erlang Language + Small and quick to learn + Functional

    programming - Syntax gets too much in your way - No object orientation sexta-feira, 2 de março de 12
  4. puts Lexe [:identifier, “puts”], [:call, “puts”,[ [:string, Parse Semanti c

    [:call, “puts”,[ [:string, sexta-feira, 2 de março de 12
  5. puts Lexe [:identifier, “puts”], [:call, “puts”,[ [:string, Parse Semanti c

    [:call, “puts”,[ [:string, Native / Bytecod sexta-feira, 2 de março de 12
  6. puts Lexe [:identifier, “puts”], [:call, “puts”,[ [:string, Parse Semanti c

    [:call, “puts”,[ [:string, Native / Bytecod sexta-feira, 2 de março de 12
  7. def foo 1 end foo #=> 1 self.foo #=> 1

    sexta-feira, 2 de março de 12
  8. def foo 1 end foo #=> 1 self.foo #=> 1

    foo = 2 foo #=> 2 self.foo #=> 1 sexta-feira, 2 de março de 12
  9. def bar foo = 1 foo end [:method,:bar,[ [:assign, "foo",

    [:integer,1]], [:identifier,"foo"] ]] lexer + parser sexta-feira, 2 de março de 12
  10. def bar foo = 1 foo end [:method,:bar,[ [:assign, "foo",

    [:integer,1]], [:identifier,"foo"] ]] lexer + parser [:method,:bar,[ [:assign, "foo", [:integer,1]], [:var,"foo"] ]] semantic analysis sexta-feira, 2 de março de 12
  11. def bar(arg) arg.class end bar /foo/m bar, foo, m =

    0, 1, 2 bar /foo/m sexta-feira, 2 de março de 12
  12. def show @user = User.find(self.params[:id]) if @user.name =~ %r/^Ph\.D/i self.render

    :action => "show" else self.flash[:notice] = "Ph.D required" self.redirect_to "/" end end sexta-feira, 2 de março de 12
  13. def show @user = User.find(params[:id]) if @user.name =~ /^Ph\.D/i render

    :action => "show" else flash[:notice] = "Ph.D required" redirect_to "/" end end sexta-feira, 2 de março de 12
  14. Trivia array = [1,2,3] array.length+1 #=> 4 array.length +1 #=>

    ArgumentError sexta-feira, 2 de março de 12
  15. Trivia array = [1,2,3] array.length+1 #=> 4 array.length +1 #=>

    ArgumentError array.length + 1 sexta-feira, 2 de março de 12
  16. Trivia array = [1,2,3] array.length+1 #=> 4 array.length +1 #=>

    ArgumentError array.length + 1 #=> 4 sexta-feira, 2 de março de 12
  17. Trivia p { } p { a: 1 } Is

    it a block or a sexta-feira, 2 de março de 12
  18. module Greeter def greet(name) "Hello #{name}" end end class Person

    include Greeter end Person.new.greet "Matz" sexta-feira, 2 de março de 12
  19. object.class.ancestors #=> [Object, Kernel, BasicObject] object.class.ancestors.any? do |r| r.method_defined?(:greet) end

    #=> false object.singleton_class. method_defined?(:greet) #=> true sexta-feira, 2 de março de 12
  20. object.class.ancestors #=> [Object, Kernel, BasicObject] object.class.ancestors.any? do |r| r.method_defined?(:greet) end

    #=> false object.singleton_class. method_defined?(:greet) #=> true object.singleton_class.is_a?(Module) #=> true sexta-feira, 2 de março de 12
  21. _why once said: Creating your own programming language is fun

    if you can keep it Trivia sexta-feira, 2 de março de 12
  22. do_it = do |f| f.write "doing it live" end File.open

    "gogaruco.txt", do_it sexta-feira, 2 de março de 12
  23. No blocks + No need for yield, &block + Passing

    more than one block around is more natural sexta-feira, 2 de março de 12
  24. n = [1,2,3,4] [x * 2 for x in n]

    # => [2,4,6,8] sexta-feira, 2 de março de 12
  25. n = [1,2,3] [x * 2 for x in n,

    x.odd?] # => [2,6] sexta-feira, 2 de março de 12
  26. n = [1,2,3,4] [[x,y] for x in n, y in

    n, x * x == y] # => [[1,1],[2,4]] sexta-feira, 2 de março de 12
  27. n = [1,2,3,4] {x => y for x in n,

    y in n, x * x == y} # => { 1 => 1, 2 => 4 } sexta-feira, 2 de março de 12
  28. Trivia { "a-b": 1 } == { :"a-b" => 1

    } sexta-feira, 2 de março de 12
  29. x, y, *z = [1,2,3,4,5] x #=> 1 y #=>

    2 z #=> [3,4,5] sexta-feira, 2 de março de 12
  30. x, [y1,*y2], *z = [1,[2,3,4],5] x #=> 1 y1 #=>

    2 y2 #=> [3,4] z #=> [5] sexta-feira, 2 de março de 12
  31. x = 1 ^x, *y = [3, 2, 1] #=>

    Raises an error! ^x, *y = [1, 2, 3] # => Works! sexta-feira, 2 de março de 12
  32. def form_for(object) case object when Hash # ... when Array

    # ... else # ... end end sexta-feira, 2 de março de 12
  33. def form_for(record : Hash) # ... end def form_for(record :

    Array) # ... end def form_for(record) # ... end sexta-feira, 2 de março de 12
  34. + Better to maintain + Better to document - No

    duck typing Method pattern matching sexta-feira, 2 de março de 12
  35. Haskell / Go interfaces interface ActiveModel::Compliance def :to_key def :persisted?

    end def form_for(object : ActiveModel::Compliance) # ... end sexta-feira, 2 de março de 12
  36. puts(_) #=> lambda { |x| puts(x) } respond_to?(_, _) #=>

    lambda { |x,y| respond_to?(x,y) } sexta-feira, 2 de março de 12