一些連接, 關於不可變數據

這篇筆記介紹不可變數據, Persistent Data Structure 和 Immutable.
可是不深刻數據結構實現, 函數式編程理論.javascript


定義

https://en.wikipedia.org/wiki/Persistent_data_structurehtml

In computing, a persistent data structure is a data structure that always preserves the previous version of itself when it is modified. Such data structures are effectively immutable, as their operations do not (visibly) update the structure in-place, but instead always yield a new updated structure.java


編程語言

FP: Haskell, Clojure, Elixir
類庫: immutable-jsreact


概念的區別

http://vkostyukov.ru/posts/designing-a-pfds/git

Immutability and persistent are quite similar terms, which often substitute each other. We say immutable vector (in Scala) but mean persistent vector (in Clojure): both implementations are based on the same abstract data structure Bit-Mapped Vector Trie but named differently. Although, there is a slight difference between immutability and persistence as they apply to data structures.github

  • Persistent data structures support multiple versions
  • Immutable data structures aren't changeable

優點

http://stackoverflow.com/a/4400389/883571
http://www.quora.com/What-are-the-advantages-and-disadvantages-of-immu...編程

  • 多線程安全, 可靠
  • 對於須要多份數據的狀況, 能夠重用結構
  • 函數式編程

劣勢

http://concurrencyfreaks.blogspot.sg/2013/10/immutable-data-structures...api

  • 使用門檻
  • 須要編程語言實現好的 GC

底層實現

  • Clojure

Clojure 的數據結構實現
Understanding Clojure's Persistent Vectors, pt. 1
http://hypirion.com/musings/understanding-persistent-vector-pt-1
安全

  • Haskell

Haskell lists are represented as singly linked list性能優化

haskelldata [] a = [] | a : [a]

http://stackoverflow.com/a/15063181/883571
http://i.stack.imgur.com/Y1Ajv.png

  • Paper

A Functional Approach to Standard Binary Heaps
http://arxiv.org/pdf/1312.4666v1.pdf


寫法

  • Clojure

有變量. 可是複合數據結構是不可變的

clojure(def x 1)
(defn p []
  x)

(p)
(def x 2)
(p)
  • Haskell

沒有變量的寫法, 只能用 let 定義表達式 alias name
或者在 do notation 裏有賦值, 但底層不是賦值
https://en.wikibooks.org/wiki/Haskell/do_notation

haskelldo x1 <- action1
   x2 <- action2
   action3 x1 x2
haskellaction1 >>= \ x1 ->
  action2 >>= \ x2 ->
    action3 x1 x2
  • Elixir

變量被引用就是不可變的值(不過在 process 級別有私有數據)

iex(6)> a = 1
1
iex(7)> b = fn -> IO.puts a end
#Function<20.90072148/0 in :erl_eval.expr/5>
iex(8)> b.()
1
:ok
iex(9)> a = 2
2
iex(10)> b.()
1
:ok

性能問題

  • Performance

http://www.quora.com/Is-object-immutability-in-functional-programming-...

  • GHC

Data immutability forces us to produce a lot of temporary data but it also helps to collect this garbage rapidly.

https://wiki.haskell.org/GHC/Memory_Management

  • React 的性能優化
jsshouldComponentUpdate: function(nextProps, nextState) {
  return true;
}

https://facebook.github.io/react/docs/advanced-performance.html


immutable-js

http://facebook.github.io/immutable-js/docs/#/
https://github.com/intelie/immutable-js-diff
https://github.com/intelie/immutable-js-patch


seamless-immutable

This level of backwards compatibility requires ECMAScript 5 features like Object.defineProperty and Object.freeze to exist and work correctly, which limits the browsers that can use this library to the ones shown in the test results below. (tl;dr IE9+)

  • object.freeze

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glob...

jsvar o = Object.freeze(obj);

然而沒有複用數據結構, 將會有性能問題:
https://medium.com/google-developers/javascript-application-architectu...

Well, you technically could use Object.freeze() to achieve immutability, however, the moment you need to modify those immutable objects you will need to perform a deep copy of the entire object, mutate the copy and then freeze it. This is often too slow to be of practical use in most use-cases.


怎樣編寫程序

  • sum
haskellfoldl f z []     = z                  
foldl f z (x:xs) = foldl f (f z x) xs
  • maximum
haskellmaximum' :: (Ord a) => [a] -> a  
maximum' [] = error "maximum of empty list"  
maximum' [x] = x  
maximum' (x:xs) = max x (maximum' xs)
  • white/for

http://www.haskellforall.com/2012/01/haskell-for-c-programmers-for-loo...

haskellwhile :: (Monad m) => m Bool -> m a -> m ()
while cond action = do
    c <- cond
    when c $ do
        action
        while cond action

for :: (Monad m) => m a -> m Bool -> m b -> m c -> m ()
for init cond post action = do
    init
    while cond $ do
        action
        post
  • model
elm-- manage the model of our application over time
model : Signal Model
model =
  Signal.foldp update initialModel actions.signal

https://github.com/evancz/elm-todomvc/blob/master/Todo.elm#L314

相關文章
相關標籤/搜索