2010-04-17 11 views
22

में एक अस्थायी फ़ंक्शन कैसे बनाएं I फ़ंक्शंस के समूह में कुछ थकाऊ कॉल कर रहा हूं, लेकिन पैरामीटर रनटाइम पर निर्धारित किए जाएंगे। मैंने अपना कोड DRY रखने के लिए एक सरल कार्य लिखा लेकिन इसे एक नाम देना अनावश्यक है। मैं कहीं और इस समारोह का उपयोग नहीं करता हूं।Emacs Lisp

मैं इसे जिस तरह से मैं योजना में होगा करने के लिए कोशिश कर रहा हूँ, लेकिन मैं एक void-function त्रुटि मिलती है:

(let ((do-work (lambda (x y z) 
        (do-x x) 
        (do-y y) 
        ;; etc 
       ))) 
    (cond (test-1 (do-work 'a 'b 'c)) 
     (test-2 (do-work 'i 'j 'k)))) 

मैं एक apply (जैसे, (apply (lambda ...) (cond ...))) लेकिन वह नहीं है में यह सब छड़ी सकता है बहुत पठनीय क्या कोई बेहतर तरीका है?

उत्तर

27

अन्य लिस्प्स (लेकिन योजना नहीं) की तरह, Emacs Lisp के चर और कार्यों के लिए अलग-अलग नामस्थान हैं (यानी यह ‘Lisp2’, not a ‘Lisp1 है; इन शर्तों के मूल और अर्थ के लिए Technical Issues of Separation in Function Cells and Value Cells देखें)।

एक चर में संग्रहीत एक लैम्ब्डा (या अन्य फ़ंक्शन) को कॉल करने के लिए आपको funcall या apply का उपयोग करने की आवश्यकता होगी।

(cond (test-1 (funcall do-work 'a 'b 'c)) 
     (test-2 (funcall do-work 'i 'j 'k)) 

उपयोग funcall यदि आप हमेशा बहस के एक ही नंबर भेज देंगे। यदि आपको तर्कों की एक चर संख्या भेजने में सक्षम होना चाहिए तो apply का उपयोग करें।

आंतरिक तंत्र यह है कि प्रत्येक प्रतीक में multiple “cells” है। कौन सा सेल उपयोग किया जाता है where the symbol is in an evaluated form पर निर्भर करता है। जब कोई प्रतीक मूल्यांकन फॉर्म का पहला तत्व होता है, its “function” cell is used। किसी अन्य स्थिति में, its “value” cell is used। अपने कोड में, do-work में इसके मूल्य कक्ष में कार्य है। इसे फ़ंक्शन के रूप में एक्सेस करने के लिए आप funcall या apply का उपयोग करते हैं। यदि यह फ़ंक्शन सेल में था, तो आप इसे अपने नाम का उपयोग मूल्यांकन फॉर्म की कार के रूप में सीधे कर सकते हैं। आप इसे flet or labels from the cl package के साथ पूरा कर सकते हैं।

21

करो (require 'cl) कॉमन लिस्प पैकेज में खींचने के लिए है, तो flet बजाय let का उपयोग करें:

(flet ((do-work (x y z) 
      (do-x x) 
      (do-y y) 
      ;; etc 
     )) 
    (cond (test-1 (do-work 'a 'b 'c)) 
     (test-2 (do-work 'i 'j 'k)))) 
+2

+1। मुझे वास्तव में Lisp-2s पसंद नहीं है। – progo

4

हालांकि मुझे लगता है कि कुछ Emacs devels है कि आप दे देंगे देखते हैं आप इस एएनएसआई कॉमन लिस्प तरह से कर सकते हैं (बुरा लगता):

(flet ((do-work (x y z) 
       (do-x x) 
       (do-y y) 
       ;; etc 
       )) 
    (cond (test-1 (do-work 'a 'b 'c)) 
     (test-2 (do-work 'i 'j 'k)))) 

पता नहीं अगर आप पहले (require 'cl) (या cl-macs करना होगा) flet उपयोग करने के लिए। यदि आप पुनरावर्ती कार्यों को परिभाषित करना चाहते हैं तो आपको labels आईआईआरसी का उपयोग करने की आवश्यकता होगी।

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