@continuation vs callcc {}

G

Giles Bowkett

http://pastie.caboo.se/102022

Greg Brown and I wrote this at Ruby East. It uses a continuation. The
thing is, the purpose of this code is to allow you to pop out of irb
into vi (or emacs, or TextMate, etc.) so you can edit your code, and
then pop back into irb to evaluate it. We use a continuation because
if there's a syntax error in the code, you want to be able to get back
to vi and rework the code without having to do a lot of work.

The final version (or at least most up-to-date version) uses a
different method. But the question here is - is this a real
continuation? And also, we looked at switching it to use callcc(), but
it looked like there wouldn't be any real difference. What is the
difference there? Would this code be better with callcc?

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com/
 
L

Logan Capaldo

I don't know you're getting much benefit from the apparent
contiuationess of this so much as the captured binding. I think you
get the same effect from something like the following

def bnd
@b ||= binding
end

def vi
system "vim #{file.path}"
eval(file.read, bnd)
end

Some code ellided
 
R

Robert Dober

I don't know you're getting much benefit from the apparent
contiuationess of this so much as the captured binding. I think you
get the same effect from something like the following

def bnd
@b ||= binding
end

def vi
system "vim #{file.path}"
eval(file.read, bnd)
end

Hmm Logan your solution does not seem to save state, I tried
vi
-->@a=1
-->:wq
vi
-->p @a
--> :wq
nil

I have no clue where the problem is.

To Giles: no this is not a continuation, I have however never been up
to the task to understand continuations, so unfortunately I cannot
really answer your questions.
OTOH Why use the complicated stuff if the simple does? Or do you have
a hidden agenda ;).

There seems to be a problem with reopen too, I guess I fixed that, I
have changed the name from @continuation to closure.
What do you think about this version?

------------------------- 8< ----------------------------
require 'tempfile'
def closure
file = Tempfile.new("irb_tempfile")
lambda do
system("vim #{file.path}")
eval(file.read)
file.rewind
end
end

def vi
(@closure = closure).call
rescue => error
puts error
end

def reopen
@closure.call if @closure
rescue => error
puts error
end

------------------------- >8 ----------------------------

Robert
 
L

Logan Capaldo

Hmm Logan your solution does not seem to save state, I tried
vi
-->@a=1
-->:wq
vi
-->p @a
--> :wq
nil

I have no clue where the problem is.

Interesting. I'm a little surprised but not very surprised. I wasn't
sure if that would work, and at the time I had no ruby to test with.
 
R

Robert Dober

Interesting. I'm a little surprised but not very surprised. I wasn't
sure if that would work, and at the time I had no ruby to test with.
Sorry Logan, I just fixed it, and when fixing it I found it strange
and retested your solution, which ...

works perfectly!

Need new glasses, sorry!

Robert
 
G

Giles Bowkett

I don't know you're getting much benefit from the apparent
contiuationess of this so much as the captured binding. I think you
get the same effect from something like the following

yeah, we were calling it a "poor man's continuation" when we were
hacking on it. it's not really a continuation, yet it is a thing which
allows you to continue. (so to speak.)
To Giles: no this is not a continuation, I have however never been up
to the task to understand continuations, so unfortunately I cannot
really answer your questions.
OTOH Why use the complicated stuff if the simple does? Or do you have
a hidden agenda ;).

Actually I hacked on it some more and ended up with a much simpler
version, no continuations or bindings, much easier to work with.

http://pastie.caboo.se/102939

It just creates an object which stores stuff, basically.

I'm curious though about the difference between a continuation and a
proc you call manually when you want to continue with it. I had a book
somewhere that explained what callcc is really for, it showed how to
use call/cc in Lisp, I think Scheme, but I'm not sure where I left it.
Actually I think it was "The Scheme Programming Language."
There seems to be a problem with reopen too, I guess I fixed that, I
have changed the name from @continuation to closure.
What do you think about this version?

------------------------- 8< ----------------------------
require 'tempfile'
def closure
file = Tempfile.new("irb_tempfile")
lambda do
system("vim #{file.path}")
eval(file.read)
file.rewind
end
end

def vi
(@closure = closure).call
rescue => error
puts error
end

def reopen
@closure.call if @closure
rescue => error
puts error
end

I think the file.rewind might not be necessary any more. I think
refactoring it into a method like that was a good idea. reopen was
kind of a hack in the original, the more fully worked-out version will
automatically reopen if you created a file (and will create different
buffers if you use different editors, brag brag brag) but I think you
could accomplish very much the same thing if you combine #vi and
#reopen like this:

def vi
(@closure ||= closure).call
rescue => error
puts error
end

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com/
 
A

ara.t.howard

I'm curious though about the difference between a continuation and a
proc you call manually when you want to continue with it. I had a book
somewhere that explained what callcc is really for, it showed how to
use call/cc in Lisp, I think Scheme, but I'm not sure where I left it.
Actually I think it was "The Scheme Programming Language."


"Continuations are the functional expression of the GOTO statement,
and the same caveats apply.[citation needed] While many believe that
they are a sensible option in some special cases such as web
programming, use of continuations can result in code that is
difficult to follow. In fact, the esoteric programming language
Unlambda includes call-with-current-continuation as one of its
features solely because of its resistance to understanding. The
external links below illustrate the concept in more detail.

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

;-)


a @ http://drawohara.com/
 
R

Robert Dober

On 10/4/07 said:
I think the file.rewind might not be necessary any more.
Hmm on my Linux it definitely was, did you test it on Windows?
I think
refactoring it into a method like that was a good idea. reopen was
kind of a hack in the original, the more fully worked-out version will
automatically reopen if you created a file (and will create different
buffers if you use different editors, brag brag brag) but I think you
could accomplish very much the same thing if you combine #vi and
#reopen like this:

def vi
(@closure ||= closure).call
rescue => error
puts error
end
Yup I just do not like instance variables ;) (as one can see on my
Blog), I still had to use one as I was not capable of creating a
closure into the IRB session (that would be cool BTW).
And as I needed the rewind I had to complicate the code anyway :(
Robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,160
Messages
2,570,889
Members
47,422
Latest member
LatashiaZc

Latest Threads

Top