Skip to content

2025🔗

YS Summer Break

When I started the Summer of YS blog series on June 1st, I committed to writing a blog post every day until September 1st (92 days in a row).

Today it's Friday, August 1st, 2025 and today's post is number 62.

It's also the last one!

The loop and more loops

The looping function that offers the most control in YS is called loop. It's also the most verbose.

There are lots of alternatives that are more specific and require less code, but they don't let you do everything, like decide when to stop.

We'll talk about both today.

Sometimes it's hard to be lazy

YS (being Clojure) is a functional language with immutable data structures and lazy evaluation.

Laziness is cool because you can do complicated operations on large (even infinite) sequences without having to load everything into memory.

But laziness can be very confusing when you're not used to it or you don't expect it.

Fun in the SundaYS

Let's do a Fun FridaYS post on Sunday.

I wrote the YS one liner to open 40 random Rosetta Code tasks written in Clojure.

$ cd RosettaCodeData
$ vim $(ys -e 'sh-out("find Lang/Clojure"):lines:shuffle
               .mapv(fn([d] sh-out("ls $d"):lines
               .mapv(fn([f] say("$d/$f")))))' |
        grep -v '\-[0-9]' |
        head -40)

Pretty cool, right?

The YS Core YAML-Schema

The term "YAML Schema" is a bit of unfortunate history.

It's not the YAML version of a JSON Schema.

In my opinion it needs to be renamed because it's not a schema in the typical sense of the word. The term has been part of the YAML spec since the beginning.

Let's use the term "YAML-Schema" instead of "YAML Schema" to be clear that this is not a typical schema applied to a YAML file.

Typically a schema is a set of rules that are used to validate data.

A YAML-Schema is a set of rules about how untagged nodes are implicitly tagged during the loading process.

Allow me to explain.

YS on the Go

Yesterday I hinted at the idea of YS hosted on Go.

This doesn't mean that YS would be rewritten in Go or that it wouldn't compile to Clojure. The Lisp is still essential to YS.

Where I was going was the possibility of creating a Clojure hosted on Go, which I've been thinking about for a while.

Go is the backbone of technologies like Kubernetes, where YS wants to provide a more powerful YAML experience.

As I was getting ready for bed, the word "Glojure" popped into my head.

What a perfect name for a Go hosted Clojure!

Why YS Chose Clojure

So YS compiles to Clojure.

It also has a Clojure runtime and access to the Clojure ecosystem.

It's also written in Clojure. (It didn't have to be. The compiler could have been written in any language.)

Why Clojure?

I'll explore that topic today.

YS Streaming Mode

We've seen before that YS can work with YAML files that contain multiple documents. "Document" is the YAML term for a single top level node (object).

YS returns the last document in the file by default.

YS can also load all the documents in the file.

This is called streaming mode, and we'll learn more about it today.

ys and yq

Today I met Mike Farah, the creator of yq!

I help maintain the go-yaml YAML framework for Go, and am working with Mike to help it fix certain issues in yq.

It looks like a promising future for both go-yaml and yq.

It turns out that YS has a lot of crossovers with yq.

Let's take a closer look at how they compare.

Calling Shell Commands from YAML

Wouldn't it be handy to get data from shell commands in YAML?

Well you can, and it's really easy.

YS has a bunch of functions in its Standard Library for calling shell commands, and passing data to and from them.

Let's take a look...

YAML Best Practices

YAML has a Core Development Team of five people that I am a member of.

In May 2024, 4 of us met in Berlin. One of the things we did was to write a list of best practices for YAML. We came up with a list of 40 or so things that we all agreed on.

Today I'll share some of those with you.

YAML Explicit Keys and YS

Did you know that in YAML you can write:

? foo
: bar

instead of:

foo: bar

The ? is called an explicit key indicator.

But why would you want to use it?

It's not often useful in YAML config files, but it is actually useful in YS code.

YS Comment Syntax

What is the syntax for comments in YS?

Well that's simple.

YS code is YAML, so the comment syntax is the same as YAML.

Well, there's a little bit more to it than that.

Making YS be Valid YAML

I'll say it again. All YS syntax is 100% YAML. The YS compiler uses a third party YAML parser so there is no way that YS code cannot be YAML.

YS code also uses a lot of Clojure syntax. This makes sense since the code gets compiled to Clojure in the end.

Some Clojure code looks a lot like YAML but with subtle differences.

Today we'll talk about the little gotchas that can trip you up when you're writing YS code, and how to work around them.

YS Currying in YAML Configs

In functional programming, currying is a technique where a function that takes multiple arguments is called with fewer arguments than it takes and returns a function that takes the remaining arguments.

In Clojure and YS, the partial function is used to create a curried function.

Here's an example:

$ ys -e '
multiply-by-6 =: partial(mul 6)
multiply-by-7 =: mul.partial(7)
say: multiply-by-6(7)
say: multiply-by-7(6)
'
42
42

That's neat but how is it useful in YAML configs?

YS Mapping Key Uniqueness

I've said it before, but YS code is 100% valid YAML.

Here's a YS program:

!YS-v0
say: 'You say Goodbye'
say: 'I say Hello'

YAML says that mapping keys must be unique.

That program seems to be a YAML mapping with two keys that are the same.

How can this be valid YAML?

YS Testing

YS is a great language for writing tests in.

Why?

Well tests are mostly data. Inputs and outputs for some code you want to test. Code is usually in functions, and functions usually have names and names are just strings and strings are just data.

YAML is a great format for data. YS is YAML with code (expressed as YAML data).

So it seems like YS should be a great language for writing tests in. And it is.

YAML gets YS in PHP, C#, Lua & Haskell

YS is a YAML loader module. On one hand it does have super powers, but on the other hand it's just a plain YAML loader.

A YAML loader is a utility that can turn YAML into a data structure. Every modern language has a YAML loader. Most have many.

YS is the first YAML loader that was made for every programming language.

Well that's the goal anyway.

For the past year it's only had loaders for 11 languages: Clojure, Crystal, Go, Java, Julia, NodeJS, Perl, Python, Raku, Ruby, and Rust.

Until this week, that is...

Building YS

Try running these commands on Linux or Mac:

git clone https://github.com/yaml/yamlscript
cd yamlscript
make install

Chances are that everything will just work. You'll have new builds of ~/.local/ys and ~/.local/lib/libys.so (.dylib on a Mac).

YS actually has a lot of heavy dependencies like Clojure, Java, Maven, GraalVM, etc.

So how does it just work?

Today I'll tell you!

About the v0

The current version of YS as of today is 0.2.1.

I'm sure you've noticed the v0 part of the !YS-v0 tag by now.

YS intends to be a "versioned programming language", where v2 can behave very differently from v1 while still being able to use v1 libraries and such.

Today I'll tell you a bit more about the versioning and how things are expected to work.

Remember, we are still officially at v0 so even the rules of how versioning works are not yet set in stone!