@continuation vs callcc {}

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/

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

···

On 10/3/07, Giles Bowkett <gilesb@gmail.com> wrote:

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/

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

···

On 10/3/07, Logan Capaldo <logancapaldo@gmail.com> wrote:

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

--
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/

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.

···

On 10/4/07, Robert Dober <robert.dober@gmail.com> wrote:

On 10/3/07, Logan Capaldo <logancapaldo@gmail.com> wrote:
> 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.

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/

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

···

On 10/4/07, Logan Capaldo <logancapaldo@gmail.com> wrote:

On 10/4/07, Robert Dober <robert.dober@gmail.com> wrote:
> On 10/3/07, Logan Capaldo <logancapaldo@gmail.com> wrote:
> > 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.

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.

"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.

:wink:

a @ http://drawohara.com/

···

On Oct 4, 2007, at 12:54 PM, Giles Bowkett wrote:

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."

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

<snip>

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 :wink: (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 :frowning:
Robert

···

On 10/4/07, Giles Bowkett <gilesb@gmail.com> wrote:
--
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/