yamlscript

Ingy döt Net 2024-04-18T18:25:29.166789Z

Last week @pez asked me if YS could be used to refactor his Calva CircleCI config.yml https://github.com/BetterThanTomorrow/calva/blob/published/.circleci/config.yml I just finished a PR for that with 30 iterative commits resulting in: https://github.com/ingydotnet/calva/blob/dev/.circleci/config.ys which evaluates to an equivalent config.yml file with:

$ make build
ys --load --yaml --ordered config.ys >> _config.yml
mv _config.yml config.yml
The README.md explains it pretty well: https://github.com/ingydotnet/calva/blob/dev/.circleci/README.md

👍 1
💯 2
Ingy döt Net 2024-04-18T18:25:58.455569Z

Starting a thread to link elsewhere.

delon 2024-05-01T13:44:30.366319Z

That's awesome

pez 2024-04-18T21:14:26.964849Z

This Calva was released with YamlScript. 💪 🚀

💪 1
🎉 1
2024-04-19T00:31:26.334549Z

Three weeks ago, homoiconicity was just a gentlefolks' conceit. Now it is rising, reptilian, out of the drains.

💯 1
delon 2024-05-01T13:51:59.793109Z

I'm late to this party, but I agree wholeheartedly with @phill. Though I wonder... Do you think "code-as-data" might be a preferable expression to "homoiconic"? To my mind "code-as-data" is the important concept and would likely result in less debates.

Ingy döt Net 2024-04-19T14:39:40.053479Z

@phill what are you alluding to exactly? Don't want to make assumptions.

2024-04-19T15:38:26.265459Z

I am impressed & thrilled but most of all honored to be present at this time in history.

2024-04-19T15:38:58.664749Z

Because there is some serious pedantry (and I mean that in the most positive sense) about homoiconicity.

pez 2024-04-19T15:39:48.227899Z

I feel the same sense of being there when something really important is happening!

2024-04-19T15:40:14.138759Z

But there is nothing elitist about YAML.

2024-04-19T15:41:09.671079Z

And while (on one hand) Lisp macros owe a lot to homoiconicity, (on the other hand) the Everyman in programming and IT does not know why they should care about macros.

2024-04-19T15:41:47.615919Z

But now with YamlScript, basically a self-transforming data instance, the homoiconicity shoe is completely on the other foot.

2024-04-19T15:42:33.970209Z

The Everyman in IT will dabble happily in YamlScript, because it is homoiconic!

1
2024-04-19T15:53:04.568229Z

It was a bit poetic to describe it as "homoiconicity rising up, reptilian, out of the drains"; but my powers of expression were inadequate to convey the revolution that we're on the cusp of: the abstruse concept having been plucked from the ivory towers, and offered to the IT masses: who will shortly topple all ramparts to bring it to all corners of dull-and-boring configuration. A bottom-up crash introduction of functional expression from the very people the ivory tower considered least likely!

💯 1
🔥 1
Ingy döt Net 2024-04-19T16:03:59.519309Z

This is quite interesting I was thinking that you were saying clojure is homoiconic and the yamlscript is not. I thought about this topic quite a bit and I'm unsure whether YS is truly homoiconic and also whether a clojure is. Some differing opinions out there.

pez 2024-04-19T16:09:38.561889Z

The opinions doesn’t matter so much, me thinks. 😃

Ingy döt Net 2024-04-19T16:18:03.953439Z

This is a compilation, where =: forms transform into defs or lets. I'm not sure if this breaks homoiconicity.

$ ys -ce '
x =: 123
defn foo(y):
  z =: 321
  =>: z / y
'
(def x 123)
(+++ (defn foo [y] (let [z 321] (/ z y))))

Ingy döt Net 2024-04-19T16:22:30.523489Z

I guess you could think of it as an elaborate macro expansion.

Ingy döt Net 2024-04-19T16:24:03.500949Z

This is the same compilation with each of the 7 stages exposed.

$ ys -ce '
x =: 123
defn foo(y):
  z =: 321
  =>: z / y
' -d
*** parse output ***
({:+ "+MAP", :! "yamlscript/v0/code"}
 {:+ "=VAL", := "x ="}
 {:+ "=VAL", := "123"}
 {:+ "=VAL", := "defn foo(y)"}
 {:+ "+MAP"}
 {:+ "=VAL", := "z ="}
 {:+ "=VAL", := "321"}
 {:+ "=VAL", := "=>"}
 {:+ "=VAL", := "z / y"}
 {:+ "-MAP"}
 {:+ "-MAP"}
 {:+ "-DOC"})

*** compose output ***
{:! "yamlscript/v0/code",
 :%
 [{:= "x ="}
  {:= "123"}
  {:= "defn foo(y)"}
  {:% [{:= "z ="} {:= "321"} {:= "=>"} {:= "z / y"}]}]}

*** resolve output ***
{:pairs
 [{:def "x ="}
  {:exp "123"}
  {:defn "defn foo(y)"}
  {:pairs [{:def "z ="} {:exp "321"} {:exp "=>"} {:exp "z / y"}]}]}

*** build output ***
{:pairs
 [[{:Sym def} {:Sym x}]
  {:Int 123}
  [{:Sym defn} {:Sym foo} nil {:Vec [{:Sym y}]}]
  {:pairs
   [[{:Sym def} {:Sym z}]
    {:Int 321}
    {:Sym =>}
    {:Lst [{:Sym /} {:Sym z} {:Sym y}]}]}]}

*** transform output ***
{:pairs
 [[{:Sym def} {:Sym x}]
  {:Int 123}
  [{:Sym defn} {:Sym foo} nil {:Vec [{:Sym y}]}]
  {:pairs
   [[{:Sym def} {:Sym z}]
    {:Int 321}
    {:Sym =>}
    {:Lst [{:Sym /} {:Sym z} {:Sym y}]}]}]}

*** construct output ***
{:Top
 [{:Lst [{:Sym def} {:Sym x} {:Int 123}]}
  {:Lst
   [{:Sym +++}
    {:Lst
     [{:Sym defn}
      {:Sym foo}
      nil
      {:Vec [{:Sym y}]}
      {:Lst
       [{:Sym let}
        {:Vec [{:Sym z} {:Int 321}]}
        {:Lst [{:Sym /} {:Sym z} {:Sym y}]}]}]}]}]}

*** print output ***
"(def x 123)(+++ (defn foo  [y] (let [z 321] (/ z y))))"

(def x 123)
(+++ (defn foo [y] (let [z 321] (/ z y))))

Ingy döt Net 2024-04-19T16:24:31.940099Z

It's certainly all data transformations.

👍 1
Ingy döt Net 2024-04-19T16:25:37.380639Z

I'd like to have a solid story for yamlscript homoiconicity...

2024-04-19T16:25:53.672599Z

Am much too exuberant to split hairs. If YS is YAML & its data literals are YAML, then that just about does it for me, and if YS can generate data that also happens to be valid YS then that's 110%.

👍 1
Ingy döt Net 2024-04-19T16:26:45.227929Z

I think it's a topic that will be raised in the future. Glad to have your insights 🙂

Ingy döt Net 2024-04-19T16:28:47.981119Z

YS is and must be valid YAML. I didn't even write the first stage (parser). That's the java yaml parser snakeyaml-engine. Writing a parser is a LOT of work 🙂

Ingy döt Net 2024-04-19T16:29:38.413809Z

snakeyaml (or maybe snakeyaml-engine) backs clj-yaml

Ingy döt Net 2024-04-19T16:30:03.181849Z

snakeyaml -> yaml 1.1 snakeyaml-engine -> 1.2

Ingy döt Net 2024-04-19T16:30:47.118869Z

I will likely swap out that parser later as it has edge cases spec failures. but more than good enough for now.