【激突】関数型言語 VS オブジェクト指向言語2at TECH
【激突】関数型言語 VS オブジェクト指向言語2 - 暇つぶし2ch600:デフォルトの名無しさん
12/04/29 12:10:48.87
>>586
Scalaって事前(?)にコンパイルする以外になんか実行方法あったっけ?

601:デフォルトの名無しさん
12/04/29 12:18:53.17
>>600

>>581はコンパイルしたらエラーがでます。

602:デフォルトの名無しさん
12/04/29 12:21:46.03
コンパイルしない場合は、そのまま動きます。

603:デフォルトの名無しさん
12/04/29 12:31:37.65
>581はscalaスクリプトだから、コンパイルする場合は
-Xscript XXX オプションをつける必要があるかと

604:デフォルトの名無しさん
12/04/29 12:42:00.90
動くね

$ time scala Lifegame.scala
0,1,1,0,0
0,1,0,1,0
0,0,0,0,0
0,0,0,0,0
0,0,1,0,0
scala Lifegame.scala 1.44s user 0.09s system 4% cpu 37.965 total
AMD MV-40 1.6GHz シングルコア

605:デフォルトの名無しさん
12/04/29 12:42:30.36
>>599
それで、代入を禁止するのと共用体を禁止するのは、どっちが良いんですか

606:デフォルトの名無しさん
12/04/29 12:48:02.58
スクリプト実行
time scala LifeGame.scala
0,1,1,0,0
0,1,0,1,0
0,0,0,0,0
0,0,0,0,0
0,0,1,0,0
real 0m1.819s
user 0m0.704s
sys 0m0.104s

コンパイル実行
time scala LifeGame
0,1,1,0,0
0,1,0,1,0
0,0,0,0,0
0,0,0,0,0
0,0,1,0,0
real 0m0.585s
user 0m0.528s
sys 0m0.072s

コンパイル時間の分、スクリプト実行だと起動に時間がかかるね

607:デフォルトの名無しさん
12/04/29 12:48:20.97
>>605
両方いいです。

608:デフォルトの名無しさん
12/04/29 12:51:30.57
>>597
よく見れ。
msgにtrueを代入してる。

609:デフォルトの名無しさん
12/04/29 12:53:31.56
>>608
どのtrueを代入してるんですか?

全文を引用して、該当のtrueを【】でくくって下さい。

610:デフォルトの名無しさん
12/04/29 13:04:26.07
>>601
コンパイル通らないのでAppにして通したんだけどこれでも遅いままなのかな?

object LifeCell extends App {
val board = Board(List(List(0,1,1,1,0),List(0,1,0,0,0),List(0,0,1,0,0),List(0,0,0,0,0),List(0,0,0,0,0)))
board.life
println(board)
val rand = new Random()
val b500 = Board(List.fill(500, 500){rand nextInt 2})
val s = new Date().getTime
for (i <- 1 to 500) b500.life
println(new Date().getTime - s)
}

>>603
あ、Scalaスクリプトなんてモードがあるんですね。
実行オプションでそんなに差が出るものなんですか?

611:デフォルトの名無しさん
12/04/29 13:31:36.87
Javaの実行環境に詳しくないとまともにベンチとれないんじゃないかと思う

>>608
$ cat hello.cs
class Program {
public static void Main() {
var hoge = true ? "*true*" : "*false*";
System.Console.WriteLine(hoge); } }
$ mono hello.exe
*true*

612:デフォルトの名無しさん
12/04/29 13:56:15.31
>>608
お前が良く見た方がいい

613:デフォルトの名無しさん
12/04/29 14:10:28.74
括弧を省略する言語は危険
式と文を区別しない言語も危険

614:デフォルトの名無しさん
12/04/29 14:12:28.08
>>613
蛇の国からようこそおこしやす

615:デフォルトの名無しさん
12/04/29 14:22:29.08
Lisp系から見るとHaskellも括弧省略言語だな

616:デフォルトの名無しさん
12/04/29 19:36:04.13
λ式に比べたらLispだって

617:デフォルトの名無しさん
12/04/30 00:25:42.19
>>616
Lispの関数は
apply = foldl ($)
(((f x) y) z) == (apply f) [x, y, z]
省略ではなく、式を変形している
(x, y, zの型が異なる場合、Haskellは上の式が間違っていると主張する)

618:デフォルトの名無しさん
12/04/30 01:24:53.48
>610
core i5で90s程度だね。
ちなみに
 def life() {
  cells.foreach(_.foreach(_.evaluate))
  cells.foreach(_.foreach(_.update))
 }

 def life() {
  cells.par.foreach(_.foreach(_.evaluate))
  cells.par.foreach(_.foreach(_.update))
 }
にして並列化すると30s。
まだまだ遅いけど。

619:デフォルトの名無しさん
12/04/30 01:28:51.62
>>587
遅くなって悪い。確かに待ち合わせが抜けてるね。
BoardもActorをextendsしてlifeを以下のactに替えればよさそう。
 def act() {
  cells.foreach(_.foreach((c:Actor) => {link(c); c.start}))
  var count = 0
  loopWhile(count < m * n) { receive { case _ => count += 1 } } andThen { print(this) }
}

620:デフォルトの名無しさん
12/04/30 01:42:08.34
やっぱり手続き型のC言語が
こういうのは一番早いね。

621:デフォルトの名無しさん
12/04/30 06:36:40.19
つまりCの関数を簡単に呼べる言語が優秀

622:デフォルトの名無しさん
12/04/30 08:02:32.77
なんだ。Rubyが最強ってことか。

623:デフォルトの名無しさん
12/04/30 09:21:02.55
>>546のCの関数を呼び出してみた


from __future__ import print_function
from ctypes import *

clife = cdll.LoadLibrary('liblife.so')
clife.life.argtypes = [POINTER(POINTER(c_int)), POINTER(POINTER(c_int)), c_int, c_int]

x = [[0,1,1,1,0], [0,1,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]]
a, b = (POINTER(c_int) * 5)(), (POINTER(c_int) * 5)()
for i in xrange(5):
    a[i], b[i] = (c_int * 5)(*x[i]), (c_int * 5)()
clife.life(a, b, 5, 5)
print('\n'.join(''.join(str(b[i][j]) for j in xrange(5)) for i in xrange(5)))

624:デフォルトの名無しさん
12/04/30 15:16:50.31
Haskell(GHC)からC関数を使用


import Foreign.Marshal (newArray, mallocArray, peekArray, free)
import Foreign.C.Types (CInt)
import Foreign.Ptr (Ptr, plusPtr)
import Foreign.Storable (sizeOf, peek)
import Data.List (unfoldr)

foreign import ccall "life" cLife ::
    Ptr (Ptr CInt) -> Ptr (Ptr CInt) -> CInt -> CInt -> IO ()

main = do
  x' <- newArray $ concat xss :: IO (Ptr (CInt))
  y' <- mallocArray (m * n)
  x <- f x' =<< peek x'
  y <- f y' =<< peek y'
  cLife x y (fromIntegral m) (fromIntegral n)
  z <- peekArray (m * n) y'
  mapM_ free [x, y]
  mapM_ free [x',y']
  print $ unfoldr (\xs -> if null xs then Nothing else Just $ splitAt n xs) z
  where
    xss = [[0,1,1,1,0], [0,1,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]]
    m = length xss
    n = length (concat xss) `div` m
    f p h = newArray [plusPtr p (sizeOf h * i * n) | i <- [0..m-1]]

625:デフォルトの名無しさん
12/04/30 20:00:22.80
速度が必要な極一部の処理だけ
速い言語(C/C++/Java)で書けば良いのに
クソ遅い言語で速度競っててワロタwww

626:デフォルトの名無しさん
12/04/30 20:14:25.98
なんだJava厨か

627:デフォルトの名無しさん
12/04/30 20:25:46.03
Ruby「実行速度とかそんなの求めてませんから(キリッ」

628:デフォルトの名無しさん
12/04/30 21:11:28.94
>>546のコードをJavaにベタ移植したんですが
C言語に比べて物凄く遅いです(6.5倍遅い)
(出力が遅すぎるので、そこをコメントアウトしてもまだ遅いです)

URLリンク(ideone.com)

どうやったら速くなりますか?

629:デフォルトの名無しさん
12/04/30 21:27:32.39
すいません正しく移植したら速くなりました
URLリンク(ideone.com)

630:デフォルトの名無しさん
12/05/01 03:28:55.35
関数型言語で書くとどうしてもボトムアップになる,
そこが問題,
小さい処理ならそれでいいが,大きなシステムだとはなしにならん

631:デフォルトの名無しさん
12/05/01 03:59:53.53
関数型言語はトップダウンでもボトムアップでも組む事が出来る
出来ないのはそいつが未熟なだけ

632:デフォルトの名無しさん
12/05/01 04:44:27.14
>>630
自分は逆に関数型言語でトップダウンだが・・・
入れ子になった関数を変更するときぐらいだな。ボトムアップな感じになるのは


633:デフォルトの名無しさん
12/05/01 05:04:37.25
マクロな関数(処理)から書き始め、マクロな関数から呼ばれる
ミクロな関数は入出力の型だけ決めて実装は後回し

なんでこんな簡単なことが>>630には出来ないの?

634:デフォルトの名無しさん
12/05/01 07:57:45.80
トップダウンはどうしても車輪の再発明になる
再利用はどうしてもボトムアップになる

635:デフォルトの名無しさん
12/05/01 09:19:19.80
え?

636: ◆QZaw55cn4c
12/05/01 12:12:45.49
>>634
実感として、トップダウンとボトムアップの出会うところでうんうんうなっています。

637:デフォルトの名無しさん
12/05/01 15:17:57.73
>>634
ボディを違う色で塗って「ニューモデル」っていうだけだろ

638:デフォルトの名無しさん
12/05/01 19:35:01.49
Excel内臓の関数型言語の普及率はすげぇよな。
窓際に座ってる禿ですら操作できるんだからなぁ。
URLリンク(research.microsoft.com)

639:デフォルトの名無しさん
12/05/01 19:48:21.14
simonpj先生の勤務先都合仕事だからだまされないで!

640:デフォルトの名無しさん
12/05/01 19:53:04.34
騙されるも何も、内容は事実じゃん。

641:デフォルトの名無しさん
12/05/01 19:57:17.64
スプレッドシート猿によるアホな決定というリスクマネジメントのための学会?

642:デフォルトの名無しさん
12/05/01 20:11:03.69
現実には使えないExcelの拡張の話だけどなw

643:デフォルトの名無しさん
12/05/01 20:20:54.13
拡張せずとも、普通に計算するだけで関数型だろ?
何言ってんだ?

644:デフォルトの名無しさん
12/05/01 20:54:33.43
A1=3
A2=A1-32
A3=A2*5/9

これは静的単一代入 (SSA) です。
SSAは関数型に入りますか?

645:デフォルトの名無しさん
12/05/01 20:59:05.32
y = x + 5 は一次関数。あとは説明要らんよな。

646:デフォルトの名無しさん
12/05/01 21:02:58.15
そもそも、型に入るとか入らないとかいう型の理論が要らない

647:デフォルトの名無しさん
12/05/01 21:47:34.44
型がないと、実行時にしかメソッド名の解決ができない。
これは開発工数が伸びる原因になる。

648:デフォルトの名無しさん
12/05/01 21:56:43.18
なんという緻密な分析

649:デフォルトの名無しさん
12/05/01 22:03:59.52
関数"型"の話してんだろコミュ障

650:デフォルトの名無しさん
12/05/01 22:36:11.12
>>649
だから、型ですよね?

651:デフォルトの名無しさん
12/05/01 22:36:32.17
型だよ型。

652:デフォルトの名無しさん
12/05/01 22:37:00.05
型の話しようぜ。

653:uy
12/05/02 01:30:41.35
>>67
class Array
  def my_permu
    return [self] if size < 1
    inject [] do |r , n|
      reject{|x| x == n }
      .my_permu.inject r do |r,ary|
        r << [n] + ary
      end
    end
  end
end
p (1..3).to_a.my_permu

654:デフォルトの名無しさん
12/05/02 03:53:50.68
ぶっちゃけ関数型もオブジェクト指向もどうでも良くて
自分が使ってる言語以外をdisりたいだけだよね

655:デフォルトの名無しさん
12/05/02 11:28:46.31
>>653
まだpermutationやってんのかよ、こんなもんがそんな面白いか?

perm [] = [[]]
perm xs = [x:y | x <- xs, y <- perm $ filter (/=x) xs]

main = print $ perm [1,2,3]

656:デフォルトの名無しさん
12/05/02 11:34:39.78
こっちは要素の重複を取り除かないバージョン

import Data.List
perm' [] = [[]]
perm' xs = [x:y | x <- xs, y <- perm $ delete x xs]

657:uy
12/05/02 13:23:15.71
>>655
Rubyのpermutationって誰も知らないのか話題にならないから俺が最初に2chにコード投下したやつじゃん(半年前くらいに)
67の冗長ゴミカスRubyソースコードを添削しただけだよ

658:デフォルトの名無しさん
12/05/02 13:33:49.06
へえー、これ良いね。

659:デフォルトの名無しさん
12/05/02 15:29:43.37
>>658
いやHaskellでもRubyでも標準添付や組み込みのライブラリに入ってますし…

660:デフォルトの名無しさん
12/05/03 10:07:46.90
>>655
要素の重複を取り除くところでバグるかもしれない点は面白い

661:デフォルトの名無しさん
12/05/03 14:24:19.11
>>655 を Squeak Smalltalk で書いてみた。バグもそのまま。

perm := [:xs |
   xs ifEmpty: [#(())] ifNotEmpty: [
      xs gather: [:x | (perm value: (xs copyWithout: x)) collect: [:ys | {x}, ys]]]].

perm value: #(1 2 3) "=> #((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)) "

662:デフォルトの名無しさん
12/05/03 20:11:32.07
>>653 も書いてみた。これも重複要素があるとバグる。

SequenceableCollection >> perm
   self size < 1 ifTrue: [^Array with: self].
   ^self inject: #() into: [:r1 :n |
      (self reject: [:x | x = n]) perm inject: r1 into: [:r2 :ary |
         r2 copyWith: (ary copyWithFirst: n)]]

#(1 2 3) perm "=> #((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)) "

ちなみに、Squeak Smalltalkで組み込みのpermutation相当を見たらこんなふうに
破壊的操作による実装だった。

class Array
  def perm_each(&block)
    clone.perm_start_at(0, &block)
  end

  def perm_start_at(n, &block)
    return if n > size-1
    return block.call(self) if n == size-1
    (n..size-1).each do |i|
      swap!(n, i)
      perm_start_at(n+1, &block)
      swap!(n, i)
    end
  end

  def swap!(a, b); self[a], self[b] = self[b], self[a] end
end

663:デフォルトの名無しさん
12/05/04 12:04:28.46
F#で遅延評価

let bind m f = seq {for x in m do yield! (f x)}
let ret x = Seq.singleton x
let rec perm xs =
  if Seq.isEmpty xs then ret Seq.empty else
    bind (seq {0 .. (Seq.length xs - 1)}) (fun n ->
      bind (perm (Seq.append (Seq.take n xs) (Seq.skip (n+1) xs))) (fun ys ->
        ret (seq {yield (Seq.nth n xs); yield! ys})))

664:デフォルトの名無しさん
12/05/05 00:05:09.38
 URLリンク(metalab.at)
こんなひとおる?

665:デフォルトの名無しさん
12/05/06 08:01:00.40
未だに関数型言語の機能が欲しいと思ったことがない。
俺みたいな奴は案外多いんじゃないかね。
そんなことよりトランザクショナルメモリはよ。

666:デフォルトの名無しさん
12/05/06 09:25:35.24
欲しいと思う機能はそれほど多くない
だが変な機能をゴリ押しされるとそれに対抗するものが欲しくなる
ゴリ押しを断るために、先約があるとかいって他のを抜擢するみたいな話は案外多い

667:デフォルトの名無しさん
12/05/06 11:09:05.44
うむ。関数型言語というより
コレクションライブラリがあれば
十分だったりするw

Guavaおすすめ

668:デフォルトの名無しさん
12/05/06 12:23:52.01
ム板の関数型言語派の大半は「関数型言語派」ではなく「型推論派」だろ

669:デフォルトの名無しさん
12/05/06 12:33:51.12
スレタイが無知だな。

手続型 vs 関数型
構造化設計 vs オブジェクト指向設計

670:デフォルトの名無しさん
12/05/06 12:34:57.95
>666
メタプログラミングなんてどう?
LISPのように構文を犠牲にしないMPといえば、OO系が主流だろう。

671:デフォルトの名無しさん
12/05/06 12:59:41.15
コレクションにもpush型とpull型があって
push型は一昔前のOO
pull型は遅延評価できるので関数型に近い印象がある

最近はpull型も普及したので、まだ売れ残っている型推論の方が関数型らしく見える

メタプログラミングは、共通のVMまたはC言語の上に好きな言語を乗せるのが主流

672:デフォルトの名無しさん
12/05/06 13:07:46.75
メタオブジェクトプロトコルみたいな話は最近どうなったのか

673:デフォルトの名無しさん
12/05/06 16:21:50.38
>>671
一昔前がよくわからないのでpull型とpush型の違いがよくわからんです

674:デフォルトの名無しさん
12/05/06 17:41:19.49
>>673
getterを呼び出したり成功か失敗か調べたりするのがpull型
getter反対派はpush型

675:デフォルトの名無しさん
12/05/06 19:43:30.18
言語はなんでもいいので具体例をプリーズ。

676:デフォルトの名無しさん
12/05/06 20:31:27.12
pushとかpullなんて名前は知らないけどこんな感じなんじゃね?

サンプルはJava。上がきっとpushで下がpull

URLリンク(www.akirakoyasu.net)
List<B> blist = new ArrayList<B>(alist.size());
for (A a : alist) {
 blist.add(new B(a));
}

Guavaを使う場合は次のように書きます。
List<B> blist = Lists.transform(alist, new Function<A, B>(){
 @Override
 public B apply(A a) {
  return new B(a);
 }
});

677:デフォルトの名無しさん
12/05/06 20:34:08.65
いまさらだけど、>>671
pullとpushの言葉の使い方逆じゃね?

678:デフォルトの名無しさん
12/05/06 20:43:49.33
>>677
放置したほうがいい人だと思うがどうか?

"Push-Pull Functional Reactive Programming"風に、
pull: demand driven
push: data driven
ってことでいいかと。

679:デフォルトの名無しさん
12/05/06 20:45:09.00
言葉のままに捉えればよいんじゃない?

pullは引く。
result = hoge( piyo( huga() ) );

pushは押す。
huga( result );
piyo( result );
hoge( result );

680:デフォルトの名無しさん
12/05/06 20:59:16.39
>>678
遅延評価はdemand drivenだから、671は合ってるだろ

681:デフォルトの名無しさん
12/05/06 21:05:42.54
一箇所だけ取り上げてそんな事言われても困りますよ。

682:デフォルトの名無しさん
12/05/06 21:16:14.00
>>677は0箇所ですよ
0箇所よりも1箇所の方がいいんじゃないか

683:デフォルトの名無しさん
12/05/06 21:18:45.89
pullとかpushって>>671が作った言葉だろ?

手続きタイプと、コールバックタイプとかでいいんじゃね?

684:デフォルトの名無しさん
12/05/06 21:23:25.41
なんだ、オレオレ用語かよ

685:デフォルトの名無しさん
12/05/06 21:44:18.93
>>682
まあそりゃそうだねw

push/pullは、上に上げたようにFRPでも取り上げられてるし、
他にはWebアプリフレームワークとかXML系APIとか、
いろいろなところでAPIデザインの選択肢として語られてる。
大げさに騒ぐような概念じゃないけど。

686:デフォルトの名無しさん
12/05/06 21:51:58.49
URLリンク(ja.wikipedia.org)繊維強化プラスチック

繊維強化プラスチック(せんいきょうかプラスチック、Fiber Reinforced Plastics、FRP)は、
ガラス繊維などの繊維をプラスチックの中に入れて強度を向上させた複合材料のこと。

単に FRP と書いて、ガラス繊維強化プラスチックを指すことも多いが、
ガラス繊維であることを明示したい場合は GFRP または
GRP (Glass fiber reinforced plastics, Glass-reinforced plastics) と書かれる。

687:デフォルトの名無しさん
12/05/06 22:02:41.17
URL貼れってか
URLリンク(conal.net)

688:デフォルトの名無しさん
12/05/06 22:14:04.87
でも、FRP自体は明らかに関係ない概念だよね?
pullとpushの概念引っ張ってくるためだとしても。

それに、Getter/SetterをPull or Pushに分類しようとするのは
独自解釈が過ぎるでしょ

689:デフォルトの名無しさん
12/05/06 22:15:07.62
なんだF#用語か。URLリンク(pro.art55.jp)

690:デフォルトの名無しさん
12/05/06 22:19:52.64
>>671 はオレオレ定義すぎ。
>>676 の下がpush。上はシラネ。

だろ。普通にpull/pushを考えるなら。

691:デフォルトの名無しさん
12/05/06 22:23:38.07
>>688
> でも、FRP自体は明らかに関係ない概念だよね?

ちょっと難しい例でごめんね。


692:デフォルトの名無しさん
12/05/06 22:28:26.04
>>691
難しい例もなにも、普通にFRP関係ない例しかでてないぞ。
関係あるんなら関係ある例になるコードをださんと。

693:デフォルトの名無しさん
12/05/06 23:30:20.47
>>688
つまり、まず質問をして、独自ではない回答が出るまで待っていればいいんですかね

関数型言語がgetterの使用を制限しない理由は何でしょうか

694:デフォルトの名無しさん
12/05/07 06:32:00.39
関数型ってパターンマッチとか、再帰とか、モナドとか、そんな程度のものなの?
もっとすごい秘密兵器があるんじゃないかなぁと期待しているんだけど、イマイチ見えてきません。
型クラスのメリットは、クラスを使った不完全な抽象データ型オブジェクト指向より
定式化され優れているとわかるとしても、両者は必ずしも背反するものではないですよね?
参照透明性にしても抽象度やモジュラリティは上げられる反面、直感的でない回りくどい処理や
そのための記述を強いられたりする局面も少なからずあるし、そうしたやり難さと引き換えに
関数型でゴリ押しするメリットってどこら辺にあるのでしょうか?

695:デフォルトの名無しさん
12/05/07 09:50:54.31
高階プログラミングではないかと昨夜から今朝にかけて思った。

いわゆるメタプログラミングや自己反映計算を実現する方法として、
自己書き換え→テンプレやマクロ→...というように発展してきて、
関数合成とかでプログラミングをするようになった、というか。

696:デフォルトの名無しさん
12/05/07 10:34:09.89
関数合成はメタプログラミングに入りますか?

697:デフォルトの名無しさん
12/05/07 11:00:16.79
>>694
代入を制限する関数型が、get/setの両方を制限するオブジェクト指向よりも回りくどい
と言われるのは何故ですか?

698:デフォルトの名無しさん
12/05/07 11:08:18.79
Smalltalkが普及しなかったようにHaskellは普及しない

699:デフォルトの名無しさん
12/05/07 11:19:44.93
「get/setの両方を制限」のところがよくわからないので具体的にお願いします。
あとなんでその「get/setの両方を制限」が関数型の再代入制限に対応すると
思われたのでしょうか?

700:デフォルトの名無しさん
12/05/07 11:50:13.94
こうかいかんすう

701:デフォルトの名無しさん
12/05/07 12:01:35.13
高階関数って関数オブジェクトがファーストクラスなら
どうということなく使えますよね。それでもやっぱり
関数型の秘密兵器なんでしょうか?
カリー化が自動だったり関数合成演算子が組み込みなのは嬉しいけど、
OOPLであっても関数オブジェクトがそうであればいいだけって気もしますし、
ポイントフリースタイルで書こうとしてパズルみたいになるのも
何だか本末転倒な感も否めません。

702:デフォルトの名無しさん
12/05/07 12:15:37.81
OOPLでもできるって
頑固なOOPLのスタイルを変えさせることができるなら凄い兵器だ

703:デフォルトの名無しさん
12/05/07 12:35:48.84
頑固なOOPLのスタイルってどんなの?

704:デフォルトの名無しさん
12/05/07 12:54:07.33
>>701
別に秘密兵器でも何でもなく、関数型の思想のうち
手続き型でも適用出来そうな部分は既に受け入れられてるってことさ

705:デフォルトの名無しさん
12/05/07 15:35:46.86
>>694
「ゴリ押しする」ってのは、あなたの心の問題じゃないの?

706:デフォルトの名無しさん
12/05/07 15:47:21.06
関数型の主力は副作用が無いこと
手続き型の主力は副作用が有ること
OOPは副作用の局所化を目指すもの

異論は認める

707:デフォルトの名無しさん
12/05/07 17:50:02.95
副作用があるのはsetterだけ
getterの局所化には副作用以外の目的があるだろう

708:デフォルトの名無しさん
12/05/07 18:08:27.94
そうかしら?

709:デフォルトの名無しさん
12/05/07 18:09:54.21
>>707
一体いつからgetterに副作用が無いと錯覚していた?

getで内部キャッシュを生成,保持しても良く
副作用は外から分からずとも、仕様(期待)通り動作すればいい

710:デフォルトの名無しさん
12/05/07 18:47:24.86
しかし実際にはオブジェクトが他のオブジェクトの参照を握ってたりして、
一回のメソッド呼び出しがどんどんたらい回しされてって。
特にオブジェクト指向では多態のためにメソッドのシグネチャを固定化するから、
オブジェクトが他のオブジェクトの参照を握る傾向は強い。
つまり、オブジェクト指向で副作用の局所化はされないし、元々狙っても無い。
オブジェクト指向はオブジェクトに関するコードや変数の依存関係を纏めたってだけ。
これを手続き型で実行すれば、処理がオブジェクトを跨いであちこちに飛び回る。
このとき、副作用は局所化されない。
副作用の局所化するためには、処理がオブジェクトを跨がないように
する必要がある。
しかし、それはオブジェクト指向とは関係無く、手続き型一般における、設計のテクニックだ。

711:デフォルトの名無しさん
12/05/07 19:01:14.42
・シグネチャを固定化 → 他のオブジェクトの参照を握る
・副作用の局所化するため → 跨がないように
この辺前後の関連がよく分からないので詳しくお願いします

712:デフォルトの名無しさん
12/05/07 19:09:28.48
どう言えばよいんだろうね。
オブジェクト指向はオブジェクト単位で色々纏めるが、これらは変数やコードといった、
静的な要素を分類したに過ぎない。
言い換えれば、「ソースコード」をオブジェクト単位で分類したに過ぎない。
一方で副作用はソースコード上には現れない。
実行時に「処理」にくっ付いて現れる。
だから、副作用を局所化するためには、処理の流れそのものを
局所化する必要があって、これは手続き型一般の設計の問題で、
OOだからどうこうという話ではない。
OOはあくまでソースコードをオブジェクト単位で局所化するだけで、
それ以上は助けてくれない。

713:デフォルトの名無しさん
12/05/07 19:26:38.69
>>709
それはgetterを作って良いし副作用が有って良いという意見だな
そういう自由な考え方が定着すれば、OOに反対する人はいなくなると思う

714:デフォルトの名無しさん
12/05/07 19:29:05.25
そんでついでに言うと、
オブジェクト指向は処理の流れに関して凄く無頓着な一面がある。
というのも、仮想関数だ多態だといってな。
そんで、むしろソースコードみたいな静的なものは怖くねーよ、
こんなの綺麗に分類するより、
処理の流れとその副作用の方がよほど怖えーよ、そっち整理しろよ、
って考え方もあって、OOは使いどころが難しく、2chなんかで議論もこじれる。
だから皆だんだん嫌になってきて、
処理の流れそのものを気にしなくて良い関数型に白羽の矢が立ったってわけ。

715:デフォルトの名無しさん
12/05/07 19:48:12.05
俺にとっての副作用を局所化というのは
「この変数を触るのはこの処理だけ」といった
スコープを小さくしたり責任範囲の壁を作ったりすることなんだけど

>>712にとっての副作用の局所化というのは
何かのメソッド呼んだときに変化するN個のオブジェクトのN個の変数とか
その辺りに言及してるのかな?

メソッドの中で自身(A)が持ってる別のオブジェクト(B)のメソッドを呼んだとして
そこから先でファイルアクセスが発生しようと
それはBの範疇なのでAの中での局所化には関係無い
というスタンスかな、俺はね

>処理の流れに関して凄く無頓着
そうかもね
他のオブジェクトは外面(インターフェイスと仕様)しか見ないので
処理の内容は「あとは任せた」って感じだし

