Skip to content

Instantly share code, notes, and snippets.

View cgrand's full-sized avatar

Christophe Grand cgrand

View GitHub Profile

While writing a new reader I used clojure.lang.LispReader code as the reference and I discovered there are two type of spaces:

  • pure whitespace (anything that matches #"[ \t\n\r,]+"),
  • unvalued stuff (any sequence of: whitespace, comments, discard (#_), elided conditionals).

This leads to some quirks. For example in namespaced map syntax is:

namespaced-map:
 "#:" (?! whitespace) unvalued-stuff symbol whitespace map

That's the kind of code that I'd like to make work across lumo & planck (and ideally any bootstrapped)

Is this unreasonable? Do you see any objection or technical issue with that?

  (def repl
    (letfn [(rep []
              (println (str (ns-name *ns*)) "=>")
              (read (fn [form ex]
 (if ex
(ns unrepl.evented-reader
(:require [goog.string :as gstring]))
(defprotocol Stream
(read! [stream])
(unread! [stream])
(on-more [stream f]
"f is a function of two arguments: stream and an array where to push values.
f will be called as soon as input is available.
f returns true when no additional input is required."))
@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 (<)