作者: Hiroshi Shinohara
日時: 2003/11/03(00:21)
  今回は、Co-Expressionの説明です。 辞書を引くと、Co-という接頭辞は、「共同、
共通、相互、同等」という意味らしいですね。
  Expressionは「式」ですから直訳は、共同式、共通式、相互式、同等式とか  なり
ますね。
  でも日本語にしても相変わらず意味不明なので、Icon教典(The Icon Programming
Language)を ひもといてみます。

  generatorを1つ考えます。  "A"〜"E"までの文字を発生する !"ABCDE"を取り上げ
ます。
  この generatorを使う場合は、例えば、こんなプログラムを書いて、
-----^ CEXP01.ICN ( date:03-11-02 time:18:47 ) -------------<cut here
####################
# Co-Expression 1
####################
# Cexp01.icn Rev.1.1 2003/11/02 hshinoh
# generatorの出力例。
# This file is in the public domain.

procedure main()
  write("Co-Expression テスト1")
  write("Generatorの書き出し")

  every s := !"ABCDE" do write(s)  # generatorをプログラムの中のある所で
                                   # 使うが、出力を小出しに使うことはできない。

end
-----$ CEXP01.ICN ( lines:15 words:36 ) --------------------<cut here

  動かすとこんな風になります。
-----^ CEXP01.1 ( date:03-11-02 time:23:08 ) ---------------<cut here
Co-Expression テスト1
Generatorの書き出し
A
B
C
D
E
-----$ CEXP01.1 ( lines:7 words:8 ) ------------------------<cut here

  この generatorの出力を、プログラムのある場所で最初の "A"、次の場所で "B"、
更に次の場所で "C"と順に使っていくことはできません。
  一旦 listに入れて、順に 取り出して使うとかの手を使えば、できない訳ではあり
ませんが、面倒になります。

  そこで、Co-Expressionの出番となります。 早速、Co-Expressionの生成とそれを
順に使っていく例を次に。

-----^ CEXP02.ICN ( date:03-11-02 time:18:43 ) -------------<cut here
####################
# Co-Expression 2
####################
# Cex02.icn Rev.1.1 2003/11/02 風つかい
# This file is in the public domain.

procedure main()
  write("Co-Expression テスト2")

# ↓Co-Expression ↓generator
  C1 := create(!"ABCDE")            # !"ABCDE"は、"A","B","C","D","E"を順次
       # ↑Co-Expression生成        # 発生する generator

  # 最初のデータを使用
  write("1番目:",@C1)
  # 次のデータを使用
  write("2番目:",@C1)

  # 以降のデータを使用
  n := 2
  while write(n +:= 1,"番目:",@C1)

end
-----$ CEXP02.ICN ( lines:23 words:51 ) --------------------<cut here

  Co-Expressionを生成するには、generatorの前に createと書くだけです。
  generator以外でも文法的には良いのですが、generatorでないと 1個しかデータが
生成されませんので、多分 意味が無いと思います。
  使うときは、Co-Expressionの前に @を付けます。
  Co-Expressionから続けて データを取り出すには 前に whileを付けます。

  動かすとこんな風になります。
-----^ CEXP02.1 ( date:03-11-02 time:23:08 ) ---------------<cut here
Co-Expression テスト2
1番目:A
2番目:B
3番目:C
4番目:D
5番目:E
-----$ CEXP02.1 ( lines:6 words:7 ) ------------------------<cut here

  この例は、main()内で Co-Expressionを生成して使っていますが、別の procedureに
Co-Expressionを引き継ぐことができます。
  そのサンプルを次に
-----^ CEXP03.ICN ( date:03-11-02 time:23:32 ) -------------<cut here
####################
# Co-Expression 3
####################
# Cexp03.icn Rev.1.1 2003/11/02 風つかい
# Co-Expressionの別 procedureへの引き継ぎ
# This file is in the public domain.

procedure main()
  write("Co-Expression テスト3")

  C1 := create("A" || seq() \10)   # Co-Expressionの生成 "A1"〜"A10"を生成

  write("親:",@C1)
  child(C1)                        # 別 procedureへ引き継ぐ
  write("親:",@C1)

end

procedure child(C)
  write("  子:",@C)
  grandchild(C)                    # 更に別 procedureへ引き継ぐ
  write("  子:",@C)
end

procedure grandchild(Cexp)
  write("    孫:",@Cexp)
  write("    孫:",@Cexp)
  write("    孫:",@Cexp)
end

-----$ CEXP03.ICN ( lines:30 words:61 ) --------------------<cut here

  結果は次のように、別 procedureに渡っても Co-Expressionが生成するデータが
引き続いていることが、分かります。
-----^ CEXP03.1 ( date:03-11-02 time:23:32 ) ---------------<cut here
Co-Expression テスト3
親:A1
  子:A2
    孫:A3
    孫:A4
    孫:A5
  子:A6
親:A7
-----$ CEXP03.1 ( lines:8 words:9 ) ------------------------<cut here

  このように、generatorを単に別 procedureの引数に指定しても、generatorのデータ
生成機能は渡せませんが、Co-Expressionにすると、データ生成機能付きで渡せます。
  というところで、やっと generatorの出力書き出しを 別 procedureに渡せるように
なりました。

  Unicon-MLで教えて頂いたプログラムを、少し修正してものが 次になります。
-----^ CEXP04.ICN ( date:03-11-03 time:00:04 ) -------------<cut here
####################
# Co-Expression 
####################
# Cexp04.icn Rev.1.1 2003/11/02 風つかい
# seq() \10 を 別 procedureを使って書き出し
# This file is in the public domain.

procedure main()
  write("Co-Expression テスト4")
  C1 := create(seq() \10) # Co-Expressionの生成 1 〜 10 を生成
  write(gen_out(C1))      # generator出力の書き出し
end

####################
# generatorの一行書き出し procedure
####################
procedure gen_out(C,s)
  /s := " "               # 間隔文字
  s1 := ""                # 足し込み用 空文字列
  while s_cex := @C do {  # Co-Expressionから順に取り出して
    s1 ||:= s_cex || s    # 足し込む
  }
  return s1[1:-*s]
end
-----$ CEXP04.ICN ( lines:24 words:79 ) --------------------<cut here

  動かすとこうなります。
-----^ CEXP04.1 ( date:03-11-03 time:00:09 ) ---------------<cut here
Co-Expression テスト4
1 2 3 4 5 6 7 8 9 10
-----$ CEXP04.1 ( lines:2 words:12 ) -----------------------<cut here

風つかい(hshinoh@...)
IconのWWWは、  http://www.cs.arizona.edu/icon/
UniconのWWWは、http://unicon.sourceforge.net/index.html
BGM: バビロニア・ウインド / 杉本喜代志