Skip to content

The YS Blog🔗

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 get 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!

v0 is now Stable (essentially)

I'd like to start off by saying that v0 is essentially stable at this point.

This means that YAML files starting with !YS-v0 should continue to work without any changes.

Put another way... "Don't worry, be YS!"

Work is currently under way to put out a stable v1 release in the next couple of months and then start work on v2.

What is v1?

It might seem strange to only spend a couple of months on v1. It won't be much different from v0 when it is released.

Actually that's the point.

Declaring the stable version to be v0 doesn't make much sense. At least it doesn't seem like it would spark much confidence.

Having a stable v1 out there is what many people are waiting for. In reality it shouldn't be much different than how things stand today. But it will be a promise.

The promise is that, once released, all code written for v1 will continue to work in the future.

While v1 is under development, it will be available to use as !YS-v1-a.

In essence, the v1 (short) dev period will be useful for ironing out the details of creating a new YS version.

More About the Version Numbering

The v0, v1, v2 etc indicates the major version number (in the semver sense) of the YS language version.

The plan is to use semver for the versioning.

v1 shows up in several places:

  • The !YS-v1 tag
  • The #!/usr/bin/env ys-0 shebang line
  • The ys-0 and ys-0.2.1 binary names

Somehow any piece of YS code needs to know what version of YS it was written for.

When v3 comes out, it should be able to use libraries written for v1, v2, or v3.

It's an ambitious goal, but it should allow for a lot of flexibility and an ever improving language.

Clojure Stability

To pull this off, it is very fortunate that Clojure is extremely stable and backwards compatible.

In my personal experience, I've never seen Clojure code break when upgrading to a new major version of the language and/or tooling.

What is the actual Plan?

I wrote up a couple of internal documents for the YS team about v1 and versioning.

I'll share them with you now that the team has had a chance to review them:

These documents are still subject to change, but they are what we are working with now.

If you have any questions, or suggestions, please let us know.

You can start in the comments below.

YS External Modules

Reusing code is the cornerstone of good programming.

If you see duplicate logic, refactor it into a function.

If you see a function that's used in multiple places, move it to a module.

If you need the module in multiple repos, publish it online.

Today let's see how we'd go about refactoring a YS program's useful functions into an external module for reuse by anyone.

YS Regular Expressions

All modern programming languages have regular expressions.

YS has them too.

Perl was the first modern language to include them as a built-in feature.

YS regexes borrow quite a bit from Perl's, but also behave as functions that return matching results (unlike Perl, and more like all the others).

Let's take a look...

The Special Little Symbol

Yesterday I showed you a FizzBuzz solution in YS. Here it is again:

!YS-v0

defn main(n=100):
  each x (1 .. n): !:say
    or? _ x:
      str ((x % 3).! &&& 'Fizz'):
          ((x % 5).! &&& 'Buzz')

See that _ sitting there in the middle all by itself?

What's that all about?

Well _ is a special symbol in YS, and it means different things in different contexts.

YS / Java Interoperability

We know that YS is made from Clojure and the Clojure is made from Java. Clojure code is interoperable with Java code.

So is YS interoperable with Java?

Yes, YS is can call Java methods on its objects.

Let's see how to do it.

YS Shorties

From the start, YAML has always been about making data clean and easy to read.

This carries over to YS code as well.

Even though YS code compiles to Clojure, YS often has shorter alternatives for Clojure's commonly used and longer function names.

Fun FridaYS — Rosetta Code

It's Friday and I feel like having some fun. With YS, of course.

Rosetta Code is a super fun site that has over 1000 programming tasks that people solve in nearly 1000 programming languages (including YS). If you've never heard of it, you should check it out.

Let's solve a task in YS that hasn't been solved yet!

YS Mode Switching

I've mentioned YS "modes" in passing several times in this series.

YS has 3 modes: data, code, and bare.

Fully understanding modes is one of the most important things to understand about YS.

Today I want to go deeper on the details of modes. This will make everything else much easier to explain going forward.

AI + Clojure Functions in YAML

Yesterday we learned that all YS YAML input compiles to Clojure (Lisp) before being evaluated by a native binary Clojure interpreter runtime.

Does this mean that you could write Lisp functions in your YAML data files? And then call them on your data?

Of course it does!

How Does YS Work?

What if I told you that...

  • YS is made out of Java
  • YS uses no JVM
  • YS is a binary Executable
  • YS is also a Shared Library
  • YS is actually a Lisp
  • YS can use S-Expressions
  • YS prefers YeS-Expressions
  • YS can use modules written in:
    • YS
    • Any other language

Make sense?

YS One Liners

There's almost nothing I like more about programming than one liners.

A one liner is a single line of code that does something useful and doesn't require any extra steps to compile or run.

You type one line, press enter, and get your result.

I first learned about one liners in Perl.

If we have a file.txt with the following content:

one
two
three
four
five

Here's a Perl one liner that counts the number of lines in a file:

$ perl -E '@l = <>; say scalar(@l)' < file.txt
5

The gist of YS

Yesterday we started learning about the ys CLI and there's a lot more cool stuff to learn about it.

But today I want to switch it up and talk about one of my favorite programs that I use many times a day.

You probably know about GitHub gists. They are one of the best ways to share text files with others.

Let's take a look!

The ys Command

There are different ways to use YS but the most common is to use it via the YS command-line tool: ys; a very versatile tool indeed.

There's a lot you can do with ys including using it like you would use jq or yq one-liners:

$ jq .bar < <(echo '{"foo": 123, "bar": 456, "baz": 789}')
456
$ yq .bar < <(echo -e 'foo: 123\nbar: 456\nbaz: 789')
456
$ ys .bar < <(echo -e 'foo: 123\nbar: 456\nbaz: 789')
456

Each of these tools have their own advantages and we'll be diving deep into those waters soon enough.

Today let's just start by exploring the basic things you can do with the ys CLI.

Fancier YS Conditionals

Most languages support a case or switch construct which is a way to handle multiple conditions.

YS supports several similar but different constructs for this.

Today we'll focus on the cond and case functions.