Conseils pour jouer au golf en raquette / schéma


15

Quels conseils généraux avez-vous pour jouer au golf en raquette / schéma ? Je recherche des idées qui peuvent être appliquées aux problèmes de golf de code en général qui sont au moins quelque peu spécifiques à Racket / Scheme (par exemple, "supprimer les commentaires" n'est pas une réponse).


Je suis conscient que Scheme et Racket (anciennement PLT Scheme) sont des langages techniquement différents mais sont assez similaires à bien des égards et beaucoup de code (je suppose) fonctionnera principalement comme prévu dans les deux. Si votre conseil ne s'applique qu'à l'une des langues susmentionnées, notez-le en tant que tel.

Réponses:


3

Les expressions 'x, `x, ,x, une ,@xexpansion automatiquement (quote x), (quasiquote x), (unquote x)et (unquote-splicing x), respectivement. Il s'agit uniquement d'une transformation syntaxique et peut être appliquée n'importe où. Cela donne une notation pratique pour les fonctions à une variable:

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

qui s'étend à

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

Je ne sais pas quelle sémantique pour observer un mot-clé syntaxique tel que quoteou quasiquoteavec une variable liée, bien que du code comme celui-ci ait fonctionné dans les interprètes sur lesquels je l'ai testé, et unquote-splicingsoit loin d'être idéal car il a une abréviation à deux caractères, mais unquoteest une syntaxe auxiliaire avec une abréviation à un caractère et est donc idéale pour ce hack.


8

Dans Racket , λet lambdasont des mots clés synonymes pour la construction de fonctions anonymes, mais λest de 2 octets où lambdaest 6.

Dans Scheme , il n'y a pas un tel mot λ- clé et vous êtes coincé avec lambda.


6

Utilisez ~apour convertir des nombres et des symboles en chaînes.


5

Lorsque vous utilisez Racket , liez les variables à l'aide de λpour raser quelques octets. Dans Scheme , lambdarend cette astuce non applicable, à moins que l'on lie quatre variables ou plus.

Exemple: une variable enregistre 2 octets sur let/define

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

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

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

Je n'appellerais pas cela contraignant. Vous utilisez différentes fonctions. Dans certains cas, l'utilisation d'une fonction anonyme est plus courte que la liaison d'une variable.
Michael Vehrs

Je ne sais pas ce que votre opinion a à voir avec la terminologie typique utilisée dans les cercles de schéma. Je peux vous assurer que les deux façons lient les variables à une portée lexicale et sont souvent implémentées en termes de . letlambda
Winny

5

Dans Racket , les requireformulaires peuvent avoir plusieurs arguments.

(require net/url net/uri-codec)

Est bien plus court que

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

Je ne sais pas grand chose sur Scheme , mais il ne semble pas avoir de fonction requireintégrée.


5

Utilisez des synonymes plus courts

Il y a un certain nombre de procédures dans Racket qui ont des versions plus courtes pour la plupart équivalentes. (Ils ne sont généralement pas équivalents: par exemple, (car (cons 1 2))fonctionne là où (first (cons 1 2))échoue. Mais vous pouvez effectuer la substitution si vous savez que ce sont des synonymes dans votre cas.)

Cette liste est probablement incomplète: je ne connais probablement pas encore la plupart des choses qui pourraient y figurer.

  • (= a b)au lieu de (equal? a b)comparer les nombres.
  • '(1 2)au lieu de (list 1 2).
  • car, cadr, cdrPour first, secondet rest.
  • null? au lieu de empty?
  • moduloau lieu de remainderquand le module est positif.
  • floorau lieu de truncatequand son argument est positif.

4

Omettre les espaces inutiles

Cela peut être considéré comme un conseil "trivial", mais il faut le signaler quelque part.

Chaque fois que vous lisez du code Racket écrit par des gens normaux (par exemple dans la documentation de Racket ), tous les espaces sont insérés: par exemple,

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

En fait, puisque (et )ne pouvant pas faire partie des noms de variables, nous pouvons supprimer tous les espaces autour d'eux et ne perdre aucune ambiguïté (et, plus important encore, obtenir toujours du code valide). Ainsi, l'expression ci-dessus peut être à la place:

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

2

Les conseils suivants concernent la raquette :

Arguments par défaut

Particulièrement utile pour créer des alias pour les noms de fonction longs qui sont souvent utilisés.

Supposons que le golf vous permet d'écrire une fonction qui consomme l'argument et supposez que vous devez en utiliser reversebeaucoup. Vous commencerez par quelque chose comme:

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

Vous pouvez à la place prendre un argument supplémentaire, avec un nom plus court que reverse, et définir sa valeur par défaut sur reverse:

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

De plus, c'est utile si vous avez une fonction d'assistance que vous utilisez à de nombreux endroits avec certains des mêmes arguments. N'oubliez pas de réorganiser les arguments de la fonction selon vos besoins, afin de pouvoir utiliser autant d'arguments par défaut que possible et de supprimer les arguments de plusieurs appels.

match

Celui-ci est un peu plus difficile à résumer dans un petit post, alors lisez les documents de raquette pour celui-ci. En bref, matchvous permet d'extraire des éléments et des séquences d'éléments dans un certain ordre à partir d'une liste, et la syntaxe de quasiquote vous permet de recoudre la liste mutilée ensemble:

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

Il vous donne également un moyen facile de travailler avec des expressions régulières et d'effectuer des calculs supplémentaires sur les groupes résultants par la suite,

Nommé let

Voir la syntaxe nommée ici .let proc-id ...

Cela vous permet d'écrire des fonctions récursives qui sont appelées immédiatement sans defineou réellement appeler la fonction après l'avoir définie.

Quelque chose comme:

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

peut être raccourci à:

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


Ce dernier est idiot, mais je n'ai pas pu utiliser ce petit truc jusqu'ici:
(apply map list matrix)prend une transposition de matrix, où matrixest une liste rectangulaire de listes, comme '((1 2 3) (a b c)).
Faites-moi savoir si cela s'avère utile.


1

Comme l'a souligné Winny , #!peut généralement être utilisé à la place de #lang, économisant quatre octets.

#lang racket ;12 bytes
#!racket ;8 bytes
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.