Created
April 18, 2020 06:12
-
-
Save saikyun/906b19e466b1f2e83e5bd48e8f43dc0c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns miracle.thread | |
(:require [clojure.pprint :refer [pprint]] | |
[clojure.string :as str] | |
[clojure.walk :refer [postwalk]])) | |
(defn used-vars | |
[form] | |
(let [vars (transient [])] | |
(postwalk (fn [f] | |
(when (and (symbol? f) | |
(str/starts-with? (name f) "$")) | |
(conj! vars f)) | |
f) | |
form) | |
(persistent! vars))) | |
(defn has-var? | |
[form] | |
(seq (used-vars form))) | |
(comment | |
(used-vars '(a b c)) | |
(used-vars '(a b (let [x $1] (+ x x)))) | |
(has-var? '(a b c)) | |
(has-var? '(a b (let [x $1] (+ x x)))) | |
) | |
(defn fix-fun-call | |
[sym form] | |
#_(if sym | |
(if (seq? form) | |
(if (has-var? form) | |
form | |
(concat form [sym])) | |
(list form sym)) | |
form) | |
(let [new-form (if sym | |
(if (seq? form) | |
(if (has-var? form) | |
form | |
(concat form [sym])) | |
(list form sym)) | |
form)] | |
`(try ~new-form | |
(catch Exception ~'e | |
(println "Exited at:" '~new-form) | |
~@(for [v (used-vars new-form)] | |
`(println (str "(def " '~v " " ~v ")"))) | |
(throw ~'e))))) | |
(defn handle-form | |
[res forms] | |
(if (empty? forms) | |
res | |
(let [[form & more] forms] | |
(cond | |
(nil? form) res | |
(and (symbol? form) | |
(= form '_)) | |
(let [[form & more] more] | |
`(do ~(fix-fun-call res form) | |
~(handle-form res more))) | |
(and (symbol? form) | |
(str/starts-with? (name form) "$")) | |
(let [sym form | |
[form & more] more] | |
(if (and (seq? more) | |
(symbol? (first more)) | |
(= (first more) '|)) | |
(let [f form | |
[_ err-f & more] more] | |
`(do (try | |
(let [~sym ~(fix-fun-call res form)] | |
~(handle-form sym more)) | |
(catch Error e# | |
(let [~sym (~err-f e#)] | |
~(handle-form sym more)))))) | |
`(let [~sym ~(fix-fun-call res form)] | |
~(handle-form sym more)))) | |
(and (seq? more) | |
(symbol? (first more)) | |
(= (first more) '|)) | |
(let [f form | |
[_ err-f & more] more] | |
`(do (try | |
~(handle-form res (concat [f] more)) | |
(catch Exception e# | |
(~err-f e#))))) | |
:else | |
`(let [~'$last ~(fix-fun-call res form)] | |
~(handle-form '$last more)))))) | |
(defmacro =>> | |
[& forms] | |
(handle-form nil forms)) | |
(name 'aoe) | |
#_(pprint (macroexpand '(=>> 1 | |
inc | |
(* 2)))) | |
#_(pprint (macroexpand '(=>> 1 | |
$1 inc | #(println %) | |
_ (println "$1 is" $1) | |
(* 2)))) | |
#_(->> -1 | |
inc | |
(#(/ 2 %))) | |
;;=> Divide by zero | |
(=>> -1 | |
inc | |
_ (println "curr") ;; _ means "skip this step" | |
(/ 2)) | |
(=>> -1 | |
inc | |
_ (println "curr") ;; _ means "skip this step" | |
(#(/ 2 %))) | |
;;=> curr 0 | |
;;=> Divide by zero | |
(=>> -1 | |
inc | |
_ (println "curr") ;; _ means "skip this step" | |
$v inc ;; $v means "store in $v" | |
_ (println "$v =" $v) | |
(#(/ 2 %))) | |
;;=> curr 0 | |
;;=> $v = 1 | |
;;=> 2 | |
(=>> -1 | |
inc | |
_ (println "curr") | |
(#(/ 2 %)) | (constantly 1337)) | |
;;=> curr 0 | |
;;=> 1337 | |
(=>> 1 | |
$1 (do (throw (Error. "HEHE")) (inc $last)) | |
| (fn [err] | |
(println "Error:" (-> err Throwable->map :via first :message)) | |
10) | |
_ (println "$1 is" $1) | |
(* 2)) | |
(=>> 1 inc (* 2)) | |
(comment | |
(=>> [1 2 3] | |
(map inc) | |
(filter #(<= 3 %))) | |
(->> [1 2 3] | |
(map inc) | |
(filter #(<= 3 %))) | |
(defn handle-form | |
[v forms] | |
(if (empty? forms) | |
v | |
(let [[form & more] forms] | |
(cond | |
(nil? form) v | |
:else (let [f# (if v | |
(if (seq? form) | |
(concat form [v]) | |
(list form v)) | |
form)] | |
(handle-form f# more)))))) | |
(defmacro =>> | |
[& forms] | |
(handle-form nil forms)) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment