Implement :|┃ in Ruby

:|┃

A tech talk at Tokyu RubyKaigi 12, featuring how to implement musical repeat sign :|┃ in Ruby, using continuation (callcc) which is a killer feature of Ruby.

repeat

# this is a pseudo code
puts 'step 1'
:|┃
puts 'step 2'

If it’s a music score this repeats the first line. Here let’s redefine the repeat sign to repeat forever instead of once. This is nontrivial to provide infinite loop version from finite repeat, but it’s trivial to provide finite repeat with using intinite loop right?

output:
  step 1
  step 1
  step 1
  step 1
  ... (continues forever)

I found one of the possible ways. I’m sure there would be better ways though.

# a.rb
require 'continuation'

class String
  def |(x)
    x.()
  end
end

def ┃
  -> { $c.call($c) }
end

class Proc
  def |(_)
    $c = callcc {|c| c }
  end
end
$c ||= callcc {|c| c }

and its usage:

require 'a'

puts 'before'
%: :|┃
puts 'after'

This repeats the first line forever.

Let’s look at this part carefully.

%: :|┃

%: : is equivalent to a string with a single space " ". | is an operator which means it’s just a method String#| with single argument.
The argument is a unicode character , which is either a local variable or a method. In this case it’s Object#┃ defined in a.rb.
This lets runtime goes back to the line in a.rb

$c ||= callcc {|c| c }

Note that this feature requires Ruby’s continuation. Without callcc, this feature is impossible to implement.

┃|:

You can also specify where to repeat from with using ┃|:

require 'a'

puts 'first'
┃|:"start\n".display
puts 'before'
%: :|┃
p 'after
# output:
  first
  start
  before
  before
  before
  before
  before
  ... (continues forever)

This also requires continuation.

Advertisements
Previous Post
Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: