• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Writing your own programming language to understand Ruby better - Euruko 2011
 

Writing your own programming language to understand Ruby better - Euruko 2011

on

  • 6,421 views

José Valim describes what he learned when working on Elixir and how you can understand Ruby better by writing your own programming language.

José Valim describes what he learned when working on Elixir and how you can understand Ruby better by writing your own programming language.

Statistics

Views

Total Views
6,421
Views on SlideShare
4,939
Embed Views
1,482

Actions

Likes
12
Downloads
40
Comments
0

11 Embeds 1,482

http://blog.redturtle.it 1177
http://www.scoop.it 242
http://lanyrd.com 29
http://localhost:8208 8
http://paper.li 8
http://twitter.com 7
http://webcache.googleusercontent.com 5
http://translate.googleusercontent.com 3
https://twitter.com 1
http://castell.hosting.redturtle.it:9180 1
http://localhost 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • And that was it. There are other small things I found interesting, like implementing super in Elixir, but we can discuss later if you are interested because now it is time to move to the second part of the talk. “What if?”\n\nSome of the “What if?” cases here are very unlikely to be added to Ruby because it would generate incompatibilities, but some could be there someday and some are even under discussion for Ruby 2.0.\n
  • \n
  • First off, I love Ruby blocks. But I am going to give you an alternative and explain why it maybe could be better. The point is to start a discussion and see if you think I am completely insane or not.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Maybe this can cause conflict with ternaries, but I am not sure.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • And, in the same way, you mentioned at the time that Larry Wall (the guy how created Perl) was your hero, I can safely say your mine.\n
  • Several things I discussed here already exists in Elixir. There are a bunch other differences, like immutability and the Erlang VM is quite awesome. Come, try it and you will learn a lot.\n
  • Also, keep an eye on Rubinius VM.\n
  • \n
  • \n
  • \n

