一、為什么聲明性語言往往適合于并行執行
函數式編程里的程序在輸入相同時總是得到相同的輸出,不包含其他狀態,也不影響其他程序的狀態,所以在哪里執行都一樣,這樣就很容易調度到其他線程、進程甚至遠程服務器上。而命令式代碼通常隱含地使用全局狀態,這些狀態在不同代碼之間是共享的,代碼的執行時序會影響執行結果,這就導致難以并行化。
但這并非沒有代價。純粹的函數式編程無法處理帶有狀態的外部組件,而磁盤讀寫、網絡輸入輸出等IO操作天生是有狀態的,如果不能處理這些對象,語言的適用范圍是很窄的。所以函數式編程語言通常也會要么帶有命令式的支持,要么將處理有狀態的對象的過程封裝到某些外部的統一模型當中(比如Erlang的消息機制)
聲明性范式只要求程序員提供程序的目的,然后系統自己有編譯器,lib或優化器去計算出”怎么達到目的”較好的執行路徑,而不用程序員提供怎么達到目的方法或者hint。而命令式范式需要程序員手把手的告訴機器怎么完成任務。機器無法區分目的和手段,而必須嚴格按照程序指定的來執行。
相比之下,就是根據“優化器”計算出來的執行路徑好,還是人指定的好呢?(把“好”定義為價值除以產生價值需要的時間)
舉個例子: 對SQL來說,你只需要指定你想找什么。數據庫會自己算出來怎么按照你的要求找。 你如果用java或C在一大塊硬盤上找數據,你就要自己去指定機器每一步怎么運行才能給你結果。
延伸閱讀:
二、聲明式與命令式
命令式(Imperative)和聲明式(Declarative)是很早就有的概念,比如 SQL、HTML、CSS 是典型的聲明式語言,而我們使用的絕大部分編程語言都是命令式的。
命令式編程就像它的名字一樣,它由開發者我們一步一步的告述計算機,執行一系列的操作,然后得到想要的結果,起主要作用的是開發者,計算機只是幫助開發者執行計算而已。
而聲明式編程卻與此相反,它不是告述計算機做什么做,而是直接告述計算它想要的結果,至于怎么做,由預先寫好的程序依據一定的算法由計算機自動推算出來。
聲明式與命令式的主要區別在于,聲明式描述的是結果,它不關心過程。比如 SQL,我們告述數據庫的是,我們要查詢某張表滿足某某條件的數據,但我們并不會告述數據庫怎么去查,怎么查數據是數據庫系統自己關心的事情。