लिस्ट कॉम्प्रिहेंशन

From Vigyanwiki
Revision as of 10:31, 14 August 2023 by Manidh (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

लिस्ट कॉम्प्रिहेंशन उपस्थित लिस्ट के आधार पर लिस्ट बनाने के लिए कुछ प्रोग्रामिंग भाषाओं में उपलब्ध एक वाक्यात्मक संरचना है। यह गणितीय सेट-बिल्डर संकेतन (सेट कॉम्प्रिहेंशन) के रूप का अनुसरण करता है जो मानचित्र और फ़िल्टर फ़ंक्शंस के उपयोग से अलग है।

अवलोकन

सेट-बिल्डर संकेतन में निम्नलिखित उदाहरण पर विचार करें।

या प्रायः

इसे रीड किया जा सकता है, " सभी संख्याओं का सेट है "2 गुना " सच दैट प्राकृतिक संख्याओं () के सेट का एलिमेंट या मेंमबर है, एंड का वर्ग से बड़ा है।"

सबसे छोटी प्राकृतिक संख्या, x = 1, स्थिति x2>3 को संतुष्ट करने में विफल रहती है (स्थिति 12>3 गलत है) इसलिए 2 ·1 को S में सम्मिलित नहीं किया गया है। अगली प्राकृतिक संख्या, 2, प्रत्येक अन्य प्राकृतिक संख्या की तरह स्थिति (22>3) को संतुष्ट करती है। इस प्रकार x में 2, 3, 4, 5... होते हैं चूँकि सेट S में सभी संख्याएँ "2 गुना x" होती हैं, इसलिए इसे S = {4, 6, 8, 10,...} द्वारा दिया जाता है। दूसरे शब्दों में, S, 2 से बड़ी सभी सम संख्याओं का सेट है।

उदाहरण के इस एनोटेटेड संस्करण में-

  • एक इनपुट सेट के सदस्यों का प्रतिनिधित्व करने वाला चर है।
  • इनपुट सेट का प्रतिनिधित्व करता है, जो इस उदाहरण में प्राकृतिक संख्याओं का सेट है
  • इनपुट सेट के सदस्यों पर फ़िल्टर के रूप में कार्य करने वाली निर्धारक अभिव्यक्ति है।
  • आउटपुट अभिव्यक्ति है जो इनपुट सेट के सदस्यों से नए सेट के सदस्यों का उत्पादन करती है जो विधेय अभिव्यक्ति को संतुष्ट करते हैं।
  • ब्रेसिज़ इंगित करते हैं कि परिणाम एक सेट है
  • ऊर्ध्वाधर पट्टी को "सच दैट" के रूप में रीड किया जाता है। बार और कोलन ":" का प्रयोग एक दूसरे के स्थान पर किया जाता है।
  • अल्पविराम निर्धारक को अलग करते हैं और इसे "एंड" के रूप में रीड किया जा सकता है।

लिस्ट कॉम्प्रिहेंशन में इनपुट लिस्ट या पुनरावर्तक के क्रम में लिस्ट की पीढ़ी का प्रतिनिधित्व करने के लिए समान वाक्यात्मक घटक होते हैं-

  • इनपुट लिस्ट के सदस्यों का प्रतिनिधित्व करने वाला चर।
  • इनपुट लिस्ट (या पुनरावर्तक)।
  • वैकल्पिक निर्धारक अभिव्यक्ति।
  • और आउटपुट अभिव्यक्ति, इनपुट पुनरावर्तनीय के सदस्यों से आउटपुट लिस्ट के सदस्यों का उत्पादन करती है जो निर्धारक को संतुष्ट करते हैं।

आउटपुट लिस्ट के सदस्यों की पीढ़ी का क्रम इनपुट में वस्तुओं के क्रम पर आधारित है।

हास्केल के लिस्ट कॉम्प्रिहेंशन सिंटैक्स में, यह सेट-बिल्डर निर्माण इसी तरह लिखा जाएगा, जैसे-

s = [ 2*x | x <- [0..], x^2 > 3 ]

यहां, लिस्ट [0..] का प्रतिनिधित्व करती है, x^2>3 निर्धारक का प्रतिनिधित्व करती है, और 2*x आउटपुट अभिव्यक्ति का प्रतिनिधित्व करती है।

लिस्ट कॉम्प्रिहेंशन एक परिभाषित क्रम (सेट के सदस्यों के विपरीत) में परिणाम देता है और लिस्ट का कॉम्प्रिहेंशन किसी लिस्ट के सदस्यों को क्रम में उत्पन्न कर सकता है, न कि संपूर्ण लिस्ट तैयार करने से, उदाहरण के लिए, अनंत लिस्ट के सदस्यों को पिछली हास्केल परिभाषा की अनुमति मिलती है।

इतिहास

संबंधित निर्माणों का अस्तित्व "लिस्ट कॉम्प्रिहेंशन" शब्द के उपयोग से पहले का है। एसईटीएल (SETL) प्रोग्रामिंग भाषा (1969) में एक सेट निर्माण संरचना है जो लिस्ट कॉम्प्रिहेंशन के समान है। उदाहरण के लिए, यह कोड 2 से N तक सभी अभाज्य संख्याओं को प्रिंट करता है-

print([n in [2..N] | forall m in {2..n - 1} | n mod m > 0]);

कंप्यूटर बीजगणित प्रणाली एएक्सआईओएम (AXIOM) (1973) में समान निर्माण होता है जो स्ट्रीम को प्रोसेस करता है।

ऐसे निर्माणों के लिए "कॉम्प्रिहेंशन" शब्द का प्रथम उपयोग रॉड बर्स्टल और जॉन डार्लिंगटन द्वारा 1977 से उनकी कार्यात्मक प्रोग्रामिंग भाषा एनपीएल (NPL) के विवरण में किया गया था। डेविड टर्नर अपने पूर्वव्यापी "कार्यात्मक प्रोग्रामिंग भाषाओं के कुछ इतिहास" में[1] याद करते हैं-

एनपीएल को बर्स्टॉल द्वारा पीओपी2 (POP2) में कार्यान्वित किया गया था और प्रोग्राम ट्रांसफॉर्मेशन (बर्स्टल और डार्लिंगटन 1977) पर डार्लिंगटन के काम के लिए उपयोग किया गया था। भाषा प्रथम क्रम की थी, दृढ़ता से (लेकिन बहुरूपी रूप से नहीं) टाइप की गई, पूरी तरह कार्यात्मक, कॉल-बाय-वैल्यू थी। इसमें "सेट अभिव्यक्तियाँ" भी थे जैसे

setofeven (X)  <=  <:x : x in X & even(x):>}}

