Evita i condizionali
K ha un costrutto condizionale ( :[
) che equivale a uno stile Lisp cond
:
:[cond1;result1; cond2;result2; cond3;result3; default]
Puoi avere tutte le condizioni che desideri e se nessuna corrisponde al valore predefinito viene restituito.
A volte (come nei programmi ricorsivi o programmi che altrimenti si basano su una sequenza di effetti collaterali), non è possibile muoversi usando uno di questi. Tuttavia, in situazioni in cui puoi permetterti di fare un po 'di lavoro extra, puoi spesso sostituire un "cond" con l'indicizzazione dell'elenco.
Considera il famigerato programma Fizzbuzz . Scritto in uno stile di programmazione imperativo convenzionale, potremmo andare con:
{:[~x!15;"FizzBuzz";~x!3;"Fizz";~x!5;"Buzz";x]}'1+!100
C'è un po 'di ripetizione qui nei test di divisibilità. Un approccio diverso riconosce che ci sono 4 casi (un numero, divisibilità per solo 3, divisibilità per solo 5, divisibilità per 3 e 5) e tenta di calcolare direttamente un indice che sceglie uno di questi casi da un elenco:
{(x;"Fizz";"Buzz";"FizzBuzz")@+/1 2*~x!/:3 5}'1+!100
Due caratteri più brevi e un migliore utilizzo della lingua. Sapendo che i valori letterali dell'elenco vengono valutati da destra a sinistra, otteniamo anche ulteriori opportunità di golf per combinare sottoespressioni riutilizzate. Non avremmo potuto farlo facilmente nella versione basata su cond, poiché i casi di stringhe non vengono affatto valutati se non sono selezionati:
{(x;4#t;4_ t;t:"FizzBuzz")@+/1 2*~x!/:3 5}'1+!100
Ora abbiamo salvato 5 caratteri in totale. Per inciso, questo esempio particolare funziona ancora meglio in k5, dal momento che abbiamo il sovraccarico "pack" per /
gestire la fase di moltiplicazione per un vettore di coefficienti e somma:
{(x;4_t;4#t;t:"FizzBuzz")@2 2/~3 5!\:x}'1+!100
Si noti inoltre che il comportamento di "find" ( ?
), che produce un indice oltre la fine dell'elenco di chiavi se l'elemento non viene trovato, è specificamente progettato per supportare la gestione di un caso "predefinito" in questo tipo di indicizzazione. Considera questo frammento per convertire le vocali in maiuscolo:
{("AEIOU",x)"aeiou"?x}'
Contro uno di:
{t:"aeiou"?x;:[t<5;"AEIOU"t;x]}'
{:[~4<t:"aeiou"?x;"AEIOU"t;x]}'
(So che preferirei leggere anche io!)