Racket - code-golf/code-golf GitHub Wiki

Basic Tips

  • Many tips from the Scheme and Common Lisp pages also apply to Racket. Racket is more closely related to Scheme.
    • Notably graph marks (#0=) cannot be used in Racket.
  • lambda can be abbreviated as λ. (Look out for byte/char count discrepancies in others' solutions as a hint for where they might be using lambdas!)
  • Lambdas allow default arguments, which can be used to bind extra variables. They can even refer to previous parameters, similar to let*: (λ(a[b(+ a 1)])b).
  • Using λ instead of let to bind variables usually saves, even for a single variable. (let([a 1])...) vs ((λ(a)...)1) saves 3 chars/2 bytes.
  • Look out for opportunities to use higher-order functions like curry and compose, which are usually shorter than lambdas.

Output

  • Each top-level form produces a line of output implicitly, unless it evaluates to void. Strings and symbols are quoted, but implicit output can sometimes be useful for numbers.
    • The best way to suppress unwanted implicit output is to crash the program before the top-level form is fully evaluated.
  • Use write/writeln to print numbers or symbols.
  • Use display/displayln to print strings.
  • Use printf to print formatted strings. The syntax is similar to Common Lisp format, but its functionality is much more limited.
  • The ~a function converts all its arguments to strings and concatenates them into a single string. It can sometimes be better to use ~a and pass the result to display instead of using printf.
  • The ~s function can print numbers separated by spaces.

Looping

  • The for macro family is good for looping over ranges of numbers, or over non-list sequences such as strings or byte strings. Sometimes they're the best option for lists too.
    • Printing 0 to 9: (for([n 10])(writeln n))
  • map, foldl, and other list-based functions are worth considering if you're working with a list.
  • do works exactly like in Scheme and Common Lisp, and is the most general looping macro.

Handling Arguments

Usually command-line is the best way to handle arguments:

(command-line #:args a(for([a a])(displayln a)))

However if the first argument begins with - or +, it causes an error, and you'll have to use current-command-line-arguments instead:

(for([a(current-command-line-arguments)])(displayln a))

Currently this is necessary on the Brainfuck and Proximity Grid holes.

Byte Strings

Byte strings are sequences of integers, but print as strings. They have a few uses:

  • #"..." byte string literals can hard-code a list of integers that can be iterated using a for macro.
  • Use bytes to convert an ASCII-range integer to a printable string, avoiding the long integer->char.
  • Regular expressions can be byte-based as well: #px#"..." This implicitly converts a string to a byte array when matching, which can be useful.