2014-07-16 11 views
10

Zauważyłem, że następujący kod kompiluje i działa w VS 2013:Dlaczego "do" jest dozwolone w funkcji?

let f() = 
    do Console.WriteLine(41) 
    42 

Ale patrząc na specyfikację F # 3.0 nie mogę znaleźć żadnej wzmianki do wykorzystywane w ten sposób. O ile mogę powiedzieć, do mogą mieć następujących zastosowań:

  • W ramach pętli (np while expr do expr done), to nie w tym przypadku.
  • Wewnątrz wyrażeń obliczeniowych, np .:

    seq { 
        for i in 1..2 do 
        do Console.WriteLine(i) 
        yield i * 2 
    } 
    

    To nie o to chodzi tutaj zarówno, f nie zawiera żadnych wyrażeń obliczeniowych.

    Mimo wszystko co mnie tu mylą to, że zgodnie ze specyfikacją, do powinno następować po in. Ten in powinien być opcjonalny ze względu na lekką składnię, ale dodanie go tutaj powoduje błąd kompilacji ("nieoczekiwany token" w wyrażeniu "lub niekompletny").

  • Oświadczenie w module lub klasie. Tak też nie jest w tym przypadku, do znajduje się wewnątrz funkcji, a nie wewnątrz modułu lub klasy.

Zauważyłem również, że z #light "off", kod nie kompiluje („Nieoczekiwane słowa kluczowego«do»wiązania”), ale nie znaleźliśmy niczego, co mogłoby wyjaśnić to w sekcji lekkiej składni albo .

Bazując na tym wszystkim, zakładam, że używanie funkcji do wewnątrz funkcji w ten sposób nie powinno się kompilować, ale działa. Czy tęskniłem za czymś w specyfikacji? Czy jest to rzeczywiście błąd w kompilatorze lub w specyfikacji?

+2

To się nazywa wiązanie 'do'. Nie mogłem go znaleźć w specyfikacji, ale jest to [udokumentowane w MSDN] (http://msdn.microsoft.com/en-us/library/dd393786.aspx). – Daniel

+0

@Daniel Trzeci przypadek, o którym wspomniałem, "wykonaj" wewnątrz modułu. "Użyj a do wiązania, jeśli chcesz wykonać kod * niezależnie od funkcji *" – svick

+1

Aby zakończyć cytat: _ niezależnie od funkcji * lub definicji wartości * ._ Drugi przypadek może mieć zastosowanie w funkcji. – Daniel

Odpowiedz

7

Z documentation on MSDN:

do wiązania służy do wykonywania kodu bez definiowania funkcji lub wartości.

Mimo że specyfikacja nie zawiera obszernej listy dozwolonych miejsc, jest to jedynie wyrażenie o typie unit. Niektóre przykłady:

if ((do()); true) then() 
let x: unit = do() 

Jest na ogół pomijany. Każdy z powyższych przykładów jest ważny bez do. Dlatego do służy tylko do twierdzenie,, że wyrażenie jest typu unit.

+0

Myślę, że specyfikacja nie pozwala na to, ponieważ nie jest wymieniony jako jeden z wyborów 'expr' (§6 i §A.2.3). – svick

+0

W ciągu ostatnich kilku lat widziałem wiele przykładów "do" używanych w funkcji lub metody. Jeśli takie zachowanie nie jest zamierzone, jest ono faktycznie ważne w tym momencie. Uważam jednak, że tak nie jest i specyfikacja jest niepełna w tym punkcie. – Daniel

0

Przechodzi składni F# 3.0 specification ekspresyjnych do expr jako wybór class-function-or-value-defn (typy) [CH 8, A.2.5] i module-function-or-value-defn (moduły) [CH 10 A.2.1.1].

Nie widzę w specyfikacji, gdzie function-defn może mieć więcej niż jedno wyrażenie, tak długo, jak wszystkie ostatnie, ale ostatnie oceniają na unit - lub że wszystkie oprócz ostatniego wyrażenia są ignorowane przy określaniu funkcji zwracanej wartości.

Wydaje się, że jest to niedopatrzenie w dokumentacji.

+0

"Nie widzę w specyfikacji, gdzie' funkcja-defn' może mieć więcej niż jedno wyrażenie "To dzięki" expr = wyrażenie; reguła expr' i fakt, że lekka składnia sprawia, że ​​średnik jest opcjonalny. – svick

Powiązane problemy