Skip to content

Instantly share code, notes, and snippets.

@kmicinski
Created January 22, 2025 00:16
Show Gist options
  • Save kmicinski/be61a5ff5f11349b5189a516a2c18645 to your computer and use it in GitHub Desktop.
Save kmicinski/be61a5ff5f11349b5189a516a2c18645 to your computer and use it in GitHub Desktop.
#lang racket
;; 0 argument function which calls itself
;; (with zero arguments...)
(define (loop) (loop))
(if #t 42 (loop))
;; if cannot be a function, because if it were,
;; it would have to evaluate all of its arguments
;; until they were values
;;
;; what's value? A value is a primitively
;; representable thing held by the language.
;; (In other words, something you can return
;; from a function)
;; what does this function do?
;; first: - and + are both functions
(define (foo x) (if (< x 0) - +))
((foo 0) 1 2)
;; Let's say we wrapped if in a function
(define (my-if e0 e1 e2) (if e0 e1 e2))
;; because we call my-if as a function
;; we force the evaluation of each argument
;; to a value -- in the case of an infinite
;; loop, this cases the whole expression to
;; diverge (not terminate).
(define (foo-again x) (my-if (< x 0) - (loop)))
(if (< 2 3)
(foo -3)
(foo-again -3))
;; the if form allows us to do branching
;; control flow, its evaluation is the
;; evaluation of either the true or false
;; branch, based on whether or not the guard
;; evaluates to #t or #f
;; these are equivalent
;; (and e0 e1)
;; (if e0 e1 #f)
;; further, because these are equivalent
;; the following terminates
(and #f (loop))
;; (and #t (loop)) -- does not terminate
(define (f x)
(if (> x 0)
(* x 2)
(* x -2)))
(f 20)
(f -20)
(define (collatz x)
(if (equal? (modulo x 2) 0)
(/ x 2)
(+ 1 (* 3 x))))
(collatz 10)
(collatz (collatz 10))
(collatz (collatz (collatz 10)))
(collatz (collatz (collatz (collatz 10))))
(collatz (collatz (collatz (collatz (collatz 10)))))
(collatz (collatz (collatz (collatz (collatz (collatz 10))))))
(define (bar x)
(cond [(equal? x "hello") 5]
[(> x 3) 20]
[else 15]))
(bar "hello")
(bar 5)
(bar 2)
(define x 42)
(define (f2 x) x)
(displayln x)
(displayln (f2 -3))
#;(define (foo x)
(define y (+ x 2))
(define z (* x 1)))
;; with let, I can define multiple binding pairs
;; a binding pair is a variable alongside
;; an expression. Within the body of the let
;; (every let has a body, at least one)
;; the variables will be instantiated to values
;; given by evaluating the corresponding expressions
(let ([x (+ 1 2)]
[y (* 2 3)])
(* x y))
;; but, crucially, the variable bindings of
;; previous variables are not in scope in
;; subsequent bindings
#;(let ([a (* 2 3)]
[y (+ a a)]) ;; ERROR : can't see x
(+ a y))
;; I can imagine let as evaluating each of
;; the expressions "in parallel"
;; let* gives us "sequenced let"
;; where each binding is evaluated one at
;; a time.
(let* ([a (* 2 3)]
[y (+ a a)])
(+ a y))
;; everywhere you have a let*, expand it into
;; a nested sequence of lets
(let ([a (* 2 3)])
(let ([y (+ a a)])
(+ a y)))
;; the list of 3 followed by the empty
;; list is printed as:
;; '(3)
;; in general, when Racket prints (renders
;; to the screen) a list, it prints it
;; surrounded in parentheses, and quoted.
(not (equal? 3 '(3)))
(cons 1 (cons 2 (cons 3 '())))
(list 1 2 3 4 5)
(define (is-length-gt1 l)
(and (list? l)
(not (empty? l))
(not (empty? (cdr l)))))
(is-length-gt1 '())
(is-length-gt1 '(1))
(is-length-gt1 '(1 2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment