Skip to content

Instantly share code, notes, and snippets.

@pasberth
Last active December 16, 2015 02:29
Show Gist options
  • Save pasberth/5363232 to your computer and use it in GitHub Desktop.
Save pasberth/5363232 to your computer and use it in GitHub Desktop.
(ns macro-combinator
(:refer-clojure :exclude [=]))
(defn prim [x] (fn [a] `(fn [~x] ~a)))
(defn in [v a] (v a))
(defn where [a v] (v a))
(defn = [v b] (fn [a] `(~(v a) ~b)))
(defn <- [v b] (fn [a] `(>>= ~b ~(v a))))
(println (in (= (prim 'x) 42) 'x))
; ((clojure.core/fn [x] x) 42)
(println (in (<- (prim 'x) 42) 'x))
; (macro-combinator/>>= 42 (clojure.core/fn [x] x))

What's the Macro?

Macro is the parameter of Lambda.

m = \x    -- A primitive macro.
f = m {x} -- The m builds an lambda with first argumenet, parameter of which is x.
f 1       -- 1

Primitive definition

Name Syntax Type Detail
macro \ p a -> b -> a right recursion.
closure { x } a Makes a function which has no parameter.

How to use lambdas?

We can build an lambda, by giving a function for the primitive macro.

Examples

let = \m \a \v { m v a }
-- let \x 42 x => 42

compose = \m \k \a { m (k a) }
-- compose (let \x a) (let \y b)
-- == \p { let \x a (let \y b p) }
-- == \p { \x (\y p b) a }
(\a {
(\let a) -- binds ``let" onto a
(\m \a \v {m v a}) -- definition of the let
}) {
-- macro composition
let \, (\m \k \a { m (k a) })
{
let \:= let `,` let \in (\m \a {m a})
{
\flip `:=` (\f \x \y (f y x)) `,`
\where `:=` (mlip in) `in` {
\<- `:=` (\m \k \a (k `>>=` (m a)))
-- The do operations were all defined. For example,
-- \x `<-` m `in` {k}
)))
}}}}
@pasberth
Copy link
Author

p = x (q = y) == (p -> (q = y)) x == (p -> (q -> (¥a -> a)) y) x

@pasberth
Copy link
Author

置換コマンド

s "(\d+)" $a

を考える。 $a は遅延評価であり、なおかつダイナミックスコープである。
s コマンドは "(\d+)" にマッチした場合、グループを a, b, .. z の順に変数に束縛したのち、 右辺を評価し、その結果で置換する関数である
すると、 $a はグローバルでも、特別な構文でもないが、 s の中で宣言された a という変数を参照できる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment