Suggerimenti per giocare a golf in Racket / Scheme


15

Quali consigli generali hai per giocare a golf in Racket / Scheme ? Sto cercando idee che possano essere applicate ai problemi del codice golf in generale che siano almeno in qualche modo specifiche per Racket / Scheme (ad esempio "rimuovere i commenti" non è una risposta).


Sono consapevole che Scheme e Racket (precedentemente PLT Scheme) sono linguaggi tecnicamente diversi ma sono abbastanza simili in molti modi e molto codice (sospetto) verrà eseguito principalmente come previsto in entrambi. Se il tuo suggerimento si applica solo a una delle lingue sopra menzionate, nota come tale.

Risposte:


3

Le espressioni 'x, `x, ,x, un ,@xespandono automaticamente (quote x), (quasiquote x), (unquote x), e (unquote-splicing x), rispettivamente. Questa è puramente una trasformazione sintattica e può essere applicata ovunque. Ciò fornisce una nota utile per le funzioni a una variabile:

; Defining a function:
(define ,x (+ x x))
; Calling a function:
(display ,2)

che si espande a

; Defining a function:
(define (unquote x) (+ x x))
; Calling a function:
(display (unquote 2))

Non sono sicuro di quale sia la semantica per l'ombra di una parola chiave sintattica come quoteo quasiquotecon una variabile associata, anche se un codice come quello sopra ha funzionato negli interpreti su cui l'ho provato, ed unquote-splicingè tutt'altro che ideale poiché ha un'abbreviazione di due caratteri, ma unquoteè una sintassi ausiliaria con un'abbreviazione di un carattere ed è quindi ideale per questo hack.


8

In Racket , λe lambdasono parole chiave sinonimo per la costruzione di funzioni anonime, ma λè di 2 byte, dove lambdaè 6.

In Scheme , non esiste una parola chiave del genere λe sei bloccato lambda.


6

Utilizzare ~aper convertire numeri e simboli in stringhe.


5

Quando si usa la racchetta , associare le variabili usando λper radere alcuni byte. In Scheme , lambdaquesto trucco non è applicabile, a meno che uno non stia vincolando quattro o più variabili.

Esempio: una variabile salva 2 byte su let/define

(define n 55)(* n n) ; 20 bytes

(let([n 55])(* n n)) ; 20 bytes

((λ(n)(* n n))55) ; 18 bytes

Non lo definirei vincolante. Stai utilizzando diverse funzioni. In alcuni casi, l'utilizzo di una funzione anonima è più breve rispetto all'associazione di una variabile.
Michael Vehrs,

Non sono sicuro di cosa abbia a che fare la tua opinione con la terminologia tipica utilizzata nei circoli degli schemi. Vi posso assicurare che entrambi i modi sono vincolanti per le variabili in un ambito lessicale e spesso sono implementati in termini di . letlambda
Winny,

5

In Racket , i requiremoduli possono avere più argomenti.

(require net/url net/uri-codec)

È molto più breve di

(require net/url)(require net/uri-codec)

Non so molto su Scheme , ma non sembra avere un requirebuiltin.


5

Usa sinonimi più brevi

C'è una serie di procedure in Racket che hanno versioni più brevi equivalenti. (Di solito non sono equivalenti: ad esempio, (car (cons 1 2))funziona dove (first (cons 1 2))fallisce. Ma puoi fare la sostituzione se sai che sono sinonimi nel tuo caso.)

Questo elenco è probabilmente incompleto: probabilmente non conosco ancora la maggior parte delle cose che potrebbero essere incluse in questo elenco.

  • (= a b)invece di (equal? a b)confrontare i numeri.
  • '(1 2)invece di (list 1 2).
  • car, cadr, cdrPer first, seconde rest.
  • null? invece di empty?
  • moduloinvece di remainderquando il modulo è positivo.
  • floorinvece di truncatequando il suo argomento è positivo.

4

Ometti spazi inutili

Questo può essere considerato un suggerimento "banale", ma deve essere sottolineato da qualche parte.

Ogni volta che leggi il codice della racchetta scritto da persone normali (ad es. Nella documentazione della racchetta ), verranno inseriti tutti gli spazi: ad esempio,

(append (list 1 2) (list 3 4) (list 5 6) (list 7 8))

Infatti, poiché (e )non possono far parte dei nomi delle variabili, possiamo eliminare tutti gli spazi circostanti e non perdere alcuna ambiguità (e, cosa ancora più importante, ottenere comunque un codice valido). Quindi l'espressione sopra può invece essere:

(append(list 1 2)(list 3 4)(list 5 6)(list 7 8))

2

I seguenti suggerimenti sono per la racchetta :

Argomenti predefiniti

Particolarmente utile per la creazione di alias per nomi di funzioni lunghe che vengono spesso utilizzati.

Supponiamo che il golf ti permetta di scrivere una funzione che consuma l'argomento e supponi che devi usare reversemolto. Inizierai con qualcosa come:

(λ(x) ... reverse ... reverse ... reverse ...

Puoi invece prendere un argomento aggiuntivo, con un nome più breve di reverse, e impostare il suo valore predefinito su reverse:

(λ(x[r reverse]) ... r ... r ... r ...

Inoltre, è utile se si dispone di una funzione di supporto che si utilizza in molti punti con alcuni degli stessi argomenti. Ricordare di riordinare gli argomenti nella funzione secondo necessità, in modo da poter utilizzare quanti più argomenti predefiniti possibili e rimuovere gli argomenti da più siti di chiamata.

match

Questo è un po 'più difficile da riassumere in un piccolo post, quindi leggi i documenti di Racket per questo. In poche parole, matchconsente di estrarre elementi e sequenze di elementi in un certo ordine da un elenco e la sintassi quasiquote consente di ricucire insieme l'elenco mutilato:

(match (range 10)
 [`(,xs ... 3 ,ys ... 6 ,zs ...)
  `(,@(map f xs) 3 ,@(map f ys) 6 ,@(map f sz))]
 ...

Ti offre anche un modo semplice per lavorare con le espressioni regolari e successivamente eseguire ulteriori calcoli sui gruppi risultanti,

Di nome let

Vedi la sintassi denominata qui .let proc-id ...

Ciò consente di scrivere funzioni ricorsive che vengono chiamate immediatamente senza defineo effettivamente chiamare la funzione dopo averla definita.

Qualcosa di simile a:

(define (fib i)
  (if (< i 2) i
      (+ (fib (- i 1)) (fib (- i 2)))))
(fib 10)

può essere abbreviato in:

(let fib {[i 10]}
  (if (< i 2) i
      (+ (fib (- i 1)) (fib (- i 2)))))


Quest'ultimo è sciocco, ma finora non sono stato in grado di usare questo piccolo trucco:
(apply map list matrix)prende una trasposizione matrix, dove matrixc'è un elenco rettangolare di elenchi, come '((1 2 3) (a b c)).
Fammi sapere se questo si rivela utile.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.