2010-12-08 10 views
7

मैं क्लिसप का उपयोग कर रहा हूं और मुझे आश्चर्य है कि क्या कोई लाइब्रेरी है जो nthcdr के सेटफेबल संस्करण के साथ है जिसका मैं उपयोग कर सकता हूं। जब n 0 है, हालांकिक्या एक सेट करने योग्य nthcdr कार्यान्वयन मौजूद है?

उत्तर

5

आप के साथ चारों ओर हैक कर सकते हैं:

(let ((lst (list 1 2 3 4)) 
     (n 2)) 
    (setf (cdr (nthcdr (1- n) lst)) '(5 6 7)) 
    l) 
> (1 2 5 6 7) 

या यह के लिए अपने स्वयं के setf को परिभाषित:

;; !!warning!! only an example, lots of nasty edge cases 
(defsetf nthcdr (n lst) (new-val) 
    `(setf (cdr (nthcdr (1- ,n) ,lst)) ,new-val)) 

मैं क्यों nthcdr एक setf परिभाषित नहीं है पता नहीं है। यहां तक ​​कि Alexandria अंतिम के लिए setf को परिभाषित करने लगता है, लेकिन nthcdr नहीं।

पीएस। मैं आपके कोड में एक खराब गंध के रूप में एक nthcdr सेट करने के लिए चाहते हैं का इलाज करेंगे।

+1

यह एक बुरी गंध क्यों है? विशेष रूप से जब आप यह इंगित करते हैं कि कोई सेटफेबल nthcdr परिभाषित नहीं करने का कोई कारण नहीं है। – Paralife

+0

कारण यह है कि मैं चाहता हूं कि मैं एक आईडी तत्व के साथ एक लिंग के प्रत्येक नोड को इंजेक्ट करना चाहता हूं और उसी समय सेक्स न पेड़ को घुमाने के दौरान प्रत्येक नोड को हैश-टेबल में स्टोर करता हूं। तो यदि सजावट जगह में नहीं होती है, तो हैश-टेबल में मान सजाए गए सबनोड – Paralife

+1

को नहीं देखते हैं कि आम तौर पर सामान्य लिस्प में यह परिभाषित नहीं होता है कि जब आप शाब्दिक डेटा संशोधित करते हैं तो क्या होता है। –

1
(defsetf my-nthcdr (n list) (store) 
    (let ((tmp (gensym))) 
    `(let ((,tmp (nthcdr (1- ,n) ,list))) 
     (rplacd ,tmp ,store) 
     (cdr ,tmp))))

काम करता है नहीं, तो आप यह काम जब सूची एक प्रतीक है कर सकता है, पता चल सके कि एन macroexpansion समय पर शून्य या तो है, लेकिन फिर यह तभी काम करता है एन एक संख्या है, या विस्तारित कोड में चेक सहित।

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