discovering joy

Post on 28-May-2015

290 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

Slides for Ruby Manor 4 talk

TRANSCRIPT

on Discovering JoyFrancis Fish (@fjfish)

Fish?

NOT COMPUTER SCIENTIST

LIKE PROGRAMMING

LEARN NEW LANGUAGE LONG TIME NOW

KNOW NOTHING, YOU MUCH CLEVERER THAN ME

DISCOVERING JOY - NOT EXPERT!

Blame Braithwaite

Appendix

Finding joy in combinators

Combinators

Combinator?

http://en.wikipedia.org/wiki/Combinator

A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.

(no parameters, functions as arguments)

Joy Resources

http://en.wikipedia.org/wiki/Joy_(programming_language)

Invented by Manfred von Thun of La Trobe University in Melbourne, Australia (retired)

Purely functional, combinatorial, stack based

Mirror http://www.kevinalbrecht.com/code/joy-mirror/joy.html

Interesting

Program is data (like Lisp)

Stack based - no parameters

Post-fix (goes with stack)

Does functional stuff well

Combinators - take what’s on the stack and do stuff - including combining other combinators

Not Forth - no dictionary - functional

Quoted programs called by combinators

Stack Based?

Let’s go see

Example: Square

5 dup * .

- will print 25 and leave the stack empty

(as a function)

square == dup *

(== is the only infix operator - not runtime)

WAT?

Parameters, None

A stack of combinators

Code acts on the stack

dup *

Copy it and multiply the top 2 elements together

Cube - you tell me :)

5 dup dup * *.

5 # 5

dup # 5 5

dup # 5 5 5

* # 5 25

* # 125

125

Programs

Joy programs are built from smaller programs by just two operations: concatenation and quotation.

Quoted Programs[bob alice]

Is a list, but also a quoted program

You can plug it into things and then execute

Built in functions, anonymous Y combinator etc.

Fill in the blanks

Types

character, file, float, integer, list, set, string, truth

What else do you need?

(Except maybe hash)

And sets are weird

Combinators

ifte - if then else

The ifte combinator expects three quoted programs on the stack, an if-part, a then-part and an else-part, in that order, with the else-part on top

dip

dip combinator expects a program on top of the stack and below that another value. It saves the value, executes the program on the remainder of the stack and then restores the saved value.

i

identity - run the quoted program on the top of the stack

Combinators

concat

Join two aggregates together

cons - lisp

Add the top thing to the aggregate behind it on the stack

dup

Duplicate the stack top

swap

cause a flight of penguins

Combinators

Not talking about:

construct, dupd, map, popd, rolldown, rolldownd, rollup, rollupd, rotate, succ, pred, swap, swapd, swons, times, take, ternary, treegenrec, unswons, x, first ...

Example:Factorial

Linear Recursion

5 [null] [succ] [dup pred] [*] linrec .

["null" false]["dup pred" 4 5]["null" false 5]["null" false 3 4 5]["*" 6 4 5]...["*" 120]["linrec" 120]

120

linrec : [P] [T] [R1] [R2] -> ....Executes P. If that yields true, executes T.Else executes R1, recurses, executes R2.

Primitive Recursion

5 [1] [*] primrec .

["R0" 1 1 2 3 4 5]["*" 1 2 3 4 5]["*" 2 3 4 5]["*" 6 4 5]["*" 24 5]["*" 120]120

(HINT: it’s not recursion)

primrec : X [I] [C] -> R.Executes I to obtain an initial value R0.For integer X uses increasing positive integers to X, combines by C for new R.For aggregate X uses successive members and combines by C for new R.

Y-Combinator

5

[ [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte ]

[dup cons] swap concat dup cons i

Explanation

5

[ [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte ]

[dup cons] swap concat dup cons i

Cond Else Then

[ [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte ]

If the top of the stack is 0

discard the copied program and the 0 left and push 1

else

duplicate the top of the stack and subtract 1 from the top valuethen dip and call the copy of yourself underneath the stack topon return apply *

* the value below with the one you calculated and put it on the stack (this is the accumulator)

[dup cons] swap concat dup cons i

(We already have the quoted program and the integer on the top of the stack)

(We push a quoted dup cons onto the stack)

run whats comes out of:

Take the stack top and cons to aggregate underneath

dup the aggregate

concat them together swap with whatever’s on the stack top

We end up with the previous quoted program on the stack top and run it

Just for laffs[ [pop 0 = '1 printstack] [pop pop 1 '2 printstack] [[dup 1 - '3 printstack] dip i * '4 printstack] ifte '5 printstack][dup cons '6 printstack] swap concat '7 printstack dup cons '8 printstack i

['7 [dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] 5]['8 [[dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] 5]['6 [[dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] 5]['1 false]['3 4 5]['6 [[dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] 4 5]['1 false 5]['3 3 4 5]['6 [[dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] 3 4 5]

['1 false 4 5]

['3 2 3 4 5]

['6 [[dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] 2 3 4 5]

['1 false 3 4 5]

['3 1 2 3 4 5]

['6 [[dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] 1 2 3 4 5]

['1 false 2 3 4 5]

['3 0 1 2 3 4 5]

['6 [[dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] dup cons [pop 0 =] [pop pop 1] [[dup 1 -] dip i *] ifte] 0 1 2 3 4 5]

['1 true 1 2 3 4 5]

['2 1 1 2 3 4 5]

['5 1 1 2 3 4 5]

['4 1 2 3 4 5]

['5 1 2 3 4 5]

['4 2 3 4 5]

['5 2 3 4 5]

['4 6 4 5]

['5 6 4 5]

['4 24 5]

['5 24 5]

['4 120]

['5 120]

120

What Have I discovered?

Ruby Practice

How do we do recursion?

We can see the stack, this reminds us of things we had forgotten

Recursion can always be recast as iteration

Quick poll - how many people know this?

How many had forgotten?

Can make difficult problems more tractable

Ruby Practice

Program is data?

Method missing/symbols

Dispatch tables etc.

ERB - macro languages

THings to think about

Can we use stacks and combinators to solve problems more easily?

Can we create DSL’s that do this?

Would we want to :)

Building a web app

Who needs HAML when we could have:

[ [ [ ["Hello" div] ] body ] [ [ [“My App” title] [“main.js” script] ] head]] html

Next?

http://programjoy.eu - £1.40 :)

Will front a runtime and links to the mirror

Will run the tutorial

If you want to help - contact me

More fun to work on rather than <corporate-bs>next big ecommerce social doo dah site</corporate-bs>

Finis/QuestionsFrancis Fish (@fjfish)www.francisfish.com

www.leanpub.com/fjfish

top related