Skip to content

The Truth about Sunday

Or better yet...

The Sunday about Truth🔗

If I were to tell you that YS has a system,
to determine if something is true...
I'd deserve hell and fire,
and be labeled a liar,
for in total truth, YS has 2!

Boolean Truths🔗

As I was telling you yesterday, programming languages each have their own set of rules for truthiness. In essence, this is their "boolean" system.

In general, a language defines a set of values that are considered "false" and then all other values are considered "true".

Java is very strict in that only false and true can be used in boolean contexts, and if only accepts boolean values.

Python, on the other hand, is very lenient: False, None, 0, and empty sequences like "", [] and {} are "false". Everything else is "true".

Lisps generally have one or two false values, although there is not general consistency between them. Scheme has #f, Common Lisp has nil and () and Clojure has false and nil.

Since YS is really Clojure in disguise, it also defines false and nil as false and everything else as true.

The YS Alternate Truth🔗

A boolean system using false and nil is a solid and practical foundation, in my opinion. But it doesn't always offer the best developer experience in code.

As a programming language YS chose to build on a solid foundation, and Clojure most certainly is a solid, practical, immutable, FP (functional programming) language. But YS also embraces the mantra of Perl's "Make simple things simple, and hard things possible".

So YS has a second truth system, where values are considered "truey" or "falsey".

This system is much like Python's: false, nil, 0, 0.0, "" and other empty sequences are "falsey" and everything else is "truey".

Let's look at a simple example:

$ ys -e '
if ARGS.count() > 0:
  say: "The command line arguments were: $ARGS"
  say: "No command line arguments were provided"
' -- a b c
The command line arguments were: ["a" "b" "c"]

The "truey" way to write this is:

$ ys -e '
if ARGS.?:
  say: "The command line arguments were: $ARGS"
  say: "No command line arguments were provided"
'
No command line arguments were provided

That's short for:

$ ys -e '
if ARGS:truey?:
  say: "The command line arguments were: $ARGS"
  say: "No command line arguments were provided"
' -- foo 42
The command line arguments were: ["foo" 42]

It might not seem like a huge improvement to use ARGS.? instead of ARGS.count() > 0 here, but these boolean operations show up so often that being able to state them succinctly can be a big win in readability.

The choice, of course, is yours.

All the Truey Operations🔗

If truth be told, this "alternate truth system" is not really a system at all. It is merely a set of functions and operators that behave according to the YS truey rules.

Here they are:

  • truey?(x) - A function that returns the value if it is truey, otherwise nil
  • falsey?(x) - A function that returns true if the value is falsey, otherwise false
  • or?(x y z...) - A function that returns the first truey value or nil if none are truey
  • and?(x y z...) - A function that returns the last truey value or nil if one is falsey
  • ||| - The binary operator for or?
  • &&& - The binary operator for and?
  • T? - A short alias for truey?
  • F? - A short alias for falsey?
  • .? - The chain operator for truey?
  • .! - The chain operator for falsey?

There's also the related operators for the normal boolean functions:

  • .?? - The chain operator for boolean(x)
  • .!! - The chain operator for not(x)

These both return either true or false.

The Truth is In There🔗

In my experience, this combination of ways to test for truthiness lead to a cleaner way to ask questions in YS code.

Let me know what you think in the comments below!

Comments