"लिस्ट कॉम्प्रिहेंशन" शब्द से जुड़े फ़ुटनोट में, टर्नर यह भी नोट करते है

मैंने प्रारम्भ में इन जेडएफ (ZF) अभिव्यक्तियों को ज़र्मेलो-फ्रैंकल सेट सिद्धांत का संदर्भ कहा था - यह फिल वाडलर थे जिन्होंने बेहतर शब्द लिस्ट कॉम्प्रिहेंशन को गढ़ा था।

एनपीएल के साथ बर्स्टॉल और डार्लिंगटन के काम ने 1980 के दशक के दौरान कई कार्यात्मक प्रोग्रामिंग भाषाओं को प्रभावित किया, लेकिन सभी में लिस्ट कॉम्प्रिहेंशन सम्मिलित नहीं था। 1985 में जारी टर्नर की प्रभावशाली, शुद्ध, स्लो, कार्यात्मक प्रोग्रामिंग भाषा मिरांडा एक अपवाद थी। बाद में विकसित मानक शुद्ध स्लो कार्यात्मक भाषा हास्केल में लिस्ट कॉम्प्रिहेंशन सहित मिरांडा की कई विशेषताएं सम्मिलित हैं।

कॉम्प्रिहेंशन को डेटाबेस के लिए क्वेरी संकेतन के रूप में प्रस्तावित किया गया था[2] और इसे क्लेस्ली डेटाबेस क्वेरी भाषा में लागू किया गया था।[3]

विभिन्न प्रोग्रामिंग भाषाओं में उदाहरण

समान निर्माण

मोनाड कॉम्प्रिहेंशन

हास्केल में, मोनैड कॉम्प्रिहेंशन कार्यात्मक प्रोग्रामिंग में अन्य मोनैड के लिए लिस्ट कॉम्प्रिहेंशन का सामान्यीकरण है।

सेट कॉम्प्रिहेंशन

पायथन भाषा का संस्करण 3.x और 2.7 सेट कॉम्प्रिहेंशन के लिए सिंटैक्स का परिचय देता है। लिस्ट कॉम्प्रिहेंशन के समान, सेट कॉम्प्रिहेंशन लिस्ट के स्थान पर पायथन सेट उत्पन्न करते हैं।

>>> s = {v for v in 'ABCDABCD' if v not in 'CB'}
>>> print(s)
{'A', 'D'}
>>> type(s)
<class 'set'>
>>>

रैकेट सेट कॉम्प्रिहेंशन लिस्ट के स्थान पर रैकेट सेट उत्पन्न करता है।

(for/set ([v "ABCDABCD"] #:unless (member v (string->list "CB")))
         v))

शब्दकोश कॉम्प्रिहेंशन

पायथन भाषा के संस्करण 3.x और 2.7 ने शब्दकोश कॉम्प्रिहेंशन के लिए एक नया सिंटैक्स पेश किया, जो लिस्ट कॉम्प्रिहेंशन के रूप में समान था लेकिन जो लिस्ट के स्थान पर पायथन डिक्ट उत्पन्न करता था।

>>> s = {key: val for key, val in enumerate('ABCD') if val not in 'CB'}
>>> s
{0: 'A', 3: 'D'}
>>>

रैकेट हैश टेबल कॉम्प्रिहेंशन रैकेट हैश टेबल (रैकेट शब्दकोश प्रकार का कार्यान्वयन) उत्पन्न करती है।

(for/hash ([(val key) (in-indexed "ABCD")]
           #:unless (member val (string->list "CB")))
  (values key val))

समानांतर लिस्ट कॉम्प्रिहेंशन

ग्लासगो हास्केल संकलक में समानांतर लिस्ट कॉम्प्रिहेंशन (जिसे ज़िप-कॉम्प्रिहेंशन के रूप में भी जाना जाता है) नामक एक्सटेंशन है जो लिस्ट कॉम्प्रिहेंशन सिंटैक्स के भीतर विशेषण की कई स्वतंत्र शाखाओं की अनुमति देता है। जबकि अल्पविराम द्वारा अलग किए गए विशेषण आश्रित ("नेस्टेड") होते हैं, पाइपों द्वारा अलग किए गए विशेषण शाखाओं का मूल्यांकन समानांतर (यह मल्टीथ्रेडेडनेस के किसी भी रूप को संदर्भित नहीं करता है- इसका अर्थ केवल यह है कि शाखाएं ज़िप की गई हैं) में किया जाता है।

-- regular list comprehension
a = [(x,y) | x <- [1..5], y <- [3..5]]
-- [(1,3),(1,4),(1,5),(2,3),(2,4) ...

-- zipped list comprehension
b = [(x,y) | (x,y) <- zip [1..5] [3..5]]
-- [(1,3),(2,4),(3,5)]

-- parallel list comprehension
c = [(x,y) | x <- [1..5] | y <- [3..5]]
-- [(1,3),(2,4),(3,5)]

रैकेट की कॉम्प्रिहेंशन मानक लाइब्रेरी में इसके कॉम्प्रिहेंशन के समानांतर और नेस्टेड संस्करण सम्मिलित हैं, जो नाम में "फॉर" बनाम "फॉर*" द्वारा प्रतिष्ठित हैं। उदाहरण के लिए, वेक्टर कॉम्प्रिहेंशन "फॉर/वेक्टर" और "फॉर*/वेक्टर" अनुक्रमों पर समानांतर बनाम नेस्टेड पुनरावृत्ति द्वारा वेक्टर बनाते हैं। हास्केल लिस्ट कॉम्प्रिहेंशन उदाहरणों के लिए रैकेट कोड निम्नलिखित है।

> (for*/list ([x (in-range 1 6)] [y (in-range 3 6)]) (list x y))
'((1 3) (1 4) (1 5) (2 3) (2 4) (2 5) (3 3) (3 4) (3 5) (4 3) (4 4) (4 5) (5 3) (5 4) (5 5))
> (for/list ([x (in-range 1 6)] [y (in-range 3 6)]) (list x y))
'((1 3) (2 4) (3 5))

पायथन में, हम निम्नानुसार कार्य कर सकते हैं-

# regular list comprehension
>>> a = [(x, y) for x in range(1, 6) for y in range(3, 6)]
[(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), ...

# parallel/zipped list comprehension
>>> b = [x for x in zip(range(1, 6), range(3, 6))]
[(1, 3), (2, 4), (3, 5)]

जूलिया में, व्यावहारिक रूप से समान परिणाम निम्नानुसार प्राप्त किए जा सकते हैं-

# regular array comprehension
>>> a = [(x, y) for x in 1:5 for y in 3:5]

# parallel/zipped array comprehension
>>> b = [x for x in zip(1:3, 3:5)]

एकमात्र अंतर यह है कि जूलिया में लिस्ट के स्थान पर, हमारे पास अरे हैं।

एक्सक्वेरी और एक्सपाथ

मूल एनपीएल उपयोग की तरह, ये मूलतः डेटाबेस एक्सेस भाषाएं हैं।

यह कॉम्प्रिहेंशन की अवधारणा को और अधिक महत्वपूर्ण बनाता है, क्योंकि संपूर्ण लिस्ट को पुनः प्राप्त करना और उस पर काम करना कम्प्यूटेशनल रूप से असंभव है (प्रारंभिक 'संपूर्ण लिस्ट' संपूर्ण एक्सएमएल (XML) डेटाबेस हो सकती है)।

एक्सपाथ में, अभिव्यक्ति-

/library/book//paragraph[@style='first-in-chapter']

वैचारिक रूप से "चरणों" की श्रृंखला के रूप में मूल्यांकन किया जाता है जहां प्रत्येक चरण एक लिस्ट तैयार करता है और अगला चरण पिछले चरण के आउटपुट में प्रत्येक तत्व पर फ़िल्टर फ़ंक्शन लागू करता है।[4]

एक्सक्वेरी में, पूर्ण एक्सपाथ उपलब्ध है, लेकिन एफएलडब्लयूओआर (FLWOR) कथनों का भी उपयोग किया जाता है, जो कि अधिक शक्तिशाली कॉम्प्रिहेंशन निर्माण है।[5]

for $b in //book
where $b[@pages < 400]
order by $b//title
return
  <shortBook>
    <title>{$b//title}</title>
    <firstPara>{($book//paragraph)[1]}</firstPara>
  </shortBook>

यहां एक्सपाथ //बुक का मूल्यांकन अनुक्रम (उर्फ लिस्ट) बनाने के लिए किया जाता है जहां क्लॉस कार्यात्मक "फ़िल्टर" है, परिणाम को क्रमबद्ध करता है, और ‎<शॉर्टबुक>...‎</शॉर्टबुक> एक्सएमएल स्निपेट वास्तव में एक अज्ञात फ़ंक्शन है जो अन्य कार्यात्मक भाषाओं में पाए जाने वाले 'मैप' दृष्टिकोण का उपयोग करके अनुक्रम में प्रत्येक तत्व के लिए एक्सएमएल बनाता/बदलता है।

तो, किसी अन्य कार्यात्मक भाषा में उपरोक्त एफएलडब्लयूओआर कथन को इस प्रकार कार्यान्वित किया जा सकता है-

map(
  newXML(shortBook, newXML(title, $1.title), newXML(firstPara, $1...))
  filter(
    lt($1.pages, 400),
    xpath(//book)
  )
)

C# में एलआईएनक्यू (LINQ)

C# 3.0 में संबंधित सुविधाओं का एक समूह है जिसे एलआईएनक्यू कहा जाता है, जो ऑब्जेक्ट गणना में हेरफेर करने के लिए क्वेरी ऑपरेटरों के सेट को परिभाषित करता है।

var s = Enumerable.Range(0, 100).Where(x => x * x > 3).Select(x => x * 2);

यह एसक्यूएल (SQL) की याद दिलाते हुए वैकल्पिक कॉम्प्रिहेंशन सिंटैक्स भी प्रदान करता है-

var s = from x in Enumerable.Range(0, 100) where x * x > 3 select x * 2;

एलआईएनक्यू विशिष्ट लिस्ट कॉम्प्रिहेंशन कार्यान्वयन पर क्षमता प्रदान करता है। जब कॉम्प्रिहेंशन का मूल ऑब्जेक्ट आईक्वेरीबल(IQueryable) इंटरफ़ेस को कार्यान्वित करता है, तो केवल कॉम्प्रिहेंशन की श्रृंखलाबद्ध विधियों को निष्पादित करने के स्थान पर, कमांड का पूरा अनुक्रम संक्षेप सिंटैक्स ट्री (एएसटी) ऑब्जेक्ट में परिवर्तित हो जाता है, जिसे व्याख्या और निष्पादित करने के लिए आईक्वेरीबल ऑब्जेक्ट को पास किया जाता है।

यह, अन्य बातों के अलावा, आईक्वेरीबल को इसकी अनुमति देता है

  • किसी असंगत या अप्रभावी कॉम्प्रिहेंशन को दोबारा लिखें
  • निष्पादन के लिए एएसटी (AST) को किसी अन्य क्वेरी भाषा (उदाहरण के लिए एसक्यूएल) में अनुवाद करें

C++

C++ में सीधे तौर पर लिस्ट कॉम्प्रिहेंशन का सपोर्ट करने वाली कोई भाषा सुविधा नहीं है, लेकिन ऑपरेटर ओवरलोडिंग (उदाहरण के लिए, ओवरलोडिंग |, >>, >>=) का उपयोग "अंतः स्थापित" क्वेरी डोमेन-विशिष्ट भाषाओं (डीएसएल (DSL)) के लिए अभिव्यंजक सिंटैक्स प्रदान करने के लिए सफलतापूर्वक किया गया है। वैकल्पिक रूप से, कंटेनर में तत्वों का चयन करने के लिए मिटाओ-हटाओ मुहावरे का उपयोग करके लिस्ट कॉम्प्रिहेंशन का निर्माण किया जा सकता है और उन्हें बदलने के लिए एसटीएल (STL) एल्गोरिदम फॉर_ईच का उपयोग किया जा सकता है।

#include <algorithm>
#include <list>
#include <numeric>

using namespace std;

template<class C, class P, class T>
C comprehend(C&& source, const P& predicate, const T& transformation)
{
  // initialize destination
  C d = forward<C>(source);

  // filter elements
  d.erase(remove_if(begin(d), end(d), predicate), end(d));

  // apply transformation
  for_each(begin(d), end(d), transformation);

  return d;
}

int main()
{
  list<int> range(10);
      // range is a list of 10 elements, all zero
  iota(begin(range), end(range), 1);
      // range now contains 1, 2, ..., 10

  list<int> result = comprehend(
      range,
      [](int x) { return x * x <= 3; },
      [](int &x) { x *= 2; });
      // result now contains 4, 6, ..., 20
}

C++ को सेट बिल्डर संकेतन के समान लिस्ट-कॉम्प्रिहेंशन निर्माण/सिंटैक्स प्रदान करने में कुछ प्रयास किए गए हैं।

  • बूस्ट में।[1] रेंज लाइब्रेरी में एडेप्टर की एक अवधारणा है[2] जिसे किसी भी रेंज पर लागू किया जा सकता है और फ़िल्टरिंग, ट्रांसफॉर्मेशन आदि किया जा सकता है। इस लाइब्रेरी के साथ, मूल हास्केल उदाहरण इस तरह दिखेगा (अनाम फ़िल्टरिंग और ट्रांसफॉर्मिंग फ़ंक्शंस के लिए बूस्ट.लैम्बडा[3] का उपयोग करना) (पूर्ण उदाहरण)-
    counting_range(1,10) | filtered( _1*_1 > 3 ) | transformed(ret<int>( _1*2 ))
    
  • यह[6] कार्यान्वयन एक मैक्रो का उपयोग करता है और << ऑपरेटर को ओवरलोड करता है। यह 'इफ' के अंदर मान्य किसी भी अभिव्यक्ति का मूल्यांकन करता है, और कोई भी चर नाम चुना जा सकता है। हालाँकि, यह थ्रेड सुरक्षित नहीं है। उपयोग उदाहरण-
list<int> N;
list<double> S;

for (int i = 0; i < 10; i++)
    N.push_back(i);

S << list_comprehension(3.1415 * x, x, N, x * x > 3)
  • यह[7] कार्यान्वयन क्लासेस और ऑपरेटर ओवरलोडिंग का उपयोग करके हेड/टेल स्लाइसिंग प्रदान करता है, और | लिस्ट को फ़िल्टर करने के लिए ऑपरेटर (फ़ंक्शन का उपयोग करके)। उपयोग उदाहरण-
bool even(int x) { return x % 2 == 0; }
bool x2(int &x) { x *= 2; return true; }

list<int> l, t;
int x, y;

for (int i = 0; i < 10; i++)
     l.push_back(i);

(x, t) = l | x2;
(t, y) = t;

t = l < 9;
t = t < 7 | even | x2;
  • एंबेडेड क्वेरी और ट्रैवर्सल के लिए भाषा (एलईईएसए (LEESA)[8]) C++ में अंतः स्थापित डीएसएल है जो ऑपरेटर ओवरलोडिंग का उपयोग करके एक्स-पाथ-जैसी क्वेरीज़ को कार्यान्वित करता है। क्वेरीज़ को एक्सएसडी (XSD) से एक्सएमएल-से-सी++ बाइंडिंग का उपयोग करके प्राप्त किए गए समृद्ध रूप से टाइप किए गए एक्सएमएल ट्री पर निष्पादित किया जाता है। इसमें बिल्कुल कोई स्ट्रिंग एन्कोडिंग नहीं है। यहां तक कि एक्सएमएल टैग के नाम भी क्लासेस हैं और इसलिए, टाइपो के लिए कोई मार्ग नहीं है। यदि कोई एलईईएसए अभिव्यक्ति गलत पाथ बनाती है जो डेटा मॉडल में उपस्थित नहीं है, तो C++ संकलक कोड को अस्वीकार कर देगा।
    कैटलॉग एक्सएमएल पर विचार करें।
<catalog>
  <book>
    <title>Hamlet</title>
    <price>9.99</price>
    <author>
      <name>William Shakespeare</name>
      <country>England</country>
    </author>
  </book>
  <book>...</book>
...
</catalog>

एलईईएसए एक्सपाथ/विभाजक के लिए >> प्रदान करता है। एक्सपाथ का // विभाजक जो ट्री में मध्यवर्ती नोड्स को "स्किप्स" करता है, उसे एलईईएसए में युक्‍तिपूर्ण प्रोग्रामिंग के रूप में जाना जाता है का उपयोग करके कार्यान्वित किया जाता है। नीचे दिए गए उदाहरण में, कैटलॉग_, बुक_, ऑथर_ और नाम_ क्रमशः कैटलॉग, बुक, ऑथर और नाम क्लासेज के उदाहरण हैं।

// Equivalent X-Path: "catalog/book/author/name"
std::vector<name> author_names = 
evaluate(root, catalog_ >> book_ >> author_ >> name_);

// Equivalent X-Path: "catalog//name"
std::vector<name> author_names = 
evaluate(root, catalog_ >> DescendantsOf(catalog_, name_));

// Equivalent X-Path: "catalog//author[country=="England"]"
std::vector<name> author_names = 
evaluate(root, catalog_  >> DescendantsOf(catalog_, author_)
                         >> Select(author_, [](const author & a) { return a.country() == "England"; })
                         >> name_);

यह भी देखें

  • सेट-बिल्डर संकेतन
  • एसक्यूएल में सेलेक्ट स्टेटमेंट इसके फ़्रॉम और वेयर क्लॉसेस के साथ

नोट्स और संदर्भ

  1. Turner, David (2012). "कार्यात्मक प्रोग्रामिंग भाषाओं का कुछ इतिहास" (PDF). International Symposium on Trends in Functional Programming, Springer, Berlin, Heidelberg. pp. 1–20.
  2. Comprehensions, a query notation for DBPLs
  3. The functional guts of the Kleisli query system
  4. "2.1 Location Steps". XML Path Language (XPath). W3C. 16 November 1999. Archived from the original on 9 December 2012. Retrieved 24 December 2008.
  5. "XQuery FLWOR अभिव्यक्तियाँ". W3Schools. Archived from the original on 2011-10-08.
  6. "प्रीप्रोसेसर मैक्रोज़ का उपयोग करके C++ में एकल-चर सूची समझ". Archived from the original on 2011-08-21. Retrieved 2011-01-09.
  7. "सी++ सूची समझ". Archived from the original on 2017-07-07. Retrieved 2011-01-09.
  8. "Language for Embedded Query and Traversal (LEESA)".

बाहरी संबंध

स्वयंसिद्ध

क्लोजर

सामान्य लिस्प

हास्केल

OCaml

पायथन

श्रेणी:प्रोग्रामिंग निर्माण श्रेणी:उदाहरण कोड वाले लेख श्रेणी:हास्केल कोड के उदाहरण वाले लेख श्रेणी: पायथन (प्रोग्रामिंग भाषा) कोड के उदाहरण वाले लेख श्रेणी: उदाहरण रैकेट कोड वाले लेख