2011-03-02 74 views
18

通常,我發現自己處理{foo->value,...}這種形式的函數選項列表(或更一般的替換列表)。當foo已經在$ Context中有一個值時,這會導致錯誤。一種明顯的方法是使用字符串「foo」而不是符號:{"foo"->value,...}。這種方法很有效,但似乎吸引了我認識的一些經驗豐富的LISPers的憤怒,他們責怪我混淆了符號和字符串,並告訴我使用內置的引用構造。使用字符串而不是符號:好還是壞?

雖然它當然可以編寫代碼避免碰撞而不使用字符串,但它往往看起來比它的價值更麻煩。另一方面,我沒有看到太多的{"string"->value}類型替換規則的例子。所以對你的問題是 - 這是一個可接受的使用模式?..有沒有情況下,它是特別合適的?..應該在哪裏應該避免...?

回答

16

在我看來(這是隻有我意見),最好避免使用字符串作爲選項名稱,至少對於函數中的「主要」選項。字符串OTOH作爲設置(選項的r.h.s.)是完全正確的。這並不是說你不能使用字符串,就像你指出的那樣。也許,它們可能更適合子選項,並且它們通過許多系統功能(通常是「超級功能」,如NDSolve,可能在選項內具有子選項)以這種方式使用。我在使用字符串時看到的主要問題是,它們降低了系統和用戶的自省能力。換句話說,發現一個字符串名稱比帶有符號名稱的選項更難 - 對於後者,我可以檢查包中符號的名稱,並且符號選項名稱也具有使用消息。你也可能希望自動化一些事情,比如編寫一個實用程序來查找包中的所有選項名稱等。當選項名稱是符號時更容易,因爲它們都屬於同一個上下文。發現某些選項沒有使用消息也很容易,可以通過編寫實用程序函數自動完成。

最後,您可以更好地防止類似選項名稱意外碰撞。可能很多選項序列會傳遞給你的函數,偶爾它們可能包含具有相同名稱的選項。如果選項名稱是符號,則完整符號名稱將會不同。然後,你們都會得到一個隱藏的警告,同時還有一個保護 - 只有正確的選項(全名)纔會被使用。對於字符串,您不會收到任何警告,並且如果重複的字符串選項名稱設置錯誤(用於其他功能,比如說)恰好在列表中處於第一位,您可能會收到錯誤的選項設置。這種情況更可能發生在大型項目中,但是像這樣的錯誤很可能很難發現(這是一種猜測,我從來沒有遇到過這種情況)。

至於可能的衝突,如果您遵循一些命名約定,如選項名稱始終以大寫字母開頭,並且將大部分代碼放在包中,並且不要啓動變量或函數名稱(對於交互中的函數會議),大寫字母,那麼你將大大減少這種衝突的機會。另外,您應該在選擇名稱時定義它們,或者在包裝的末尾使用Protect。然後,碰撞將被檢測爲陰影的情況。 OTOH是避免陰影的一種必要條件,所以在這方面選項的情況並不比函數名等更爲特殊。

+2

+1技術上,大寫的符號是爲Mathematica內置函數保留的,但是這個約定很廣泛忽略。原因在於,人們幾乎可以肯定,大寫的符號不會有降價。我儘量尊重函數名稱的保留,但在選項中,我經常使用大寫名稱來定義我自己的選項。 – WReach 2011-03-02 15:07:36

+1

@WReach:大寫的名字只保留給'System''上下文中的符號。其他規則只是約定,而且,只適用於在交互式會話中創建的符號,而不是包裝中的符號。在包中,慣例是大寫導出的函數和選項名稱。這可以在WRI和第三方製作的許多附加軟件包中看到。此外,這是Roman Maeder在他的「Mathematica編程」中給出的建議,這是一個標準參考,尤其是對於包裝書寫。由於全名不同,碰撞會導致屏蔽,因此會發出警告 – 2011-03-02 16:12:31

+1

+1「我使用字符串看到的主要問題是它們降低了內省功能」 – 2011-03-02 17:01:26

相關問題