動的言語で大規模開発

■ このスレッドは過去ログ倉庫に格納されています
1uy
垢版 |
2012/07/24(火) 09:10:42.04
たててみた
2014/12/04(木) 22:16:14.84ID:RpORv8ek
>>713
だからそれのどこにtraitが出てくるのさ。

Scalaのtraitsの出自について言及はこっちでしょ。
http://www.bytelabs.org/pub/tpl/slides/sm@lausanne/expressionProblem.pdf

Traits in SCALA[23] are abstract classes without state or
parameterized constructors; another way to characterize them
would be as JAVA-like interfaces that may also contain
inner classes and concrete implementations for some
methods. Unlike the original trait proposal[29], traits in Scala
are not different from classes. In the example above
and all examples that follow one could have also used
abstract class instead of trait.
2014/12/04(木) 22:20:18.91ID:8pz5p6Zv
>>715
どこにって、implicitを使うために中で何度でも出てくるよ?
2014/12/04(木) 22:24:26.97ID:8pz5p6Zv
こういう研究の流れを受けてか、後発のRustのtraitは
最初からHaskellのType Classそっくりになっているんですってよ
2014/12/04(木) 22:29:19.94ID:RpORv8ek
>>716
>>712

In this definition, the role of ord T is to provide the comparison
function for elements of type T. The Ord[T] interface, expressed
as a trait in Scala,
2014/12/04(木) 22:30:05.46ID:tYdcY83W
始めに実装したというのは凄いかもしれないけど、
その凄いっていうのは、始めに実装したことであって
その機能がすごいってことじゃないんだよな。
後発のほうがもっとその機能を強化している。

そして始めに実装した言語は互換性を保つために
機能強化できずにずっと続けないといけない。
2014/12/04(木) 22:45:30.93ID:RpORv8ek
>>719
それははじめに機能ありきで、それをただ実装した場合の話だろう。
試行錯誤して生まれるには、それをインキュベートする環境が必要でって話なんだが
計算機の言語を狭い意味でとらえる人にSmalltalkの特徴を説明するのは難しい。
2014/12/04(木) 22:52:15.50ID:8pz5p6Zv
>>718

> The trait Ord[T] is an example of a concept interface.

> Concept interfaces for the type classes Show and Read presented in Section 2.1 are:
2014/12/04(木) 23:00:58.08ID:5ZEJ+Feh
宇宙服みたいな言語とモビルスーツみたいな言語があるけど
どうせ結局両方使うんだよな
2014/12/04(木) 23:08:55.47ID:RpORv8ek
>>721
何そのパズルみたいな抜粋。
どうこねくり回したところでScalaのtraitに限っては
その出自はミックスインみたいなもので、型クラスそのものではないよ。
2014/12/04(木) 23:11:32.11ID:8pz5p6Zv
>>723
ついに反論しきれなくなって、traitとtype classは無関係から
そのものでは無いまで意見が後退しちゃったねw
自分もtype classそのものなんて一度も言ってないので、もうそれで良いよ
2014/12/04(木) 23:13:27.66ID:BoUkojKR
>>722
両方を備えたc++ですね分かります
2014/12/04(木) 23:24:08.54ID:BoUkojKR
A君「絵を描くのは好きだけど、仕事と両立するのは難しいなぁ」
ニート「一日中ヒマだから絵を描き放題だぜ」

A君「ついに絵を描く仕事に就いたぞ。好きなことして食べていける」
ニート「もう20年前から好きなことだけやれてたわ〜。遅れてんな〜やれやれ」
2014/12/04(木) 23:40:50.93ID:RpORv8ek
>>724
わっかんないやつだなぁ。
traitが型クラス由来なら、なぜtraitを使わないで型クラスの例が書けるのさ。
http://www.scala-lang.org/old/node/114

説明してミソ
2014/12/05(金) 00:15:41.66ID:RG1/KShi
>>727
Rubyではblockを使わずにlambdaが書けるから
blockはクロージャ由来じゃないってことだね
2014/12/05(金) 00:20:26.42ID:lYb7FfYs
C++のclassはstructでも書けるな
2014/12/05(金) 02:25:30.08ID:3qncuvNa
>>728
おまえ頭わるいな
2014/12/05(金) 07:42:45.52ID:ViNbqhcv
>>730
いや、お前が頭悪い
(理由は省略、いう必要もないから)
2014/12/05(金) 09:04:37.51ID:t8jCTeme
RubyのブロックってCLUのイテレーター由来じゃなかったっけ?
ずいぶん前にMatzがそんなようなことを言っていた記憶が
2014/12/05(金) 09:13:02.76ID:A1Nk4WQY
クロージャとラムダ式の区別がついていない人ってよくいるよね
2014/12/05(金) 09:16:51.57ID:+TXyzC2W
>>733
それお前じゃね?

