Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Lucas faucet-pipeline.org complate

Slide 3

Slide 3 text

Part 1: Motivation

Slide 4

Slide 4 text

“FP vs. OO”

Slide 5

Slide 5 text

Identity Behavior State In Clojure…

Slide 6

Slide 6 text

Identity Behavior State In Halunke…

Slide 7

Slide 7 text

Part 2: The Language

Slide 8

Slide 8 text

(1 + 2) Receiver Argument Message

Slide 9

Slide 9 text

(“Halunke” replace “Ha” with “Spe”) Receiver Argument Message

Slide 10

Slide 10 text

(“Halunke” replace “Ha” with “Spe”) Sends “Halunke” the message “replace with” with the arguments [“Ha” “Spe”]

Slide 11

Slide 11 text

(‘a = 2) Receiver Argument Message

Slide 12

Slide 12 text

•All objects are immutable •A reference created with ‘a can’t be reassigned •In the future, there will be reassignable references with @a

Slide 13

Slide 13 text

No nil/null REPL Define own functions Define own classes Conditionals are messages, not syntax Number, String, Array, Dictionary, Regexp Web Module & a tiny Routing Lib

Slide 14

Slide 14 text

('a = 12) ('my = "str") ("hello" replace (my replac "i" wit "a") with "mumpf") (stdio puts "a") Currently in Development 4 | ("hello" replace (my replac "i" wit "a") with "mumpf") ^^^^^^^^^^^^^^^^^^^^^^^ The String "str" received the message `replac wit`. It doesn't know how to handle that. Did you mean `replace with`?

Slide 15

Slide 15 text

Live Demo :)

Slide 16

Slide 16 text

Part 3: Implementation Written in Ruby!

Slide 17

Slide 17 text

(“Halunke” replace “Ha” with “Spe”)

Slide 18

Slide 18 text

=> [[:OPEN_PAREN, “(“], [:STRING, “Halunke“], [:BAREWORD, “replace“], [:STRING, “Ha“], [:BAREWORD, “with“], [:STRING, “Spe“], [:CLOSE_PAREN, “)“]] a = Halunke ::Lexer.new a.tokenize(‘ ‘) (“Halunke“ replace “Ha“ with “Spe“) Lexer

Slide 19

Slide 19 text

Lexer (with Ragel) string = '"' [^"]* '"'; bareword = [a-zA-Z_]+ | '+' | '-' | '*' | '/' | '<' | '>' | '=' | '@'; open_paren = '('; close_paren = ')'; 1. Define Tokens

Slide 20

Slide 20 text

Lexer (with Ragel) 2. React to tokens string => { emit(:STRING, data[ts+1 ...te-1]) }; bareword => { emit(:BAREWORD, data[ts ...te]) }; open_paren => { emit(:OPEN_PAREN, data[ts ...te]) }; close_paren => { emit(:CLOSE_PAREN, data[ts ...te]) }; space; any => { raise "Could not lex ' #{ data[ts ...te] }'" };

Slide 21

Slide 21 text

Parser b = Halunke ::Parser.new b.parse('("Halunke" replace "Ha" with “Spe")') => #, message=#, #, #, # ]> > ]>

Slide 22

Slide 22 text

Parser (with racc) Program: Expressions { val[0] } ; Expressions: /* empty */ { Nodes.new([]) } | Expression Expressions { Nodes.new([val[0]].concat(val[1].nodes)) } ; Expression: STRING { StringNode.new(val[0]) } | BAREWORD { BarewordNode.new(val[0]) } | OPEN_PAREN Expression Expressions CLOSE_PAREN { MessageSendNode.new(val[1], val[2].to_message) } ;

Slide 23

Slide 23 text

Why doesn’t the parser just lex as well?

Slide 24

Slide 24 text

Regular C ontext Free C ontext Sensitive Recursively Enum erable Chomsky hierarchy Finite Statem achine Pushdow n Autom aton Linear-bounded non-determ inistic Turing m achine Turing M achine More powerful, less guarantees, less performance

Slide 25

Slide 25 text

Regular C ontext Free Chomsky hierarchy Finite Statem achine Pushdow n Autom aton More powerful, less guarantees, less performance

Slide 26

Slide 26 text

Regular C ontext Free Chomsky hierarchy Regular Expressions C ontext Free G ram m ar More powerful, less guarantees, less performance

Slide 27

Slide 27 text

We have nodes now. What’s next?

Slide 28

Slide 28 text

Tree-Walk Interpreter

Slide 29

Slide 29 text

Every node has an eval method

Slide 30

Slide 30 text

Nodes = Struct.new(:nodes) do def eval(context) nodes.map { |node| node.eval(context) }.last end end

Slide 31

Slide 31 text

What happens now? Let’s dive into the code

Slide 32

Slide 32 text

⌨ https://try.halunke.jetzt @moonbeamlabs