https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112014-11-26T11:51:04ZRuby Issue Tracking SystemRuby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=501042014-11-26T11:51:04Ztarui (Masaya Tarui)tarui@prx.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>Applied in changeset r48588.</p>
<hr>
<ul>
<li>ext/continuation/continuation.c (Init_continuation): obsolete callcc.<br>
first step of [Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: remove callcc (Callcc is now going obsoleted. Please use Fiber.) (Open)" href="https://redmine.ruby-lang.org/issues/10548">#10548</a>].</li>
</ul> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=501052014-11-26T11:52:56Ztarui (Masaya Tarui)tarui@prx.jp
<ul><li><strong>Subject</strong> changed from <i>Callcc is now going obsoleted. Please use Fiber.</i> to <i>remove callcc (Callcc is now going obsoleted. Please use Fiber.)</i></li><li><strong>Category</strong> set to <i>ext</i></li><li><strong>Status</strong> changed from <i>Closed</i> to <i>Open</i></li><li><strong>Target version</strong> set to <i>2.6</i></li></ul> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=501072014-11-26T14:33:59Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>That's a bummer!</p>
<p>Callcc is the most exciting toy for the functional programmers.<br>
If Ruby had no callcc, I couldn't have been interested in Ruby.</p>
<p>No one think it production ready.<br>
When callcc is used, the user is (or should be) not serious but mischievous.<br>
You don't have to pay any cost for its consistency.<br>
SEGV is welcome when used in combination with another feature.</p>
<p>Instead of making it obsoleted, how about printing a big warning banner when "contination" is required?</p>
<pre><code>rb_warn("****************************************");
rb_warn("** WARNING!! callcc is a JOKE feature **");
rb_warn("** Are you ready to see nasal demons? **");
rb_warn("****************************************");
</code></pre>
<p>I wish you'd reconsider.</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@ruby-lang.org" class="email">mame@ruby-lang.org</a></p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=502062014-11-30T11:52:31Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><p>I am neutral on this, I have no pro or con opinion here, but I wanted to comment<br>
on what Yusuke Endoh wrote, and in particular suggest perhaps something for<br>
future feature-references that are not extremely important but also not totally<br>
useless or "fun features".</p>
<p>I think we also have goto operator in Ruby which is also a joke feature.</p>
<p>I also remember evil.rb from ... Florian G. or someone, which added things<br>
like .unfreeze and such back then (I think it was in ruby 1.8.x era).</p>
<p>Perhaps the ruby stdlib/corelib can add a submodule or perhaps a smaller<br>
subprojects within ruby of "JOKE features", where matz/the ruby core team<br>
does not promote this, but if people want to play with that, they can do<br>
so. And such things can be bundled together into that project, like</p>
<p>require 'ruby/jokes'</p>
<p>or</p>
<p>require 'ruby/jokes'</p>
<p>or</p>
<p>require 'specialities'</p>
<p>Or something like that. :)</p>
<p>If things would become more popular, they could be moved out<br>
of it again, and if things are not popular then they can<br>
remain there (and people who like those features ideally could<br>
maintain it there too!)</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=517112015-03-01T02:52:11Zstephenprater (Stephen Prater)me@stephenprater.com
<ul></ul><p>I agree with Yusuke.</p>
<p>I'd be sorry to see it go - it does some neat tricks that are a lot harder to pull off with Fibers.</p>
<p>Here for instance is a PoC reversible debugger: <a href="https://gist.github.com/stephenprater/ca312d24578455f36550" class="external">https://gist.github.com/stephenprater/ca312d24578455f36550</a></p>
<p>I don't think you can do that with Fibers, since the control flow with fibers is still always forward.</p>
<p>prater</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=560372016-01-10T05:23:14Ztank_bohr (Alexey Nikitin)
<ul></ul><p>Please don't do it. Continuations are awesome</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=583562016-04-27T11:35:39ZOverbryd (Lukas Rieder)
<ul></ul><p><strong>Please keep callcc, they are inherently awesome to build constraint solvers.</strong></p>
<p>I am using them in a real life application. I am calculating the available tables for a full calendar with many time slots and with respect to many configurable business rules for restaurants.<br>
Using callcc this feature got blazingly fast and very nicely readable. Also we use it to optimise table arrangements with respect to complex restaurant business rules (even something like: Guest A doesn't like to sit near Guest B).</p>
<p>Please just have a look at these resources:</p>
<ul>
<li><a href="https://github.com/chikamichi/amb/tree/master/examples" class="external">https://github.com/chikamichi/amb/tree/master/examples</a></li>
<li><a href="http://web.archive.org/web/20151116124853/http://liufengyun.chaos-lab.com/prog/2013/10/23/continuation-in-ruby.html" class="external">http://web.archive.org/web/20151116124853/http://liufengyun.chaos-lab.com/prog/2013/10/23/continuation-in-ruby.html</a></li>
</ul>
<p>Please help me to keep Guest A away from Guest B. Bad things might happen.</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=647872017-05-13T10:32:20Zjphelps (Jeremy Phelps)
<ul></ul><p>I just learned that Ruby has continuations. Then I learned that they're considered obsolete, and "instead" we're supposed to use a feature (basically just Python's yield statement) that has zero use cases in common with continuations.</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=647882017-05-13T11:47:37ZEregon (Benoit Daloze)
<ul></ul><p>jphelps (Jeremy Phelps) wrote:</p>
<blockquote>
<p>I just learned that Ruby has continuations. Then I learned that they're considered obsolete, and "instead" we're supposed to use a feature (basically just Python's yield statement) that has zero use cases in common with continuations.</p>
</blockquote>
<p>This is untrue. Ruby Fibers have little in common with Python generators.<br>
The most important feature is they have a stack.<br>
In other words, they are stackful coroutines, which can be used both as asymmetric coroutines (yield/resume) and symmetric coroutines (transfer).</p>
<p>But yes, they cannot go back in the control flow, in opposition to coroutines.<br>
IMHO coroutines are extremely hard to understand and have drawbacks similar to GOTO.</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=647992017-05-13T19:01:08Zjwmittag (Jörg W Mittag)Ruby-Lang@JoergWMittag.De
<ul></ul><p>jphelps (Jeremy Phelps) wrote:</p>
<blockquote>
<p>I just learned that Ruby has continuations. Then I learned that they're considered obsolete, and "instead" we're supposed to use a feature (basically just Python's yield statement) that has zero use cases in common with continuations.</p>
</blockquote>
<p>Even back when <code>callcc</code> was still officially considered to be "part of Ruby", it was actually not implemented by the majority of Ruby implementations.</p>
<ul>
<li>JRuby doesn't implement it,</li>
<li>Rubinius doesn't implement it,</li>
<li>Opal doesn't implement it,</li>
<li>Topaz doesn't implement it,</li>
<li>TruffleRuby doesn't implement it,</li>
<li>IronRuby doesn't implement it,</li>
<li>even MRuby, the implementation written by matz himself doesn't implement it.</li>
</ul>
<p>The only two implementations that currently implement <code>callcc</code> are YARV and MagLev.</p>
<p>So, yes, it is <em>officially</em> still part of Ruby, but … no-one cares.</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=648002017-05-13T19:40:31Zjphelps (Jeremy Phelps)
<ul></ul><p>Eregon, I have no idea what you're talking about. All the examples of Fiber usage over on ruby-doc.org shows identical behavior to Python's yield statement. The only difference is that in Python, "resume" is spelled "next", and you can iterate over the sequence of return values (just a monkey patch away with Fibers). Oh, and the way Python handles a dead generator is different (you start getting void instead of an exception).</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=648012017-05-14T02:32:06Zko1 (Koichi Sasada)
<ul></ul><p>On 2017/05/14 4:40, <a href="mailto:jeremy.phelps@instacart.com" class="email">jeremy.phelps@instacart.com</a> wrote:</p>
<blockquote>
<p>Eregon, I have no idea what you're talking about. All the examples of Fiber usage over on ruby-doc.org shows identical behavior to Python's yield statement. The only difference is that in Python, "resume" is spelled "next", and you can iterate over the sequence of return values (just a monkey patch away with Fibers). Oh, and the way Python handles a dead generator is different (you start getting void instead of an exception).</p>
</blockquote>
<p>COMPLETELY Off topic:</p>
<p>"Context" manipulation is one of big topic and there are many related<br>
terminologies (academic, language/implementation specific, promotion<br>
terminologies). In fact, there is confusing.</p>
<p>In few minutes I remember the following related words and it is good CS<br>
exam to describe each :p</p>
<ul>
<li>Thread (Ruby)</li>
<li>Green thread (CS terminology)</li>
<li>Native thread (CS terminology)</li>
<li>Non-preemptive thread (CS terminology)</li>
<li>Preemptive thread (CS terminology)</li>
<li>Fiber (Ruby/using resume/yield)</li>
<li>Fiber (Ruby/using transfer)</li>
<li>Fiber (Win32API)</li>
<li>Generator (Python/JavaScript)</li>
<li>Generator (Ruby)</li>
<li>Continuation (CS terminology/Ruby, Scheme, ...)</li>
<li>Partial continuation (CS terminology/ functional lang.)</li>
<li>Exception handling (many languages)</li>
<li>Coroutine (CS terminology/ALGOL)</li>
<li>Semi-coroutine (CS terminology)</li>
<li>Process (Unix/Ruby)</li>
<li>Process (Erlang/Elixir)</li>
<li>setjmp/longjmp (C)</li>
<li>makecontext/swapcontext (POSIX)</li>
<li>Task (...)<br>
(maybe more and more words in the world)</li>
</ul>
<p>(1) describe each words (10 point/each).<br>
(2) describe how to make each words (100 point/each).<br>
(joking. do not submit it to me :p)</p>
<p>Reviewing my carrier, I may love to consider how to control "context".<br>
My bachelor/master thesis is about how to make a threading library and<br>
doctor thesis is about how to introduce new threading mechanism on Ruby.<br>
I introduced Fiber into Ruby 1.9 and recently I'm thinking about Guild.</p>
<p>--<br>
// SASADA Koichi at atdot dot net</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=648052017-05-14T10:25:12ZEregon (Benoit Daloze)
<ul></ul><p>jphelps (Jeremy Phelps) wrote:</p>
<blockquote>
<p>Eregon, I have no idea what you're talking about. All the examples of Fiber usage over on ruby-doc.org shows identical behavior to Python's yield statement. The only difference is that in Python, "resume" is spelled "next", and you can iterate over the sequence of return values (just a monkey patch away with Fibers). Oh, and the way Python handles a dead generator is different (you start getting void instead of an exception).</p>
</blockquote>
<p>Then look for other examples than just the ones in the documentation.<br>
The fact that Fibers have a stack means Fiber.yield can be called anywhere during the Fiber execution, including in deeply nested method calls, while Python and JavaScript generators are lexically bound and restricted to only call "yield" in the generator function and not deeper. Try to reproduce this in Python:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">powers_of</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">max</span><span class="p">)</span>
<span class="n">n</span> <span class="o">=</span> <span class="n">x</span>
<span class="k">while</span> <span class="n">n</span> <span class="o"><</span> <span class="n">max</span>
<span class="no">Fiber</span><span class="p">.</span><span class="nf">yield</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="n">n</span> <span class="o">*=</span> <span class="n">x</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">powers_of_range</span><span class="p">(</span><span class="n">range</span><span class="p">,</span> <span class="n">max</span><span class="p">)</span>
<span class="n">range</span><span class="p">.</span><span class="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">powers_of</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">max</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="n">f</span> <span class="o">=</span> <span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">powers_of_range</span><span class="p">(</span><span class="mi">2</span><span class="o">..</span><span class="mi">4</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
<span class="k">raise</span> <span class="no">StopIteration</span>
<span class="k">end</span>
<span class="kp">loop</span> <span class="p">{</span>
<span class="nb">p</span> <span class="n">f</span><span class="p">.</span><span class="nf">resume</span>
<span class="p">}</span>
</code></pre>
<p>It's possible, but you either have to manually inline the two methods, or use multiple generators instead of just one Fiber here.<br>
For a more interesting usage of Fiber see <a href="https://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/" class="external">https://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/</a> for example.</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=750172018-11-21T21:17:16Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><p>Since this may be discussed in the next upcoming developer meeting, perhaps<br>
callcc could be put into a standalone gem, if it is removed? Just in the event<br>
that some people may want to keep it, could install it if they want to (a bit<br>
like the syck gem is still about, for those whose yaml files are not yet usable<br>
via psych due to errors in these yaml files, such as non-unicode yaml files).</p>
<p>This is just an idea though, please feel free to disregard if it is not<br>
applicable or too much effort.</p>
<p>Edit: In regards to mame stating years ago how callcc is fun, this also reminds me<br>
a bit of the old evil.rb and fun with "shapechanging" objects in ruby. :D I<br>
never really used callcc much at all, but it may be nice to keep old code around<br>
for some more years (there are gems on rubygems.org that are like ~15 years old,<br>
almost). Just like with the more recent theme of "keeping ruby weird", we could<br>
say we could also keep old ruby weirdness "alive" - and weird. ;)</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=752312018-11-28T05:22:28Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p><a href="mailto:tarui@prx.jp" class="email">tarui@prx.jp</a> wrote:</p>
<blockquote>
<p>Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: remove callcc (Callcc is now going obsoleted. Please use Fiber.) (Open)" href="https://redmine.ruby-lang.org/issues/10548">#10548</a>: Callcc is now going obsoleted. Please use Fiber.<br>
<a href="https://bugs.ruby-lang.org/issues/10548" class="external">https://bugs.ruby-lang.org/issues/10548</a></p>
</blockquote>
<p>How about adding --disable-callcc configure option?</p>
<p><a href="https://80x24.org/spew/20181128051213.19518-1-e@80x24.org/raw" class="external">https://80x24.org/spew/20181128051213.19518-1-e@80x24.org/raw</a></p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=752992018-11-29T21:32:45Znormalperson (Eric Wong)normalperson@yhbt.net
<ul></ul><p>Eric Wong wrote:</p>
<blockquote>
<p><a href="mailto:tarui@prx.jp" class="email">tarui@prx.jp</a> wrote:</p>
<blockquote>
<p>Feature <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: remove callcc (Callcc is now going obsoleted. Please use Fiber.) (Open)" href="https://redmine.ruby-lang.org/issues/10548">#10548</a>: Callcc is now going obsoleted. Please use Fiber.<br>
<a href="https://bugs.ruby-lang.org/issues/10548" class="external">https://bugs.ruby-lang.org/issues/10548</a></p>
</blockquote>
<p>How about adding --disable-callcc configure option?</p>
<p><a href="https://80x24.org/spew/20181128051213.19518-1-e@80x24.org/raw" class="external">https://80x24.org/spew/20181128051213.19518-1-e@80x24.org/raw</a></p>
</blockquote>
<p>Also removed ec->protect_tag when callcc is disabled:</p>
<p><a href="https://80x24.org/spew/20181129212602.12362-1-e@80x24.org/raw" class="external">https://80x24.org/spew/20181129212602.12362-1-e@80x24.org/raw</a></p>
<p>I am also considering adding an rb_ensure_nocallcc internal function<br>
to reduce stack use when b_proc and e_proc are guaranteed to not<br>
yield.</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=760192018-12-31T11:28:46Zdecuplet (Nikita Shilnikov)fg@flashgordon.ru
<ul></ul><p>FWIW, I do have a practical example for <code>callcc</code> which cannot be implemented with fibers, or at least I don't see the way it could.<br>
I'm the author of the <a href="https://github.com/dry-rb/dry-monads/" class="external">dry-monads</a> gem. Along with a bunch of monads it provides an emulation of Haskell's do notation:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Operation</span>
<span class="kp">include</span> <span class="no">Dry</span><span class="o">::</span><span class="no">Monads</span><span class="o">::</span><span class="no">Result</span><span class="o">::</span><span class="no">Mixin</span>
<span class="kp">include</span> <span class="no">Dry</span><span class="o">::</span><span class="no">Monads</span><span class="o">::</span><span class="no">Do</span>
<span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="n">monadic_value</span><span class="p">)</span>
<span class="n">extracted_value</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">monadic_value</span>
<span class="c1"># ...</span>
<span class="no">Success</span><span class="p">(</span><span class="n">extracted_value</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Here if <code>monadic_value</code> is <code>Success(value)</code> then <code>yield</code> will extract <code>value</code> from it and continue the execution. And if <code>monadic_value</code> is <code>Failure(...)</code> it will halt the execution and return this <code>Failure</code> as a result of <code>call</code>. Everything works perfectly fine and allows writing robust production code but only for monads that wrap 1 value inside. That is, it doesn't work for the list monad:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Operation</span>
<span class="kp">include</span> <span class="no">Dry</span><span class="o">::</span><span class="no">Monads</span><span class="o">::</span><span class="no">Do</span>
<span class="kp">include</span> <span class="no">Dry</span><span class="o">::</span><span class="no">Monads</span><span class="o">::</span><span class="no">List</span><span class="o">::</span><span class="no">Mixin</span>
<span class="k">def</span> <span class="nf">call</span>
<span class="n">v</span> <span class="o">=</span> <span class="k">yield</span> <span class="no">List</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
<span class="no">List</span><span class="p">[</span><span class="n">v</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>^this will return <code>List[2]</code> rather than <code>List[2, 3, 4]</code>. In order to make it work as expected, I would need to capture the continuation within <code>yield</code> so it can continue <code>call</code> more than once. I tested it, and it indeed works, but I don't want to depend on a to-be-removed feature.</p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=972852022-04-15T14:17:26Zjimwise00 (Jim Wise)
<ul></ul><p>I know it's late to weight in on this, but see the ambit[1] and unific[2] gems and the in-progress rulog[2] gem for examples of nontrivial uses of callcc which absolutely do not translate into Fibers.</p>
<p>And on a lighter note, without callcc, such key language features as the reconsidered[4] gem would not be possible, either.</p>
<p>[1] <a href="https://github.com/jimwise/ambit" class="external">https://github.com/jimwise/ambit</a><br>
[2] <a href="https://github.com/jimwise/unific" class="external">https://github.com/jimwise/unific</a><br>
[2] <a href="https://github.com/jimwise/rulog" class="external">https://github.com/jimwise/rulog</a><br>
[4] <a href="https://github.com/jimwise/reconsidered" class="external">https://github.com/jimwise/reconsidered</a></p> Ruby master - Feature #10548: remove callcc (Callcc is now going obsoleted. Please use Fiber.)https://redmine.ruby-lang.org/issues/10548?journal_id=973002022-04-18T09:07:08Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Never use callcc in practical applications or libraries. It violates a common assumption of control flow that many programs have. It allows one method call to return twice or more, which may lead to a critical consequence including a segfault.</p>
<p>Let's enjoy it as a joke feature only in toy programs. I want to keep callcc just because it is interesting. Use it seriously will shorten the life of callcc.</p>