Skip to content

Commit 4b2d6b6

Browse files
committed
Emmy Infix Notation with YAMLScript
1 parent 2409682 commit 4b2d6b6

1 file changed

Lines changed: 66 additions & 27 deletions

File tree

src/mentat_collective/emmy/fdg_ch01_ys.clj

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
^{:kindly/hide-code true
2-
:clay {:title "Emmy, the Algebra System: YAMLScript for the world!"
2+
:clay {:title "Emmy, the Algebra System: Infix Notation"
33
:quarto {:author :kloimhardt
4-
:type :post
5-
:date "2025-09-10"
6-
:image "sicm_ch01.png"
4+
:type :draft
5+
:date "2025-11-15"
76
:category :libs
8-
:tags [:emmy :physics]}}}
7+
:tags [:emmy :infix :yamlscript]}}}
98

109
(ns mentat-collective.emmy.fdg-ch01-ys
1110
(:refer-clojure :exclude [+ - * / zero? compare divide numerator denominator
1211
time infinite? abs ref partial =])
13-
(:require [emmy.env :refer :all]
12+
(:require [emmy.env :refer :all :exclude [D F->C]]
1413
[yamlscript.compiler :as ys]
1514
[scicloj.kindly.v4.api :as kindly]
1615
[scicloj.kindly.v4.kind :as kind]))
@@ -48,7 +47,7 @@
4847

4948
^:kindly/hide-code
5049
(kind/scittle
51-
'(require '[emmy.env :as e :refer :all :exclude [D F->C]]))
50+
'(require '[emmy.env :refer :all :exclude [D F->C]]))
5251

5352
^:kindly/hide-code
5453
(def time first)
@@ -61,7 +60,9 @@
6160
(kind/scittle
6261
'(def D partial))
6362

64-
;; The Clojure code below is taken from the examples of [this previous post](https://clojurecivitas.github.io/mentat_collective/emmy/fdg_ch01.html). It is not necessary to understand what the Clojure code does, the purpose is comparison to the infix notation.
63+
;; The Clojure code below is taken from the snippets of [a previous entry](https://clojurecivitas.github.io/mentat_collective/emmy/fdg_ch01.html). Please make pull requests to [the source file of this notebook](https://github.com/kloimhardt/clojurecivitas.github.io/blob/infix/src/mentat_collective/emmy/fdg_ch01_ys.clj). It is not necessary to understand what the Clojure code does. As this semantics does not matter here, it is rather the syntax, the notation, that should be compared and critiqued vis-a-vis the proposed infix notation.
64+
65+
;; ## First Example
6566

6667
(kind/scittle
6768
'(defn Lfree [mass]
@@ -74,7 +75,9 @@ defn LFree(mass):
7475
fn([_ _ v]): mass * 1/2 * square(v)
7576
")
7677

77-
;; I proceed to the next infix
78+
;; ## Another one
79+
80+
;; I proceed to the next infix snippet
7881

7982
(ys "
8083
defn sphere-to-R3(R):
@@ -94,11 +97,17 @@ defn sphere-to-R3(R):
9497
(* R (sin theta) (sin phi))
9598
(* R (cos theta))))))
9699

100+
;; ## Higher order functions
101+
102+
;; For the next infix, I introduce `call` (with obvious behaviour) and two aliases.
103+
97104
(do
98105
(defn call [f x] (f x))
99106
(def of call)
100107
(def at call))
101108

109+
(def D partial)
110+
102111
(ys "
103112
defn F-to-C(F):
104113
fn(state):
@@ -108,6 +117,8 @@ defn F-to-C(F):
108117
=>: D(0).of(F).at(state) + ( D(1).of(F).at(state) * velocity(state) )
109118
")
110119

120+
;; With `of` and `at` like that, the above `D(0).of(F).at(state)` (which means "take the zeroth derivative of the function F at point state") translates into what are higher order functions in the Clojure version.
121+
111122
(kind/scittle
112123
'(defn F->C [F]
113124
(fn [state]
@@ -117,6 +128,8 @@ defn F-to-C(F):
117128
(* (((D 1) F) state)
118129
(velocity state)))))))
119130

131+
;; ## Another one
132+
120133
(ys "
121134
defn Lsphere(m R):
122135
compose:
@@ -128,6 +141,10 @@ defn Lsphere(m R):
128141
'(defn Lsphere [m R]
129142
(compose (Lfree m) (F->C (sphere->R3 R)))))
130143

144+
;; ## The proof is in the pudding
145+
146+
;; In order to quote symbols, I introduce a macro called `q`
147+
131148
(defmacro q [f] (list 'quote f))
132149

133150
(ys "
@@ -139,24 +156,47 @@ simplify:
139156
up: thetadot:q phidot:q
140157
")
141158

159+
(kind/reagent
160+
(vector :tt
161+
'(simplify
162+
((Lsphere 'm 'R)
163+
(up 't (up 'theta 'phi) (up 'thetadot 'phidot))))))
164+
165+
;; Indeed the results are the same which proves the infix technically works.
166+
167+
;; ## Intermission
168+
169+
;; The infix notation I use here is `YS` (say "wise"), also called [YAMLScript](https://yamlscript.org/). I have read one opinion that says "I do not want my program to run through a YAML parser". This is a vantage point which is not applicable to Clay notebooks. A Clay notebook is not about maintaining a codebase, it is about conveying ideas and concepts. It is not about the writing of code, it is about the audience which reads the code.
170+
171+
;; And concerning reading code, YS has a lot to offer for the Clojure community. Namely that with YS we can communicate the idea of functional+immutable to that particular audience which is not even willing to read code that has the "parens in the wrong place".
172+
173+
;; I'd like to put into light a related project of mine. With [LisRoot](https://github.com/kloimhardt/LisRoot) I try to lure away the HEP-community from Python towards Clojure/jank. And here YS is the single best way to show code snippets that are functional+immutable. Those people who like that concept will eventually learn to install a code editor for slurp/barfing and then also cherish the nrepl as we all do.
174+
175+
;; I did not find the appropriate YS-compiler on Clojars (for Clay I do not want a dependency on the shared compiled library) , so to deps.edn, I added the following git-sha:
176+
142177
^:kindly/hide-code
143-
(defn show-expression [e] (kind/reagent [:tt e]))
178+
(kind/code "
179+
yamlscript/core {:git/url \"https://github.com/yaml/yamlscript\"
180+
:git/sha \"ed7adfbf90a39f379d5a7193bb2e4bdd7f0eecf8\"
181+
:deps/root \"core\"}
182+
")
144183

145-
(show-expression
146-
'(simplify
147-
((Lsphere 'm 'R)
148-
(up 't (up 'theta 'phi) (up 'thetadot 'phidot)))))
184+
;; ### Some more examples
149185

186+
;; ## 1
150187
(ys "
151188
defn L2(mass metric):
152189
fn(place velocity): mass * 1/2 * metric(velocity velocity).at(place)
153190
")
154-
155191
(kind/scittle
156192
'(defn L2 [mass metric]
157193
(fn [place velocity]
158194
(* 1/2 mass ((metric velocity velocity) place)))))
159195

196+
197+
;; ## 2
198+
199+
^:kindly/hide-code
160200
(def coordinate-system-to-vector-basis coordinate-system->vector-basis)
161201

162202
(ys "
@@ -172,20 +212,27 @@ defn Lc(mass metric coordsys):
172212
(fn [[_ x v]]
173213
((L2 mass metric) ((point coordsys) x) (* e v))))))
174214

215+
;; ## 3
216+
175217
(ys "
176218
the-metric =: literal-metric(g:q R2-rect)
177219
")
178220

179221
(kind/scittle
180222
'(def the-metric (literal-metric 'g R2-rect)))
181223

224+
225+
;; ## 4
182226
(ys "
183227
L =: Lc(m:q the-metric R2-rect)
184228
")
185229

186230
(kind/scittle
187231
'(def L (Lc 'm the-metric R2-rect)))
188232

233+
234+
;; ## and the pudding
235+
189236
(ys "
190237
simplify:
191238
L:
@@ -195,15 +242,7 @@ simplify:
195242
up: vx:q vy:q
196243
")
197244

198-
(show-expression
199-
'(simplify
200-
(L (up 't (up 'x 'y) (up 'vx 'vy)))))
201-
202-
;; YAMLScript, no Clojars thus git-sha
203-
204-
^:kindly/hide-code
205-
(kind/code "
206-
yamlscript/core {:git/url \"https://github.com/yaml/yamlscript\"
207-
:git/sha \"ed7adfbf90a39f379d5a7193bb2e4bdd7f0eecf8\"
208-
:deps/root \"core\"}
209-
")
245+
(kind/reagent
246+
(vector :tt
247+
'(simplify
248+
(L (up 't (up 'x 'y) (up 'vx 'vy))))))

0 commit comments

Comments
 (0)