2015-06-25 11 views
13

Ho iniziato la codifica in F # circa 2 mesi fa.F # Domande sulla qualità della vita

Mi piace molto questo linguaggio di programmazione. Vengo da uno sfondo C#, e ogni volta che ho bisogno di tornare a C#, sembra così ingombrante e gonfio.

Ma ci sono ancora cose che penso sono problematici in F #, e questo è ciò che le mie domande sono relative a:

  1. Non si può auto completare come VS ha per C# giusto? Per esempio. all'interno di una funzione che prende parametro aParameter, se scrivo aPara non viene visualizzato il completamento automatico. Esiste una funzionalità in VS che può risolvere questo problema e di cui non sono a conoscenza?

  2. Il debugging è a dir poco noioso. Dato che F # supporta piping/concatenazione o qualsiasi altra cosa tu voglia chiamare, in genere cerco di concatenare quante più cose possibili (ovunque abbia senso, ovviamente). Esempio:

    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 
    

E questo è solo quarto di tutta la mia concatenamento fatto. Ogni volta che rovino qualcosa in queste catene, trovo molto difficile eseguire il debug dove tutto è andato storto.

Sto facendo questo concatenamento sbagliato (abusando di esso)? Dal mio punto di vista, nulla di intermedio da questo concatenamento ha senso esistere atomicamente, quindi non c'è ragione di avere valori intermedi. Ma a causa di questo punto di vista semantico, perdo anche il potere di avere valori intermedi che mi aiutano a fare il debug. Quindi devo inserirli nel codice, eseguire il debug e quindi rimuoverli di nuovo. Ma questo è uno sforzo inutile. C'è un modo per aggirare questo?

Inoltre, il debug di una funzione anonima di List.map all'interno di una catena risulta di nuovo scomoda e difficile rispetto ad es. un ciclo for.

Sono sicuro che mi manca qualcosa e che il mio attuale modo di eseguire il debug non è probabilmente ottimale, non da un punto lungo, quindi qualsiasi suggerimento è benvenuto.

+1

Contrassegna la tua domanda con VS edition, questa sembra riguardare la tua prima domanda: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2149735-improve-intellisense-support-for-f –

+2

Ho paura che non sia solo F # - il supporto per il debug di solito non è molto buono con i linguaggi funzionali. Invece, sei incoraggiato a costruire il tuo codice da piccoli pezzi che puoi testare in modo indipendente e interattivo. L'attenzione si concentra principalmente sul fatto di farlo bene in primo luogo, piuttosto che risolvere i problemi mentre emergono in un debugger. Aggiungi i messaggi di errore un po 'criptici e molti guadagni di produttività scompaiono molto rapidamente se non stai attento fin dall'inizio. Il tuo esempio con il concatenamento si applica anche all'approccio LINQ di C# e, ancora una volta, si tratta di assicurarsi che i * pezzi * funzionino. – Luaan

risposta

10

1.There è senza completamento automatico come VS ha per C# diritto

C'è completamento automatico per F #. Tuttavia, non viene attivato automaticamente quando si inizia a digitare. Se sei in Visual Studio e scrivie poi premi Ctrl + Spazio, dovrebbe essere completato automaticamente su aParameter se è incluso nell'oscilloscopio. Allo stesso modo, puoi farlo nell'ambito di alto livello per vedere tipi e spazi dei nomi disponibili. Completamento automatico anche ottenere attivato automaticamente quando si digita .

2.Debugging è noioso a dir poco

ero d'accordo con questo - debug gasdotti (in particolare con le sequenze pigri) è difficile. Questo è un po 'di confusione anche quando sei in C#, ma C# ha un lavoro sorprendentemente buono su questo. Ci sono due modi per affrontare questo:

  • Usa F # Interattiva altro. Scrivo la maggior parte del mio codice in un file F # Script, in cui è possibile eseguire le soluzioni parzialmente complete e vedere immediatamente i risultati.Per me, questo praticamente sostituisce il debug, perché quando il mio codice è completo, so che funziona.

  • È possibile definire una funzione tap che materializza i dati nella pipeline e consente di vedere cosa sta attraversando il tubo. Io non uso questo molto, ma so che alcune persone piace:

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

    Quindi è possibile utilizzare nel vostro cantiere:

    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 
    

    Questo aggiunge un po 'di rumore al gasdotto, ma si puoi rimuoverlo di nuovo una volta terminato il debug.

7

La domanda di migliorare l'esperienza di debug con F # ha molti aspetti quindi merita un grande articolo. Quindi temo che la domanda sarà chiusa.
Tuttavia, qui ci sono due trucchetti che sto usando. Devo notare che sono anche un grande fan dell'approccio alla pipeline e quindi affronterò esattamente gli stessi problemi.

Conosci i tuoi tipi.

Avere un valore inserito in una catena di molte trasformazioni può portare rapidamente alla difficoltà di ricordare i tipi esatti ad ogni passaggio. Il trucco è:

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

Questo consente di:

  1. vedere il tipo esatto di x in fase di progettazione;
  2. impostare un punto di interruzione (posizionare il cursore sul corpo della funzione ) e visualizzare il valore al momento del debug;
  3. Anche se dimenticato nel codice dopo il completamento, questo lascia un ingombro minimo.

Effettuare il dump dei valori sulla console.

Avendo complicato lambda, i punti di interruzione possono essere di scarso aiuto. Ecco ancora un altro trucco, correlato a quello descritto in risposta @Tomas': scrivere una piccola funzione, in questo modo:

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 

Il codice di utilizzo è simile al seguente:

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

L'idea è che:

  1. si imposta un punto di interruzione poco prima della chiamata debug, come descritto sopra;
  2. Caps interruttore di blocco sul
  3. e scavalcare o semplicemente lasciare che l'applicazione eseguita

Se si dispone di più luoghi in cui debug chiamata sedere, non avrebbero rovinare l'uscita.

0

Sul problema di debug |> pipeline - provare ad avere uno standard di codifica personale che non si dispone di più di tre o al massimo quattro righe in tale pipeline. Quando diventano più lunghi, refactoring. Questo è quello che faccio e aiuta molto.

Problemi correlati