Skip to content

Instantly share code, notes, and snippets.

View cgrand's full-sized avatar

Christophe Grand cgrand

View GitHub Profile
@cgrand
cgrand / binding-conveying.clj
Created April 4, 2017 09:04
Did you know? #clojure
;; did you know that binding conveying is not immutable but read-only? (the future sees updates performed by the original thread)
=> (with-local-vars [a 1]
(future (Thread/sleep 1000) (prn 'future @a))
(var-set a 2))
2
future 2
;; you have to push new bindings to isolate:
=> (with-local-vars [a 1]
(with-bindings {a @a}
@cgrand
cgrand / unrepl.md
Created March 27, 2017 14:27
Unrepl: the ski lift notes

UNleash the REPL

I spent some hammock time (ski lift time actually), brooding over unrepl.

What's ok

  • cleanly multiplexed output (out, err, eval, exception etc.)
  • elisions (which can provide all sort of browsing navigation)
  • attachments
  • :bye
@cgrand
cgrand / demo.clj
Last active April 26, 2019 06:47
For toolsmithes really caring about isolation
;; Clojure 1.6.0
=> *clojure-version*
{:major 1, :minor 6, :incremental 0, :qualifier nil}
=> (def env1 (create-clojure-env))
#'net.cgrand.quarantine/env1
=> (env1 *in* *out*)
clojure.core=> *clojure-version*
{:major 1, :minor 8, :incremental 0, :qualifier nil}
clojure.core=>
(ns powderkeg.sql
(:require [clojure.spec :as s]
[clojure.edn :as edn]
[powderkeg.core :as keg]
[net.cgrand.xforms :as x])
(:import
[org.apache.spark.sql functions Column Row RowFactory DataFrame]
[org.apache.spark.sql.types StructType StructField ArrayType DataType DataTypes Metadata MetadataBuilder]))
(defmulti expr first)

So I have a full working prototype (at https://github.com/cgrand/unrepl) but I haven’t wrote the spec yet for the input part.

Clojure 1.9.0-alpha14
user=> (require 'unrepl.repl)
nil
user=> (unrepl.repl/start)

outputs:

REPL the Ultimate Protocol: Notes for a hopefully better "tooling over repl" approach for Clojure

The single point of agreement between the server and the client should be that: there exists a stream-based plain repl running and connected (socket or pipes etc. is not relevant).

From there one can upgrade to a richer repl. The interesting fact is that since the upgrade is triggered by the client there can't be any mismatch between capabilities. Even if your editor scripting power is limited (coughvimcough) you can treat the clojure snippet required for upgrade as a blob.

@cgrand
cgrand / ednrepl.clj
Last active March 28, 2018 19:00
What if a REPL out was a stream of EDN forms?
;; some sample interaction with a clojure socket repl whose output stream consists only of valid edn forms.
;; the edn stream is not meant for the end user but for the client UI.
;; it demoes several features:
;; • prompt, out, err, eval and exceptions are demultiplexed; unstructred ones (err & out) are just text but the others give data.
;; • elided content (because data too deep or wide) is replaced by a tagged literal (which optionally contains the expr to evaluate to get more items)
;; this last point makes possible navigation
;; lines are prefixed by > or < to tell what is sent to the repl (>) and what is received from it (<)
@cgrand
cgrand / retrospec.clj
Created February 15, 2017 15:07
Retro-spec-ing a dataframe
=> (ns user (:require [powderkeg.sql :as sql] [clojure.spec :as s]))
=> (s/def ::age int?)(s/def ::name string?) (s/def ::friends (s/* ::name))
:user/age
:user/name
:user/friends
=> (sql/df [{:name "Gaël" :age 6 :friends ["Alix"]}
{:name "Estelle" :age 4 :friends ["Léana"]}
{:name "Lilly" :age 1 :friends ["Tigger" "Cuddly"]}]
(s/keys :req-un [::name ::age ::friends]))
@cgrand
cgrand / dataframes.clj
Last active February 14, 2017 11:41
DataFrames are coming to Powderkeg!
;; first, define some specs
=> (s/def ::name string?)
(s/def ::age int?)
(s/def ::friends (s/* ::name))
:user/name
:user/age
:user/friends
;; second create a dataframe from a RDD and a spec
=> (sql/df (rdd [{:name "Gaël" :age 6 :friends ["Alix"]}
@cgrand
cgrand / spec.clj
Created February 13, 2017 14:20
from clojure spec to spark schema [PoC]
(ns powderkeg.spec
(:require [clojure.spec :as s])
(:import [org.apache.spark.sql.types DataType DataTypes]))
(defmulti expr first)
(def ^:private regexp-repeat
(s/and
(s/cat :tag any? :type ::datatype)
(s/conformer