java 板


LINE

果然出去吃个饭回来就断线了 orz p 币看来会少很多 :s ※ 引述《sbrhsieh (sbr)》之铭言: : ※ 引述《godfat (godfat 真常)》之铭言: : : 其实我觉得简单地说就是,不能有任何 side-effect, : : 因此不能有任何 state. 大概就这样,其他都是衍生出来的性质。 : : 这边不会跟 no side-effect 直接连上关系的原因, : : 我想是有些情况下 side-effect 是可以被允许的。 : 这边的 side-effect 该怎麽定义?涵盖的范围? 我想 side-effect 的涵盖范围应该不太可能能被定义..? 如果是 side-effect 本身要怎麽定义的话,大概就是不能有 state, 然後 function/expression 本身具有感染性,只要用上任何有含 side-effect 的东西,本身就会变得具有 side-effect. : 我试想过如果一个 FP 语言不允许 function/procedure 有任何的 side-effect, : 那麽这个语言写出来的程式会蛮受限的,几乎只能写纯处理数据的工作。 : 有太多的工作本身就是一种 side-effect,是无法单纯 consume 某些 input,并 : 以特定 output value 来呈现(resource manage、IO)。比如: : 「删除给定路径的某个档案」,这件工作本身就是变更档案系统的状态,这不可能 : 由一个毫无 side-effect 的 procedure(expression)来实现。 我觉得这个就可以去找特定的资料来看,例如 Haskell. Haskell 本身是 purely functional, 但同样允许 side-effect, 也可以做 IO, 因此并不是只能处理纯数据的工作... 这靠 monad 来达成这件事。这是借自 category theory 的词: http://en.wikipedia.org/wiki/Monad_(functional_programming) 很不幸的是 XD 虽然我一直想把他读完,不过到现在还是一直没找到 机会把他读完,所以细节都不是很清楚... 虽然听说这是 haskell 里, 会第一个碰到的障碍,甚至也有文章副标题是: "Don't Panic" http://pages.cpsc.ucalgary.ca/~robin/class/521/monadGuide.pdf 噫,我应该想办法找时间来把这些看完的。 最早我是看 Yet Another Haskell Toturial: http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf 这篇我之前看的时候还没写完,很多地方是空白的,现在不知道写完了没? 总而言之,我可以大概提一下目前的理解。很可能有错,就大概看看..... 跟下面的 stream 一起说好了。 : Stream 这种观念/东西感觉上也跟状态很有关系,有玩过比较纯的 FP 语言(诸如 : Clojure)的人,可否说明一下该 FP 语言是否有实做 stream 概念的东西? : 若有,又是如何去实现管理/操作(manipulation) stream 的 procedure,能够 : 让这些 procedure 没有 side effect 又有好的效率? 我稍微查了一下,在 haskell 中,拿来对付类似的东西,好像大多是用 Data.ByteString.Lazy: http://www.cse.unsw.edu.au/~dons/fps.html 效率好不好嘛,上面是说效率很好,有人说效率有 C 的 1/2 我觉得像是这种本身就具有大量 state 的问题, purely functional 本身是不太可能比得赢 C 之类直接的操作啦... 这跟架构有关,在别人的地盘上,先天上就输了不是吗 XD 我个人觉得类似的效能评比,应该用在其他架构上,例如 distributed 最近很红的 Erlang, 实作 CouchDB, 诸如此类从「架构上」寻求的解答。 或许没什麽关系,不过有个类似的语言,也是写在 JVM 上: http://en.wikipedia.org/wiki/E_(programming_language) 不过这个没怎麽维护了的样子?或许直接看 Erlang 即可... 回到 monad, 大抵上的概念就是我们把「状态」视为一种值, 而每一次状态改变,则会产生新的值,再把这个值继续传递下去。 就像 Schelfaniel 在推文里提到的: : → Schelfaniel:函数式语言的变数,都是不变的吧,但物件导向有可能变 08/04 20 : → Schelfaniel:也就是说,如果process1要变,变化会放在它的传回值 08/04 20 : → Schelfaniel:像是这样 (process2 (process1 java-object)) 取其变 08/04 20 我们假设现在的系统状态是 X, 则两次对萤幕输出 Hello, World! 则可看成: puts("Hello, World!", puts("Hello, World!", X)) 而不是: puts("Hello, World!") puts("Hello, World!") 也就是说,puts 这个 function, 他会回传一个新的系统状态,假设叫 Y, 就可以看成是: Y = puts("Hello, World!", X) Z = puts("Heelo, World!", Y) 因为第二个 puts depend on 第一个 puts 的 return value, 也就是新的系统状态,因此两者的顺序是不可以被颠倒的, 这边不是两个各自独立的 statement, 而是一个不可分割的 expression. haskell 的 monad 就是把这件事包装起来。很多 IO function 的回传 都是 IO (), 表示他是一个 IO monad. Prelude> :t putStr putStr :: String -> IO () putStr 本身是一个 String -> IO () 的 function. 来看刚刚 ByteString 的范例: module Test where import Data.ByteString.Lazy.Char8 as L test = do s <- L.readFile "/dev/zero" -- 这边就是把 /dev/zero 这个档案的内容,读到一个 IO ByteString 里面: -- L.readFile :: FilePath -> IO ByteString -- 前面 IO () 是表示我们不关心这个 IO monad 究竟存有什麽状态, -- 比方说,我们并不关心萤幕(or remote)被输出了什麽资料, -- 但这边我们关心我们读入了什麽资料,因此是 IO ByteString return (L.unpack (L.take 10 s)) -- 这边从刚刚的 s 里,读取前面前 10 个 Char8 -- 而 L.unpack 则是把这个 ByteString, 转成 haskell 原本的 String, -- 也就是 [Char], 字元串列。最後再把整个结果回传回去。 -- return 是用在 monad 里面,他会把现在的「状态」包起来。 -- test :: IO [Char] -- 我们最後是回传 String (等同於 [Char]), 因此整个 test 的结果, -- 就是一个 IO String main = do s <- test Prelude.putStr s -- 这边我们把 test 的结果,也就是刚刚的 IO String, -- 存到 s 里面,然後再把这个 s 印出来。 也就是说,monad 本身是有感染力的,只要你用到 monad, 整个 function 也会变成 monad. 要让你的 function 不成为 monad, 只能完全避开任何的 monad, 也就是任何 IO. 接着再由其他 monad function 去使用你其他的 pure function. 这边也可以参考 Eiffle, 在昨天 referential transparency 的连结里: http://en.wikipedia.org/wiki/Referential_transparency_(computer_science) 提到 command-query separation: http://en.wikipedia.org/wiki/Command-query_separation command 有 side-effect, 而 query 没有,因此是 referential transparency. 这边其实有点类似这样的味道,像在上面的 main 里有: s <- test Prelude.putStr s 但是不能简写成: Prelude.putStr test 因为 test 是回传 IO String, 而 putStr 是要吃 String 的。 透过 s <- test 把 IO String 里的 String 抓出来,放在 s 里, 才能把这个 s 丢给 putStr 把结果印出来。 在这边由於使用了 do notation, 因此写起来的感觉跟一般 imperative 的程式差不多:逐次执行,可以有 side-effect. 但实际上这其实是 syntactic 上的 sugar: http://en.wikipedia.org/wiki/Monad_(functional_programming)#do-notation 看起来是一行一行的,也没有牵涉到 state 间的转换,是底层帮你做好了。 如果要全部自己来的话,写起来是会很可怕,很复杂的结构,例如上面的范例: a = do x <- [3..4] [1..2] return (x, 42) 会被转成: a = [3..4] >>= (\x -> [1..2] >>= (\_ -> return (x, 42))) 没有人会想这样写程式的... XD 简单地说,利用 monad, 我们在 pure function 的世界里, 做出一种模拟 side-effect 的结构,然後让你把 pure function 跟其他 side-effect 做一层切割,有点像是防火墙这样的味道... 因此如果写 haskell 程式只用 monad 和 do notation 的话, 感觉就没什麽用 pure function (thus haskell) 的意义在了... 然而如果谈到效率的话,当然不可能会有最底层那样来得好。 当然是越接近机器架构会越快,这是当然的。不过这也不表示说 用这种 monad 的方式会很慢很慢,因为很显然,大部份的时候 那些 state 根本不需要真的被 evaluate 出来,既然不需要被观察, 这些 state 也不会影响到其他 state, 那在 compile 时, 基本上就可以完全舍弃掉。这就是最佳化要解决的问题了... 理想上当然是能把抽象化程式,依照目前机器架构,做最好的最佳化。 把所有多余也不关心的操作都拿掉。GHC 本身就有很多很多的最佳化.. XD == 我打太久了,不能再花时间在这上面,就暂时不校稿了... -- Hear me exalted spirits. Hear me, be you gods or devils, ye who hold dominion here: I am a wizard without a home. I am a wonderer seeking refuge. Sacrifice --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.128.121.85 ※ 编辑: godfat 来自: 220.135.28.18 (08/05 20:56)







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP