新太的ivr語音平台在業內赫赫有名,號稱占領sp-ivr的半壁江山,其指令碼之難寫早有耳聞。而最近竟然發現,高陽的指令碼語言和新太指令碼語言如出一轍,以高陽在金融和通訊領域的實力,我斷難相信,他們會失去最基本的判斷力,採用這種如此原始,形同彙編的語言。
我一直堅信,寫程式是一種愉悅的享受,作為語音ivr應用開發也是如此,開發者應該得到最好的工具,他們在使用高階語言的經驗應該得到尊重。是什麼力量能夠讓他們返回到彙編時代?也許是市場的力量。我只能借用三國人物的一聲嘆息了:
世無英雄,遂使豎子成名。
好了,看看我的具體點評吧。
(由於高陽指令碼和新太指令碼非常相似,以下統稱為新太指令碼或新太指令碼語言)
一. 最低階的語言,彙編特性
讓我們看看這樣的**:
[assign sr1,"i am "]
[assign sr2,"a boy."]
[strcat sr1,sr2]
[printregister 2] //sr1="i am a boy.",sr2="a boy."
這和組合語言有什麼兩樣?如果採用高階語言,就是這個意思:
s = "i am " + "a boy";
組合語言比較底層,程式設計效率較低,幾乎每個操作都要借用暫存器。
用組合語言寫幾十句,敲幾百個字元,在高階語言裡面只要一兩行。
行數多了,還增加出錯的概率,也增加了除錯的難度。
來看看我曾經多次引用的,ruby語言的設計者日本人yukihiro matsumoto的一段話:
"基於圖靈機的完整性理論,每一種具備圖靈完整性的語言能做的事情理論上都可以由另一種具備圖靈完整性的語言所代替,只是花費的代價不同。您可以用組合語言實現所有的功能,但是現在已經沒有人再想用彙編程式設計序了。"
("ruby的設計思想"-《程式設計師雜誌》2003.12)
二. goto語句
任何乙個學過最基礎計算機理論的人都知道,goto語句是高階程式設計之大忌,它使程式流程任意轉向,缺乏結構化。
新太和高陽的 -> 符號就是goto語句,它指向乙個標號。
有人會說,c語言甚至最新的c#也有goto語句啊,事實是,你在c、c#中不用一句goto語句也能夠寫出好的應用程式,在新太的指令碼裡面可以嗎?不可以,其 -> 無所不在。這除了和這種語言的彙編特性有關外,還和它依賴於「狀態機」的實現方式有關,在本文的後續部分我還會闡述。
此外,最簡單、最直觀的迴圈,如:
for(i=0; i<10; i++)
在新太指令碼語言裡,也只能用 -> 來實現。
三. 冷冰冰的暫存器
在新太指令碼裡面,幾乎每個操作都必須使用暫存器,如:sr1, sr2, sr3等等。在高階語言裡面已經被變數所取代。
暫存器和變數相比較,最大的問題是暫存器沒法命名,如比較:
在高階語言裡面: istimeout = true; // 不用注釋,望文即能生義
在新太指令碼裡面: [assign sr1,1] // 看不出含義
高下立現。
即使如此,新太的暫存器變數還是有很多限制,如數量的限制,最多只能多少個暫存器,如果構造大型專案則比較麻煩。此外,如果是字串型別,還有長度限制,如最多只能256個位元組,要拼接乙個複雜查詢的sql語句就沒辦法了。
四. 缺乏表達能力的語法
程式設計序如同寫文章,要是我們還用商周時代的甲骨文,憑那點可憐的詞彙和語法,是無法寫出結構清晰、段落分明的錦繡文章,甚至無法描述複雜的事物。
新太指令碼在語法上沒有任何現代高階語言的特性,比如:等號賦值,多個字串相加,直觀的迴圈語句、條件判斷,複雜表示式,陣列,形式引數等等。這種編**是乙個痛苦的體驗。
新太指令碼也提供了最基本的封裝,比如函式,問題是其函式和我們任何高階語言的程式設計經驗不相符,那就是沒有形式引數,沒有區域性變數,一切都還要借助那幾十個暫存器。
沒有現代高階語言的結構,**平鋪直敘,顯得沒有層次,我看什麼**縮排,變數命名風格,在新太指令碼裡面完全可以不要。你需要的只是函式命名風格,標號命名風格。
正因為如此,我覺得如果單憑該指令碼語言本身,試圖構造大型複雜的ivr應用是困難的。如果你發現某項功能沒有,往往你只能借助於所謂的外部閘道器,或者乾脆等待新太的公升級。這也是新太推出某項新的業務時,往往要擴充一批庫函式的原因。
五. 狀態機, 我們真的需要嗎?
在某些情況下狀態機是乙個很好的概念,也是很簡單的概念。概括地說就是把流程劃分為多個狀態,每個狀態下將會執行某個動作(也可能是一組動作),根據該動作的結果決定流程走向下乙個狀態。
很顯然,新太指令碼的標號表示狀態, 如 :label ;
而轉移語句如 -> label 表示狀態的遷移。動作就是其系統函式。
理論和實踐都已經證明,當狀態較少,或者是基於控制的系統,使用狀態機比較有效,如著名的電梯控制。當狀態很多,比如複雜的ivr應用,分支較多,看起來就像一團亂麻了,你數數複雜的新太指令碼有多少個標號就明白了。
實際上,狀態機的實現很容易,我曾經和乙個業內朋友開玩笑說,我可以花1到2周寫出乙個新太的指令碼引擎,相信有底層程式設計經驗的朋友會同意我的看法。
這種把「狀態機」呈現給使用者的模式,必然陷入類似組合語言的困境,指令碼很難編寫也很難閱讀。如果以使用者為中心的話--這裡所說的使用者當然是指ivr指令碼的開發者,應該反過來,把複雜的東西留給平台去做,而給使用者乙個簡單的開發環境。
狀態機的實現模式還和語音板卡程式設計的歷史有關,早期的板卡和作業系統都是基於單執行緒模式的,多條通道同時執行,系統在每個時刻必須記錄通道的當前狀態,使用狀態機是合適的。
看看東進或三匯語音板卡的例子程式就明白了,都是乙個個狀態機。
多執行緒作業系統的出現,改變了這種狀況,我們完全可以不用狀態機的概念來實現乙個語音平台,呈現給使用者的指令碼也可以像高階語言一樣簡單、明白,而且指令碼可以繫結在單一的通道上。
六. 圖形化, 最後一根不能救命的稻草
也許新太公司也意識到其指令碼語言太低階,學習門檻較高,所以在近年也推出了所謂的圖形化拖拉環境。
我現在的觀點依然不變,簡而言之:
1. 圖形介面試圖以不懂電腦的終端使用者為物件,是錯誤的,ivr的開發者往往都是程式設計師;
2. 當流程複雜時,往往線如亂麻;
3. 當超過一幅圖時,很難直接從圖上看清楚它們之間的關係;
4. 圖沒有標準,各個廠家的大不相同,同樣很難學習。
5. 現代的高階語言,其語法結構類似,如學習c語言的經驗很容易轉換到pascal上;但圖形拖拉介面則沒有什麼相同的經驗可以借鑑。和高階語言不同,圖形拖拉介面缺少堅實的理論基礎;
而且,新太的圖形拖拉介面僅僅是其指令碼語言的圖形化,基本上乙個節點對應一條語句,指令碼裡面的goto語句就是『->』符號變成了線條,標號變成了節點的命名,完全繼承了指令碼語言的弊端,前面指出的指令碼語言的問題在圖形拖拉介面下依然存在,甚至還多出一些問題。
實際上,我認為圖形化不應該只是底層指令碼語言的簡單對映,只有業務的抽象和圖形化才有意義,類似工作流,每個節點應該完成乙個封裝的業務,很遺憾,現在沒有廠家提供這樣的產品。(這個想法還不是很成熟,也許我應該實踐一下,做出這樣的產品,呵呵。:) )
當然,國內企業市場推廣的能力是很強大的,強大的營銷能力也許能夠一時掩蓋技術的不足。問題是,重營銷而輕研發,怎麼能夠長久?
bluesen 2005.1.8 於深圳
(首發於sp門戶論壇:http://www.sp-ivr.com/forum/read.php?tid=3529&fpage=1 )
新陣容無懼大場面 中國冰壺女隊壓哨挺進世錦賽
1月23日電 北京時間23日,2018 2019賽季冰壺世錦賽資格賽進入最後乙個比賽日。由梅傑 王芮 姚茗悅 麻敬宜組成的中國女隊在晉級賽淘汰賽中4 3險勝芬蘭女隊,斬獲一張世錦賽門票。本次比賽,中國隊由四壘王芮 三壘梅傑 二壘姚茗悅 一壘麻敬宜和替補王美妮的新陣容組成。這支隊伍在去年的全國錦標賽上...