यह एक आम गलत धारणा है कि हम let
अनुप्रयोगों के लिए -expresions का अनुवाद कर सकते हैं । के बीच का अंतर let x : t := b in v
और (fun x : t => v) b
है कि में है let
की -expression, दौरान प्रकार की जाँच v
हम जानते हैं कि x
के बराबर है b
, लेकिन आवेदन में हम नहीं (उपसूचक fun x : t => v
अपने आप ही समझ बनाने के लिए है)।
यहाँ एक उदाहरण है:
(* Dependent type of vectors. *)
Inductive Vector {A : Type} : nat -> Type :=
| nil : Vector 0
| cons : forall n, A -> Vector n -> Vector (S n).
(* This works. *)
Check (let n := 0 in cons n 42 nil).
(* This fails. *)
Check ((fun (n : nat) => cons n 42 nil) 0).
आवेदन को (fun x : t => v) b
एक विशेष मामला बनाने के लिए आपका सुझाव वास्तव में काम नहीं करता है। आइए हम इसके बारे में अधिक सावधानी से विचार करें।
उदाहरण के लिए, उपरोक्त उदाहरण को जारी रखते हुए आप इससे कैसे निपटेंगे?
Definition a := (fun (n : nat) => cons n 42 nil).
Check a 0.
संभवतः यह काम नहीं करेगा क्योंकि a
टाइप नहीं किया जा सकता है, लेकिन यदि हम इसकी परिभाषा को प्रकट करते हैं, तो हमें एक अच्छी तरह से टाइप की गई अभिव्यक्ति मिलती है। क्या आपको लगता है कि उपयोगकर्ता हमसे प्यार करेंगे, या हमारे डिजाइन निर्णय के लिए हमसे नफरत करेंगे?
आपको ध्यान से सोचने की ज़रूरत है कि "विशेष मामले" का क्या मतलब है। अगर मेरे पास कोई एप्लिकेशन है e₁ e₂
, तो क्या मुझे e₁
यह तय करने से पहले सामान्य करना चाहिए कि क्या यह एक हैλ-abstraction? यदि हां, तो इसका मतलब है कि मैं बीमार टाइप के भावों को सामान्य करूंगा, और वे साइकिल चला सकते हैं। यदि नहीं, तो आपके प्रस्ताव की उपयोगिता संदिग्ध लगती है।
आप उस मौलिक प्रमेय को भी तोड़ देंगे जो कहता है कि अच्छी तरह से टाइप की गई हर अभिव्यक्ति अच्छी तरह से टाइप की जाती है। कि null
जावा में शुरू करने के रूप में समझदार है ।
let
भावों से बचने के लिए हैक जोड़ना , लेकिन ए)let
अभिव्यक्ति से बचने का कोई कारण नहीं है और वे सुविधाजनक भी हैं, और b) आपकी मूल भाषा में हैक जोड़ना कोई बहुत अच्छा विचार नहीं है।