Skip to content

Instantly share code, notes, and snippets.

@ympbyc
Last active April 4, 2017 18:00
Show Gist options
  • Save ympbyc/f2d970f92180e1f35b23fae0b63e862f to your computer and use it in GitHub Desktop.
Save ympbyc/f2d970f92180e1f35b23fae0b63e862f to your computer and use it in GitHub Desktop.
Carrot3 idea #1. Caller transforming macro rough sketch.
;;Strip down the core language to its bones and provide a really powerful macro facility.
;;Just skim over. Don't read carefully.
;;It's just an idea. I'm not happy with this yet.
;; Macros with ability to scan and transform callers of a function
(defmacro (deflazy fname . rest)
(let ((expr (last rest))
(params (butlast rest)))
`(= ,fname ,@params
,(tree-walk (^ token (member? token params
`(force ,token)
token)
expr))))
:scan-caller fname
:caller-transform
(^ call `(apply ,(car call) ,(map (^ arg `(freeze ,arg) (cdr call))))))
(defmacro (deftyped (fname . typeclause) . rest)
`(= ,fname ,@rest)
:scan-caller fname
:caller-transform
(^ call (every?
(map (^ t arg (isa? arg t)) (butlast typeclause) (cdr call))
`(typed ,call ,(last typeclause))
*type-error*)
(defmacro (defrefined (fname typeclause refinement) . rest)
(let ((raw-types (map (^ t (named? t (cadr t) t)))))
`(deftyped (,fname ,@raw-types) ,@rest))
:scan-caller fname
:caller-transform
(^ call
(every? (map (^ t arg (named? t (check-arg-against-refinement arg refinement) true)) typeclause (cdr call))
`(typed ,call ,(last typeclause))
*type-error*)))
;;examples
(deflazy integers i
(cons i (integers (+ i 1))))
;;transforms into
(= integers i
(cons (force i) (integers (freeze (+ (force i) 1)))))
(cadr (integers 0))
;;transforms into
(cadr (integers (freeze 0)))
(deftyped (twice Number Number) x (* x 2))
;;transforms into
(= twice x (* x 2))
(twice 2)
;;transforms into
(typed (twice 2) 'Number)
(twice 'hello)
;;transforms into
*type-error*
(defrefined (foo ((a Number) (b Number) Number)
((> a 3) (< a b)))
x y
(- x y))
;;transforms into
(deftyped (foo Number Number Number)
x y
(- x y))
;;which in turn transforms into
(= foo x y (- x y))
(foo 4 7)
;;transforms into
(typed (foo 4 7) Number)
(foo 4 4)
;;transforms into
*type-error*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment