[#34722] cgi.rb の form の挙動 — FUJIOKA Takeyuki <fujioka@...>

藤岡です。

18 messages 2002/04/02

[#34724] 「たのしい Ruby 」 — Shin-ichiro HARA <sinara@...>

原(信)です。

18 messages 2002/04/02
[#34728] Re: 「たのしい Ruby 」 — matz@... (Yukihiro Matsumoto) 2002/04/02

まつもと ゆきひろです

[#34746] Re: 「たのしい Ruby 」 — TAKAHASHI Masayoshi <maki@...> 2002/04/02

高橋征義です。

[#34752] Re: 「たのしい Ruby 」 — Shin-ichiro HARA <sinara@...> 2002/04/03

原(信)です。

[#34842] [ann] Web 家計簿(β版)リリース — 堀川 久 <vzw00011@...>

こんにちは。

18 messages 2002/04/07
[#34869] Re: [ann] Web 家計簿(β版)リリース — Nobuhide Kanagawa <nobuhide@...> 2002/04/11

こんばんわ!

[#34885] creating a scope / anonymous module — Takaaki Tateishi <ttate@...>

立石です.

38 messages 2002/04/13
[#34891] Re: creating a scope / anonymous module — nobu.nakada@... 2002/04/14

なかだです。

[#34892] Re: creating a scope / anonymous module — Takaaki Tateishi <ttate@...> 2002/04/14

At Sun, 14 Apr 2002 18:00:12 +0900,

[#34894] Re: creating a scope / anonymous module — nobu.nakada@... 2002/04/14

なかだです。

[#34896] Re: creating a scope / anonymous module — Takaaki Tateishi <ttate@...> 2002/04/14

At Sun, 14 Apr 2002 21:08:47 +0900,

[#34899] Re: creating a scope / anonymous module — matz@... (Yukihiro Matsumoto) 2002/04/15

まつもと ゆきひろです

[#34901] Re: creating a scope / anonymous module — Takaaki Tateishi <ttate@...> 2002/04/15

At Mon, 15 Apr 2002 09:51:05 +0900,

[#34902] Re: creating a scope / anonymous module — matz@... (Yukihiro Matsumoto) 2002/04/15

まつもと ゆきひろです

[#34903] Re: creating a scope / anonymous module — Takaaki Tateishi <ttate@...> 2002/04/15

At Mon, 15 Apr 2002 13:53:53 +0900,

[#34904] Re: creating a scope / anonymous module — matz@... (Yukihiro Matsumoto) 2002/04/15

まつもと ゆきひろです

[#34910] Re: creating a scope / anonymous module — Takaaki Tateishi <ttate@...> 2002/04/15

At Mon, 15 Apr 2002 15:07:57 +0900,

[#34958] windows 版 ruby でシステムコマンドが動かない — "jazzski _comp" <jazzski_comp@...>

はじめてrubyを使うのですが、windows版(cygwin版1.6.1)で下記のように

12 messages 2002/04/23

[ruby-list:34952] Re: Thread by callcc

From: Tanaka Akira <akr@...17n.org>
Date: 2002-04-21 05:41:14 UTC
List: ruby-list #34952
In article <4.3.2-J.20020418180027.03565ca0@blade.nagaokaut.ac.jp>,
  Shin-ichiro HARA <sinara@blade.nagaokaut.ac.jp> writes:

> 事の起こりは立石さんが [rubyist:1340] で、もうちょっと Continuation
> の応用例で良いのをあげましょう、という話だったんですが、新井さんが、
> Continuation なんかいらないんじゃないかと、暴言:-)を吐き、しまいには
> まつもとさんも、Rite じゃやめちゃうかも、などと言う始末。一方、Tosh 
> さんが、[rubyist:1352] で、choose という Non-deterministic Programming
> を実現する非常に興味深い例をあげて、でもちょっとまずいところもあるん
> だ、という話でした。

個人的には callcc のような怪しい機能は大好きなのですが、知合いの
callcc 有害論ももっともだと思うこともあり、態度を決めかねていたりしま
す。

> 前置きが長くなりましたが、この CoThread というのが、かなり良く出来て
> いるかもしれない、と思うので説明します。

これって単にロックを書かなくていいというだけでは?

だとしたら、むしろスレッドの亜種としてコルーチンのサポートを入れるとい
う手もあるのでは?

と、思ったので、試してみました。

コルーチンを coroutine.rb というので(内部でスレッドを使って)実装し、

> (2) 平行 each
> (3) 内部イテレータの外部イテレータへの変換

と同じ API をコルーチンで作りなおしてみました。

coroutine.rb は次のようなものです。

--- coroutine.rb ---
require 'thread'

class Thread
  def mutex
    @mutex = Mutex.new unless defined? @mutex
    @mutex
  end

  def resume(val=nil)
    self.mutex.lock
    @val = val
    self.run
    Thread.current.mutex.unlock
    Thread.stop

    self.queue.enq val
    Thread.current.queue.deq
  end
end

class Coroutine < Thread
  def initialize(&block)
    caller = Thread.current
    super() {
      Thread.stop

      caller.resume block.call(self.queue.deq)
    }
  end
end

if $0 == __FILE__
  main = Thread.current
  c = Coroutine.new {|a|
    p a
    p 2
    p main.resume(2.5)
    p 4
    p main.resume(4.5)
    p 6
    p main.resume(6.5)
  }
  p 1
  p c.resume(1.5)
  p 3
  p c.resume(3.5)
  p 5
  p c.resume(5.5)
end
------

で、これを使うと sync-each.rb と generator.rb は次のように書けます。

--- sync-each.rb ---
require 'coroutine'

class SyncEach
  include Enumerable

  def initialize(*es)
    @size = es.first.size
    @cs = es.map {|e|
      Coroutine.new {|t|
        e.each {|x|
	  t = t.resume x
	}
      }
    }
  end

  def each
    @size.times {
      yield @cs.map {|c| c.resume(Thread.current)}
    }
  end
end

if $0 == __FILE__
   foo = SyncEach.new(0..3, 10..13, 20..23)
   foo.each do |a|
     p a
   end
end
------

--- generator.rb ---
require 'coroutine'

class Generator
  def initialize(enum, iter = :each, eoi = :eoi)
    @c = Coroutine.new {|t|
      enum.send(iter) {|x|
        t = t.resume x
      }
      t.resume(eoi)
    }
  end

  def next
    @c.resume(Thread.current)
  end
end

if $0 == __FILE__
   g = Generator.new(0..3)

   while :eoi != (x = g.next)
     p x
   end

   puts

   module Fibonacci
     def self.each
       a, b = -1, 1
       loop do
        a, b = b, a + b
        yield b
       end
     end
   end

   g = Generator.new(Fibonacci)
   while (x = g.next) < 200
     p x
   end
end
------

行数を比較してみるとわかりますが、ほとんど同じです。

というわけで、

> それぞれ、Thread を使うとかなり気を使わなければならないところが、
> ずいぶん素直に書けていると思います。

という主張は、やはり、単にロックを気にしなくていいというところに起因す
るのであろうという結論に至りました。

> こんな風にライブラリを充実させていけば、callcc も生き延びられる?

思うに、コルーチンでは済まない用途を模索しないと生き延びられないんじゃ
ないでしょうか。ところが、そういう

In article <4.3.2-J.20020419184737.031a7f58@blade.nagaokaut.ac.jp>,
  Shin-ichiro HARA <sinara@blade.nagaokaut.ac.jp> writes:

> この Thread by callcc のフレームに乗らない callcc の例を考えて
> みたのですが、こういうバックトラッキングシステムが該当するよう
> です。

というようなやつをサポートするには言語およびライブラリの手厚い支援が必
要です。

とくにライブラリは厄介で、こういうのを安全に使うには、全ての(あるいは
少なくとも大部分の)ライブラリが、常にクライアントのコードを実行したら
そこで継続を保存されて、何回も再入してくるという可能性を考慮して書かな
いといけません。これはライブラリの作者にとって負荷が高すぎ、しかも、そ
れに対して用途が少な過ぎる、というのが知合い(g新部さん)の callcc 有害
論です。

なかなか反論するのは難しいです。

理論的な意味合いで、primitive が少なくなるからよい、というのには同意し
てくれるんですが、それが実際的なプログラミングに結び付くかというとなか
なか難しいわけです。

なお、Ruby には dynamic-wind がないのでライブラリを callcc safe にする
のは難しいでしょうね。いや、あっても難しいという気はしますが。
-- 
[田中 哲][たなか あきら][Tanaka Akira]
「ふえろ! わかめちゃん作戦です$(C⊇」(Little Worker, 桂遊生丸)

In This Thread