Skip to content

Instantly share code, notes, and snippets.


Christophe Grand cgrand

View GitHub Profile
cgrand / for.clj
Created Jul 14, 2021
ClojureDart's for macro
View for.clj
;; For ClojureDart in a bout of NIH syndrome we rewrote Clojure for
;; it seems to be faster because we don't use concat
(defmacro for
"List comprehension. Takes a vector of one or more
binding-form/collection-expr pairs, each followed by zero or more
modifiers, and yields a lazy sequence of evaluations of expr.
Collections are iterated in a nested fashion, rightmost fastest,
and nested coll-exprs can refer to bindings created in prior
binding-forms. Supported modifiers are: :let [binding-form expr ...],
:while test, :when test.
View main.dart
log(String msg, x) {
return x;
var a = log("Init A", 1);
var b = log("Init B", 2);
var c = log("Init C", 3);
main() {
cgrand /
Last active Jun 24, 2021
super in ClojureDart

Accessing super members in ClojureDart

In ClojureDart deftype (and reify) can extend abstract classes and, as a consequence, we need a way to call super implementations (even on fields because of getters/setters).

For example, this Dart

class WebViewExampleState extends State<WebViewExample> {
  void initState() {

Quick notes on how the fallback pseudo-type is used in cljd (ClojureDart).

Like cljs, cljd is built on protocols. Like in clj, each protocol is backed by an interface for the fast path. Let's call this interface the direct interface.

Cljd protocols are also backed by a second interface used for extensions to 3rd-party classes. Let's call this interface the extension interface.

Protocols are reified as instances of an IProtocol interface:

// emitted code
cgrand / gist:564d6e8ad57299f64beb438e4a8b709f
Created Jul 11, 2020 — forked from KingCode/gist:773560f4ab5bf91e660a2a26e581b036
cond-let and cond-let| macros, to leverage bindings between test and result expressions, as well as earlier ones (for cond-let)
View gist:564d6e8ad57299f64beb438e4a8b709f
;; (cond-let
;; (odd? x) [x n] (inc x)
;; (< n 10) [y (inc n)] 10
;; :else n))
;; we want the above to yield
;; (let [x n]
;; (if (odd? x)
;; (inc x)
View demo.clj
(ns enlivez.demo
(:require [enlivez.core :as ez]
[datascript.core :as d]))
(ez/deftemplate new-item []
:state {:db/id self
new-todo ""}
[:input {:value new-todo
:on-change (doto [[:db/add self ::new-todo (-> % .-target .-value)]] prn)}]
package doubetrouble;
import java.util.concurrent.Callable;
public class Main implements Callable<Object> {
private static class Constants {
final static Object constant;
static {


Frequently I want to use reductions only to quickly realize that I'm not interested in the successive values of the state.

A simple example is to imagine one wants to increment a number represented by a sequence of its binary digits:

(inc '()) is (1)
(inc '(1)) is (0 1) ; yes the list is inversed, the lowest significant bit is the first item
(inc '(0 1)) is (1 1)
View maze-generation
(require '[clojure.string :as s])
(defn north-of [[row col]] [(dec row) col])
(defn south-of [[row col]] [(inc row) col])
(defn west-of [[row col]] [row (dec col)])
(defn east-of [[row col]] [row (inc col)])
(defn neighbours [rows cols cell]
cgrand / heredoc.clj
Last active Mar 6, 2021
An ugly hacky heredoc for Clojure
View heredoc.clj
(defn heredoc []
(let [delim (.readLine *in*)]
(->> (repeatedly #(.readLine *in*))
(take-while #(not= delim %))
(interpose \newline)
(apply str))))
; The following lines are read (by the reader) as:
; "Look )(\"\\T\na here doc!\n"