Skip to content

Instantly share code, notes, and snippets.

Avatar
💭
be gay, do crimes

Kyle Kingsbury aphyr

💭
be gay, do crimes
View GitHub Profile
@aphyr
aphyr / minikanren.pl
Created Oct 12, 2020
Minikanren in Lisp in Prolog
View minikanren.pl
:- use_module(library(pairs)).
:- use_module(library(reif)).
not_in_list(K, L) :-
if_((L = []),
true,
([X | More] = L,
dif(K, X),
not_in_list(K, More))).
@aphyr
aphyr / biglisp.pl
Created Oct 12, 2020
Another Lisp interpreter, in Prolog
View biglisp.pl
use_module(library(lists)).
/* Bind updates a state given a list of binding names and a list of
corresponding values. The special binding form &(args) binds `args` to all
remaining arguments. Used to update contexts for e.g. function evaluation. */
bind(S, S, [], []).
/* Varargs */
bind(S1, S2, [&(Var)], Vals) :-
S2 = S1.put(Var, Vals).
bind(S1, S3, [Var | Vars], [Val | Vals]) :-
@aphyr
aphyr / smolisp.pl
Created Oct 12, 2020
Prolog implementation of McCarthy's metacircular lisp interpreter, following pg's explication
View smolisp.pl
:- use_module(library(reif)).
axiom([quote, X], X).
axiom([atom, X], R) :-
axiom(X, XR),
((atomic(XR), R = t, !) ;
(compound(XR), R = [])).
axiom([eq, X, Y], R) :-
@aphyr
aphyr / download.txt
Last active Jan 9, 2020
clj-ssh errors
View download.txt
java.lang.IllegalArgumentException: No matching clause: 
at clj_ssh.ssh$scp_sink.invokeStatic(ssh.clj:981) ~[classes/:na]
at clj_ssh.ssh$scp_sink.invoke(ssh.clj:977) ~[classes/:na]
at clj_ssh.ssh$scp_from.invokeStatic(ssh.clj:1094) ~[classes/:na]
at clj_ssh.ssh$scp_from.doInvoke(ssh.clj:1044) ~[classes/:na]
View converge.clj
(defn converger
"Generates a convergence context for n threads, where values are converged
when (converged? values) returns true."
[n converged?]
(atom {; The convergence function
:converged? converged?
; What threads are involved?
:threads []
; And what values did they most recently come to?
:values (vec (repeat n ::init))}))
@aphyr
aphyr / banned-friends.rb
Created Jun 12, 2019
A small script to list which of the people you follow are visible in public twitter autocomplete searches.
View banned-friends.rb
#!/usr/bin/ruby
# This script tells you which of your friends (people you follow) are
# auto-completable in public twitter user searches, e.g. by typing
# @username" into the search box. It takes four arguments for twitter
# API credentials: consumer_key, consumer_secret, access_token, and
# access_token_secret. You can create an twitter API app at
# https://developer.twitter.com/.
# Output is a tab-separated list of accounts, one per line, where the
View gist:66946e62f44aa3c461ffbdced6af74eb
Let:
T1 = {:type :ok, :f :txn, :value [[:r 132 [1 2]] [:append 134 2] [:r 127 [1 2 3 6]]], :process 13, :time 174587090574, :index 2314}
T2 = {:type :ok, :f :txn, :value [[:append 132 3] [:r 133 [1]] [:append 134 1] [:r 132 [1 2 3]]], :process 14, :time 174415701895, :index 2300}
T3 = {:type :ok, :f :txn, :value [[:append 134 4] [:r 127 [1 2 3 6]]], :process 14, :time 174480602924, :index 2308}
Then:
- T1 < T2, because T1 did not observe T2's append of 3 to 132.
- T2 < T3, because T3 appended 4 after T2 appended 1 to 134.
- However, T3 < T1, because T1 appended 2 after T3 appended 4 to 134: a contradiction!
View gist:fafdcd31a662f75cbb01432a04eaa18e
Let:
T1 = {:type :ok, :f :txn, :value [[:append 237 3] [:r 233 [1 3 5 6 7 8 9]] [:append 237 4] [:append 238 1]], :process 16, :time 207412818568, :index 4098}
T2 = {:type :ok, :f :txn, :value [[:append 233 10] [:r 239 [1]] [:append 237 5]], :process 22, :time 206702615066, :index 4054}
T3 = {:type :ok, :f :txn, :value [[:r 233 [1 3 5 6 7 8 9 10]] [:r 238 [2]] [:append 237 7] [:r 239 [1]]], :process 22, :time 206769955506, :index 4058}
T4 = {:type :ok, :f :txn, :value [[:append 238 3] [:append 237 8]], :process 22, :time 206852651070, :index 4060}
T5 = {:type :ok, :f :txn, :value [[:append 238 4] [:r 239 [1]] [:r 241 nil]], :process 22, :time 206919825209, :index 4064}
T6 = {:type :ok, :f :txn, :value [[:r 238 [2 3 4]] [:append 239 2] [:append 241 1] [:append 239 3]], :process 22, :time 206984932481, :index 4068}
T7 = {:type :ok, :f :txn, :value [[:r 241 [1 2 3]] [:r 239 [1 2 3]] [:append 238 6]], :process 22, :time 207330867948, :index 4090}
Then:
View gist:8e661dc2e45b35cd451f4831c524bb92
Let:
T1 = {:type :ok, :f :txn, :value [[:append 1 4] [:r 0 nil]], :process 3, :time 8230766125, :index 17}
T2 = {:type :ok, :f :txn, :value [[:r 1 [2]] [:r 1 [2]] [:append 0 3]], :process 4, :time 8212723312, :index 15}
Then:
- T1 < T2, because T1 observed the initial (nil) state of 0, which T2 created by appending 3.
- However, T2 < T1, because T2 did not observe T1's append of 4 to 1: a contradiction!
Let:
View tarjan-multi-increment.clj
(let [r0 {:type :ok, :f :read, :value {:x 0, :y 0} ; Initially, x and y are 0
i1 {:type :ok, :f :inc, :value [:x]} ; Increment key x by 1
r1 {:type :ok, :f :read, :value {:x 1, :y 0}} ; Read x and y
i2 {:type :ok, :f :inc, :value [:y] ; Increment y
r2 {:type :ok, :f :read, :value {:x 1, :y 1}} ; Read x and y
; So far, so good. The above set of txns is consistent with an order
; where i1 precedes i2. Now, let's have a read transaction which observed
; the *opposite* order of increments: i2 < i1.
r3 {:type :ok, :f :read, :value {:x 0, :y 1}}
You can’t perform that action at this time.