-
-
Notifications
You must be signed in to change notification settings - Fork 12
Cheat Sheet: Clojure
gilch edited this page Nov 22, 2024
·
18 revisions
This is a cheat sheet, not a tutorial. It's meant to refresh your memory or help you find search terms for the docs, for those familiar with Clojure. Not all alternatives are macros. Not all macros are listed, only those that correspond to Clojure features.
For a more Clojure-like experience, also check out toolz
, pyrsistent
, and Garden of EDN.
Clojure Special Forms | Alternatives |
---|---|
def |
define |
if |
if-else /when
|
do |
progn |
let* |
let*from (does simple destructuring and self-shadowing), |
letfn |
my# . Maybe type . |
quote |
Same: quote /' . |
var |
proxy# , See also: defvar , contextvars . |
fn |
lambda , fun
|
loop /recur
|
loop-from /recur-from
|
set! |
set! (items), set@ (attributes) |
throw |
throw . See also: throw-from . |
try |
engarde (prelude ) |
monitor-enter /monitor-exit
|
Maybe enter (prelude ) combined with the threading module and locks. Not really used in "user"-level Clojure. |
Clojure Macros | Alternatives |
---|---|
-> /->>
|
-> /-<>>
|
. |
(.bar self ...) (methods), foo.bar (attribute from identifier), @##' (attribute lookup tag), getattr (builtin function) |
.. |
foo.bar.baz (from identifier) or -> with @#' , like (-> foo @#'bar.baz)
|
alias |
alias |
amap |
map and array.
|
and |
ands . Python's truthiness is different from Clojure's. |
areduce |
/# , /XY# , functools..reduce
|
as-> |
-<>> with :<> . Maybe combined with my# or X# for repeats. |
assert |
assure . See also: avow . |
binding |
binding (see defvar , contextvars ). Maybe unittest.mock.patch (like with-redefs ). |
bound-fn /bound-fn*
|
??? |
case |
case |
comment |
Useless? Try ()_#( -) or similar. Trivial to implement yourself. |
cond |
cond |
cond-> /cond->>
|
??? |
condp |
??? (maybe just use cond ?) |
declare |
(define foo None) , probably. Python mostly doesn't need it, but it affects template quotes, which mostly work anyway. |
definline |
??? ("Experimental" in Clojure?) |
definterface |
abc. , probably. Python is not Java. |
defmacro |
defmacro |
defmethod /defmulti
|
deftypeonce /defun , probably. Maybe :@##functools..singledispatch . Not properly reloadable (but neither are Clojure multimethods). |
defn |
defun |
defn- |
defun and prepend an underscore to the name. Python mostly doesn't enforce privacy, but this is the convention. |
defonce |
defonce |
defprotocol |
abc. , probably. Python's not Java. |
defrecord |
deftupleonce |
deftype |
deftypeonce |
delay |
Probably Ensue (prelude ). |
deref |
(.get foo) , if foo is a context variable. |
doseq |
any-map |
dosync |
No STM in Python (ClojureScript either, really). Maybe in-memory sqlite3.
|
dotimes |
any-map on a range
|
doto |
doto |
extend-protocol |
Not applicable, duck typing. |
extend-type |
Maybe register (if using @singledispatch ). Python classes are mutable. |
for |
Ensue , probably. Also the iterator builtins and itertools (i# ). Maybe with my# . Maybe mix on a Python comprehension. |
future |
concurrent.futures. |
gen-class |
types..new_class . (See also: exec , type , deftypeonce , @dataclass .) |
gen-interface |
abc. , probably. Python's not Java. |
if-let |
my# on if-else or when
|
if-not |
unless |
if-some |
my# on if-else or when , with an is not None check or something. |
import |
define on a fully qualified name. Prefer aliases. |
io! |
Not applicable. No STM, but see sqlite3 . |
lazy-cat |
chain , chain# . |
lazy-seq |
Ensue (prelude ). See also: tee . |
let |
destruct-> . Yes, this is a macro in Clojure. You can macroexpand it to let* . See also: let . |
locking |
enter (prelude ) with threading. locks. |
memfn |
No need. Python's not Java. |
ns |
prelude , alias . Need something to set _macro_ , rather than *ns* . |
or |
ors . Python's truthiness is different from Clojure's. |
proxy , proxy-super
|
type , probably. Usually not required due to duck typing (ClojureScript either). |
pvalues |
concurrent.futures..map |
refer |
define on a fully qualified name. E.g., (define _macro_.foo bar.._macro_.foo)
|
refer-clojure |
prelude , or custom variants. |
reify |
type , probably. Usually not required due to duck typing. |
require |
importlib. , module handles, define , alias . |
some-> /some->>
|
??? |
sync |
No STM, but see sqlite3.
|
time |
time# , timeit..timeit
|
vswap! |
Not applicable. (Everything's on the heap in Python.) |
when |
when |
when-first |
Wouldn't work in Python. Iterators are mutable. Empty collections are already falsey. |
when-let |
my# on when
|
when-not |
unless |
when-some |
my# on when , with an is not None check or something. |
while |
takewhile , dropwhile , loop-from , Ensue (prelude ). |
Clojure with - Macros |
Alternatives (See enter from prelude ) |
---|---|
with-bindings |
contextvars..copy_context.run |
with-in-str |
with mk#patch on sys.stdin , replaced with an io..StringIO . |
with-local-vars |
my# |
with-open |
with contextlib..closing
|
with-out-str |
with contextlib..redirect_stdout
|
with-precision |
with decimal..localcontext
|
with-redefs |
with mk#patch
|
Clojure Special Reader Syntax | Alternatives |
---|---|
#inst |
inst# |
#uuid |
uuid# |
*data-readers* |
_macro_ |
*default-data-reader-fn* |
__getattr__ (In _macro_ 's class.) |
#? |
Not applicable, but .#(cond - could be similar. |
#?@ |
Not applicable, but .#` and ,@(cond - could be similar. |
' |
' |
\x |
"x" . Use a length-1 string instead (also works in ClojureScript). |
\space |
"\N{space}" (Any Unicode name, not case sensitive.) |
; |
; Beware these can be arguments for tags. |
@ |
(.get -) for context vars. No STM types. |
^ |
Maybe the __annotations__ attribute in some cases. Python doesn't really have an equivalent. |
#{ -}
|
(# -)
|
#"regex" |
`re..compile# |
#' |
proxy# , See also: defvar , contextvars . |
#( -)
|
%# or Xᵢ# from the macro tutorial. See also, O# , X# , XY# , XYZ# , XYZW# , en#X# /!## . |
#_ |
_# |
` |
` |
~ |
, (Use an extra space or comment for grouping instead.) |
~@ |
,@ |
foo# |
$#foo (automatic gensym) |