Prosedür olarak uygulanmayan bir sürdürmenin örneği nedir?


15

Geri aramalar ve SO üzerinde devamları arasındaki ayrım hakkında ilginç bir tartışma bu soruyu gündeme getirmiştir . Tanım olarak, devam, bir hesaplamayı tamamlamak için gereken mantığın soyut bir temsilidir. Çoğu dilde bu, işlemeye devam edilmesi gereken değer ne olursa olsun geçtiğiniz tek bir argüman prosedürü olarak kendini gösterir.

Tamamen işlevsel bir dilde (tüm işlevlerin saf ve birinci sınıf vatandaşlar olduğu yerlerde), bir devamın tamamen bir işlev olarak modellenebileceğini düşünürdüm. Sonuçta, bu noktaya kadar devam eden süreçleri daha önce nasıl anladım. Bununla birlikte, dünya devletle doludur (iç çeker ..) ve bu yüzden genel tanım, bir devam yakalama programı devleti gerektirmez - sadece niyeti kapsaması gerekir.

Anlayışıma yardımcı olmak için, devam etmenin bir işlevden daha soyut bir şekilde ifade edildiği işlevsel bir dilde bir örnek verilebilir mi? Şema'nın mevcut devam etmeyi birinci sınıf bir şekilde yakalamanıza izin verdiğini biliyorum (çağrı / cc), ancak öyle olsa bile, çağrı / cc'ye iletilen bir argüman prosedürünün sadece geçerli devamını başka bir formda verildiği anlaşılıyor. call / cc'd işlevinin sonucunu uygulayabileceği bağımsız değişken yordamı.


Belki de devamların kesişmesi ve işlev bozukluğu şu şekildedir: süreklilikler işlev bozukluğu yoluyla veri yapılarına dönüştürülebilir; bakmak ilginç bir alan olabilir.
Dan D.

@DanD. okuyabileceğim ilginç edebiyat için önerileriniz var mı? Bu konu kulağa yararlı geliyor.
David Cowden

Yanıtlar:


11

tl; dr; Türü bir devamı boyunca kapsayıcı soyutlamasıdır


Devam, girdilerinin ve çıktılarının türüdür

Prosedür temelli olmayan bir sürüme bulacağınız en yakın şey , Haskell'deki devam monadının, kesme, devam ettirme, geri izleme vb.

Bu kapamayı ContHaskell'deki tür gibi, monad soyutlamasını "daha yüksek seviye bir soyutlama" olarak aldığınız bir tipte kapsülleyebilirsiniz ve sürekliliğe devam yerine bir tür olarak baktığınızda aldığınız süreler üzerinde başka soyutlama şekilleri de vardır . basitçe bir prosedür , örneğin

  • Tip yasaları bir olmak izliyorsa iki devamlılık almak ve aralarındaki alternatif yapabilirsiniz monoid
  • Kapamayı bir işlevin yasalarına uyan bir türde kapsüllerseniz, devamın giriş veya çıkış türlerini değiştirmek için türün üzerine yazabilirsiniz.
  • Sen keyfi ve kısmen uygulamak veya bir kanunlarını izleyen bir tip kapatma encapsulate eğer böyle onaylanmış veya giriş dönüşüm olarak işlevlerle devam süsleyebilirsiniz uygulamalı funktor

Kapanış ve Prosedür

Günün sonunda temel olarak haklısın; bir devam "prosedür" olsa da, bunu bir kapatma olarak adlandırmayı tercih ederim. Çoğu kez süreklilikler en iyi şekilde, bağlı bir ortamı içine alan birinci sınıf kapaklar olarak ifade edilir. Saf işlevsel bir dilde, bunun özellikle makul olmadığını söyleyebilirsiniz, çünkü referanslarınız yoktur; bu doğrudur ancak değerleri içine alabilir ve tekli atama, değeri ve referansı çevrelemekle aynı şeyi yapar. Bu Haskell'de ortaya çıkıyor:

(\x -> \y -> insideYIcanAccess x (and y))

Teknik olarak, birinci sınıf kapanışları olmayabilir bağlayıcı bir ortam içine yeteneğine sahip değildir, ancak daha sonra orada bir dil bir kapak kullanılabilir ortamı (genel olarak küresel).

Dolayısıyla, bir devamı şöyle tanımlamanın daha doğru olduğunu söyleyebilirim: Bir kapak belirli bir şekilde kullanılıyor.


Sonuç

"Devam, bir prosedür dışında herhangi bir şekilde uygulanabilir mi?" Hayır. Birinci sınıf işlevleriniz yoksa, gerçekten böyle devam edemezsiniz (evet işlev işaretçileri birinci sınıf işlevler olarak sayılır, bu nedenle alternatif olarak rasgele bellek erişimi yeterli olabilir).

Şimdi "Süreci bir prosedürden daha soyut bir şekilde ifade etmenin herhangi bir yolu var mı?" Bunu bir tür olarak ifade etmek size çok daha büyük bir soyutlama sağlar ve devam ile çok daha fazla şekilde etkileşimde bulunabilmeniz için devam etmeyi çok genel şekillerde ele almanızı sağlar.


1
Bu "devam, programın geri kalanının sonucunu almanıza izin veren herhangi bir şey olabilir" şeklinde genelleme yapar. Bu normalde bazı kodlara (programın geri kalanı) sahip olması gerektiğinden çoğu dil işlevleri kullanır. Teorik olarak her şeyden bir süreklilik inşa edebilirsiniz. Derleyicilerimin devamı sırasında kısmen doldurulmuş ağaçlar kullandım.
Daniel Gratzer

1
@jozefg kısmen doldurulmuş ağaçlar, bir hesaplamanın bir ifade olarak düzgün bir temsilidir, ancak günün sonunda, yazılmakta olan gerçek kod, anladığım gibi bir yordamdan tanımlanamayacak kadar farklı olmayan türlerin bir ifadesidir. Bunun yanı sıra, kısmen doldurulmuş ağaçlar derleyici temsilidir; geliştiricilerin temsili, dilin sözdizimi ve anlambilimi ile normatif olan bir hesaplama ifadesidir, bu da geliştiricilerin% 99'una "prosedür", "işlev" veya başka bir şekilde görünür. Derleyici geliştiricisinin perspektifinden düşünüyorsunuz
Jimmy Hoffa

2

Hoşunuza gidebilecek örneklerden biri koroutindir. Örneğin, Lua'dan gelen Coutinler veya Python veya C # 'dan gelen yineleyiciler / güçler, tek seferlik sürekliliklere (yalnızca bir kez çağırabildiğiniz süreklilikler) benzerdir, ancak devam açıkça bir işleve dönüştürülmez. Bunun yerine, koroutini bir sonraki "verim" ifadesine kadar ilerletme yollarınız vardır.

Örneğin, aşağıdaki Python programını göz önünde bulundurun:

def my_iterator():
   yield 1
   yield 2
   yield 3

def main():
   it = my_iterator()
   x = it.next()
   y = it.next()
   z = it.next()
   print x + y + z

Aşağıdaki Javascript programına benzer, açık geri çağrıları olan tür:

function my_iterator()
  return function(cb1){
    cb1(1, function(cb2){
      cb2(2, function(cb3){
        cb3(3, function(cb4){
          throw "stop iteration";
        });
      });
    });
  });
}

function main(){
   var getNext1 = my_iterator();
   getNext1(function(x, getNext2){
      getNext2(function(y, getNext3){
         getNext3(function(z, getNext4){
            console.log(x + y + z);
         });
      });
   });
}

Javascript örneği biraz gürültülüdür, çünkü her adımın verilen değeri döndürmeye ek olarak bir sonraki devamı geri döndürmesi gerekir (Python'da ite içindeki sürekliliği izler

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.