一応言っておくと、わかってると自称する
お前が説明してみろって意味だよ。
2014/12/05(金) 10:11:29.20ID:sLA7oQpI
Pythonにクロージャは無い(キリッ
2014/12/05(金) 11:25:40.15ID:viBzu9Eo
さあ728さん、クロージャとラムダの同一性の説明どーぞ!
2014/12/05(金) 12:26:12.88ID:51P5EYrc
>>732
いや。Rubyのブロック自体はLISPのlambda由来かと。
今のブロック付きメソッド呼び出し(昔はイテレータと呼んでいた)が
CLUのイテレータから発想を得た…というだけで。

もっとも個人的には(着想はともかく最終的には)
Smalltalkのブロックを引数にとるメソッド呼び出しの見た目だけパクったものだと思うけどね。

▼CLUのイテレータ
start_up = proc ()
 po : stream := stream$primary_output()
 xs : array[int] := array[int]$[1,2,3]
 for x : int in xs!elements do
  po!putl(x!unparse)
 end
end start_up

▼初期のRubyのイテレータ
do [1,2,3].each using x; print(x, "\n") end

▼現行のRubyのblock付きメソッド呼び出し(旧呼称はイテレータ)
[1,2,3].each{ |x| puts x }

▼Smalltalkのブロックを引数にとるメソッド呼び出し
#(1 2 3) do: [:x | x logCr ]

▼LISPのループ(lambdaの出番はない^^;)
(loop for x in '(1 2 3) do (print x))

▼Schemeのlambda
(for-each (lambda (x) (print x)) '(1 2 3))
(for-each print '(1 2 3)) ;;←実際はlambda使わずにこれでおk
2014/12/05(金) 12:31:26.53ID:+5KFbbdu
動的言語には型名を考えるコストがない
ある物の名前がラムダかクロージャか議論するのに何時間かかるか考えてみろ
2014/12/05(金) 13:25:22.71ID:eWvM3tpo
>>738
動的言語でも型名はあるんじゃ。もし言語がサポートしてなくても何かつけそう。
2014/12/05(金) 13:38:18.27ID:AoGRS1Po
>>738
唯一神クラスですか?
2014/12/05(金) 16:19:55.77ID:+5KFbbdu
インタフェース継承で派生クラスの名前は必須ではない
これは静的でも成り立つ
更に突き詰めると必要なのはメンバの名前のみなのでインタフェースの名前も不要

Smalltalkは実装継承にこだわっているので名前は必要かもしれんが他の動的言語は違う
2014/12/05(金) 18:10:35.44ID:N759beub
>>741
> 実装継承にこだわっているので名前は必要

なぜ実装継承にこだわると名前が必要になるのか教えてほしい。
2014/12/05(金) 20:31:39.15ID:+TXyzC2W
>>738
何言ってんだ?
型がなくてどうやってオブジェクトをnewするんだよ?w
new 型名 って書くだろが。

動的型付け言語にないのは型じゃなくて、
変数(関数の引数含む)に型が書いてないから
いろんな型が入れられてしまうって話だろ。

ローカル変数ならともかく、関数の引数、
つまり外部モジュールとのインターフェース部分にまで
型を書かないから、複数のモジュールを連携して作るような
大規模(中規模? いやいやサンプル以上の規模)になればなるほど、
大きくなっていく影響範囲を把握するのが大変になるって話だよ。

変数に型がないから、影響範囲がわからない、
もしくは限定的になり、人間の負担が大きくなる。
2014/12/05(金) 20:46:05.48ID:+TXyzC2W
>>741
> インタフェース継承で派生クラスの名前は必須ではない

そりゃそうだよ。問題にしているのは人間が大変かどうかの話なんだから。
技術者はよく、技術的に可能かどうかで答えるだけで
制限時間内に終えられるかどうかを答えなくて困る。

ミスをしない人間がいて、タイプミスもせず、ードの全てを覚えていて、
仕様の変更もしない。もしくは理想的な変更しか起こらず、時間の制限もない。
そういうありえない世界でなら何の問題もないんだよ。

現実には何万行、何十万行というコードを知っている人が
会社をやめて、新しく入ってきた人が期限内に修正しなければならない。

いいかい? 問題は可能か不可能かじゃないんだ。
コードの全てを把握していない人が、どちらの方が短い時間で
コードを把握できて、ミスをせずに修正できるかって話なんだ。

それがわかっていれば、この関数の引数は、どんなものが入ってくる可能性があって
(むしろ入ってこないものが断定できて)広大なコードの海で、どこから使われているか
目視、もしくはIDEなどのツールを使って100%の信頼性で調べれる方がいいってわかるだろう?
2014/12/05(金) 20:46:44.48ID:+5KFbbdu
実装に名前をつけて保存するからだろ

インタフェースは保存しなくてよい
下手すると名前の長さが中身より長くなるから
2014/12/05(金) 20:50:24.12ID:+5KFbbdu
>>742
>>745
2014/12/05(金) 21:12:23.79ID:+TXyzC2W
>>745
> 下手すると名前の長さが中身より長くなるから

まあ、まず無いが、仮に名前の長さが中身より長くなるからといって
どんなデメリットが有るというのかね?
2014/12/05(金) 21:28:30.39ID:5SBzstV5
>>680
>動的型付け言語じゃなくても達成出来てることを言われてもなw

>>671
> Windows ではコンポーネント間の結合に CORBA を基礎とした COM を開発して対応したが、
と書いたように、静的型付けの C++ だけでは COM を使わなければ
コンポーネントの動的結合ができない
それに対して Objective-C は一般的な動的リンクライブラリにメタデータを加えて
ファイルを構成するだけで動的結合できるフレームワークを実現できる
動的型付けな Objective-C では同じ事を実現するのに、COM は不要


>だいたい発展し続けると言っても、再起動してるじゃん。

カーネルやデバイスドライバを更新した場合には OS の再起動は必要だ
ただし、ここで議論の対象としているのはライブラリやフレームワークとして提供される
コンポーネントの部分だよ
OSX/iOS では単に規定のフォルダへフレームワークをコピーするだけ
Windows の COM のようにレジストリへ GUID を登録するといった面倒な仕掛けは不要


> なぜ動的型付け言語ならではの理由が
> あんたの言っていることには一つのないんだよね。

静的型付け言語だけではコンポーネントの動的結合ができない(COM が必須)
モジュールの静的リンクだけでいい小規模の開発であれば静的型付け言語でもかまわないが、
コンポーネントを組み合わせる大規模なシステム開発では動的型付けの柔軟性が利点になる
この言語の差が OS という大規模開発における Windows の失敗と OSX/iOS の成功に影響した(>>671)
2014/12/05(金) 21:30:47.47ID:+TXyzC2W
> と書いたように、静的型付けの C++ だけでは COM を使わなければ
> コンポーネントの動的結合ができない

別にDLLでもできるけど?

そもそもCOMがあるのは特定の言語に依存しないための
仕様を作ることが目的であって

同じ言語であれば、DLLでできるんだよ。

もうしょっぱなからだめじゃんw
2014/12/05(金) 21:32:11.34ID:+TXyzC2W
2分で論破はやり過ぎだと反省しているw
2014/12/05(金) 21:35:46.33ID:+TXyzC2W
Linuxは静的型付け言語のC言語で〜
拡張子soの動的リンクライブラリが〜

まともに?明するのも面倒くさいw
2014/12/05(金) 22:06:36.60ID:viBzu9Eo
Smalltalkの場合、名前のないクラスは名前のあるクラスと同じ数だけ存在する。だから>>741は正しくない。
ちなみにサブクラスを定義するためにはクラスインスタンスにメッセージを送信する。インスタンスを生成するのもクラスインスタンスにメッセージを送信することで行う。その意味でも、クラスに名前は必須ではない。
2014/12/05(金) 22:08:26.02ID:5SBzstV5
>>749
DLL だけでは柔軟なコンポーネント結合が実現できなかったから、
Microsoft は COM(Component Object Model) という技術を開発した
言語に依存しないバイナリ互換性も COM の特徴であるけれど、
仮に C++ に閉じた開発であっても COM は必要になる

こんな話は COM を知っていれば常識
2014/12/05(金) 22:40:22.11ID:5SBzstV5
>>732
これかな
・Rubyist Magazine - Rubyist のための他言語探訪 【第 2 回】 CLU
 http://magazine.rubyist.net/?0009-Legwork


>>737
> いや。Rubyのブロック自体はLISPのlambda由来かと。

だね
Ruby は LISP をベースにして設計された
Ruby のブロックも LISP のクロージャ(ラムダ式)に由来する
・Lisp から Ruby への設計ステップ | プログラマーズ雑記帳
 http://yohshiy.blog.fc2.com/blog-entry-250.html
2014/12/05(金) 23:20:42.11ID:5SBzstV5
>>737
> 今のブロック付きメソッド呼び出し(昔はイテレータと呼んでいた)が
> CLUのイテレータから発想を得た…というだけで。

ここは違うと思うな
どちらかといえば Ruby が CLU から強い影響を受けたのは、
要素を返すのに yield 構文を用いる、いわゆる「内部イテレータ」だと思う
たとえば >>737 の 1 から 3 の範囲を CLU では以下のイテレータで表現する
 from_to = iter(first:int, last:int) yields(int)
   n:int := first
   while n <= last
     yield(n)
     n := n + 1
   end
 end from_to

これを Ruby では以下のように書ける
 def from_to(first, last)
   n = first
   while n <= last
     yield n
     n += 1
   end
 end

yield というイテレータ向けに専用の構文を用いる内部イテレータは、汎用的な外部イテレータ、
いわゆるジェネレータよりも反復処理の抽象化を簡潔に表現できる
内部イテレータは CLU で生まれ Ruby が継承した(Smalltalk/Java/C++/Python 等には)存在しない特徴
2014/12/05(金) 23:41:12.21ID:+5KFbbdu
問題
yieldを用いると内部イテレータ風の書き方で外部イテレータを作ることができる
このイテレータの名称として適切なのは
「外部イテレータ」「内部イテレータ」のどちらか答えよ
2014/12/06(土) 04:27:17.30ID:VJF2Er6M
Pythonでも普通にyieldで
「内部イテレータ風の書き方で外部イテレータを実装する」
ことができる。
Smalltalkにも(ちょっと無理矢理っぽいが)yieldの実装がある。
2014/12/06(土) 09:50:46.00ID:75gyZyE4
Smalltalkで>>755のCLUとRubyを再現するとこんな感じか。

| fromTo |
fromTo := [:first :last | Generator on: [:g |
 | n |
 n := first.
 [n <= last] whileTrue: [
  g yield: n.
  n := n + 1
 ]
]].

(fromTo value: 1 value: 3) do: [:x | Transcript showln: x]

http://ideone.com/5UU1qM
2014/12/06(土) 10:16:45.25ID:awxYdbKb
visitメソッドのレシーバと引数のどっちがVisitorか迷うことがある
2014/12/06(土) 11:43:34.93ID:VJF2Er6M
どうしてRubyを推したい人は
他言語に元からある機能をなかったことに
したがるのだろうか?
2014/12/06(土) 11:53:26.46ID:75gyZyE4
>>760
それはMatzやその取り巻きが悪いんだよ。
まるでRubyが初めてであるようにもとれる言い方で
信者をミスリードし続けてきた立派な成果だ。
旧Mac信者がジョブズの印象操作で育成された経緯に似ている。
2014/12/06(土) 12:39:03.22ID:awxYdbKb
printf("%sには%sがあるから\n", "ruby", "yield");

誰でも言いそうなコピペを改変してるだけだよね
正しい情報ではなくコピペしやすい情報が拡散する
763755
垢版 |
2014/12/06(土) 16:06:50.42ID:viXCL8M/
>>755 では「1 から 3 の範囲を」と書いたけど、具体的なコードを忘れていた

CLU では、>>755 で定義したイテレータ from_to を以下のように利用する
 for i:int in int$from_to(1, 3) do
   ....
 end

Ruby では、>>755 で定義したイテレータ from_to を以下のように利用する
 from_to(1, 3) do |i|
   ....
 end


>>757
> Pythonでも普通にyieldで

失礼、Python にも yield 文があった
ざっと調べてみたけど、どちらかというと(Ruby よりも) Python のほうが
CLU のイテレータを忠実に実装しているようだ
2014/12/06(土) 16:45:53.73ID:viXCL8M/
>>760,761
Ruby では >>754 のリンク先文書で Matz が
「イテレータの定義の仕方は驚くほど Ruby に似ています。 真似したんだから当然です。
 元々 Ruby のブロックは CLU のイテレータに似たものを実現するためにデザインされたからです」
と書いているように、(おそらく)最初からイテレータが存在していました
少なくとも Ruby 1.4 を元にして1999年に出版された書籍「オブジェクト指向スクリプト言語Ruby」では、
節「2.18.4 yield」で(>>755 のコードのような)イテレータ定義方法が詳しく解説されている


それに対して Python にyield文が追加されたのは2001年、おそらく Pytthon 2.x の時代ではないのかな?
・PEP 255 - PEP 255 -- Simple Generators | Python.org
 https://www.python.org/dev/peps/pep-0255/
もし最初から、あるいは Python 1.x の時代から存在しているなら、ソースを提示してくれ

ソースが提示できないのなら、>>760
 > どうしてPythonを推したい人は
 > 後から追加された機能を元からあったことに
 > したがるのだろうか?
と訂正したほうがいいだろね
2014/12/06(土) 16:55:53.06ID:tymH4H6t
る厨、渾身の反撃
2014/12/06(土) 18:06:07.33ID:dOSwxHPK
>>764

755がこんな書き方するから、「いや、他の言語にもあるだろ」と突っ込まれてるんじゃないか?

> 内部イテレータは CLU で生まれ Ruby が継承した(Smalltalk/Java/C++/Python 等には)存在しない特徴
2014/12/06(土) 18:10:44.25ID:dOSwxHPK
>>764のPEP255を見ると、CLUには言及されているけどRubyは出てこないんだな
これは確かにRuby使いには腹立たしいかもなぁ
まあRoR以前のRubyはマイナーだったから仕方ないんだけど
2014/12/06(土) 18:17:10.96ID:tymH4H6t
>>766
なんだ、る厨のマッチポンプか。つまらん。
2014/12/06(土) 18:21:50.32ID:tymH4H6t
> Ruby が継承した(Smalltalk/Java/C++/Python 等には)存在しない特徴

まるで Ruby が再発見するまで CLU 以外の言語では存在し得ないような言い方だな。
さすが る厨だ。Matz ゆずりのミスリードはお手の物というわけか。
2014/12/06(土) 18:37:35.84ID:dOSwxHPK
内部イテレータ風の記法が大規模開発でどう役立つか

そういう話なら興味深いが、このスレは直ぐ「ウチこそが元祖」の話になるな……
2014/12/06(土) 18:41:59.78ID:viXCL8M/
>>767
Python にジェネレータが導入された時期(2001年)からすれば
Ruby の成功を見てyield文を追加したんだろうけど、
さすがに「Ruby の真似をしました」とは書けないから CLU にしたんだろね


>>769
> まるで Ruby が再発見するまで CLU 以外の言語では存在し得ないような言い方だな。

え、CLU 以降に登場したメジャーな言語で yield 文によるイテレータを備えた言語があったの?
自分は知らないから、教えて欲しいなぁー

少なくとも、時期的には Ruby が再発見するまで Python にはyield文は存在していなかったよね(>>764)
存在していたなら、>>764 でも書いたように、ソースの提示をヨロシクね!


>>768
いや、(今のところ)ソースを提示できていないから、
「Pythonを推したい人は後から追加された機能を、さも元からあった(>>760)」かのように
ウソをついていたみたいだね

どうしてPython使いはウソツキばかりなの?
嘘でもなんでも、議論に勝ちさえすればいいと思っているのかなあ....
2014/12/06(土) 18:56:12.98ID:dOSwxHPK
2001年にRubyが成功してたとか、何のジョークですか
RoRは2004年ですよ
2014/12/06(土) 19:13:11.97ID:Ee/H8Kvv
CLUとかPythonのyieldはジェネレータだけど、Rubyのは違くね?
Rubyにジェネレータ入ったのって1.9だろ?
2014/12/06(土) 19:22:45.98ID:dOSwxHPK
Rubyのyieldは見た目が似てるだけでCLUのとは別物
正当に継承してるのはPythonの方でした、というオチ?
2014/12/06(土) 19:30:05.03ID:Ee/H8Kvv
>>771
当時のSatherはRubyよりは有名だっただろうね海外では
2014/12/06(土) 20:16:53.72ID:viXCL8M/
>>772
2001年に O'Reilly から "Ruby in a Nutshell" が出版され世界メジャーデビューを果たしている
・Ruby in a Nutshell&#xA0;-&#xA0;O'Reilly Media
 http://shop.oreilly.com/product/9780596002145.do
Ruby on Rails フィーバーが起きたのは2004年だけど、
すでに2001年には日本だけのガラパゴス言語から脱して
十分に世界でも知られる存在になっていた

当然、世界レベルで "Python vs Ruby" の論争は起きただろうし、
Ruby にはあるけど Python には欠けていると指摘されたのが「洗練されたイテレータ」で、
あわてて追加したのが2001年の PEP 255 (>>764)だったんじゃないかと思われ....


>>773
外部イテレータ、いわゆるジェネレータは Ruby 1.8 にも標準ライブラリで提供されていた
1.9 では、これが組込みライブラリとして再実装されただけ




で、「Python では元からyield文があった(>>760)」という主張のソースはまだかなぁーー???
やっぱりPython使いはウソツキばかりなのかね
2014/12/06(土) 20:40:35.48ID:dOSwxHPK
>>776
> November 2001

PEP255の後じゃん
2014/12/06(土) 21:59:22.89ID:7vCPkvQk
>>755は内部イテレーターがCLU発祥でRubyがその初継承だと言いたいの?
それとも、yield&コルーチン的な仕組みでイテレーターを生成できるのが
そうだと言いたいの? どっち?
2014/12/06(土) 22:26:02.16ID:tymH4H6t
きっと、あれだろう。
「yieldを使うなどしてRubyのようにCLUからイテレーターをコピーしたのはRubyが最初」
とかいうガッチガチの縛り付き起源論。

「〜は既にあったんじゃ?」とか指摘するたびに
「〜は○○がRubyのそれと違う」とか縛りがどんどん増えていくタイプの。
2014/12/06(土) 23:01:36.75ID:q7blqefO
>>770
木構造で格納した値を順番に取り出すとか?
うーんピンとこない
2014/12/07(日) 00:03:15.33ID:zkEhiByJ
結局、最新の技術を取り入れた静的型付け言語が
最も優れた言語になるのかな。
782755
垢版 |
2014/12/07(日) 00:07:58.15ID:hGORpEWm
>>755
どちらかといえば前者だな
ただし、たとえば Sather(>>755) や分散トランザクション言語の Argus があるから
初継承ではないね

まあいずれにしてもソースを出せないのだから、
「Python では元からyield文があった」と主張した >>760 はウソツキってことだ(>>764)
ナゼPython使いってのは、息を吐くようにウソをつき、
朝日新聞のようにいつまでたっても間違いを認めようとしないんだろね?
人は神様じゃないから誰でも間違えるもので、
それに気付いたなら(>>736 下段のように)とっとと間違いを認めればいいのになぁ....
2014/12/07(日) 00:14:16.44ID:dQg0RQig
>>781
だろうね。

動的型付け言語はいわば実験台。
どこで出来たものに型を取り付けることで
完全体になる。
2014/12/07(日) 00:45:01.66ID:svj68kfn
>>782
> 内部イテレーターがCLU発祥
だとすれば
Smalltalkの#do:はこの場合どういう扱いになるの?
あれも内部イテレーターだろう。
2014/12/07(日) 00:49:15.39ID:3Elo+9Qw
嘘はよくないけど逃げるのはよいよね
間違いを認めるとかはどうでもよい
2014/12/07(日) 01:50:41.36ID:hGORpEWm
>>784
Smalltalk のアレも内部イテレータだね

反復(iteration)をコルーチンとして抽象化する最初の発想は、CLU と Smalltalk の共通の祖である Simula 67 で生まれ、
それはジェネレータと呼ばれていた
そして、その発想はどちらの言語にも継承されたけど、静的型付けな手続き型言語である CLU と
動的型付けなオブジェクト指向言語である Smalltalk とでは、実現方法が異なった

CLU は iter 宣言と yield 文という抽象化向けの構文を導入し、反復処理の表現(プログラミング)を洗練させた
また反復の概念を整理/形式化し、それにイテレータという名称を与えたのは CLU の功績
だからイテレータの始祖は CLU であると、一般には認知されている

それに対してブロック(=クロージャ)を持つ Smalltalk は、(CLU のように苦労することなく)反復処理を抽象化できた
実際、Smalltalk-80 のジェネレータは first と next というメソッドが定義された任意のオブジェクトでしかない
結果として Smalltalk のコミュニティの中でジェネレータは反復処理のプログラミング技法、
いわゆるイディオムとしては認知されていたけど、それが学術的に議論されることは無かった
(実際、当時の Smalltalk の文献ではイテレータという用語は使われず、Simula と同じジェネレータが使われた)
こうした、ある新しく登場した概念が実は Smalltalk の世界だとありふれたイディオムでしかなかったという現象は、
(たとえばデザインパターンのように)しばしば見かけられる
2014/12/07(日) 02:03:23.69ID:hGORpEWm
>>785
結局、逃げたってことなのね
それならそれで、いいんじゃないかな
では、これでスレ違いなイテレータの話題は終わりにしよう

反復処理を抽象化するイテレータは大規模開発にとって重要だと思うけど、
CLU と Smalltalk の例(>>786)のように
静的型付け/動的型付けのどちらにも共通する概念だから、
スレの主旨からは外れていると思う
2014/12/07(日) 08:12:25.48ID:vPGA0H7X
Rubyコミュニティによるイテレータの歴史歪曲については
少なくともRubyが再発見したおかげで内部イテレータが再評価されたわけではない(>>777)し、
>>755には他にも事実誤認があるのだからいくら言葉尻で言い訳しても墓穴が大きくなるだけ
2014/12/07(日) 08:23:27.33ID:NlsKlGNA
ルビーより後に実装されたのはみんなルビーの真似w
2014/12/07(日) 09:49:05.54ID:3Elo+9Qw
歴史歪曲を考える暇があったら、副作用の順序を間違える事案について考えよう
2014/12/07(日) 09:51:11.11ID:bfkTF4nN
ここの住民には無理
2014/12/07(日) 09:56:13.58ID:NlsKlGNA
>>776-777の流れが全てを物語っているw
2014/12/07(日) 13:22:05.08ID:6EqZg1tl
>>786
> Smalltalk-80 のジェネレータは first と next というメソッドが定義された任意のオブジェクトでしかない

next は分かるのですが、first を定義する必要があるというのは初耳です。
そのようなプロトコルが規定されているのは何というSmalltalk処理系ですか?
あるいはそのように記述された文献をお示しいただければさいわいです。

あと、Smalltalkの外部イテレーター(内部イテレーターとしても使用できる)としては
Streamが有名ですが、これとおっしゃっておられる「Smalltalkのジェネレーター」との
関係を教えてください。

> 実際、当時の Smalltalk の文献ではイテレータという用語は使われず、Simula と同じジェネレータが使われた

寡聞にして知りませんでした。
たとえば具体的にどんな文書でそのような用語が使われていたか教えていただけると助かります。
2014/12/07(日) 13:42:54.66ID:acBjRoXT
> Smalltalk-80 のジェネレータは first と next というメソッドが定義された任意のオブジェクトでしかない

一つ疑問があるんだけどさ、firstとnextをジェネレータとは
違う用途で使ったオブジェクトはどうなるの?
正しく動かないと思うけど。

そうすると、firstとnextはジェネレータで使うための名前ですって
予約語みたいな扱いになっているということ?
2014/12/07(日) 14:10:40.21ID:3Elo+9Qw
>>794
お前はなぜ正しく動かないと分かったのか
分かったのに分からないふりをする動機は何か
この動機を打ち消すことができれば生産性が上がるんじゃないか
2014/12/07(日) 14:18:07.50ID:acBjRoXT
>>795
何を言ってるのさ?
純粋に疑問になっただけ

例えばfirstという名前で、初期化処理
secondという名前で、2番目の処理、
thirdという名前で3番目の処理
みたいなことをしているオブジェクトがあったとしたら
当然ジェネレータとしては使えない。

だからfirstという関数名はジェネレータのfirstの
仕様を守らないといけないというルールがあるのか?って話なんだが。
2014/12/07(日) 18:16:20.48ID:hGORpEWm
>>793
>next は分かるのですが、first を定義する必要があるというのは初耳です。
>そのようなプロトコルが規定されているのは何というSmalltalk処理系ですか?
>あるいはそのように記述された文献をお示しいただければさいわいです。

1986年に書かれた "The Generator Paradigm in Smalltalk" という文書です
題名でググるとPDFで見つけられます


>あと、Smalltalkの外部イテレーター(内部イテレーターとしても使用できる)としては
>Streamが有名ですが、これとおっしゃっておられる「Smalltalkのジェネレーター」との
>関係を教えてください。

単に ReadStream クラスが Smalltalk の作法(慣習)に沿って設計されたのだと思いますが、
それを裏付けるソース(文献)は知りませんし、それ以上の関係も知りません


>> 実際、当時の Smalltalk の文献ではイテレータという用語は使われず、Simula と同じジェネレータが使われた
>
>寡聞にして知りませんでした。
>たとえば具体的にどんな文書でそのような用語が使われていたか教えていただけると助かります。

上記の文献では、ジェネレータという用語が使われています


イテレータという用語は1974年に発表されたCLUの論文によって世に知られるようになりました
自分の知る範囲で、Smalltalk とイテレータとの関連が議論されたのは1995年出版のデザパタ本(GoF)が最初だと思います
少なくともブルーブックの名で知られている Smalltalk のバイブル "Smalltalk-80: The Language and Its Implementation"
では、イテレータという用語は使われていません
もしも CLU 以前の時代に Smalltalk とイテレータを扱った文献が存在していたなら、ぜひ教えてほしいですね
2014/12/07(日) 19:37:57.79ID:eR9x6pgx
>>797
なるほどティモシー・バットの実装・主張でしたか。
Smalltalkの常識が役に立たないわけです。^^;

本家Smalltalk(の、ごく初期の実装であるSmalltalk-72)からある
Streamと彼の言うジェネレータとの関係は、
彼のかなり風変わりなSmalltalk実装であるLittle Smalltalkに
ついて書かれた書籍にその記述が見つけられました。

http://sdmeta.gforge.inria.fr/FreeBooks/LittleSmalltalk/ALittleSmalltalk.pdf

In the Smalltalk-80 language (Goldberg83), the concept of
streams is in many ways similar to the idea of generators.
For the most part, streams use a slightly different interface,
namely the pair of messages reset (which initializes the
generator but does not return any value) and next (which is
used for both the first and all succeeding elements). The
message do: is adapted from the streams of (Goldberg83). An
article by Deutsch (Byte 81) discusses in more detail many
aspects of generators in the Smalltalk 80 system.

ありがとうございます。

あと老婆心ながら、パッドがSmalltalkについて書くときは、
暗黙のうちに彼独自仕様のLittle Smalltalkを前提にしている
ことがあるので、そこから得た知識をSmalltalkに一般化したり、
あるいは狭義には本家PARC謹製実装を指す「Smalltalk-80」という
呼称でそれを語るのは、聞き手に無用の混乱を招くので
今後は避けられた方がよいと思います。
2014/12/07(日) 20:20:51.08ID:hGORpEWm
>>798
結論としては、今のところ挙っているソース(文献)を前提とすれば:
・オリジナルの Smalltalk コミュニティでは概念としてのイテレータは存在していなかった
・ただしコレクションやストリームの実装で用いられた Smalltalk の作法(慣習)は、
 デザパタ本(GoF)によって内部イテレータとして分類された
ということですかね
2014/12/07(日) 21:29:04.46ID:eR9x6pgx
>>799
> もしも CLU 以前の時代に Smalltalk とイテレータを扱った文献が存在していたなら、ぜひ教えてほしい

もとより、リスコフが件のループ処理の抽象化にイテレータと名付けて発表したのは1977年のこの文献
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.112.656&;rep=rep1&type=pdf
だと思うのですが、そうすると同様のことを目指す類似の仕組みがあったとして、それを
「イテレータ」と呼称するには少なくとも1977年以降でなければ困難だと思うのですが、これは
1977年以前に実装され、活用されていたという事実を示せばいいという解釈でよろしいですか?

それとも、「イテレータ」という言葉を使っていないとダメという縛りでしょうか?
2014/12/07(日) 23:41:25.71ID:hGORpEWm
>>800
自分もその文献を参照して CLU がイテレータで生まれたと判断しました
だから、時期としてはそれ以前ということですね

またイテレータという名称にこだわる必要はありませんが、
first と next という作法で実現できる外部イテレータは
C++/Java だけでなくC言語でも実装できる一般的なプログラミング技法ですから、
CLU の内部イテレータからは外れるでしょう
またループ処理の抽象化はイテレータだけでなく LISP を始祖とする関数型言語の
map 関数がありますが、これをイテレータと呼ぶのは無理があるでしょう

CLU の内部イテレータは、当時のクロージャを持たない手続き型言語へ
コルーチンの仕掛けを洗練された形で組み込んだことに意義があると思います
もし CLU 以外にも、当時の手続き型言語の中でループ処理の抽象化に
取り組んだ研究があったなら、興味深いですね
2014/12/08(月) 08:33:17.02ID:voJSmgM1
>>801
つまり、
コルーチンを使っていなければ内部イテレータとは呼べない
という縛りですね?
2014/12/08(月) 09:55:18.35ID:kmGTZboH
外部イテレータは存在意義が分かるんだけど、
内部イテレータの存在意義が分からない
高階関数があれば全く不要じゃないの?こんなもんに予約語使うRubyは馬鹿なんじゃないの?
2014/12/08(月) 10:47:05.59ID:7TNBMlk3
結局、Rubyコミュニティ内でも、

> Rubyのイテレータは用途的にはCLUのイテレータよりも
> Smalltalkのブロック (を受け取るメソッド)に似ている
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/13374

という結論になっているんだね。
2014/12/08(月) 11:52:53.80ID:hyn7lotS
LispやSmalltalkは低級言語に似てないからダメ
同じ理由で高階関数もダメだろうと高を括っていたんじゃないか
ところが現実はC++でも高階関数を使いこなせるレベルになりつつある
2014/12/08(月) 19:51:47.86ID:Ag3PuK/D
言語の仕様の変更が柔軟なのは動的型付け言語なんだよな。
型のことを考える必要がないぶん、アイデアをすぐに実装できる。

だけど、そのアイデアそのものは静的型付け言語でも実装可能。
型を考える分だけ時間がかかるだけ。

動的型付け言語の機能はほぼ全て静的型付け言語で実装できるし、
型安全になりさらにいい形で実装される。
807801
垢版 |
2014/12/08(月) 21:41:44.49ID:9AWpAGuY
まず >>801 の日本語が変だったので訂正
X: 自分もその文献を参照して CLU がイテレータで生まれたと判断しました
O: 自分もその文献を参照してイテレータが CLU で生まれたと判断しました


>>802
いや、CLU はコルーチンを使っていないし、そんな縛りはありませんよ
ループ処理を生産者/消費者に分割するプログラミング技法としてコルーチンが
CLU 以前から知られていましたけど、保守のしづらいコードになりがちでした
そのコルーチンを使わずにループ処理を抽象化したのが CLU のイテレータです


>>803
> こんなもんに予約語使うRubyは馬鹿なんじゃないの?

だとしたら、ジェネレータ(外部イテレータ)が重要な言語の構成要素であり、
なおかつ高階関数もすでに備えていたにもかかわらず、
後からわざわざ予約語 yield を追加した Python の PEP 205(>>764) は
Ruby 以下の大馬鹿ってことですね

自分としては、ジェネレータを(まるで内部イテレータのように)簡潔に定義できるようにすることを
意図した PEP 205 の判断は適切であったと思っていますけど、
まあ、仕様追加を容認/批判するのは人それぞれなんでしょうね....
2014/12/08(月) 21:47:10.82ID:NhV7D2A0
外部イテレータを内部イテレータかのように記述できるPythonのyieldには価値がある
だからJavascript(ES6)などにも採用されている

一方、Rubyの内部イテレータには価値が無い
単純な話じゃん
809801
垢版 |
2014/12/08(月) 22:43:49.37ID:9AWpAGuY
>>804
>>754 で書いたように Ruby は LISP をベースに設計され、
ブロックも LISP のクロージャに由来します
だから、同じブロックを使う Smalltalk と意味が似るのは不思議じゃないですね

実際 >>755 のイテレータ定義は、yield を使わなくとも Smalltalk の value メッセージに
相当するメソッド Proc#call へと単純に置き換えることができます
 def from_to(first, last, &block)
   n = first
   while n <= last
     block.call n
     n += 1
   end
 end

Ruby と CLU の関連性に関しては、(あくまで私見ですが) LISP を心臓部(意味)として、
(S式ではなく)Perl に代表される手続き型言語のプログラマに受け入れられる表層の皮(構文)で
包んだ時に、手続き型言語である CLU のイテレータという概念を参考にしたのだと思います
だから外観は CLU のイテレータのように見えるけど、その実装は LISP/Smalltak と類似するという
結果になるのでしょう
810801
垢版 |
2014/12/08(月) 23:29:50.99ID:9AWpAGuY
>>805
元々の質問者(>>800, ID:eR9x6pgx)の方が Smalltalk に詳しそうなので、
1997年の CLU および Smalltalk-80 以前における初期の Smalltalk の
(後にGoF本で内部イテレータと呼ばれることになる)ループ処理設計の誕生話を期待していました
自分は Smalltalk にはそれほど詳しくないんで、それ辺りの歴史を披露してもらえたら嬉しかったですね

あるいは1970年代に Scheme で生まれた継続(コンティニュエーション)の概念や、
並行ループ処理をプロセス構造で表現する CSP や実装言語である Occam あたりかもしれないと
想像していました
これら現在ではイテレータには分類されていないけど実はループ処理の抽象化に関連していた
過去の埋もれた知見が得られるか、つまり何かを再発見できるかと期待していたんですが、
結局、想定されていたのは良く知られた(=ありふれた)高階関数だったのですかねぇ.....

まずは彼からのレスを待つことにします
2014/12/08(月) 23:59:43.81ID:wXlNa9C1
>>807
> CLU はコルーチンを使っていないし、そんな縛りはありません

おっしゃりたいことがちょっとよく分かりません。

> 801
> CLU の内部イテレータは、―
> コルーチンの仕掛けを洗練された形で組み込んだことに意義がある

これは、コルーチン“的な”仕掛け、という意味で、
コルーチンである必要はないということですか?

例えば、まだクロージャをもたないSmalltalk-76の頃からあった

stream ← #(1 2 3) asStream.
for x to stream do [user show: x; cr]

という内部イテレータとして使える外部イテレータである
ストリームという発案が

> C++/Java だけでなくC言語でも実装できる
> 一般的なプログラミング技法

とか

> 保守のしづらいコードになりがち

というよくわからない難癖で排除される理由も理解しかねます。
てっきり、コルーチンでないからダメなのかと思ったのですが?
2014/12/09(火) 00:34:52.29ID:7jn1Y2FE
>>808
つまり Ruby が CLU のイテレータを再発見するまで、いいかえると
Python 設計者は PEP 205(>>764) 発表の2001年まで yield 文の重要性に気付かず、
世界中のPythonプログラマは冗長なジェネレータを書き続けていたことになるね

しかも PEP 205 で導入された yield文(statement) は検討が不十分であった為、
PEP 342 で yield 式(expression)へと後方互換性を放棄する構文の仕様変更に追い込まれている
・PEP 342 -- Coroutines via Enhanced Generators | Python.org
 https://www.python.org/dev/peps/pep-0342/

それに対して1999年の Ruby 1.4 (>>764)では yield はブロックの評価結果を返す式として定義されている
しかも外部イテレータは 1.8 で標準ライブラリとして、 1.9 では組み込みライブラリとして提供された
もちろん(後方互換性を喪失させた Python とは異なり)言語の構文仕様へ変更を加えることなく....

最初から内部イテレータとyield式を備え、楽々と外部イテレータにも対応した Ruby、そして
Ruby を必死で追いかけて予約語 yield の追加とyield文からyield式へと仕様が迷走した Python....
どちらが言語としての先見性に優れていたか、単純な話じゃん
2014/12/09(火) 01:30:40.08ID:5nnX6sRe
>>776-777で完全論破されてんのに
まだPythonのyield導入にRubyは無関係だって認めてないのかw
2014/12/09(火) 02:00:48.32ID:WiqIx9bM
>>811
× for x to stream do [user show: x; cr]
○ for% x from: stream do% [x print. user cr]

Smalltalk-72 と 76 がごっちゃになって記述を間違えましたので訂正します。
ちなみに % のところは実際はオープンコロンという白抜きのコロン(非ASCII文字)を使います。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況