2011-10-27 12 views
5
apply-partially के लिए

Emacs कोड यह है:Emacs 24 में 'लागू-आंशिक रूप से' काम करने की परिभाषा कैसे होती है?

(defun apply-partially (fun &rest args) 
    "Return a function that is a partial application of FUN to ARGS. 
ARGS is a list of the first N arguments to pass to FUN. 
The result is a new function which does the same as FUN, except that 
the first N arguments are fixed at the values with which this function 
was called." 
    `(closure (t) (&rest args) 
      (apply ',fun ,@(mapcar (lambda (arg) `',arg) args) args))) 

यह एक सूची है कि, एक लैम्ब्डा अभिव्यक्ति की तरह एक बहुत लग रहा है, सिवाय इसके कि lambdaclosure (t) की जगह देता है। उदाहरण के लिए, (apply-partially 'cons 1) रिटर्न इस:

(closure (t) (&rest args) (apply (quote cons) (quote 1) args)) 

जो, जहाँ तक मैं बता सकता हूँ, लग रहा है और इस तरह वास्तव में काम करता है:

(lambda (&rest args) (apply (quote cons) (quote 1) args)) 
को छोड़कर "बंद" अभिव्यक्ति "आत्म नहीं है कि

-क्वॉटिंग "लैम्ब्डा की संपत्ति, इसलिए जब मैं इसका मूल्यांकन करने की कोशिश करता हूं, तो इमाक्स मुझे सूचित करता है कि closure में कोई फ़ंक्शन परिभाषा नहीं है: Lisp error: (void-function closure)

मुझे इस तरह से closure प्रतीक का उपयोग करने के लिए एलिसप मैनुअल में कोई संदर्भ नहीं मिल रहा है। ऐसा लगता है कि किसी तरह के आंतरिक Emacs जादू। सामान्य नियमों के अनुसार बंद अभिव्यक्ति का मूल्यांकन नहीं किया जा रहा है (क्योंकि ऐसा करने से मैन्युअल रूप से त्रुटि मिलती है)।

तो यहां क्या हो रहा है? क्या मुझे पता लगाने के लिए "बंद करने" के संदर्भों के लिए सी कोड को grep करने की आवश्यकता है?

संपादित करें: ऐसा प्रतीत होता है कि Emacs 23 और नीचे, apply-partially क्लोज़ पैकेज से बंद करने के लिए बस lexical-let का उपयोग करता है। उपरोक्त परिभाषा संस्करण "24.0.90.1" से है। lambda याद करते आर्ग के आंशिक सेट:

उत्तर

3

मैं, eval.c में जवाब मिल गया funcall_lambda समारोह में:

if (EQ (XCAR (fun), Qclosure)) 
{ 
    fun = XCDR (fun); /* Drop `closure'. */ 
    lexenv = XCAR (fun); 
    CHECK_LIST_CONS (fun, fun); 
} 
    else 
lexenv = Qnil; 

closure (t)lambda का शाब्दिक बराबर प्रतीत होता है। दूसरा तत्व, (t), lexenv पर असाइन किया जाता है, इसलिए मुझे लगता है कि यह तत्व फ़ंक्शन के बाहर या कुछ के बाहर परिभाषित शब्दावली मानों को बंद करने के लिए है।

मुझे लगता है कि की कमी स्वयं के हवाले से इस प्रकार एक निरीक्षण, जो ठीक किया जा सकता है हो सकता है:

(defmacro make-self-quoting (name) 
    "Make NAME into a self-quoting function like `lambda'." 
    `(defmacro ,name (&rest cdr) 
    (list 'function (cons ',name cdr)))) 
(make-self-quoting closure) 
+0

सही, आंशिक रूप से लागू होने के मामले में, व्याख्यात्मक वातावरण खाली है, लेकिन अभी भी एक अंतर है: 'तर्क' तर्क स्पष्ट रूप से बाध्य होगा, जबकि 'लैम्ब्डा' के साथ यह गतिशील रूप से बाध्य होगा। यह सुनिश्चित करता है कि 'args' नाम कहीं और उस चर के अन्य उपयोगों में हस्तक्षेप नहीं करेगा। – Stefan

+0

आत्म-उद्धरण की कमी के कारण, यह वास्तव में एक निरीक्षण नहीं है, इसकी आवश्यकता नहीं है: '(बंद करें ...) स्रोत कोड में कभी नहीं होना चाहिए। – Stefan

1
मेरी "जीएनयू Emacs 23.2.1 (i686-पीसी-cygwin)" यह

(defun apply-partially (fun &rest args) 
    "Return a function that is a partial application of FUN to ARGS.    
ARGS is a list of the first N arguments to pass to FUN.       
The result is a new function which does the same as FUN, except that    
the first N arguments are fixed at the values with which this function   
was called." 
    (lexical-let ((fun fun) (args1 args)) 
    (lambda (&rest args2) (apply fun (append args1 args2))))) 

समझना यह कैसे काम करता है यहाँ काफी आसान हो रहा है के रूप में परिभाषित किया गया है के साथ

और मूल फ़ंक्शन को कॉल करते समय बाकी को जोड़ता है।

+0

मैं Emacs 24 है, जो अब अपनी ही शाब्दिक scoping कि निर्भर नहीं करता है चल रहा हूँ सीएल पैकेज पर। मुझे लगता है कि 'बंद' चीज Emacs 24 के लिए नई है। –

+0

यदि यह 'बंद' प्रतीक है तो apropos के बारे में कुछ होना चाहिए? –

+0

http://www.emacswiki.org/emacs/closure2.el में 'डिफैमक्रो बंद' है लेकिन यह स्पष्ट नहीं है कि यह Emacs का हिस्सा है या नहीं। –

संबंधित मुद्दे