Version Checking in MiniScript
Tags: miniscript, minimicro, programming, beginners
Published: 2024-06-20 15:40:35

MiniScript runs in a lot of different environments.  Moreover, the language itself changes from time to time.  So, to write a script that works in multiple places, sometimes you need to check the version of the language and environment in which it's running.

## The `version` intrinsic

Since MiniScript version 1.4 (which came out in June 2019), there has been a `version` intrinsic which gives you information about the language itself, as well as the host environment.  Here's what it looks like in Mini Micro:

![Screen shot of `pprint version` in Mini Micro](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ryjk8whpflkqn0kf1560.png)

You can see that this screen shot was taken in Mini Micro (`hostName`), and in version 1.2.1 — represented in numeric form as 1.21 (don't worry, we'll never go beyond version 1.9.9 before advancing to version 2!).  This Mini Micro was built on April 1, 2024, and the language itself is version 1.6.2.  It also gives you some handy URLs where you can find out more about the language and host.

Now let's look at the same information in command-line MiniScript.

![Screen shot of `version` printed in command-line MiniScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6vocqle3jbkwlt4sz631.png)

The `pprint` function doesn't exist here (in Mini Micro, it's one of the handy little extras defined in /sys/startup.ms).  So, in the screenshot above, I used regular `print`, and then followed it up with a little one-liner that prints each key-value pair on its own line, similar to `pprint` in Mini Micro.

Here you can see that the screen shot was taking using the Unix command-line version of MiniScript, built on March 15, 204.  The version of that command-line host is 1.3, and the MiniScript language itself is again 1.6.2.

## Handling Host Differences

You can use this to make your code do different things depending on where it's running.  For example, the [Acey-Deucey game](https://miniscript.org/MiniMicro/index.html?cmd=run%20%22%2Fsys%2Fdemo%2Facey-deucey.ms%22) included with Mini Micro at [/sys/lib/acey-deucey.ms](https://github.com/JoeStrout/minimicro-sysdisk/blob/master/sys/demo/acey-deucey.ms) is designed to work on command-line MiniScript, too.  But the latter doesn't have the Sound class, so we "mock" that class at the start of the program, so the rest of the code doesn't need to worry about it.

```
// Define some common stuff that makes this code work both
// in Mini Micro, and in command-line MiniScript.
if version.hostName == "Mini Micro" then
	clear
	chaChing = file.loadSound("/sys/sounds/cha-ching.wav")
	hit = file.loadSound("/sys/sounds/hit.wav")
else
	// For command-line MiniScript, make dummy mock-ups 
	// for the Sound class and our two sounds.
	Sound = {}
	Sound.play = null
	chaChing = new Sound
	hit = new Sound
end if
```

## Handling Version Differences

As another example, the [Release Notes](https://miniscript.org/files/MiniScript-Release-Notes.txt) show that the second parameter to `print`, allowing you to change the line delimiter, was added in MiniScript 1.6.  So you might write something like:

```
for i in range(1, 10)
	if version.miniscript >= "1.6" then
		// print all our counts on one line (yay!)
		print i, ""
		if i < 10 then print "...", " "
	else
		// print each count on its own line (boo)
		print i
	end if
	wait 0.5
end for
```

It's important to note that, for historical reasons, `version.miniscript` is a string, while `version.host` is a number.  So you'll want to do a string or numeric comparison depending on which version you're looking at.

## Dealing with very old versions

As `version` has been around since 2019 -- and there have been a ton of other improvements since then -- hopefully you don't need to handle any environment older than that.  But what if you did?

In this case, you'd have to look for behaviors that differ from modern MiniScript, but don't actually generate an error.  Here are some thoughts (again, from the [Release Notes](https://miniscript.org/files/MiniScript-Release-Notes.txt)):

- If a non-empty map like `{1:1}` evaluates to false in an `if` statement, you're running MiniScript 1.0 (prior to September 2017).
- If comparing a map to itself with `==` returns `null`, you're running 1.1 or before (prior to June 2018).
- If expressions like `1 and null` are not evaluated correctly, you're in version 1.2 or earlier (prior to March 2019).
- If string subtraction like `"foobar" - "bar"` doesn't give the right result, then you're prior to 1.4 (June 2019) -- and if it does, then you should be safe to check `version`!

Have you ever needed to write MiniScript code that works in multiple environments (or language versions)?  Share your experiences below!