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