Writing your own programming language to understand Ruby better - Euruko 2011 Writing your own programming language to understand Ruby better - Euruko 2011 Presentation Transcript

  • Writing your own Programming Language to Understand Ruby betterJosé Valim blog.plataformatec.com @josevalim
  • Writing your own Programming Language to Understand Ruby better ID blog twitterJosé Valim blog.plataformatec.com @josevalim
  • I am José Valim @josevalim
  • I work at blog.plataformatec.com.br
  • Core Team Member
  • Elixir Simple Object Orientation andcharming syntax on top of Erlang VM
  • Erlang VM+Concurrent Processes+Message Based+Hot Code Swapping
  • Erlang Language+Small and quick to learn+Functional programming- Syntax gets too much in your way- No object orientation
  • Elixir Simple Object Orientation andcharming syntax on top of Erlang VM
  • <3 Ruby <3
  • 1.Things I learned about Ruby2.What if?3.Wrapping up
  • Things I learned about Ruby
  • The Syntax
  • puts “hi”
  • puts “hi” Lexer
  • puts “hi” Lexer [:identi er, “puts”], [:string, “hi”]
  • puts “hi” Lexer [:identi er, “puts”], [:string, “hi”] Parser
  • puts “hi” Lexer [:identi er, “puts”], [:string, “hi”] Parser[:call, “puts”,[ [:string, “hi”]]]
  • puts “hi” Lexer [:identi er, “puts”], [:string, “hi”] Parser[:call, “puts”,[ [:string, “hi”]]] Extra steps
  • puts “hi” Lexer [:identi er, “puts”], [:string, “hi”] Parser[:call, “puts”,[ [:string, “hi”]]] Extra steps [:call, “puts”,[ [:string, “hi”] ]]
  • puts “hi” Lexer [:identi er, “puts”], [:string, “hi”] Parser[:call, “puts”,[ [:string, “hi”]]] Extra steps [:call, “puts”,[ [:string, “hi”] ]] Interpreter/Compiler
  • puts “hi” Lexer [:identi er, “puts”], [:string, “hi”] Parser[:call, “puts”,[ [:string, “hi”]]] Extra steps [:call, “puts”,[ [:string, “hi”] ]] Interpreter/Compiler
  • Flexible Grammar
  • def foo 1endfoo #=> 1self.foo #=> 1
  • def foo 1endfoo #=> 1self.foo #=> 1foo = 2foo #=> 2self.foo #=> 1
  • foo
  • foo Lexer
  • foo Lexer [:identi er, “foo”]
  • foo Lexer [:identi er, “foo”] Parser
  • foo Lexer [:identi er, “foo”] Parser[:identi er, “foo”]
  • foo Lexer [:identi er, “foo”] Parser[:identi er, “foo”] Extra steps
  • foo Lexer [:identi er, “foo”] Parser[:identi er, “foo”] Extra steps ?
  • foo Lexer [:identi er, “foo”] Parser[:identi er, “foo”] Extra steps ? Interpreter/Compiler
  • def bar foo = 1 fooend
  • def bar foo = 1 lexer + parser fooend [:method,:bar,[ [:assign, "foo", [:integer,1]], [:identifier,"foo"] ]]
  • def bar foo = 1 lexer + parser fooend [:method,:bar,[ [:assign, "foo", [:integer,1]], [:identifier,"foo"] ]] extra steps [:method,:bar,[ [:assign, "foo", [:integer,1]], [:var,"foo"] ]]
  • def bar(arg) arg.classendbar /foo/m
  • def bar(arg) arg.classendbar /foo/mbar, foo, m = 0, 1, 2bar /foo/m
  • 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 "/" endend
  • def show @user = User.find(params[:id]) if @user.name =~ /^Ph.D/i render :action => "show" else flash[:notice] = "Ph.D required" redirect_to "/" endend
  • The Object Model
  • object = Object.newdef object.greet(name) puts "Hello #{name}"endobject.greet("Matz")
  • Ruby methods are stored in modules
  • module Greeter def greet(name) "Hello #{name}" endendclass Person include GreeterendPerson.new.greet "Matz"
  • class Person def greet(name) "Hello #{name}" endendPerson.new.greet "Matz"
  • Person.is_a?(Module) #=> trueClass.superclass #=> Module
  • object = Object.newdef object.greet(name) puts "Hello #{name}"endobject.greet("Matz")
  • object.class.ancestors#=> [Object, Kernel, BasicObject]
  • object.class.ancestors#=> [Object, Kernel, BasicObject]object.class.ancestors.any? do |r| r.method_defined?(:greet)end#=> false
  • object.class.ancestors#=> [Object, Kernel, BasicObject]object.class.ancestors.any? do |r| r.method_defined?(:greet)end#=> falseobject.singleton_class. method_defined?(:greet)#=> true
  • object.class.ancestors#=> [Object, Kernel, BasicObject]object.class.ancestors.any? do |r| r.method_defined?(:greet)end#=> falseobject.singleton_class. method_defined?(:greet)#=> trueobject.singleton_class.is_a?(Module)#=> true
  • What if?
  • ... we did not have blocks?
  • <3 Blocks <3
  • File.open("euruko.txt") do |f| f.write "doing it live"end
  • File.open "euruko.txt", do |f| f.write "doing it live"end
  • File.open "euruko.txt", do |f| f.write "doing it live"end
  • File.open("euruko.txt", do |f| f.write "doing it live"end)
  • do_it = do |f| f.write "doing it live"endFile.open "euruko.txt", do_it
  • No blocks+No need for yield, &block+Passing more than one block around is more natural
  • ... we had Array and Hash comprehensions?
  • n = [1,2,3,4][x * 2 for x in n]# => [2,4,6,8]
  • n = [1,2,3][x * 2 for x in n, x.odd?]# => [2,6]
  • n = [1,2,3,4][[x,y] for x in n, y in n, x * x == y]# => [[1,1],[2,4]]
  • n = [1,2,3,4]{x => y for x in n, y in n, x * x == y}# => { 1 => 1, 2 => 4 }
  • ... our hashes were more like JSON?
  • { a: 1 }
  • { "a": 1 }
  • ... we had pattern matching?
  • x, y, *z = [1,2,3,4,5]x #=> 1y #=> 2z #=> [3,4,5]
  • x, [y1,*y2], *z = [1,[2,3,4],5]x #=> 1y1 #=> 2y2 #=> [3,4]z #=> [5]
  • x, x, *z = [1,2,3,4,5]#=> Raises an error
  • x, x, *z = [1,1,3,4,5]#=> Works!
  • x = 1~x, *y = [3, 2, 1]#=> Raises an error!~x, *y = [1, 2, 3]# => Works!
  • ... we de ned a syntax tree?
  • [:method,:bar,[ [:assign, "foo", [:integer,1]], [:var,"foo"]]]
  • class Foo memoize def bar # Something endend
  • class Foo memoize(def bar # Something end)end
  • def memoize(method) tree = method.tree # Do something method.redefine! new_treeend
  • Wrapping up
  • <3 Matz <3
  • <3 Elixir <3github.com/josevalim/elixir
  • createyourproglang.com
  • ?José Valim blog.plataformatec.com @josevalim
  • ? ID blog twitterJosé Valim blog.plataformatec.com @josevalim