जनरेटर (कंप्यूटर प्रोग्रामिंग)
कंप्यूटर विज्ञान में, एक जनरेटर एक सबरूटीन है जिसका उपयोग नियंत्रण प्रवाह या लूप्स के पुनरावृत्ति व्यवहार को नियंत्रित करने के लिए किया जा सकता है। सभी जनरेटर भी इटरेटर हैं।[1] एक जनरेटर एक फ़ंक्शन के समान होता है जो एक सरणी देता है, जिसमें एक जनरेटर के पैरामीटर होते हैं, जिसे कॉल किया जा सकता है, और मानों का अनुक्रम उत्पन्न करता है। चूँकि, सभी मानों वाली एक सरणी बनाने और उन्हें एक साथ वापस करने के अतिरिक्त, एक जनरेटर एक समय में एक मान देता है, जिसके लिए कम मेमोरी की आवश्यकता होती है और कॉल करने वाले को पहले कुछ मानों को तुरंत संसाधित करने की अनुमति देता है। संक्षेप में, एक जनरेटर एक फ़ंक्शन की तरह दिखता है, किंतु एक पुनरावर्तक की तरह व्यवहार करता है।
जेनरेटर को अधिक अभिव्यंजक नियंत्रण प्रवाह निर्माणों के संदर्भ में कार्यान्वित किया जा सकता है, जैसे कि कोरटाइन या प्रथम श्रेणी निरंतरता[2] जेनरेटर, जिन्हें सेमीकोराउटाइन के रूप में भी जाना जाता है[3] कोरआउटिन का एक विशेष स्थिति है (और उससे भी अशक्त), जिसमें वे सदैव कॉल करने वाले को नियंत्रण वापस देते हैं (जब एक मूल्य वापस भेजते हैं), अतिरिक्त एक कोरआउटिन पर जाने के निर्दिष्ट करने के; जनरेटर के साथ कोरआउटिन की तुलना देखें।
उपयोग
जेनरेटर सामान्यतः निष्पादन (कंप्यूटर) लूप के अंदर होते हैं।[4] पहली बार जब एक जेनरेटर इनवोकेशन एक लूप में पहुंचता है, एक पुनरावर्तक वस्तु (कंप्यूटर विज्ञान) बनाई जाती है जो जनरेटर की दिनचर्या की स्थिति को उसकी प्रारंभिक में समाहित करती है, जिसमें संबंधित पैरामीटर (कंप्यूटर विज्ञान) के लिए तर्क होते हैं। जेनरेटर के बॉडी को तब तक उस पुनरावर्तक के संदर्भ में निष्पादित किया जाता है जब तक कि एक विशेष उपज कार्रवाई का सामना नहीं किया जाता है; उस समय, यील्ड एक्शन के साथ प्रदान किया गया मान इनवोकेशन अभिव्यक्ति के मान के रूप में उपयोग किया जाता है। अगली बार जब एक ही जनरेटर का आह्वान बाद के पुनरावृत्ति में पहुंच जाता है, तो जनरेटर के बॉडी का निष्पादन उपज कार्रवाई के बाद फिर से प्रारंभ हो जाता है, जब तक कि एक और उपज कार्रवाई का सामना नहीं करना पड़ता है। उपज क्रिया के अतिरिक्त, जनरेटर निकाय का निष्पादन भी एक पूर्ण क्रिया द्वारा समाप्त किया जा सकता है, जिस समय जेनरेटर आमंत्रण को घेरने वाला अंतरतम लूप समाप्त हो जाता है। अधिक जटिल स्थितियों में, एक पुनरावर्तक बनाने के लिए एक जनरेटर को लूप के बाहर मैन्युअल रूप से उपयोग किया जा सकता है, जिसे विभिन्न विधियों से उपयोग किया जा सकता है।
क्योंकि जनरेटर केवल मांग पर अपने उपज मूल्यों की गणना करते हैं, वे धाराओं का प्रतिनिधित्व करने के लिए उपयोगी होते हैं, जैसे अनुक्रम जो एक बार में गणना करने के लिए मूल्यवान या असंभव होंगे। इनमें उदाहरण के लिए अनंत अनुक्रम और लाइव डेटा स्ट्रीम सम्मिलित हैं।
जब उत्सुक मूल्यांकन वांछनीय होता है (मुख्य रूप से जब अनुक्रम सीमित होता है, अन्यथा मूल्यांकन कभी समाप्त नहीं होगा), कोई या तो एक सूची में परिवर्तित हो सकता है, या एक समानांतर निर्माण का उपयोग कर सकता है जो जनरेटर के अतिरिक्त एक सूची बनाता है। उदाहरण के लिए, पायथन में एक जनरेटर g
का मूल्यांकन l = list(g)
, के माध्यम से एक सूची l
में किया जा सकता है, जबकि F या में अनुक्रम अभिव्यक्ति seq { ... }
आलसी (एक जनरेटर या अनुक्रम) का मूल्यांकन करता है किंतु [ ... ]
मूल्यांकन करता है उत्सुकता से (एक सूची)।
जेनरेटर की उपस्थिति में किसी भाषा के लूप निर्माण - जैसे कि और जबकि - को एक लूप में कम किया जा सकता है ... एंड लूप निर्माण; सभी सामान्य लूप निर्माणों को सही विधियों से उपयुक्त जनरेटर का उपयोग करके आराम से अनुकरण किया जा सकता है। उदाहरण के लिए, for x = 1 to 10
के लिए एक श्रेणीबद्ध लूप को जनरेटर के माध्यम से पुनरावृत्ति के रूप में कार्यान्वित किया जा सकता है, जैसे कि पायथन में for x in range(1, 10)
.में। इसके अतिरिकित break
को जनरेटर को फिनिश भेजने और फिर लूप में जारी रखने के रूप में प्रयुक्त किया जा सकता है।
समयरेखा
जेनरेटर पहली बार सीएलयू (1975) में दिखाई दिए, [5] स्ट्रिंग मैनिपुलेशन लैंग्वेज आइकन (1977) में एक प्रमुख विशेषता थे और अब पायथन (2001), [6] सी#, [6] रूबी, पीएचपी, [7] में उपलब्ध हैं। ईसीएमएस्क्रिप्ट (ES6/ES2015 के अनुसार), और अन्य भाषाएँ। सीएलयू और सी# में, जेनरेटर को इटरेटर कहा जाता है, और रूबी में, एन्यूमरेटर।
लिस्प
अंतिम सामान्य लिस्प मानक मूल रूप से जनरेटर प्रदान नहीं करता है, फिर भी विभिन्न पुस्तकालय कार्यान्वयन उपस्थित हैं, जैसे कि शृंखला प्रलेखित सीएलटीएल2 या पाइजन में।
सीएलयू
उपयोक्ता-परिभाषित डेटा सार पर पुनरावृत्तियों को प्रयुक्त करने के लिए एक उपज विवरण का उपयोग किया जाता है।[8]
string_chars = iter (s: string) yields (char);
index: int := 1;
limit: int := string$size (s);
while index <= limit do
yield (string$fetch(s, index));
index := index + 1;
end;
end string_chars;
for c: char in string_chars(s) do
...
end;
चिह्न
प्रत्येक अभिव्यक्ति (लूप सहित) एक जनरेटर है। भाषा में कई जनरेटर अंतर्निहित हैं और यहां तक कि जनरेटर तंत्र (तार्किक संयोजन या OR इस तरह से किया जाता है) का उपयोग करके कुछ तर्क शब्दार्थों को प्रयुक्त करता है।
0 से 20 तक के मुद्रण वर्गों को लिखकर एक सह-दिनचर्या का उपयोग करके प्राप्त किया जा सकता है:
चूँकि अधिकांश समय कस्टम जनरेटर को सस्पेंड कीवर्ड के साथ प्रयुक्त किया जाता है जो सीएलयू में उपज कीवर्ड की तरह ही कार्य करता है।
सी
सी (प्रोग्रामिंग भाषा) में भाषा निर्माण के रूप में जनरेटर कार्य नहीं होते हैं, किंतु, चूंकि वे कोरटाइन का एक सबसेट हैं, इसलिए उन्हें किसी भी रूपरेखा का उपयोग करके प्रयुक्त करना आसान है जो स्टैकफुल कोरटाइन को प्रयुक्त करता है, जैसे कि लिबडिल।[9] पोसिक्स प्लेटफार्मों पर, जब प्रति पुनरावृत्ति संदर्भ स्विचिंग की व्यय चिंता का विषय नहीं है, या केवल समवर्ती (कंप्यूटर_साइंस) के अतिरिक्त पूर्ण समानांतर_कंप्यूटिंग वांछित है, तो पीथ्रेड्स और अज्ञात_पाइप का उपयोग करके एक बहुत ही सरल जनरेटर फ़ंक्शन फ्रेमवर्क प्रयुक्त किया जा सकता है।
C ++
प्री-प्रोसेसर मैक्रोज़ का उपयोग करके जेनरेटर को C ++ में प्रस्तुत करना संभव है। परिणामी कोड में ऐसे पहलू हो सकते हैं जो देशी C ++ से बहुत भिन्न हों, किंतु जनरेटर सिंटैक्स बहुत ही अस्पष्ट हो सकता है।[10] इस स्रोत में परिभाषित प्री-प्रोसेसर मैक्रोज़ का सेट जेनरेटर को निम्नलिखित उदाहरण में सिंटैक्स के साथ परिभाषित करने की अनुमति देता है:
$generator(descent)
{
int i;
// place the constructor of our generator, e.g.
// descent(int minv, int maxv) {...}
// from $emit to $stop is a body of our generator:
$emit(int) // will emit int values. Start of body of the generator.
for (i = 10; i > 0; --i)
$yield(i); // similar to yield in Python,
// returns next number in [1..10], reversed.
$stop; // stop, end of sequence. End of body of the generator.
};
इसके बाद इसका उपयोग करके पुनरावृत्त किया जा सकता है:
int main(int argc, char* argv[])
{
descent gen;
for (int n; gen(n);) // "get next" generator invocation
printf("next number is %d\n", n);
return 0;
}
इसके अतिरिक्त , C ++ 11 फ़ॉरच लूप को किसी भी वर्ग पर प्रयुक्त करने की अनुमति देता है जो प्रदान करता है begin
और end
कार्य करता है। दोनों पुनरावर्तनीय विधियों को परिभाषित करके जेनरेटर जैसी कक्षाएं लिखना संभव है (begin
और end
) और इटरेटर विधियों (operator!=
, operator++
और operator*
) समान कक्षा में। उदाहरण के लिए, निम्नलिखित प्रोग्राम लिखना संभव है:
#include <iostream>
int main()
{
for (int i: range(10))
{
std::cout << i << std::endl;
}
return 0;
}
एक मूल श्रेणी कार्यान्वयन ऐसा दिखाई देगा:
class range
{
private:
int last;
int iter;
public:
range(int end):
last(end),
iter(0)
{}
// Iterable functions
const range& begin() const { return *this; }
const range& end() const { return *this; }
// Iterator functions
bool operator!=(const range&) const { return iter < last; }
void operator++() { ++iter; }
int operator*() const { return iter; }
};
पर्ल
पर्ल मूल रूप से जनरेटर प्रदान नहीं करता है, किंतु समर्थन कोरो::जेनरेटर मॉड्यूल द्वारा प्रदान किया जाता है जो कोरो सह-नियमित रूपरेखा का उपयोग करता है। उदाहरण उपयोग:
use strict;
use warnings;
# Enable generator { BLOCK } and yield
use Coro::Generator;
# Array reference to iterate over
my $chars = ['A'...'Z'];
# New generator which can be called like a coderef.
my $letters = generator {
my $i = 0;
for my $letter (@$chars) {
# get next letter from $chars
yield $letter;
}
};
# Call the generator 15 times.
print $letters->(), "\n" for (0..15);
राकु
आइकॉन के समानांतर उदाहरण भाषा के साथ जनरेटर प्राप्त करने के कई विधियों में से एक के रूप में राकू (पूर्व/अन्य पर्ल 6) रेंज क्लास का उपयोग करता है।
0 से 20 तक के वर्गों को लिखकर प्राप्त किया जा सकता है:
for (0 .. *).map(* ** 2) -> $i {
last if $i > 20;
say $i
}
चूँकि अधिकांश समय कस्टम जनरेटर को आलसी संदर्भ में "संग्रह" और "टेक" कीवर्ड के साथ कार्यान्वित किया जाता है।
टीसीएल
टीसीएल 8.6 में, जेनरेटर मैकेनिज्म नामित कोरआउट्स पर आधारित है।
proc generator {body} {
coroutine gen[incr ::disambiguator] apply {{script} {
# Produce the result of [generator], the name of the generator
yield [info coroutine]
# Do the generation
eval $script
# Finish the loop of the caller using a 'break' exception
return -code break
}} $body
}
# Use a simple 'for' loop to do the actual generation
set count [generator {
for {set i 10} {$i <= 20} {incr i} {
yield $i
}
}]
# Pull values from the generator until it is exhausted
while 1 {
puts [$count]
}
हास्केल
हास्केल (प्रोग्रामिंग भाषा) में, अपने आलसी मूल्यांकन मॉडल के साथ गैर-सख्त मूल्यांकन के साथ बनाया गया प्रत्येक डाटाम या गैर-सख्त डेटा कन्स्ट्रक्टर मांग पर उत्पन्न होता है। उदाहरण के लिए,
countFrom :: Integer -> [Integer]
countFrom n = n : countFrom (n + 1)
from10to20 :: [Integer]
from10to20 = takeWhile (<= 20) $ countFrom 10
primes :: [Integer]
primes = 2 : 3 : nextPrime 5
where
nextPrime n
| notDivisible n = n : nextPrime (n + 2)
| otherwise = nextPrime (n + 2)
notDivisible n =
all ((/= 0) . (rem n)) $ takeWhile ((<= n) . (^ 2)) $ tail primes
कहाँ (:)
एक गैर-सख्त सूची निर्माता, विपक्ष और है $
केवल एक तथाकथित ऑपरेटर है, जिसका उपयोग कोष्ठक के लिए किया जाता है। यह मानक एडेप्टर फ़ंक्शन का उपयोग करता है,
जहां(:)
एक गैर-सख्त सूची निर्माता है, विपक्ष, और $
केवल एक "कॉल-विथ" ऑपरेटर है, जिसका उपयोग कोष्ठकीकरण के लिए किया जाता है। यह मानक एडाप्टर फ़ंक्शन का उपयोग करता है,
takeWhile p [] = []
takeWhile p (x:xs) | p x = x : takeWhile p xs
| otherwise = []
जो सूची में नीचे चलता है और पहले तत्व पर रुकता है जो विधेय को संतुष्ट नहीं करता है। यदि सूची उस बिंदु तक पहले चली गई है, तो यह केवल एक सख्त डेटा संरचना है, किंतु यदि कोई भाग पहले नहीं चला है, तो यह मांग पर उत्पन्न होगा। सूची की समझ का स्वतंत्र रूप से उपयोग किया जा सकता है:
squaresUnder20 = takeWhile (<= 20) [x * x | x <- countFrom 10]
squaresForNumbersUnder20 = [x * x | x <- takeWhile (<= 20) $ countFrom 10]
रैकेट
रैकेट (प्रोग्रामिंग भाषा) जनरेटर के लिए कई संबंधित सुविधाएं प्रदान करता है। सबसे पहले, इसके फॉर-लूप फॉर्म अनुक्रमों के साथ काम करते हैं, जो एक तरह के निर्माता हैं:
(for ([i (in-range 10 20)])
(printf "i = ~s\n" i))
और ये क्रम प्रथम श्रेणी के मान भी हैं:
(define 10-to-20 (in-range 10 20))
(for ([i 10-to-20])
(printf "i = ~s\n" i))
कुछ अनुक्रमों को अनिवार्य रूप से प्रयुक्त किया जाता है (निजी अवस्था चर के साथ) और कुछ को (संभवतः अनंत) आलसी सूचियों के रूप में प्रयुक्त किया जाता है। साथ ही, नई संरचना परिभाषाओं में एक संपत्ति हो सकती है जो निर्दिष्ट करती है कि उन्हें अनुक्रमों के रूप में कैसे उपयोग किया जा सकता है।
किंतु अधिक सीधे रूप से, अधिक पारंपरिक जनरेटर विनिर्देश के लिए रैकेट जनरेटर लाइब्रेरी के साथ आता है। उदाहरण के लिए,
#lang racket
(require racket/generator)
(define (ints-from from)
(generator ()
(for ([i (in-naturals from)]) ; infinite sequence of integers from 0
(yield i))))
(define g (ints-from 10))
(list (g) (g) (g)) ; -> '(10 11 12)
ध्यान दें कि रैकेट कोर शक्तिशाली निरंतरता सुविधाओं को प्रयुक्त करता है, जो सामान्य (पुनः प्रवेशी) निरंतरता प्रदान करता है जो रचना योग्य हैं, और निरंतरता भी सीमित हैं। इसका उपयोग करके रैकेट में जनरेटर लाइब्रेरी प्रयुक्त की जाती है।
पीएचपी
पीएचपी के समुदाय ने पीएचपी 5.5 में जेनरेटर प्रयुक्त किए। विवरण मूल टिप्पणियों के लिए अनुरोध: जेनरेटर में पाया जा सकता है।
अनंत फाइबोनैचि अनुक्रम:
function fibonacci()
{
$last = 0;
$current = 1;
yield 1;
while (true) {
$current = $last + $current;
$last = $current - $last;
yield $current;
}
}
foreach (fibonacci() as $number) {
echo $number, "\n";
}
सीमा के साथ फाइबोनैचि अनुक्रम:
function fibonacci(int $limit): generator
{
yield $a = $b = $i = 1;
while (++$i < $limit) {
yield $a = ($b = $a + $b) - $a;
}
}
foreach (fibonacci(10) as $number) {
echo "$number\n";
}
कोई भी फंक्शन जिसमें यील्ड स्टेटमेंट स्वचालित रूप से एक जनरेटर फ़ंक्शन है।
रूबी
रूबी बिल्ट-इन एन्युमरेटर वर्ग के रूप में जेनरेटर (संस्करण 1.9 से प्रारंभ) का समर्थन करता है।
# Generator from an Enumerator object
chars = Enumerator.new(['A', 'B', 'C', 'Z'])
4.times { puts chars.next }
# Generator from a block
count = Enumerator.new do |yielder|
i = 0
loop { yielder.yield i += 1 }
end
100.times { puts count.next }
जावा
जावा के प्रारंभिक दिनों से इटरेटर्स को प्रयुक्त करने के लिए एक मानक इंटरफ़ेस रहा है, और जावा 5 के बाद से, फ़ॉरच कंस्ट्रक्शन उन ऑब्जेक्ट्स पर लूप करना आसान बनाता है जो java.lang.Iterable
इंटरफ़ेस प्रदान करते हैं। (जावा संग्रह रूपरेखा और अन्य संग्रह रूपरेखा, सामान्यतः सभी संग्रहों के लिए इटरेटर प्रदान करते हैं।)
record Pair(int a, int b) {};
Iterable<Integer> myIterable = Stream.iterate(new Pair(1, 1), p -> new Pair(p.b, p.a + p.b))
.limit(10)
.map(p -> p.a)::iterator;
myIterable.forEach(System.out::println);
या जावा 8 सुपर-इंटरफ़ेस बेसस्ट्रीम ऑफ़ स्ट्रीम इंटरफ़ेस से एक इटरेटर प्राप्त करें।
record Pair(int a, int b) {};
// Save the iterator of a stream that generates fib sequence
Iterator<Integer> myGenerator = Stream
// Generates Fib sequence
.iterate(new Pair(1, 1), p -> new Pair(p.b, p.a + p.b))
.map(p -> p.a).iterator();
// Print the first 5 elements
for (int i = 0; i < 5; i++) {
System.out.println(myGenerator.next());
}
System.out.println("done with first iteration");
// Print the next 5 elements
for (int i = 0; i < 5; i++) {
System.out.println(myGenerator.next());
}
आउटपुट:
1
1
2
3
5
done with first iteration
8
13
21
34
55
सी#
एक उदाहरण c# 2.0 जनरेटर ( yield
c# संस्करण 2.0 के बाद से उपलब्ध है):
ये दोनों उदाहरण जेनरिक का उपयोग करते हैं, किंतु इसकी आवश्यकता नहीं है। उपज कीवर्ड संग्रह पर कस्टम स्टेटफुल पुनरावृत्तियों को प्रयुक्त करने में भी मदद करता है जैसा कि इस चर्चा में चर्चा की गई है।[11]
// Method that takes an iterable input (possibly an array)
// and returns all even numbers.
public static IEnumerable<int> GetEven(IEnumerable<int> numbers)
{
foreach (int number in numbers)
{
if ((number % 2) == 0)
{
yield return number;
}
}
}
एकाधिक का उपयोग करना संभव है yield return
बयान और वे प्रत्येक पुनरावृत्ति पर अनुक्रम में प्रयुक्त होते हैं:
public class CityCollection : IEnumerable<string>
{
public IEnumerator<string> GetEnumerator()
{
yield return "New York";
yield return "Paris";
yield return "London";
}
}
एक्सएल
एक्सएल (प्रोग्रामिंग भाषा) में, इटरेटर 'लूप' के लिए आधार हैं:
import IO = XL.UI.CONSOLE
iterator IntegerIterator (var out Counter : integer; Low, High : integer) written Counter in Low..High is
Counter := Low
while Counter <= High loop
yield
Counter += 1
// Note that I needs not be declared, because declared 'var out' in the iterator
// An implicit declaration of I as an integer is therefore made here
for I in 1..5 loop
IO.WriteLn "I=", I
एफ #
F# संस्करण 1.9.1 के बाद से अनुक्रम अभिव्यक्ति के माध्यम से जनरेटर प्रदान करता है।[12] ये एक अनुक्रम (आलस्यपूर्ण मूल्यांकन, अनुक्रमिक पहुंच) के माध्यम से परिभाषित कर सकते हैं seq { ... }
, एक सूची (उत्सुकता से मूल्यांकन, अनुक्रमिक पहुंच) के माध्यम से [ ... ]
या एक सरणी (उत्सुकता से मूल्यांकन, अनुक्रमित पहुंच) के माध्यम से [| ... |]
जिसमें कोड होता है जो मान उत्पन्न करता है। उदाहरण के लिए,
seq { for b in 0 .. 25 do
if b < 15 then
yield b * b }
0 से 25 तक की संख्याओं की श्रेणी से संख्याओं को छानकर 0 से 14 तक की संख्याओं के वर्गों का एक क्रम बनाता है।
पायथन
जनरेटर को 2001 में संस्करण 2.2 में पायथन (प्रोग्रामिंग भाषा) में जोड़ा गया था।[13] एक उदाहरण जनरेटर:
from typing import Iterator
def countfrom(n: int) -> Iterator[int]:
while True:
yield n
n += 1
# Example use: printing out the integers from 10 to 20.
# Note that this iteration terminates normally, despite
# countfrom() being written as an infinite loop.
for i in countfrom(10):
if i <= 20:
print(i)
else:
break
# Another generator, which produces prime numbers indefinitely as needed.
import itertools
def primes() -> Iterator[int]:
"""Generate prime numbers indefinitely as needed."""
yield 2
n = 3
p = []
while True:
# If dividing n by all the numbers in p, up to and including sqrt(n),
# produces a non-zero remainder then n is prime.
if all(n % f > 0 for f in itertools.takewhile(lambda f: f * f <= n, p)):
yield n
p.append(n)
n += 2
पायथन में, एक जनरेटर को एक पुनरावर्तक के रूप में माना जा सकता है जिसमें एक जमे हुए स्टैक फ्रेम होता है। जब कभी भी next()
पुनरावर्तक पर कहा जाता है, पायथन जमे हुए फ्रेम को फिर से प्रारंभ करता है, जो अगले तक सामान्य रूप से निष्पादित होता है yield
कथन पर पहुंच गया है। जनरेटर का फ्रेम फिर से जम जाता है, और उपज मूल्य कॉलर को वापस कर दिया जाता है।
पीईपी 380 (पायथन 3.3 में प्रयुक्त) जोड़ता है yield from
अभिव्यक्ति, एक जनरेटर को अपने संचालन का भाग दूसरे जनरेटर या पुनरावर्तनीय को सौंपने की अनुमति देता है।[14]
जेनरेटर भाव
पायथन में सूची समझ पर आधारित एक वाक्यविन्यास है, जिसे जनरेटर अभिव्यक्ति कहा जाता है जो जनरेटर के निर्माण में सहायता करता है। countfrom
जनरेटर फ़ंक्शन से वर्गों की गणना करने के लिए जनरेटर अभिव्यक्ति का उपयोग करके निम्नलिखित पहले उदाहरण का विस्तार करता है:
squares = (n * n for n in countfrom(2))
for j in squares:
if j <= 20:
print(j)
else:
break
ईसीएमएस्क्रिप्ट
ईसीएमएस्क्रिप्ट (या हार्मनी) ने जेनरेटर फ़ंक्शंस प्रस्तुत किए थे।
एक फ़ंक्शन जनरेटर का उपयोग करके एक अनंत फाइबोनैचि अनुक्रम लिखा जा सकता है:
function* fibonacci(limit) {
let [prev, curr] = [0, 1];
while (!limit || curr <= limit) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
// bounded by upper limit 10
for (const n of fibonacci(10)) {
console.log(n);
}
// generator without an upper bound limit
for (const n of fibonacci()) {
console.log(n);
if (n > 10000) break;
}
// manually iterating
let fibGen = fibonacci();
console.log(fibGen.next().value); // 1
console.log(fibGen.next().value); // 1
console.log(fibGen.next().value); // 2
console.log(fibGen.next().value); // 3
console.log(fibGen.next().value); // 5
console.log(fibGen.next().value); // 8
// picks up from where you stopped
for (const n of fibGen) {
console.log(n);
if (n > 10000) break;
}
आर
इस उद्देश्य के लिए इटरेटर्स पैकेज का उपयोग किया जा सकता है।[15][16]
library(iterators)
# Example ------------------
abc <- iter(c('a','b','c'))
nextElem(abc)
स्मालटॉक
फिरौन में उदाहरण:
नीचे दिया गया गोल्डन अनुपात जेनरेटर प्रत्येक इनवोकेशन 'गोल्डनरेशियो नेक्स्ट' को गोल्डन रेशियो का एक उत्तम सन्निकटन देता है।
goldenRatio := Generator on: [ :g | | x y z r |
x := 0.
y := 1.
[
z := x + y.
r := (z / y) asFloat.
x := y.
y := z.
g yield: r
] repeat
].
goldenRatio next.
नीचे दिया गया व्यंजक अगले 10 सन्निकटन लौटाता है।
Character cr join: ((1 to: 10) collect: [ :dummy | ratio next ]).
अधिक जानकारी फ़ारो: जेनरेटर. में देखें।
यह भी देखें
- मूल्यों के अनुक्रम उत्पन्न करने वाले अन्य निर्माण के लिए सूची समझ
- एक समय में एक सूची एक तत्व बनाने की अवधारणा के लिए पुनरावर्तक
- एक विकल्प के लिए पुनरावृत्त करें
- जरूरत पड़ने पर मूल्यों के उत्पादन के लिए आलसी मूल्यांकन
- उपज के अतिरिक्त पुनरावर्तन द्वारा संभावित अनंत डेटा के लिए कोरकर्शन
- सबरूटीन से और भी अधिक सामान्यीकरण के लिए कोरूटीन
- नियंत्रण प्रवाह के सामान्यीकरण के लिए निरंतरता
टिप्पणियाँ
- ↑ What is the difference between an Iterator and a Generator?
- ↑ Kiselyov, Oleg (January 2004). "General ways to traverse collections in Scheme".
- ↑ Anthony Ralston (2000). कंप्यूटर विज्ञान का विश्वकोश. Nature Pub. Group. ISBN 978-1-56159-248-7. Retrieved 11 May 2013.
- ↑ The Icon Programming Language utilizes generators to implement its goal directed evaluation. In Icon, generators can be invoked in contexts outside of the normal looping control structures.
- ↑ Liskov, Barbara (April 1992). "A History of CLU" (PDF). Archived from the original (PDF) on 2003-09-17. Retrieved 2006-01-05.
- ↑ yield (C# Reference)
- ↑ "PHP: Generators overview - Manual".
- ↑ Liskov, B.; Snyder, A.; Atkinson, R.; Schaffert, C. (1977). "सीएलयू में अमूर्त तंत्र". Communications of the ACM. 20 (8): 564–576. CiteSeerX 10.1.1.112.656. doi:10.1145/359763.359789. S2CID 17343380.
- ↑ "Structured Concurrency for C".
- ↑ "सी ++ में जेनरेटर". 21 September 2008.
- ↑ "What is the yield keyword used for in C#?". stackoverflow.com. Retrieved 2018-01-01.
- ↑ "एफ # कंप्यूटेशन एक्सप्रेशंस पर कुछ विवरण". Retrieved 2007-12-14.
- ↑ Python Enhancement Proposals: PEP 255: Simple Generators, PEP 289: Generator Expressions, PEP 342: Coroutines via Enhanced Generators
- ↑ PEP 380 -- Syntax for Delegating to a Subgenerator
- ↑ Generator functions in R
- ↑ "आर में अनंत जनरेटर". 5 January 2013.
संदर्भ
- Stephan Murer, Stephen Omohundro, David Stoutamire and Clemens Szyperski: Iteration abstraction in Sather. ACM Transactions on Programming Languages and Systems, 18(1):1-15 (1996) [1]