Skip to content

Instantly share code, notes, and snippets.

@nyuichi
Created January 9, 2013 17:27
Show Gist options
  • Select an option

  • Save nyuichi/4495038 to your computer and use it in GitHub Desktop.

Select an option

Save nyuichi/4495038 to your computer and use it in GitHub Desktop.
C++-like template system for Common Lisp
(define-template-function add ((n) m)
(+ n m))
; (add (1) 2)
; => 3
; (add-1 3)
; => 4
(define-template-function lower-bound ((cmp key) value seq)
(loop :with low := 0 :and high := (1- (length seq))
:while (< low high)
:for mid := (truncate (+ low high) 2)
:do (if (cmp (key (elt seq mid)) value)
(setf low (1+ mid))
(setf high mid))
:finally (return (if (cmp (key (elt seq low)) value)
(length seq)
Low))))
; (lower-bound (< identity) 1 '(0 0 0 0 1 1 1 1 2 3 4))
; => 4
(defpackage :template
(:use :common-lisp))
(in-package :template)
(defmacro define-template-function (name (template-args &rest args) &body body)
`(defmacro ,name ,(cons template-args args)
(multiple-value-bind (func-name status)
(intern (format nil "~a~{-~a~}" ',name ,(cons 'list template-args))
:template)
(unless status
(let ((func-body
(list 'symbol-macrolet
(list ,@(loop :for arg :in template-args
:collect `(list ',arg ,arg)))
(list 'macrolet
(list ,@(loop :for arg :in template-args
:collect (list 'list (list 'quote arg)
''(&rest args)
`(list 'cons (list 'quote ,arg) 'args))))
'(progn ,@body)))))
(compile func-name (list 'lambda ',args func-body))))
(list func-name ,@args))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment