2015-06-25 9 views
13

Zacząłem kodowanie w F # około 2 miesięcy temu.F # Pytania dotyczące jakości życia

Jestem bardzo zadowolony z tego języka programowania. Pochodzę z tła C# i za każdym razem, gdy muszę wrócić do C#, czuję się tak nieporęczny i nadęty.

Ale nadal istnieją rzeczy, myślę, że są problematyczne w F #, a to, co moje pytania są związane z:

  1. Nie ma auto zakończyć jak VS ma prawo do C#? Na przykład. wewnątrz funkcji, która pobiera parametr aParameter, jeśli napiszę aPara, nie pojawi się auto complete. Czy w VS istnieje funkcjonalność, która może rozwiązać ten problem i którego nie znam?

  2. Debagowanie jest co najmniej uciążliwe. Ponieważ F # obsługuje orurowanie/łańcuchowanie lub cokolwiek chcesz nazwać, zazwyczaj staram się łączyć jak najwięcej rzeczy (tam, gdzie ma to sens oczywiście). Przykład:

    correctedData 
    |> List.filter (fun (_, r, _) -> r <= 3) 
    |> Seq.ofList 
    |> Seq.groupBy (fun (_, r, cti) -> (r,cti))        
    |> Seq.map (fun ((r,cti),xs) -> (r, cti, Seq.length xs)) 
    |> Seq.toList 
    

A to dopiero czwarta całego mojego łańcuchowych zrobić. Ilekroć coś robię w tych łańcuchach, bardzo trudno jest debugować, gdzie wszystko poszło nie tak.

Czy robię to źle łańcuchowo (nadużywanie)? Z mojego punktu widzenia nic pośredniczącego z tego łańcucha nie ma sensu egzystować atomowo, a zatem nie ma powodu, by mieć wartości pośredniczące. Ale z powodu tego semantycznego punktu widzenia tracę również moc posiadania wartości pośrednich, które pomagają mi w debugowaniu. Tak więc muszę wstawić je do kodu, debugować, a następnie usunąć ponownie. Ale to zmarnowany wysiłek. Czy jest jakiś sposób obejścia tego?

Ponadto debugowanie anonimowej funkcji List.map w łańcuchu wydaje się znowu niezręczne i trudne w porównaniu do np. pętla for.

Jestem pewna, że ​​czegoś mi brakuje i że mój obecny sposób debugowania prawdopodobnie nie jest optymalny - nie przez długie ujęcie - więc wszelkie sugestie są mile widziane.

+1

Oznacz swoje pytanie za pomocą edycji VS. Wydaje się, że dotyczy to Twojego pierwszego pytania: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2149735-improve-intellisense-support-for-f –

+2

Obawiam się, że nie tylko F # - obsługa debugowania zwykle nie jest zbyt dobra w przypadku języków funkcjonalnych. Zamiast tego jesteś zachęcany do budowania swojego kodu z małych kawałków, które możesz testować niezależnie - i interaktywnie. Koncentrujemy się przede wszystkim na poprawieniu go, a nie na naprawianiu problemów pojawiających się w debugerze. Dodaj nieco tajemniczych komunikatów o błędach, a wiele wzrostów wydajności zniknie bardzo szybko, jeśli nie będziesz ostrożny od samego początku. Twój przykład z łańcuchem stosuje się również do metody LINQ w C# - i znowu chodzi o upewnienie się, że * kawałki * działają. – Luaan

Odpowiedz

10

1. Nie ma auto kompletne jak VS ma dla C# prawej

Jest autouzupełnianie dla F #. Nie uruchamia się automatycznie po rozpoczęciu pisania. Jeśli jesteś w Visual Studio i wpisz aPara, a następnie naciśnij Ctrl + Przestrzeń, powinien on zostać automatycznie uzupełniony do aParameter, jeśli jest w zakresie. Podobnie możesz to zrobić w zasięgu najwyższego poziomu, aby zobaczyć dostępne typy i przestrzenie nazw. Automatyczne uzupełnianie się również wyzwalane automatycznie po wpisaniu .

2.Debugging jest żmudne co najmniej

bym się z tym zgodzić - debugowanie rurociągów (szczególnie leniwych sekwencji) jest trudne. To jest nieco mylące, nawet jeśli jesteś w C#, ale C# robi zaskakująco dobrą robotę na tym. Istnieją dwa sposoby radzenia sobie z tym:

  • Skorzystaj z F # Interactive więcej. Piszę większość mojego kodu w pliku F # Script, gdzie możesz uruchomić częściowo kompletne rozwiązania i natychmiast zobaczyć wyniki.Dla mnie to prawie zastępuje debugowanie, ponieważ do czasu, gdy mój kod jest kompletny, wiem, że to działa.

  • Można zdefiniować funkcję tap, która zmaterializuje dane w potoku i pozwala zobaczyć, co przechodzi przez potok. Nie używam tego bardzo dużo, ale wiem, że niektórzy ludzie lubią go:

    let tap data = 
        let materialized = List.ofSeq data 
        materialized 
    

    Następnie można użyć go w rurociągu:

    correctedData 
    |> List.filter (fun (_, r, _) -> r <= 3) 
    |> tap 
    |> Seq.groupBy (fun (_, r, cti) -> (r,cti))        
    |> tap 
    |> Seq.map (fun ((r,cti),xs) -> (r, cti, Seq.length xs)) 
    |> Seq.toList 
    

    to dodaje trochę hałasu do rurociągu, ale można go usunąć ponownie po zakończeniu debugowania.

7

Kwestia polepszania doświadczeń związanych z debugowaniem za pomocą F # ma wiele aspektów, więc zasługuje na duży artykuł. Obawiam się, że pytanie zostanie zamknięte.
Mam jednak dwie fajne sztuczki, których używam. Muszę zauważyć, że jestem także wielkim fanem podejścia opartego na potoku, więc mam dokładnie te same problemy.

Znasz swoje typy.

Posiadanie wartości przeplecionej przez łańcuch wielu przekształceń może szybko doprowadzić do trudności z zapamiętywaniem dokładnych typów na każdym kroku. Sztuką jest:

value 
|> transformation1 
|> fun x -> x 
|> transformation2 

ta umożliwia:

  1. zobaczyć dokładny typ x w czasie projektowania;
  2. ustaw punkt przełomowy (umieść kursor na ciele funkcji ) i zobacz wartość w czasie debugowania;
  3. Nawet jeśli zapomni się w kodzie po wykonaniu, pozostawia to minimalny ślad.

Warunkowo zrzuć wartości do konsoli.

Posiadanie skomplikowanej lambdas, breakpoints mogą być mało pomocne. Oto kolejna sztuczka związana z opisanym w odpowiedzi @Tomas': napisać mały funkcję tak:

let inline debug x = 
#if DEBUG 
    if System.Console.CapsLock then 
     printfn "%A" x 
     // obviously, it must not be necessarily printf; 
     // it can be System.Diagnostics.Debug.WriteLine() 
     // or any other logger tool that exists in the project. 
#endif 
    x 

Kod Wykorzystanie wygląda następująco:

value 
|> transformation1 
|> fun x -> x 
|> debug 
|> transformation2 

Chodzi o to, że:

  1. ustawiasz punkt przerwania tuż przed wywołaniem debug, tak jak opisano powyżej;
  2. przełączników Caps Lock na
  3. i Step Over lub po prostu pozwolić uruchomić aplikacji

Jeśli istnieje wiele miejsc, gdzie debug wezwanie siedzieć, nie byłoby zepsuć wyjście.

0

W przypadku debugowania |> potoków - spróbuj mieć osobisty standard kodowania, który nie zawiera więcej niż trzy, lub co najwyżej cztery, linii w takim potoku. Kiedy będą dłużej, refaktor. To jest to, co robię i to bardzo pomaga.