Skip to content

Instantly share code, notes, and snippets.

View cgrand's full-sized avatar

Christophe Grand cgrand

View GitHub Profile

Carry

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)
(require '[clojure.string :as s])
;; Maze GENERATION
(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
cgrand / heredoc.clj
Last active March 6, 2021 17:16
An ugly hacky heredoc for Clojure
(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"
#=(heredoc)"""

Monotonic logic is eventually consistent. Eventual Consistency (https://www.voltdb.com/blog/2016/07/21/6265/) has clear limits. It doesn't matter while you are pure. It matters when you go impure (FP). So boundaries must be clear. Boundaries implies coordination. Impure snapshots are expensive.

Monotonicity is ~ relativity. Impure is ~ absolute

(defn lambda-model
"Crude model. rps is requests per second, len is a function that returns the
execution length in seconds, until is the number of seconds to run the simulation,
spawn is a function returning the number of ping sub requests, duty is the max age
for a container, keep-alive is the number of seconds before decommissioning a
container.
Returns a map with: the number of user perceived cold starts and the number of
billable seconds."
[{:keys [rps len until spawn duty keep-alive]
:or {rps 10
(ns ssh-repl.client
(:require [clojure.java.io :as io]))
(defn connect
([user host repl-port {:as options
:keys [ssh-port repl-host key password]
:or {ssh-port 22
repl-host "localhost"}}]
(let [client (doto (org.apache.sshd.client.SshClient/setUpDefaultClient) .start)
session (-> client (.connect user host ssh-port) (doto .await) .getSession)]
@cgrand
cgrand / shootout.md
Created November 24, 2017 18:01
Pretty printers compared

clojure.pprint

=> (binding [clojure.pprint/*print-right-margin* 30]
     (clojure.pprint/pprint {:a :b :c {:e :f :g :h :i :j :k :l} :m :n :o {:p {:q :r :s :t}}}))
{:a :b,
 :c
 {:e :f,
  :g :h,
  :i :j,
 :k :l},
; with the setting that values are indented by two if they are at the start of a line
=> (doseq [w (range 20)]
(prn 'width w 'non-strict)
(render (best-layout (spans '{1 2 3 (a b) 5 6}) w))
(newline)
(prn 'width w 'strict)
(render (best-layout (spans '{1 2 3 (a b) 5 6}) w true))
(newline))
width 0 non-strict
{1
@cgrand
cgrand / packed-printer.clj
Created November 22, 2017 14:16
Experiment in compact pretty printing
=> (doseq [w (range 32)]
(prn 'width w)
(render (best-layout (spans '(1 2 3 4 (a b c) 5 6)) w))
(newline))
width 0
width 1
width 2
@cgrand
cgrand / join.clj
Created October 14, 2017 16:00
Join transducer
(defn join
"Joins pairs returned by nested transducers based on their key (first item).
Each nested transducer must returns pairs made of a strictly increasing key and a value.
Emits pairs made of the join key and a vector of the joined values (nil when none).
Values in the vector appears in the same order as the xform that produced them."
([] identity)
([xform] xform)
([xform1 xform2]
(fn [rf]
(let [vq1 (volatile! clojure.lang.PersistentQueue/EMPTY)