2012-06-19 18 views
8

Kilka pytań tutaj, dotyczących letcc, które są używane w Przyprawionym Schemerze.Sezonowany Schemat, letcc i podstęp

(define (intersect-all sets) 
    (letcc hop 
    (letrec 
     ((A (lambda (sets) 
      (cond 
       ((null? (car sets)) (hop '()) 
       ((null? (cdr sets)) (car sets)) 
       (else 
       (intersect (car sets) 
          (A (cdr sets))))))) 
     ; definition of intersect removed for brevity 
     (cond 
     ((null? sets) '()) 
     (else (A sets)))))) 
  1. Chyba rozumiem, co letcc osiąga, a to jest po prostu coś catch i throw w Ruby (i pozornie CL), co w zasadzie oznacza cały blok kodu może być przerwana przez wywołanie cokolwiek nazywa się letcc. Wydaje mi się, że to najmniej "funkcjonalna" rzecz, którą spotkałem w tej krótkiej serii książek i sprawia, że ​​czuję się nieco niezdecydowana, aby z niej skorzystać, ponieważ chcę nauczyć się dobrego stylu funkcjonalnego. Czy po prostu nie rozumiem, że jest to letcc, czy też nie jest to funkcjonalna koncepcja programowania i istnieje tylko w celu poprawy wydajności? Cała idea, że ​​mogę być w trakcie rutyny, a następnie nagle dostać się do innego punktu w kodzie czuje się trochę źle ... jak nadużywanie próby/catch w Javie dla przepływu programu.

  2. letcc nie wydaje się istnieć w wersji guile (1.8.7) Zainstalowałem w OS X. Czy jest tam inna nazwa, której powinienem szukać w guile?

  3. Jeśli mam nieporozumienie letcc porównując ją z try/catch w Java lub połowu/rzucać w Ruby (co jest nie obsługa wyjątków, tak aby było jasne, dla non-Rubiego), jak dokładnie działa na poziomie funkcjonalnym? Czy można go wyrazić w dłuższej, bardziej złożonej formie, która przekonuje mnie, że mimo wszystko jest funkcjonalna?

+1

Jeśli masz implementację, która obsługuje zarówno "normalne" kontynuacje i kontynuację ucieczki, zwykle taniej jest używać tego ostatniego. Wzór w twoim przykładzie jest naturalnym dopasowaniem do kontynuacji ucieczki. Standardowy skrót to "let/ec". – soegaard

+0

FYI, [ta strona] (http://community.schemewiki.org/?seasoned-schemer) pokazuje, jak zdefiniować 'letcc' w kategoriach' call/cc' używając prostego makra. –

+0

@ JonO, czytałem to wcześniej i wypróbowałem, ale podstęp tylko mówi 'BŁĄD: nieprawidłowa składnia()' 'PRZERWA: (błąd pomyłki)'. Sprawdzone Zrobiłem to tak, jak mówi strona, ale nadal nie działa. Prawdopodobnie dowiem się dlaczego, kiedy dostaję się do nauki makr. – d11wtq

Odpowiedz

11
  1. „funkcjonalne” ma kilka znaczeń, ale nie popularne znaczenie sprzeczne kontynuacje w jakikolwiek sposób. Ale one mogą być nadużywane do tworzenia kodu, który jest trudny do odczytania. Nie są narzędziami, które mogą być "nadużywane do przepływu programu" - są one są narzędziami do programowania programu.

  2. Nie mogę ci tam pomóc. Wiem, że w Guile był pół-niedawny ciąg dalszy, ale nie wiem, gdzie się mają sprawy. Z pewnością powinien mieć wartość call-with-current-continuation, zwykle również pod bardziej przyjazną nazwą: call/cc, a let/cc to proste makro, które można zbudować przy użyciu call/cc.

    mogę powiedzieć, że rakieta jest let/cc wbudowane wraz z gronem others builtins w same family, a dodatkowo istnieje whole library różnych podmiotów kontrolnych (z obszernej listy referencji.).

  3. Proste zastosowania let/cc są w istocie podobne do chwytania/rzucania rzeczami - dokładniej, takie kontynuacje są powszechnie znane jako "kontynuacja ucieczki" (lub czasami "w górę"). Jest to rodzaj korzystania z tego kodu, który jest często używany do implementacji abort lub return.

    Ale kontynuacja w Scheme to rzeczy, które można wykorzystać w dowolnym miejscu.Przez bardzo prosty przykład, który pokazuje tę różnicę, spróbuj tego:

    (define (foo f) (f 100)) 
    (let/cc k (+ (foo k) "junk") (more junk)) 
    
  4. Wreszcie, jeśli chcesz dowiedzieć się więcej o kontynuacje można zobaczyć odpowiednie części PLAI, istnieje również bardziej brief by-example overview że Matthew Might napisał i możesz zobaczyć, że napisałem, że napisałem, że są oparte na PLAI, z kilkoma przykładami zainspirowanymi tym ostatnim postem.

+2

Wow, po przeczytaniu tego artykułu przez Matthew Right moja opinia się zmieniła. Myślę, że faktyczne zrozumienie, jak działa "call/cc" sprawia, że ​​wydaje się on o wiele czystszy, niż początkowo sądziłem. Ogromne dzięki za wyjaśnienie. Okazuje się, że moja wersja guile ma 'call/cc' i' call-with-current-continuation', ale bez 'letcc'. Także 'call/cc' jest o wiele bardziej interesujący niż' catch/throw' w ruby, ponieważ pozwala ci robić o wiele fajniejsze rzeczy. Przypuszczam, że The Seasoned Schemer przyjrzy się temu bardziej szczegółowo w późniejszych rozdziałach. – d11wtq

+0

Jeśli skończysz z jego tekstem, zapoznaj się również z notatkami z mojej klasy: jest kilka przykładów, które są znacznie bardziej rozbudowane, z kompletnym rozwojem generatorów i amb, a zaczyna się od opisu CPS - sposób wdrożenia niektórych z nich w innych językach. –

+4

I BTW, ma na imię Matthew Might. (Może mieć rację, ale ma na imię Might.) –