2013-10-17 10 views
6

हम इस फ़ंक्शन बिल्डर को पी। ग्राहम के "एएनएसआई कॉमन लिस्प" (पृष्ठ 110) में रचना का एहसास करने के लिए पाते हैं। तर्क n> 0 उद्धृत फ़ंक्शन नाम हैं। मैं यह पूरी तरह से समझ में नहीं आता, तो मैं इसे नीचे कोड यहाँ मेरे सवालों बोली और निर्दिष्ट करेंगे:(लिखें) सामान्य लिस्प में

(defun compose (&rest fns) 
    (destructuring-bind (fn1 . rest) (reverse fns) 
    #'(lambda (&rest args) 
     (reduce #'(lambda (v f) (funcall f v)) 
       rest 
       :initial-value (apply fn1 args))))) 

तर्क सूची रचना करने को उलट दिया और पैक, अपने (अब पहले) तत्व 'fn1 के लिए बाध्य है 'और बाकी' आराम 'करने के लिए। बाहरीतम लैम्ब्डा का शरीर कम हो जाता है: (funcall fi (funcall fi-1 ...)), प्रारंभिक एक को पुनर्स्थापित करने के लिए उलटा क्रम में संचालन के साथ।

1) बाहरीतम लैम्ब्डा अभिव्यक्ति की भूमिका क्या है? अर्थात्, इसे 'तर्क' कहां से मिलता है? क्या यह डेटा संरचना को विनाशकारी-बांध के पहले तर्क के रूप में निर्दिष्ट किया गया है? 2) आंतरिकतम लैम्ब्डा अपने दो तर्क कहां से लेता है?

मेरा मतलब है कि मैं कोड की सराहना कर सकता हूं लेकिन अभी भी लेक्सिकल गुंजाइश मेरे लिए एक रहस्य है। किसी भी और सभी टिप्पणियों के लिए तत्पर हैं! अग्रिम धन्यवाद, // मार्को

+0

क्यों फांसी कोष्ठक के सभी हो सकता है? – Marcin

+1

मेरी माफ़ी, मैंने इस पर चर्चा नहीं देखी http://stackoverflow.com/questions/5928106/compose-example-in-paul-grahams-ansi-common-lisp – ocramz

+0

@ मार्सिन, आंखों का मार्गदर्शन करने के लिए;) क्या यह बुरा अभ्यास है? मैं अभी भी एक नोब – ocramz

उत्तर

10

यह शायद आसान है अगर आप समझते हैं पहले व्यावहारिक उदाहरण के एक जोड़े: एक समारोह है कि किसी भी तर्क लेता है, क्या यह इसके साथ करता है आवेदन कर रहा है:

(defun compose1 (a) 
    (lambda (&rest args) 
    (apply a args))) 

(defun compose2 (a b) 
    (lambda (&rest args) 
    (funcall a (apply b args)))) 

(defun compose3 (a b c) 
    (lambda (&rest args) 
    (funcall a (funcall b (apply c args))))) 

तो सबसे बाहरी lambda वापसी मान है आखिरी समारोह और परिणामस्वरूप रिवर्स ऑर्डर में अन्य सभी को चेन करना आखिरी फ़ंक्शन से मिला।

नोट: compose1 को (defun compose1 (a) a) के रूप में अधिक आसानी से परिभाषित किया जा सकता है।

एक कुछ हद तक बराबर लेकिन कम कुशल संस्करण

(defun compose (&rest functions) 
    (if (= (length functions) 1) 
     (car functions) 
     (lambda (&rest args) 
     (funcall (first functions) 
       (apply (apply #'compose (rest functions)) 
         args))))) 
+0

उदाहरण और स्पष्टीकरण के लिए धन्यवाद, यह निश्चित रूप से मामलों को स्पष्ट करता है! – ocramz

2

1) बाहरीतम लैम्ब्डा आपके लिए बंद कर देता है, क्योंकि परिणाम (गठबंधन ...) एक ऐसा कार्य है जो अन्य कार्यों की संरचना को शांत करता है।

2) आंतरिकतम लैम्ब्डा को कार्य कम करने से आईट्स तर्क मिलता है। कम करें दो तर्कों का एक कार्य (सबसे निचला लैम्ब्डा) लेता है और इसे सूची में चरणबद्ध रूप से लागू करता है, उदा।

(reduce #'- '(1 2 3 4)) is (- (- (- 1 2) 3) 4) 
संबंधित मुद्दे