716:デフォルトの名無しさん
12/05/07 20:17:37.37
>>715
これは物凄く悪い例なんだけど、
AがBのメソッドを呼び出して、
そのメソッドの中でBがAのメソッドを呼び出したら、
カプセル化は壊れるんだよね。
そんな設計はするな、と言われそうだが、
これが結構良くあるんよ。
親が子の参照を持ってて、子も親への参照を持ってるとか。

717:デフォルトの名無しさん
12/05/07 20:22:02.86
循環参照は注意だが、カプセル化は別に崩れてなくね?

718:デフォルトの名無しさん
12/05/07 20:22:28.51
カプセル化は言葉が悪かった。
整合性だね。

719:デフォルトの名無しさん
12/05/07 20:40:40.96
AがcallするならBはreturnすればいいのに、なぜかBもcallしようとするんだな
なぜreturnを避ける設計をしてしまうのか

720:デフォルトの名無しさん
12/05/07 20:46:15.19
>719 てめぇ、CPSさんDisってんのか?

721:デフォルトの名無しさん
12/05/07 20:49:59.90
>>716
>これが結構良くあるんよ。
わかる・・・

イベントハンドラとかのインターフェイスの実体として子に自身を渡すとか
木構造で高速化のためAが別のA(親)を持つとかは許容出来るけど
一つずつ順にコンパイル出来ないような定義レベルでの循環参照は俺も嫌い

722:デフォルトの名無しさん
12/05/07 21:04:21.69
>>720
末尾呼出しなら問題なさそうだ
問題は、Aのメソッドの途中でAが参照されること

723:デフォルトの名無しさん
12/05/07 21:18:02.26
>>718
言葉が悪いんじゃない。関係ないんだよ。

724:デフォルトの名無しさん
12/05/07 21:29:27.23
>>722
ACTORさん(以下略

725:デフォルトの名無しさん
12/05/11 20:23:27.60
それぞれのオブジェクトがメッセージを投げ合い、
その結果でたらめな順序で副作用が起こっても問題が無い
仮に問題あっても例外投げときゃ無問題

そういうイイカゲンなシステム開発にオブジェクト指向は最適

726:デフォルトの名無しさん
12/05/11 21:46:23.18
さすがにそこまでいい加減なシステムは品質を確保できないだろ。バカにし過ぎ。

「そのように組むことができる」ことと「実際にそうする」は別問題。
Haskellでも副作用が発生する処理と、そうでない処理をごちゃ混ぜにすることは可能は可能だし。

727:デフォルトの名無しさん
12/05/12 18:57:50.97
ここの人らなら詳しそうだから教えてくれ。

0 :: Integer
0 = 0

みたいな感じで、数値を関数化できる言語ってないの?
0関数にラムダ与えたら、ラムダの実行を無視して、
0以外の数値関数にラムダ与えたらラムダを実行するようにしたい

728:デフォルトの名無しさん
12/05/12 19:03:59.81
は?

関数なら 'a -> 'b みたいな型を持ってるはずだけど。
Integer という型は整数の型であって、関数じゃないよ。

729:デフォルトの名無しさん
12/05/12 19:09:46.34
別にそこの式は、数値を関数化したいって例であって
関数を返すとかとは関係ないよ

730:デフォルトの名無しさん
12/05/12 19:21:16.56
「数値を関数化」ってのが、たとえば「文字列を虚数化」みたいに意味不明。

むしろ、
> 0関数にラムダ与えたら、ラムダの実行を無視して、
> 0以外の数値関数にラムダ与えたらラムダを実行するようにしたい
こっちをソースコードで表現できたら、少しはなんとかなるかもしれない。

731:デフォルトの名無しさん
12/05/12 19:41:40.45
あ゛?チャーチ数ディスってんのかメーン

732:デフォルトの名無しさん
12/05/12 23:05:55.96
>>727
「0」というシンボルと、何らかの関数を結び付けたいということ?

関数型ならそもそも、既に何かに結び付けられてるシンボルに
別の値を結び付けるのは再代入そのものだろうし
手続き型関数型問わず、特定リテラルの意味だけを変更するのはちとマズくないかな

733:デフォルトの名無しさん
12/05/12 23:10:21.88
common lispに変数としての値と関数としての値を区別するということなのか

734:デフォルトの名無しさん
12/05/12 23:11:42.30
ごめん、脱字した。

common lisp(のよう)に変数としての値と関数としての値を区別するということなのか

735:デフォルトの名無しさん
12/05/13 00:06:48.19
>>732
Smalltalkなら実現してたべ

value := 0.
value message.
こんな感じで、数値にメッセージを送ると、
数値に紐付いたメソッドを呼ぶ事ができた。
1にメッセージを送れば、1のメソッド。
2にメッセージを送れば、2のメソッドみたいにね。

736:デフォルトの名無しさん
12/05/13 01:07:22.66
本のお題がどういうものだが今一歩ピンとこないが、
チャーチ数を計算する型なしラムダ式処理系なら結構転がってる。
数値や真理値は短形表示できるが。


737:デフォルトの名無しさん
12/05/13 02:06:34.64
>>735
何が言いたいのか分からん
value message と function value は語順が違うだけじゃね?

738:デフォルトの名無しさん
12/05/13 02:12:38.75
>>737
Smalltalkが解らないとなるとlispなら解るかい

(0 arg) 0関数を実行
(1 arg) 1関数を実行

別バージョン
( (lambda ( x arg ) ( x arg ) ) 0 arg ) 0関数を実行
( (lambda ( x arg ) ( x arg ) ) 1 arg ) 1関数を実行


739:デフォルトの名無しさん
12/05/13 02:36:28.73
>>738
なるほど分かった
0や1といったリテラルに関数を割り当てたいってことだね

どっちかというと関数型 vs. オブジェクト指向じゃなくて
静的型 vs. 動的型になりそうな気配

740:デフォルトの名無しさん
12/05/13 02:40:45.66
ところで>>727のいう「ラムダ」の引数は何?
それは何時渡すの?

741:デフォルトの名無しさん
12/05/13 02:44:08.62
>>740
値が関数だって事の説明用だから引数はなんでもいいんですが

742:デフォルトの名無しさん
12/05/13 02:49:18.06
>>741
意味論的には関数型言語の値は「ゼロ引数関数」という関数

743:デフォルトの名無しさん
12/05/13 08:04:27.03
いずれにしろ 0 :: Integer では、関数になってないから

744:デフォルトの名無しさん
12/05/13 10:20:35.18
OO信者の俺ですら数値クラスにメソッド追加するような
コードは勘弁して頂きたい
オープンクラスではしゃぐのは初心者時代で終わらせてほしい

745:デフォルトの名無しさん
12/05/13 11:09:32.18
>>735>>738
シングルディスパッチでは第一引数を特別扱いしてるだけで
x.foo y z と foo x y z に本質的な差は無い

シングルディスパッチ脳には理解出来ないかもしれんけど

746:デフォルトの名無しさん
12/05/13 11:16:35.94
難しい問題だね。
func( o1, o2 )
こういった関数は後からいくらでも追加できるけど、
o1.func( o2 )
との本質的な違いはスコープだけだからな。
多態出来る出来ないの違いは有るけど、それは言語上の制約ってだけだからね。
クラスの外のスコープにいくらでも関数が定義できるのに、
クラスの中のスコープにメソッドを追加することは出来ません、
って制約に一体どれほどの意味があるかって言われると、ねぇ。
特に動的言語では。

747:デフォルトの名無しさん
12/05/13 11:37:40.06
あんたの恣意的な分類で「本質」とか「言語上の制約ってだけ」とか言われても
わかりませんわ。

748:デフォルトの名無しさん
12/05/13 12:25:07.97
別に恣意的ではないと思うけど。
本来、どこのスコープに何を追加しようが勝手なものなんじゃないの?
静的言語では実行効率の理由で制限がかかってくるのも分かるけどさ。

749:デフォルトの名無しさん
12/05/13 12:32:53.64
Haskellでやっつけ
お題の真意が掴めてないので、たぶん条件を満たしてない

URLリンク(ideone.com)

750:デフォルトの名無しさん
12/05/13 12:39:04.98
0がどうのこうのの話は、まだ続いてたの?
0と1は同じ型だろうから、同じ関数にディスパッチされるのが当たり前だしさ。

751:デフォルトの名無しさん
12/05/13 15:59:42.13
>>742
そういう形式化もあるという程度の話。

752:デフォルトの名無しさん
12/05/13 18:30:14.35
このスレには時代遅れのSmalltalkを使ってる
奇特な人が居るから質問するんだけど、
あのIDEモドキを立ち上げずにプログラム実行する方法無いの?

それと動的型付けで実行が遅いから、せめてボトルネックだけでも
C/C++で書いて実行できないとトイプログラムでしか
使いモノにならないと思うけど、簡単にC/C++のライブラリとリンクできるの?

753:デフォルトの名無しさん
12/05/13 19:25:11.00
たとえばVisualWorksやPharoといったSmalltalk処理系には
headlessといって、サーバーなどの用途に使う目的でIDE抜きで起動したり、
その際に指定した.stファイルを読み込んだり実行できる機能があります。

またGNU Smalltalkのように、標準入出力から使うことに特化して開発された
特殊な処理系もあるのでこういう処理系を最初から選ぶのもよいでしょう。

ただIDE抜きの使い方は他の言語と同様の使い方ができるというメリットがあると反面、
Smalltalkの独自の機能や優位性をかなりスポイルする使い方ということにもなるので
他の言語が選択できる状況であるならば、よほどSmalltalkを使い慣れた人でもなければ
そこまでしてSmalltalkを使うメリットはあまりないような気もします。
GNU SmalltalkやAmber Smalltalkといった特殊なSmalltalk処理系を使っての
Smalltalk入門があまり推奨されないのも同様の理由です。

SmalltalkからC/C++で書いた関数をコールするにはいくつか方法がありますが、
たとえば、商用のSmalltalkであるVisualWorksにはDLL and C Connectという方法が使えます。
URLリンク(www.cincomsmalltalk.com)

PharoやSqueakではVMプラグインを書いてバイトコードを拡張したり、FFIが使えます。
URLリンク(wiki.squeak.org)
URLリンク(wiki.squeak.org)

754:デフォルトの名無しさん
12/05/13 19:48:37.96
727です。
なぜかOOの話がでてますが関数型の話でOOは関係ありません。
OOPLでも同じ表現ができるというだけです。

で、本題ですが、最終的な目的としては下のようなラムダ演算ができる言語は
存在しないのかという話です。

( 0 (lambda () "true" ) ) 0関数はlambdaを評価せず、nilを返す
( 1 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す
( 2 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す

( (- 1 1 ) (lambda () "true" ) ) 0関数を評価する事になるのでlambda

755:727
12/05/13 19:54:33.33
間違えて途中で書き込んでしまいました。すみません。

( 0 (lambda () "true" ) ) 0関数はlambdaを評価せず、nilを返す
( 1 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す
( 2 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す

( (- 1 1 ) (lambda () "true" ) ) 0関数を評価する事になるのでlambdaを評価しない
( (+ 1 1 ) (lambda () "true" ) ) 2関数を評価する事になるのでlambdaを評価しない

数値を関数化できないかというのは、数値を評価したとき、このような
振る舞いをするように数値を定義できなる言語は無いかという事でした。
尤も、言語レベルで最初から数値をチャーチ数と同じように評価できるなら
新たに関数として数値を再定義できる必要は無いんですが。

756:デフォルトの名無しさん
12/05/13 20:00:39.51
>>752
時代遅れってアホか、通信・製造・金融・保険・政府。
お前がしらんだけで第一線で新規開発されとるわ。
国内企業なら、東洋ビジネスエンジニアリングとかが導入してんだぞ。

757:デフォルトの名無しさん
12/05/13 20:17:42.17
F#でやってみた。
拡張メソッド定義してるだけなので、実質「Execute(0, fun () -> printnf "zero")」と同じ

type System.Int32 with
    member x.Execute func = match x with 0 -> () | n -> func()

> (0).Execute (fun () -> printfn "zero");;
val it : unit = ()
> (1).Execute (fun () -> printfn "one");;
one
val it : unit = ()
> (1 - 1).Execute (fun () -> printfn "zero");;
val it : unit = ()

758:デフォルトの名無しさん
12/05/13 20:19:29.56
>>755
Integer と () -> Bool は違う型なので、
同じ数値(関数)の型が文脈に応じて変化する言語でなければ不可能。

759:727
12/05/13 20:19:44.31
むちゃくちゃになっていたので直します。何度もすいません。
( 0 (lambda () "true" ) ) 0関数はlambdaを評価せず、nilを返す
( 1 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す
( 2 (lambda () "true" ) ) 2関数はlambdaを評価し"true"を返す

( (- 1 1 ) (lambda () "true" ) ) 0関数を評価する事になるのでlambdaを評価しない
( (+ 1 1 ) (lambda () "true" ) ) 2関数を評価する事になるのでlambdaを評価する

760:デフォルトの名無しさん
12/05/13 20:20:46.22
>>758
できる言語はあるかと聞いているのですが?
あとboolは関係ないですよね

761:デフォルトの名無しさん
12/05/13 20:24:09.03
>>760
じゃあ Integer と (() -> a) -> a

それはともかく、関数型とか全然関係なくって
まともな静的型なら無理って言ってるんだけど、
動的型しか使った事無い馬鹿には分からないかな?

762:デフォルトの名無しさん
12/05/13 20:25:17.06
>>761
だから、できない言語の事は聞いてなくて、出来る言語はあるかと聞いてるんですけど。

763:デフォルトの名無しさん
12/05/13 20:29:16.10
>>762
スレ違いだし問題としても糞詰まらんから
どっか行けって言ってんだけど?

764:デフォルトの名無しさん
12/05/13 20:29:54.03
何か値を返さなきゃならないみたいなので、>>757を修正
nilと値じゃなくてoption型使ってるけど

type System.Int32 with
    member x.Execute func = match x with 0 -> None | n -> func() |> Some

> (0).Execute (fun () -> "zero");;
val it : string option = None
> (1).Execute (fun () -> "one");;
val it : string option = Some "one"
> (1 - 1).Execute (fun () -> 1 - 1);;
val it : int option = None

765:デフォルトの名無しさん
12/05/13 20:32:20.89
>>763
NGにしたいんでトリでも付けてもらえます?
スレ違い以前に話が通じないので

766:デフォルトの名無しさん
12/05/13 20:42:57.75
>>763
まず日本語の通じないお前がどっか行けよ

767:デフォルトの名無しさん
12/05/13 20:44:48.51
>>764
オブジェクトで出来てもあんまり嬉しくないんですが・・・

768:デフォルトの名無しさん
12/05/13 20:46:00.83
>>765>>766
型付けの問題だって理解できない自分の低能さを
日本語の問題にすり替えるなよw

769:デフォルトの名無しさん
12/05/13 20:52:46.02
>>761
「コンセントの付いている車はありますか?」
「軽トラなら無理です」
お前が言ってるのはこういう事だという自覚は有るのか?
普通は「あります」「ありません」この2択だろ
頭おかしいな

770:デフォルトの名無しさん
12/05/13 20:53:58.75
>>767
Int32はラッパークラスとかではなく、プリミティブかつオブジェクトなんだけど。
まぁそれでもダメというならどうしようもない。

771:デフォルトの名無しさん
12/05/13 20:55:35.08
>>764 のような Execute 的な関数を使うのってダメじゃね?
これアリなら難しくも何ともないじゃん


(|.) 0 _ = Nothing
(|.) x f = Just $ f ()

main = do
  print $ 0 |. (\_ -> "zero")
  print $ 1 |. (\_ -> "one")
  print $ (1 - 1) |. (\_ -> "zero")
  print $ (1 + 1) |. (\_ -> "two")

772:デフォルトの名無しさん
12/05/13 20:57:08.31
>>770
すいません。
関数と互換性をもってて欲しいんですよ。

773:デフォルトの名無しさん
12/05/13 21:06:51.99
>>771 >>772
てっきり拡張メソッド的なものを要求してるのかと思ってた。
Scalaなら暗黙型変換あるからできそうな気がする。

774:デフォルトの名無しさん
12/05/13 21:08:02.77
>>773
なるほど。Scalaですか、調べてみます。

775:デフォルトの名無しさん
12/05/13 22:46:41.69
で、Scalaなら出来たの?

776:デフォルトの名無しさん
12/05/14 00:37:38.04
マイナー言語使い共が
可読性皆無のコード書く御題で
型付けの弱さを競うスレはここですか?

時代に逆行してて笑えるwww

777:デフォルトの名無しさん
12/05/14 01:46:05.41
誰だって0と1は同じ型だと考えるのに、違った振る舞いをさせたいってのは、
何か前提がおかしいんだろうね。
元々何がしたかったのか聞ければよいんだけど、
彼にそういった振る舞いが出来るとも思えないしなぁ。

778:デフォルトの名無しさん
12/05/14 07:07:11.76
うーん。一番良く分からんのは、>>767を読むと出題者は>>764を見て
オブジェクトとしてなら「出来ている」認定してるっぽい処だな。

779:デフォルトの名無しさん
12/05/14 07:40:52.01
出題者がOOP厨だからオブジェクトには甘いだけだろ
別に不思議でもなんでもない

もちろん出題者は底なしのアホだけど


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch