Skip to content

Instantly share code, notes, and snippets.

@ashton314
Last active April 9, 2020 20:44
Show Gist options
  • Save ashton314/52d8a74551668800ff023dd0b4aca838 to your computer and use it in GitHub Desktop.
Save ashton314/52d8a74551668800ff023dd0b4aca838 to your computer and use it in GitHub Desktop.
The Command pattern from GoF design patterns is a nice pattern. However, the problem it solves is more deftly handled by Lambda: the Ultimate.
#lang racket
;; First, define the undo stack with a few helper functions
(define *undo-stack* '())
(define (push-undo! command)
(set! *undo-stack* (cons command *undo-stack*)))
(define (pop-undo!)
(let ([head (car *undo-stack*)])
(set! *undo-stack* (cdr *undo-stack*))
head))
(define (undo!)
(let ([undo-action (pop-undo!)])
(if (not (null? undo-action)) (undo-action) 'nothing-to-undo)))
;; Now define a helper for the command that automatically saves something onto the stack
(define (action-add-inverse action inverse)
(push-undo! inverse)
(action))
;; Now here's a sample command that inserts a character and pushes a closure to undo the most recent edit
;; (imagine that insert! and remove! operated on a document of some sort)
(define (insert-char document character)
(action-add-inverse
(lambda () (insert! document character)) ; This is like an instantiation of a Command class
(lambda () (remove! document character)))) ; This is like the inverse Command object
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment