Playful Introduction to Racket

Playful Introduction to Racket

;; This is a playful introduction to Racket, using the in-built app
;; Dr. Racket, intended for a <60 min session.

;; Racket is a polygot-friendly, language designer friendly, beginner friendly
;; multi-paradigm general purpose programming language.

;; Install Racket and then open this little tutorial using Dr. Racket, by
;; saving it as a "racket_quick_intro.rkt" text file.
;; Download link for Racket: https://download.racket-lang.org

;; 1. Introduction

;; Dr. Racket is a multi-language IDE for Racket.
;; You can use Racket to make your own language or sub-language and then set
;; that as the language with a similar #lang invocation as below:

#lang racket

;; Racket and Dr. Racket excel as a language laboratory.

;; As a basic tour of this environment, let's try to write a simple prime
;; number checker.

;; Also, let's decide to test our code using an external package called
;; "quickcheck". To install this package, `raco pkg install quickcheck`, or
;; go to File > Package Manager... and install.
(require (prefix-in qc: quickcheck))

;; 2. Basic Code

;; General notes about discovering documentation:
;; - try hovering over names; they show where their bound occurences happen,
;;   or from where an occurence was bound
;; - for each unfamiliar name, try right clicking and searching it in the
;;   help desk.

(define (prime? x)
  (let* ([maxCandidate (exact-round (sqrt x))]
        [rangeCandidates (range 2 (+ maxCandidate 1))]
        [divisor? (lambda (y)
                    (= 0 (modulo x y)))]
        [divisors (filter divisor? rangeCandidates)])
    (if (= x 1)
        #f
        (empty? divisors))))

;; 3. Basic Tests

;; Let's explore how we'll test our code.

;; `quickcheck` is one of a category of "property based testing" libraries;
;; others are Haskell's quickcheck (of which this is a port), Python's
;; hypothesis, and probably many others.

;; We define a property to be checked. Maybe think of it as a predicate
;; of sorts.
(define prime?-returns-boolean
  (qc:property ([someNumber qc:arbitrary-natural])
               (boolean? (prime? someNumber))))

;; Here, we ask quickcheck to generate random values (we defined the values to
;; be provided as qc:arbitrary-natural) and test whether our property is really
;; true.

;; To run the check, run the quoted code in the REPL.
(quote (qc:quickcheck prime?-returns-boolean))
;; You'll note that when you hit run, the above line is printed in the REPL, so
;; you can copy and run it from there.

;; Let's test another couple of basic things.

(define prime?-is-correct-for-first-10-primes
  (qc:property ([someNumber (qc:choose-one-of (list 2 3 5 7 11 13 17 19 23 29))])
               (equal? (prime? someNumber) #t)))

(define prime?-is-correct-for-10-non-primes
  (qc:property ([someNumber (qc:choose-one-of (list 1 4 6 8 10 12 14 15 16 18 20))])
               (equal? (prime? someNumber) #f)))

;; To run the checks, run the quoted code in the REPL.
(quote (qc:quickcheck prime?-is-correct-for-first-10-primes))
(quote (qc:quickcheck prime?-is-correct-for-10-non-primes))


;; Recap

;; We got introduced to Racket and Dr. Racket, learned how to write some code
;; and test it, and learned how to explore documentation and install external
;; packages.


;; Next Steps?


;; Some fun options to choose your own adventure:

;; - module languages -- create you own language!
;;   (https://docs.racket-lang.org/guide/languages.html)

;; - racklog -- Racket's take on logic programming
;;   (https://docs.racket-lang.org/racklog/)

;; - typed/racket -- Racket's typed sister language
;;   (https://docs.racket-lang.org/ts-guide/)

;; Self plug: kilotau.com.

Direct link to the gist.