2010-04-03 16 views
12

एफ # में बुला:अंतर जब नए सिरे से परिभाषित कार्यों

> let f x = x + 2;; 

val f : int -> int 

> let g x = f x;; 

val g : int -> int 

> g 10;; 
val it : int = 12 
> let f x = x + 3;; 

val f : int -> int 

> g 10;; 
val it : int = 12 

Clojure में:

1:1 user=> (defn f [x] (+ x 2)) 
#'user/f 
1:2 user=> (defn g [x] (f x)) 
#'user/g 
1:3 user=> (g 10) 
12 
1:4 user=> (defn f [x] (+ x 3)) 
#'user/f 
1:5 user=> (g 10) 
13 

नोट Clojure में च का नवीनतम संस्करण अंतिम पंक्ति में बुलाया जाता है। एफ # में हालांकि अभी भी एफ का पुराना संस्करण कहा जाता है। यह क्यों है और यह कैसे काम करता है?

उत्तर

8

रूप gabe कहा, एफ # इंटरैक्टिव का उपयोग करता है मूल्यों की पीछा जब आप एक नाम पहले से मौजूद है कि के साथ एक समारोह में प्रवेश (छाया बारे में अधिक जानकारी के लिए, उदाहरण के this SO question के लिए देखें)।

> let [email protected] x = x + 2;; 
> let [email protected] x = [email protected] x;; 
> [email protected] 10;; 
val it : int = 12 
> let [email protected] x = x + 3;; 
> [email protected] 10;; 
val it : int = 12 

एफ # कुछ घायल नाम (जैसे @) का उपयोग करता है कि आप सीधे उपयोग नहीं कर सकते मूल्य के संस्करणों के बीच भेद करने के लिए: यह है कि एफ # संकलक जब आप अपने कोड को चलाने के कुछ इस तरह देखता है मतलब है। दूसरी ओर, क्लोजर का व्यवहार शायद कार्यों के एक बड़े शब्दकोश के रूप में सबसे अच्छा समझा जा सकता है। छद्म-वाक्यविन्यास का उपयोग करके, इस तरह कुछ:

> symbols[f] = fun x -> x + 2;; 
> symbols[g] = fun x -> symbols[f] x;; 
> symbols[g] 10;; 
val it : int = 12 
> symbols[f] = fun x -> x + 3;; 
> symbols[g] 10;; 
val it : int = 13 

यह भेद को स्पष्ट करना चाहिए।

साइड-नोट के रूप में, क्लोजर दृष्टिकोण (कम से कम एक भाषा जैसे F #) के साथ एक संभावित समस्या है। आप किसी प्रकार का फ़ंक्शन घोषित कर सकते हैं, इसका उपयोग कर सकते हैं और फिर अगला आदेश फ़ंक्शन के प्रकार को बदल सकता है। यदि एफ # क्लोजर दृष्टिकोण का उपयोग करता है, तो निम्न उदाहरण कैसे काम करना चाहिए? जैसे कि वह प्रकार int की दो पैरामीटर था

> let f a b = a + b;; 
> let g x = f x x;; 
> let f() = printf "f!";; 
> g 0;; 

समारोह gf का उपयोग करता है, लेकिन तृतीय लाइन समारोह के प्रकार बदल जाता है। इससे क्लोजर टाइप-चेक की गई भाषाओं के लिए थोड़ा मुश्किल हो जाता है।

+0

आप पीछा के साथ मतलब है कि एक ही नाम 'छाया' उन अधिक की के साथ एक कम दायरे में एक चर scopes? एफ # इंटरैक्टिव में, क्या हमें लगातार नेस्टेड स्कोप के रूप में बयान देना चाहिए? यह समझाएगा! क्लोजर मामले में यह यहां दायरे का मामला नहीं है, लेकिन वास्तव में var f (vars mutable हैं) की मूल बाध्यकारी बदल रहा है। –

+0

@ मिचिल - हाँ, यह बिल्कुल सही है। एफ # के लिए गैर-हल्के सिंटैक्स का उपयोग करके, आपका उदाहरण 'चलो f = ... में होगा (चलो जी = ... में (जी 10; चलो एफ = ... जी 10 में)), जहां सृजन नए स्कोप थोड़ा और स्पष्ट है। – kvb

12

Clojure में f प्रतीक, नाम f है जबकि एफ # में f प्रतीक f का मूल्य कैप्चर करता है। तो क्लोजर में हर बार जब आप g पर कॉल करते हैं तो यह पता लगाने के लिए f दिखाई देता है कि उस समय नाम क्या है, जबकि F # में प्रत्येक कॉल gf के मान का उपयोग करता है जब g फ़ंक्शन मूल रूप से बनाया गया था।

5

गेबे और टॉमस ने मूलभूत बातें अच्छी तरह से कवर की हैं। ध्यान दें कि आप एफ चाहते हैं, तो # Clojure करता है के रूप में व्यवहार करने के लिए, आप एक अस्थायी बंधन का उपयोग करें और पुन: असाइन f कर सकते हैं:

let mutable f = fun x -> x + 2 
let g x = f x 

g 10;; // 12 

f <- fun x -> x + 3 // note, assign new value, don't create new binding 

g 10;; //13 
संबंधित मुद्दे