Skip to content

Instantly share code, notes, and snippets.

Created January 2, 2019 23:11
Show Gist options
  • Save gnarmis/30d9a2519f908fe13c6afd8f4a91e1e5 to your computer and use it in GitHub Desktop.
Save gnarmis/30d9a2519f908fe13c6afd8f4a91e1e5 to your computer and use it in GitHub Desktop.
A playful introduction to Racket (<60 min activity), with example usage of quickcheck (property based testing)
;; 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:
;; 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)
(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!
;; (
;; - racklog -- Racket's take on logic programming
;; (
;; - typed/racket -- Racket's typed sister language
;; (
;; Self plug:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment