Skip to content

Instantly share code, notes, and snippets.

View xyhp915's full-sized avatar
๐Ÿ˜‡
monadic life ...

Charlie xyhp915

๐Ÿ˜‡
monadic life ...
View GitHub Profile

(conj collection item) adds item to collection. To do that, it needs to realize collection. (I'll explain why below.) So the recursive call happens immediately, rather than being deferred.

(cons item collection) creates a sequence which begins with item, followed by everything in collection. Significantly, it doesn't need to realize collection. So the recursive call will be deferred (because of using lazy-seq) until somebody tries to get the tail of the resulting sequence.

The following is how it works internally:

cons actually returns a clojure.lang.Cons object, which is what lazy sequences are made of. conj returns the same type of collection which you pass it (whether that is a list, vector, or whatever else). conj does this using a polymorphic Java method call on the collection itself. (See line 524 of clojure/src/jvm/clojure/lang/RT.java.)

What happens w

@xyhp915
xyhp915 / tree-seq-extra.clj
Created January 24, 2021 08:29 — forked from stathissideris/tree-seq-extra.clj
Like Clojure's tree-seq, but with depth info for each node or the full path (recursive - blow up the stack for deep trees)
(defn tree-seq-depth
"Returns a lazy sequence of vectors of the nodes in a tree and their
depth as [node depth], via a depth-first walk. branch? must be a fn
of one arg that returns true if passed a node that can have
children (but may not). children must be a fn of one arg that
returns a sequence of the children. Will only be called on nodes for
which branch? returns true. Root is the root node of the tree."
[branch? children root]
(let [walk (fn walk [depth node]
(lazy-seq
@xyhp915
xyhp915 / _doc.md
Created January 14, 2021 14:09 — forked from mhuebert/_doc.md
clj(s) environment config w/ Shadow-CLJS using a build hook

Objectives/approach

  • Load config conditionally, based on a release flag passed in at the command line. We use juxt/aero to read a static config.edn file, passing in the release flag as aero's :profile.
  • Config should be exposed at runtime (in the browser / cljs) and macro-expansion time (clj). We store config in a plain map, app.env/config. Our build hook, app.build/load-env, updates this using alter-var-root!.
  • Whenever config has changed, shadow-cljs must invalidate its caches so that changes are picked up immediately. We do this in app.build/load-env by putting the current environment in the shadow build state, under [:compiler-options :external-config ::env].

Why this approach?

  • Reading config directly from macros breaks compiler caching - changing config will not cause changes to propagate to the build.
  • :clojure-defines (ie. goog-define) are not exposed in clj, & therefore can't be used by macros. We want one single way to expose config that
@xyhp915
xyhp915 / 00_destructuring.md
Created January 6, 2021 07:38 — forked from john2x/00_destructuring.md
Clojure Destructuring Tutorial and Cheat Sheet

Clojure Destructuring Tutorial and Cheat Sheet

(Related blog post)

Simply put, destructuring in Clojure is a way extract values from a datastructure and bind them to symbols, without having to explicitly traverse the datstructure. It allows for elegant and concise Clojure code.

Vectors and Sequences

@xyhp915
xyhp915 / lein-tools-deps-cursive.md
Created October 31, 2020 12:35 — forked from mfikes/lein-tools-deps-cursive.md
Using `lein-tools-deps` from Cursive (on macOS)

Note: These workarounds covered issues in lein-tools-deps 0.3.0-SNAPSHOT. If using 0.4.1 or later, you should not encounter the issues below.

The following provides some workarounds for some issues when using lein-tools-deps from Cursive on macOS.

Path to clojure

By default, the lein-tools-deps plugin won't see /usr/local/bin/clojure when Cursive processes project.clj, as it evidently has a degenerate path.

You will see an error like the following in the IntelliJ Event Log when it tries to process your project.clj file:

@xyhp915
xyhp915 / iterator.js
Created April 28, 2020 04:22 — forked from jed/iterator.js
Turning callbacks into async iterators, with a React hook-like API.
// Example usage:
//
// void async function() {
// let [clicks, onclick] = iterator()
// document.querySelector('button').addEventListener('click', onclick)
// for await (let click of clicks) console.log(click)
// }()
export default function iterator() {
let done = false
const first = source => {
if (!source) return 'empty source'
return [source[0], source.slice(1)]
}
// console.log('first', first('abc'), first(''))
const inject = value => source => [value, source]
// console.log('inject', inject(1)('123'), inject(2)(''))
@xyhp915
xyhp915 / gzipRequestTest.js
Created August 14, 2019 08:47 — forked from nickfishman/gzipRequestTest.js
Second attempt at conditional gzip decoding based on the Content-Encoding response header with the mikeal/request library for Node.js. This DOES work.
var request = require('request'),
zlib = require('zlib');
var headers = {
"accept-charset" : "ISO-8859-1,utf-8;q=0.7,*;q=0.3",
"accept-language" : "en-US,en;q=0.8",
"accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"user-agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
"accept-encoding" : "gzip,deflate",
};
@xyhp915
xyhp915 / pget.go
Created June 21, 2019 04:02 — forked from montanaflynn/pget.go
Bounded Parallel Get Requests in Golang
package main
import (
"fmt"
"net/http"
"sort"
"time"
)
// a struct to hold the result from each request including an index
@xyhp915
xyhp915 / gist:4b6767cb6f109875b5afc5e14a20e10a
Last active May 7, 2021 17:45
React Fiber Architecture

React Fiber Architecture

Introduction

React Fiber is an ongoing reimplementation of React's core algorithm. It is the culmination of over two years of research by the React team.

The goal of React Fiber is to increase its suitability for areas like animation, layout, and gestures. Its headline feature is incremental rendering: the ability to split rendering work into chunks and spread it out over multiple frames.

Other key features include the ability to pause, abort, or reuse work as new updates come in; the ability to assign priority to different types of updates; and new concurrency primitives.