~hiredman/tagbody

goto for clojure
7e5fe785 — Kevin Downey 1 year, 4 months ago
readme
3cf59fb4 — Kevin Downey 1 year, 4 months ago
readme, docs, etc
fb22f2d9 — Kevin Downey 1 year, 4 months ago
add a license

refs

master
browse  log 

clone

read-only
https://git.sr.ht/~hiredman/tagbody
read/write
git@git.sr.ht:~hiredman/tagbody

You can also use your local clone with git send-email.

#tagbody

A port of common lisp's tagbody form to clojure. Lets you enjoy unstructured control flow.

http://www.lispworks.com/documentation/HyperSpec/Body/s_tagbod.htm

#deps

com.manigfeald/tagbody {:git/url "https://git.sr.ht/~hiredman/tagbody" :sha "2ed0f6f78c01ad0c01449cbffcf29ab0a92146d2"}

#Usage

(require '[com.manigfeald.tagbody :refer [tagbody go]])

(defn incf [x v]
  (var-set x (+ (var-get x) v)))

(with-local-vars
  [v nil]
  (tagbody
   (var-set v 1)
   (go point-a)
   (incf v 16)
   point-c
   (incf v 4)
   (go point-b)
   (incf v 32)
   point-a
   (incf v 2)
   (go point-c)
   (incf v 64)
   point-b
   (incf v 8))
  (var-get v))

;;=> 15

#Limitations

tagbody uses java.lang.Throwables to jump around. This can be problematic if you catch Throwables. Exception handlers are also single threaded, so you cannot go across threads.

The way tagbody currently runs it is limitted to 254 or so expressions in a tagbody.

Expressions are converted to closures (fns) in a way that no doubt interfers with locals clearing. This will also break things like set! on mutable deftype fields.

An expression in a tagbody can never be a tail as far as loop/recur is concerned.

#Why?

Maybe I can close the tagbody tab in my browser and stop thinking about it now.

#Me

  • @hiredman@downey.family
  • hiredman on clojurians.slack.com
Do not follow this link