Jeneratör (bilgisayar programlama) - Generator (computer programming)

İçinde bilgisayar Bilimi, bir jeneratör bir rutin kontrol etmek için kullanılabilir yineleme davranışı döngü. Tüm jeneratörler ayrıca yineleyiciler.[1] Bir üretici, bir dizi döndüren bir işleve çok benzer, çünkü bir jeneratörün parametreleri vardır, çağrılabilir ve bir dizi değer üretir. Ancak, tüm değerleri içeren bir dizi oluşturmak ve hepsini bir kerede döndürmek yerine, bir üretici değerleri birer birer verir, bu da daha az bellek gerektirir ve arayanın ilk birkaç değeri hemen işlemeye başlamasını sağlar. Kısacası bir jeneratör gibi görünüyor bir işlev ama gibi davranır bir yineleyici.

Jeneratörler daha anlamlı bir şekilde uygulanabilir kontrol akışı gibi yapılar Coroutines veya birinci sınıf devamlar.[2] Yarıorutinler olarak da bilinen jeneratörler,[3] Eşitlerin özel bir durumudur (ve onlardan daha zayıftır), zıplamak için bir koroutin belirtmek yerine kontrolü her zaman arayana geri verirler (bir değeri geri iletirken); görmek koroutinlerin oluşturucularla karşılaştırılması.

Kullanımlar

Jeneratörler genellikle çağrıldı iç döngüler.[4] Bir döngüde bir jeneratör çağrısına ilk kez ulaşıldığında, bir yineleyici nesne Oluşturucu yordamının durumunu başlangıcında, karşılık gelen bağımsız değişkenlere bağlı olarak özetleyen oluşturulur. parametreleri. Üreticinin gövdesi daha sonra bu yineleyici bağlamında özel bir Yol ver eylemle karşılaşılır; o sırada, ile sağlanan değer Yol ver eylem, çağrı ifadesinin değeri olarak kullanılır. Bir sonraki yinelemede aynı jeneratör çağrısına bir dahaki sefer ulaşıldığında, jeneratör gövdesinin çalıştırılması, Yol ver eylem, bir başkasına kadar Yol ver eylemle karşılaşılır. Buna ek olarak Yol ver eylem, jeneratör gövdesinin yürütülmesi ayrıca bir bitiş eylem, bu sırada jeneratör çağrısını çevreleyen en içteki döngü sonlandırılır. Daha karmaşık durumlarda, bir yineleyici oluşturmak için bir döngü dışında manuel olarak bir jeneratör kullanılabilir ve bu daha sonra çeşitli şekillerde kullanılabilir.

Üreteçler, verilen değerleri yalnızca talep üzerine hesapladıkları için, bunları temsil etmek için kullanışlıdırlar. Canlı Yayınlar, aynı anda hesaplanması pahalı veya imkansız olan diziler gibi. Bunlar, ör. sonsuz diziler ve canlı veri akışları.

Hevesli bir değerlendirme istendiğinde (öncelikli olarak sıra sonlu olduğunda, aksi takdirde değerlendirme asla sona ermeyecektir), kişi ya bir liste veya bir jeneratör yerine bir liste oluşturan paralel bir yapı kullanın. Örneğin, Python'da bir jeneratör g bir liste olarak değerlendirilebilir l üzerinden l = liste (g)iken F # dizi ifadesi seq {...} tembel olarak değerlendirir (bir oluşturucu veya sıra) ancak [ ... ] hevesle değerlendirir (bir liste).

Üreteçlerin varlığında, bir dilin döngü yapıları - for ve while gibi - tek bir döngüye indirgenebilir ... uç döngü yapısı; tüm olağan döngü yapıları daha sonra uygun jeneratörleri doğru şekilde kullanarak rahatça simüle edilebilir. Örneğin, aşağıdaki gibi aralıklı bir döngü x = 1 ila 10 için Python'unki gibi bir jeneratör aracılığıyla yineleme olarak uygulanabilir aralıktaki x için (1, 10). Daha ileri, kırmak gönderme olarak uygulanabilir bitiş jeneratöre ve ardından kullanarak devam et döngüde.

Zaman çizelgesi

Jeneratörler ilk olarak CLU (1975),[5] dize işleme dilinde öne çıkan bir özellikti Simge (1977) ve şimdi mevcuttur Python (2001),[6] C #,[7] Yakut, ECMAScript'in sonraki sürümleri (ES6 / ES2015 itibariyle) ve diğer diller. CLU ve C # 'da, jeneratörler yineleyicilerve Ruby'de, sayıcılar.

Lisp

Son Ortak Lisp standardı yerel olarak üreteç sağlamaz, ancak çeşitli kitaplık uygulamaları mevcuttur, örneğin DİZİ CLtL2'de belgelenmiştir veya pygen.

CLU

Kullanıcı tanımlı veri soyutlamaları üzerinde yineleyicileri uygulamak için bir verim ifadesi kullanılır.[8]

string_chars = iter (s: string) verim (karakter); dizin: int: = 1; limit: int: = string $ boyut (lar); while indeks <= limit do verim (string $ getirme (s, indeks)); dizin: = dizin + 1; end; end string_chars; for c: string_chars (lar) daki karakter do ... end;

Simge

Her ifade (döngüler dahil) bir üreteçtir. Dilde birçok yerleşik üretici vardır ve hatta üreteç mekanizmasını kullanarak bazı mantık semantiğini uygular (mantıksal ayrılma veya "VEYA" bu şekilde yapılır).

0'dan 20'ye kadar olan karelerin yazdırılması, bir ortak rutin kullanılarak şu şekilde yazılabilir:

   yerel kareler, j kareler: = oluştur (seq (0) ^ 2) her j: = | @squares, j <= 20 ise yaz (j) yoksa kır

Bununla birlikte, çoğu zaman özel oluşturucular, CLU'daki "verim" anahtar sözcüğü gibi işlev gören "askıya alma" anahtar sözcüğüyle uygulanır.

C

C bir dil yapısı olarak üreteç işlevlerine sahip değildir, ancak bunlar bir alt kümesi oldukları için Coroutines libdill gibi yığınlı eş diziler uygulayan herhangi bir çerçeve kullanarak bunları uygulamak basittir.[9] POSIX platformlarında, maliyeti bağlam değiştirme yineleme başına bir sorun değil veya paralellik sadece değil eşzamanlılık istenirse, çok basit bir jeneratör işlevi çerçevesi kullanılarak uygulanabilir pthreads ve borular.

C ++

Ön işlemci makrolarını kullanarak jeneratörleri C ++ 'ya dahil etmek mümkündür. Ortaya çıkan kod, yerel C ++ 'dan çok farklı yönlere sahip olabilir, ancak oluşturucu sözdizimi çok derli toplu olabilir.[10] Bu kaynakta tanımlanan ön işlemci makroları kümesi, aşağıdaki örnekte olduğu gibi sözdizimi ile tanımlanan oluşturuculara izin verir:

$jeneratör(iniş){   int ben;   // oluşturucumuzun yapıcısını yerleştirin, ör.    // iniş (int minv, int maxv) {...}      // $ emit'ten $ stop'a, jeneratörümüzün bir gövdesi:       $yaymak(int) // int değerleri yayar. Jeneratör gövdesinin başlangıcı.      için (ben = 10; ben > 0; --ben)         $Yol ver(ben); // Python'daki verime benzer,                    // [1..10] 'daki sonraki sayıyı tersine döndürür.   $Dur; // dur, sıranın sonu. Jeneratör gövdesinin sonu.};

Bu daha sonra aşağıdakiler kullanılarak yinelenebilir:

int ana(int argc, kömür* argv[]){  iniş gen;  için(int n; gen(n);) // "sonraki" oluşturucu çağrısı    printf("sonraki numara% d n", n);  dönüş 0;}

Dahası, C ++ 11 izin verir foreach döngüleri sağlayan herhangi bir sınıfa uygulanacak başla ve son fonksiyonlar. Daha sonra, her iki yinelenebilir yöntemi tanımlayarak üreteç benzeri sınıflar yazmak mümkündür (başla ve son) ve yineleme yöntemleri (operatör! =, operatör ++ ve Şebeke*) aynı sınıfta. Örneğin aşağıdaki programı yazmak mümkündür:

#Dahil etmek <iostream>int ana(){    için (int ben: Aralık(10))    {        std::cout << ben << std::son;    }    dönüş 0;}

Temel bir aralık uygulaması şuna benzer:

sınıf Aralık{özel:    int son;    int tekrar;halka açık:    Aralık(int son):        son(son),        tekrar(0)    {}    // Yinelenebilir işlevler    sabit Aralık& başla() sabit { dönüş *bu; }    sabit Aralık& son() sabit { dönüş *bu; }    // Yineleyici işlevleri    bool Şebeke!=(sabit Aralık&) sabit { dönüş tekrar < son; }    geçersiz Şebeke++() { ++tekrar; }    int Şebeke*() sabit { dönüş tekrar; }};

Perl

Perl, yerel olarak üreteç sağlamaz, ancak destek, Coro :: Jeneratör kullanan modül Coro ortak rutin çerçeve. Örnek kullanım:

kullanım katı;kullanım uyarılar;# Jeneratörü {BLOCK} ve verimi etkinleştirkullanım Coro :: Jeneratör;# Üzerinde yineleme için dizi referansıbenim $ karakter = ['A'..."Z"];# Koderef gibi çağrılabilen yeni jeneratör.benim $ harfler = jeneratör {    benim $ i = 0;    için benim $ mektup (@ $ karakter) {        # $ chars'tan sonraki harfi al        Yol ver $ mektup;    }};# Jeneratörü 15 kez arayın.Yazdır $ harfler->(), " n" için (0..15);

Tcl

İçinde Tcl 8.6, jeneratör mekanizması adlandırılmış Coroutines.

proc jeneratör {vücut} {    Coroutine gen[incr ::belirsizliği giderici] uygulamak {{senaryo} {        # Jeneratörün adı olan [generator] sonucunu üretin        Yol ver [bilgi Coroutine]        # Nesil yap        değerlendirme $ script        # Bir 'ara' istisnası kullanarak arayanın döngüsünü bitirin        dönüş -kod sonu }} $ body}# Gerçek üretimi yapmak için basit bir 'for' döngüsü kullanınAyarlamak Miktar [jeneratör {    için {Ayarlamak ben 10} {$ i <= 20} {incr ben} {        Yol ver $ i    }}]# Tükenene kadar jeneratörden değerleri çekinsüre 1 {    koyar [$ count]}

Haskell

İçinde Haskell, onunla tembel değerlendirme model, her şey bir jeneratördür - her veri bir katı olmayan veri yapıcısı talep üzerine oluşturulur. Örneğin,

sayı n = n : sayı (n+1)- Örnek kullanım: 10 ile 20 arasındaki tam sayıları yazdırmak.test1 = mapM_ Yazdır $ takeWhile (<= 20) $ sayı 10asal = 2 : 3 : nextprime 5  nerede  nextprime n | b = n : nextprime (n+2)              | aksi takdirde = nextprime (n+2)    nerede b = herşey ((/= 0).(rem n)) $ takeWhile ((<= n).(^2)) $ kuyruk asal

nerede (:) katı olmayan bir liste oluşturucusudur, Eksileri, ve $ sadece bir "ile-aranır" operatörü, parantezleme için kullanılır. Bu, standart adaptör işlevini kullanır,

takeWhile p [] = []takeWhile p (x:xs) | p x = x : takeWhile p xs                   | aksi takdirde = []

bir yüklemle uyumlu değerleri yeniden getiren ve uygun olmayan bir taneyle karşılaşıldığında hemen yeni değerler talep etmeyi durduran. Paylaşılan depolama erişimi, Haskell'de evrensel bir arabulucu olarak kullanılır. Liste anlayışları serbestçe kullanılabilir:

test2 = mapM_ Yazdır $ takeWhile (<= 20) [x*x | x <- sayı 10]test3 = mapM_ Yazdır [x*x | x <- takeWhile (<= 20) $ sayı 10]

Raket

Raket jeneratörler için birkaç ilgili tesis sağlar. İlk olarak, for-loop formları ile çalışır dizilerbir tür yapımcı olan:

(için ([ben (aralık içi 10 20)])  (printf "i = ~ s n" ben))

ve bu diziler aynı zamanda birinci sınıf değerlerdir:

(tanımlamak 10-20 (aralık içi 10 20))(için ([ben 10-20])  (printf "i = ~ s n" ben))

Bazı diziler zorunlu olarak (özel durum değişkenleriyle) uygulanır ve bazıları (muhtemelen sonsuz) tembel listeler olarak uygulanır. Ayrıca, yeni yapı tanımları, diziler olarak nasıl kullanılabileceklerini belirten bir özelliğe sahip olabilir.

Ancak daha doğrusu, Racket daha geleneksel bir jeneratör spesifikasyonu için bir jeneratör kitaplığıyla birlikte gelir. Örneğin,

#lang raket(gerek raket / jeneratör)(tanımlamak (ints-from itibaren)  (jeneratör ()    (için ([ben (doğal itibaren)]) ; 0'dan sonsuz tamsayı dizisi      (Yol ver ben))))(tanımlamak g (ints-from 10))(liste (g) (g) (g)) ; -> '(10 11 12)

Racket çekirdeğinin güçlü devamlılık özellikleri uyguladığını, birleştirilebilir genel (yeniden giren) süreklilikler ve ayrıca sınırlandırılmış süreklilikler sağladığını unutmayın. Bunu kullanarak, jeneratör kütüphanesi Racket'te uygulanır.

PHP

PHP topluluğu, üreteçleri PHP 5.5'te uygulamıştır. Ayrıntılar orijinal belgede bulunabilir Yorum İsteği: Jeneratörler.

işlevi fibonacci(){    $ son = 0;    $ akım = 1;    Yol ver 1;    süre (doğru) {        $ akım = $ son + $ akım;        $ son = $ akım - $ son;        Yol ver $ akım;    }}her biri için (fibonacci() gibi $ numara) {    Eko $ numara, " n";}

İçeren herhangi bir işlev Yol ver ifadesi otomatik olarak bir üretici işlevidir.

Yakut

Ruby, yerleşik Enumerator sınıfı biçiminde oluşturucuları (sürüm 1.9'dan başlayarak) destekler.

# Bir Numaralandırıcı nesnesinden oluşturucukarakter = Numaralandırıcı.yeni(['A', 'B', 'C', "Z"])4.zamanlar { koyar karakter.Sonraki }# Bir bloktan jeneratörMiktar = Numaralandırıcı.yeni yapmak |veren|  ben = 0  döngü { veren.Yol ver ben += 1 }son100.zamanlar { koyar Miktar.Sonraki }

Java

Java, ilk günlerinden beri yineleyicileri uygulamak için standart bir arayüze sahiptir ve Java 5'ten bu yana, "foreach" yapısı, java.lang.Iterable arayüz. (The Java koleksiyon çerçevesi ve diğer koleksiyon çerçeveleri, genellikle tüm koleksiyonlar için yineleyiciler sağlar.)

Ancak, Java dilde yerleşik oluşturuculara sahip değil. Bu, yineleyiciler oluşturmanın, özellikle oluşturma mantığı karmaşık olduğunda, yerleşik oluşturuculara sahip dillerden çok daha karmaşık olduğu anlamına gelir. Bir öğenin bir yineleyiciden her verilişinde tüm durum kaydedilmesi ve geri yüklenmesi gerektiğinden, yerel değişkenlerde durumu depolamak veya üreteçler mevcut olduğunda olduğu gibi yerleşik döngü rutinlerini kullanmak mümkün değildir; bunun yerine tüm bunların, yerel durum ve döngü sayaçlarını tutmak için nesne alanları kullanılarak manuel olarak simüle edilmesi gerekir.

Bu şekilde oluşturulan basit yineleyiciler bile, jeneratör kullananlara göre önemli ölçüde daha hantal olma eğilimindedir. Genelge kodu.

Yukarıdaki orijinal örnek şu şekilde yazılabilir: Java 5 gibi:

// Yineleyici anonim sınıf olarak uygulandı. Bu jenerik kullanır ancak buna gerek yoktur.için (int ben: yeni Tekrarlanabilir<Tamsayı>() {    @Override    halka açık Yineleyici<Tamsayı> yineleyici() {        dönüş yeni Yineleyici<Tamsayı>() {            int sayaç = 1;            @Override            halka açık Boole hasNext() {                dönüş sayaç <= 100;            }            @Override            halka açık Tamsayı Sonraki() {                dönüş sayaç++;            }            @Override            halka açık geçersiz Kaldır() {                atmak yeni Desteklenmeyen Operasyon İstisnası();            }        };    }}) {    Sistem.dışarı.println(ben);}

Sonsuz bir Fibonacci dizisi de yazılabilir Java 5 Yineleyici olarak:

Tekrarlanabilir<Tamsayı> fibo = yeni Tekrarlanabilir<Tamsayı>() {    @Override    halka açık Yineleyici<Tamsayı> yineleyici() {        dönüş yeni Yineleyici<Tamsayı>() {            int a = 1, b = 2;            @Override            halka açık Boole hasNext() {                dönüş doğru;            }            @Override            halka açık Tamsayı Sonraki() {                int temp = a;                a = b;                b = a + temp;                dönüş temp;            }            @Override            halka açık geçersiz Kaldır() {                atmak yeni Desteklenmeyen Operasyon İstisnası();            }        };    }};// bu daha sonra şu şekilde kullanılabilir ...için (int f: fibo) {    Sistem.dışarı.println("sonraki Fibonacci sayısı" + f);    Eğer (someCondition(f)) kırmak;}

Ayrıca sonsuz bir Fibonacci dizisi kullanılarak da yazılabilir. Java 8 Akış arayüzü:

Yayın İçi.oluşturmak(yeni IntSupplier() {    int a = 1, b = 2;    halka açık int getAsInt() {        int temp = a;        a = b;        b = a + temp;        dönüş temp;    }}).her biri için(Sistem.dışarı::println);

Veya bir Yineleyici edinin Java 8 süper arayüz BaseStream of Stream arayüzü.

halka açık Tekrarlanabilir<Tamsayı> fibonacci(int limit){    dönüş Yayın İçi.oluşturmak(yeni IntSupplier() {        int a = 1, b = 2;        halka açık int getAsInt() {            int temp = a;            a = b;            b = a + temp;            dönüş temp;        }    }).limit(limit).kutulu()::yineleyici;}// bu daha sonra şu şekilde kullanılabilir ...için (int f: fibonacci(10)) {    Sistem.dışarı.println(f);}

C #

Bir örnek C # 2.0 oluşturucu ( Yol ver C # sürüm 2.0'dan beri mevcuttur): Bu örneklerin her ikisi de jenerik kullanır, ancak bu gerekli değildir. getiri anahtar sözcüğü, bu tartışmada tartışıldığı gibi bir koleksiyon üzerinde özel durum bilgisi olan yinelemelerin uygulanmasına da yardımcı olur.[11]

// Yinelenebilir girdi alan yöntem (muhtemelen bir dizi)// ve tüm çift sayıları döndürür.halka açık statik IEnumerable<int> GetEven(IEnumerable<int> sayılar) {    her biri için (int ben içinde sayılar) {        Eğer ((ben % 2) == 0) {            Yol ver dönüş ben;        }    }}

Birden çok kullanmak mümkündür getiri getirisi ifadeler ve her yinelemede sırayla uygulanır:

halka açık sınıf CityCollection : IEnumerable<dizi> {    halka açık IEnumerator<dizi> GetEnumerator() {        Yol ver dönüş "New York";        Yol ver dönüş "Paris";        Yol ver dönüş "Londra";    }}

XL

İçinde XL, yineleyiciler 'for' döngülerinin temelidir:

import IO = XL.UI.CONSOLEiterator IntegerIterator (var out Counter: integer; Low, High: integer) Düşük'te yazılmış Sayaç: = Düşük, Sayaç <= Yüksek döngü verimi Sayaç + = 1 // Unutmayın ki I iteratörde 'var out' olarak bildirildiği için bildirilmesi gerekmez // Bu nedenle, burada I için 1..5 döngü IO.WriteLn "I =" için örtük bir tamsayı yapılır, I

F #

F # aracılığıyla jeneratörler sağlar dizi ifadeleri, 1.9.1 sürümünden beri.[12] Bunlar bir dizi (tembel değerlendirilmiş, sıralı erişim) aracılığıyla seq {...}, bir liste (hevesle değerlendirilmiş, sıralı erişim) aracılığıyla [ ... ] veya bir dizi (hevesle değerlendirilmiş, indekslenmiş erişim) aracılığıyla [| ... |] değerler üreten kod içeren. Örneğin,

sıra { için b içinde 0 .. 25 yapmak          Eğer b < 15 sonra              Yol ver b * b }

0'dan 25'e kadar sayılar aralığındaki sayıları filtreleyerek, 0'dan 14'e kadar bir sayı kareleri dizisi oluşturur.

Python

Jeneratörler eklendi Python 2001'de 2.2 sürümünde.[6] Örnek bir oluşturucu:

itibaren yazıyor ithalat Yineleyicidef sayı(n: int) -> Yineleyici[int]:    süre Doğru:        Yol ver n        n += 1# Örnek kullanım: 10'dan 20'ye kadar olan tam sayıları yazdırmak.# Bu yinelemenin normal şekilde sona erdiğini unutmayın.# countfrom () sonsuz bir döngü olarak yazılıyor.için ben içinde sayı(10):    Eğer ben <= 20:        Yazdır(ben)    Başka:        kırmak# Gerektiği gibi süresiz olarak asal sayılar üreten başka bir jeneratör.ithalat itertoolsdef asal() -> Yineleyici[int]:    Yol ver 2    n = 3    p = []    süre Doğru:        # N'yi p içindeki tüm sayılara bölersek, sqrt (n) dahil olmak üzere,        # sıfırdan farklı bir kalan üretir ve n asaldır.        Eğer herşey(n % f > 0 için f içinde itertools.takmak(lambda f: f*f <= n, p)):            Yol ver n            p.eklemek(n)        n += 2

Python'da bir jeneratör, bir yineleyici donmuş yığın çerçevesi. Her ne zaman Sonraki() yineleyicide çağrıldığında, Python donmuş çerçeveyi devam ettirir ve bir sonrakine kadar normal şekilde çalışır. Yol ver ifadesine ulaşıldı. Jeneratörün çerçevesi daha sonra tekrar dondurulur ve elde edilen değer arayana geri gönderilir.

PEP 380 (Python 3.3'te uygulanmıştır), verimi ifade, bir jeneratörün işlemlerinin bir bölümünü başka bir jeneratöre veya yinelenebilir olarak devretmesine izin verir.[13]

Jeneratör ifadeleri

Python, aşağıdaki gibi modellenmiş bir sözdizimine sahiptir: liste anlayışları, jeneratörlerin oluşturulmasına yardımcı olan bir üretici ifadesi olarak adlandırılır.Aşağıda, yukarıdaki ilk örneği, kareleri hesaplamak için bir üretici ifadesi kullanarak sayı jeneratör işlevi:

kareler = (n * n için n içinde sayı(2))için j içinde kareler:    Eğer j <= 20:        Yazdır(j)    Başka:        kırmak

ECMAScript

ECMAScript 6 (a.k.a. Harmony) jeneratör işlevlerini tanıttı.

Sonsuz bir Fibonacci dizisi, bir işlev oluşturucu kullanılarak yazılabilir:

işlevi* fibonacci(limit) {    İzin Vermek [önceki, akıntı] = [0, 1];    süre (!limit || akıntı <= limit) {        Yol ver akıntı;        [önceki, akıntı] = [akıntı, önceki + akıntı];    }}// üst limit 10 ile sınırlıiçin (sabit n nın-nin fibonacci(10)) {    konsol.günlük(n);}// üst sınır sınırı olmayan oluşturucuiçin (sabit n nın-nin fibonacci()) {    konsol.günlük(n);    Eğer (n > 10000) kırmak;}// manuel olarak yinelemeİzin Vermek fibGen = fibonacci();konsol.günlük(fibGen.Sonraki().değer); // 1konsol.günlük(fibGen.Sonraki().değer); // 1konsol.günlük(fibGen.Sonraki().değer); // 2konsol.günlük(fibGen.Sonraki().değer); // 3konsol.günlük(fibGen.Sonraki().değer); // 5konsol.günlük(fibGen.Sonraki().değer); // 8// durduğunuz yerden devam ediyoriçin (sabit n nın-nin fibGen) {    konsol.günlük(n);    Eğer (n > 10000) kırmak;}

R

Yineleyiciler paketi bu amaçla kullanılabilir.[14][15]

kütüphane(yineleyiciler)# Misal ------------------ABC <- tekrar(c('a','b','c'))nextElem(ABC)

Smalltalk

Örnek Pharo Smalltalk:

altın Oran Aşağıdaki jeneratör, her bir "goldenRatio next" çağrısına Altın Orana daha iyi bir yaklaşım getirir.

altın Oran := Jeneratör üzerinde: [ :g | | x y z r | 	x := 0.	y := 1.	[  		z := x + y.		r := (z / y) asFloat.		x := y.		y := z.		g Yol ver: r	] tekrar et	].altın Oran Sonraki.

Aşağıdaki ifade sonraki 10 yaklaşımı döndürür.

Karakter cr katılmak: ((1 to: 10) toplamak: [ :kukla | oran Sonraki ]).

Daha fazlasını görün Pharo: Generator'da gizli bir mücevher.

Ayrıca bakınız

  • Liste anlama bir dizi değer oluşturan başka bir yapı için
  • Yineleyici her seferinde bir öğe bir liste oluşturma kavramı için
  • Iteratee alternatif için
  • Tembel değerlendirme gerektiğinde değer üretmek için
  • Corecursion yerine özyinelemeyle potansiyel olarak sonsuz veriler için Yol ver
  • Korutin alt programdan daha fazla genelleme için
  • Devamı kontrol akışının genelleştirilmesi için

Notlar

  1. ^ Yineleyici ve Oluşturucu arasındaki fark nedir?
  2. ^ Kiselyov, Oleg (Ocak 2004). "Scheme'de koleksiyonları dolaşmanın genel yolları".
  3. ^ Anthony Ralston (2000). Bilgisayar bilimi ansiklopedisi. Nature Pub. Grup. ISBN  978-1-56159-248-7. Alındı 11 Mayıs 2013.
  4. ^ Simge Programlama Dili Amaca yönelik değerlendirmeyi uygulamak için üreticilerden yararlanır. Icon'da jeneratörler, normal döngü kontrol yapılarının dışındaki bağlamlarda çağrılabilir.
  5. ^ Liskov, Barbara (Nisan 1992). "Bir CLU Tarihi" (PDF). Arşivlenen orijinal (pdf) 2003-09-17 tarihinde. Alındı 2006-01-05.
  6. ^ a b Python Geliştirme Önerileri:PEP 255: Basit Jeneratörler,PEP 289: Üreteç İfadeleri,PEP 342: Gelişmiş Jeneratörler aracılığıyla Coroutinler
  7. ^ verim (C # Referansı)
  8. ^ Liskov, B .; Snyder, A .; Atkinson, R .; Schaffert, C. (1977). "CLU'da soyutlama mekanizmaları". ACM'nin iletişimi. 20 (8). CiteSeerX  10.1.1.112.656. doi:10.1145/359763.359789.
  9. ^ "C için Yapılandırılmış Eş Zamanlılık".
  10. ^ http://www.codeproject.com/KB/cpp/cpp_generators.aspx
  11. ^ "C # için kullanılan getiri anahtar kelimesi nedir?". stackoverflow.com. Alındı 2018-01-01.
  12. ^ "F # Hesaplama İfadeleriyle İlgili Bazı Ayrıntılar". Alındı 2007-12-14.
  13. ^ PEP 380 - Bir Alt Üreticiye Yetki Verme Sözdizimi
  14. ^ R'deki jeneratör fonksiyonları
  15. ^ http://cartesianfaith.wordpress.com/2013/01/05/infinite-generators-in-r/

Referanslar

  • Stephan Murer, Stephen Omohundro, David Stoutamire ve Clemens Szyperski: İterasyon soyutlaması Sather. Programlama Dilleri ve Sistemlerinde ACM İşlemleri, 18(1):1-15 (1996) [1]