Come denominare la funzione annidata? [chiuso]

3

Quando hai una funzione che ne avvolge un'altra in Scala. Come si chiama la funzione nidificata?

Ho trovato questo:

def factorial(i: Int): Int = {

  def fact(i: Int, accumulator: Int): Int = {
     if (i <= 1)
        accumulator
     else
        fact(i - 1, i * accumulator)
  }

  fact(i, 1)

}

Di solito uso solo do perché è più corto, generico ed esplicito. Ma esiste un modo migliore o una convenzione di denominazione per le funzioni annidate?

def myFunction() = {

  def do(i: Int) = {
    ...
  }
  do(1)

}
    
posta user34903 10.09.2013 - 16:17
fonte

2 risposte

2

Non c'è bisogno di una convenzione. Le funzioni locali non sono esposte al resto del codice, quindi niente a cui nessun altro scriverà sarà interessato. Dico scegli qualcosa che abbia un senso nel contesto, piuttosto che preoccuparti di una convenzione che può funzionare bene in un posto, non in un altro.

Ecco un'implementazione di Fibonacci ricorsiva di coda:

def fib (n: Long): Long = {
  def loop(current: Long, next: => Long, iteration: Long): Long = {
    if (n == iteration) 
      current
    else
      loop(next, current + next, iteration + 1)
  }
  loop(0, 1, 0)
}

Avrei potuto chiamarlo fibloop , ma non penso davvero che aggiunga qualcosa. Non è accessibile da nessun'altra parte, quindi perché preoccuparsi di "namespacing"? Forse chiamarlo forwardloop potrebbe essere più chiaro, ma non fibloop . Se possibile, chiamandolo loop sottolinea che è locale.

Se i tuoi metodi / funzioni sono così lunghi che hai dimenticato dove è stata definita una funzione helper / local dal momento in cui la vedi, potrei vedere la necessità di una convenzione di denominazione (anche se la funzione è chiamata così per chiarire il suo scopo, quanto spesso avrà importanza?). Personalmente, cerco di evitare di scrivere qualcosa che sia prolisso, ma se lo fai, ti suggerisco di salvare convenzioni speciali per quei metodi in cui questo diventa effettivamente un problema. Anche allora, scommetto che un nome ben scelto sarà più utile di qualsiasi numero di underscore.

Se un metodo è abbastanza sintetico, (e anche la funzione locale è semplice) Confesso che a volte uso una funzione letterale solo per evitare di dovermi preoccupare del nome.

Ora, potresti contrastare che il prefisso delle funzioni locali con un trattino basso eviti definitivamente la possibilità di ombreggiare una funzione esterna. A cui vorrei rispondere chiedendo cosa succede se si ha una funzione locale all'interno di un'altra funzione locale? Utilizzare due caratteri di sottolineatura? Se riorganizzi il tuo codice, quante ricerche e sostituzioni sei disposto a fare, per inseguire questo problema che hai creato personalmente?

    
risposta data 10.09.2013 - 23:52
fonte
2

Una convenzione che ho visto in alcuni altri linguaggi consiste nell'utilizzare un carattere di sottolineazione iniziale o finale per una funzione privata, denominata temporanea, che esiste puramente come un dettaglio di implementazione:

def factorial(i : Int): Int = {
  def _factorial(i : Int, acc : Int): Int = {
    ...
  }
  _factorial(i)
}

Non credo che ci sia uno standard ufficiale in questo caso. Basta chiamarlo fact o factorialImplementation o qualcosa dovrebbe andare bene.

A proposito di fattoriale, presumo che questo sia stato fatto per il bene dell'apprendimento, giusto? Perché ci sono un numero di modi più brevi e potenzialmente più facili da mantenere per ottenere gli stessi risultati. Mi piace l'implementazione che utilizza reduceLeft (o foldl1 se provieni da Haskell-land):

Stream.from(1).take(n).reduceLeft(_*_)
    
risposta data 10.09.2013 - 16:24
fonte

Leggi altre domande sui tag