New Operators
Operator Aliases
These operators function the same, but they're more consistent with what's been standardized through programming today.
!
is an alias fornot
, the boolean inversion operator.!=
is an alias for~=
, the inequality operator.
Compound Operators
A plethora of compound operators are available in Pluto:
- Addition:
+=
- Subtraction:
-=
- Multiplication:
*=
- Float division:
/=
- Integer division:
//=
- Modulo:
%=
- Exponent:
^=
- Bitwise AND:
&=
- Bitwise OR:
|=
- Bitwise XOR:
~=
- In Lua, the inequality operator cannot be used in statements. It must be used in expressions. Because compound operators can only be used in statements (and cannot be used in expressions), this is not a compatibility break.
- Bitshift left:
<<=
- Bitshift right:
>>=
- Concatenation:
..=
- Nil-Coalescing:
??=
local a = 1
a = a + 1
a += 1
Compound operators are syntactic sugar. They'll call the same metamethods as their non-compound counterparts.
Coalescing Operator
The nil-coalescing operator is helpful for evaluating values against nil
.
If the left-hand operand is nil
, it returns the right-hand operand. Otherwise, it returns the left-hand operand.
local function say(message)
print(message ?? "The message was nil.")
end
say() --> The message was nil.
say(nil) --> The message was nil.
say("Hello, world!") --> Hello, world!
It's a cleaner version of this code:
local function say(message)
if message == nil then
message = "The message was nil."
end
print(message)
end
say() --> The message was nil.
say(nil) --> The message was nil.
say("Hello, world!") --> Hello, world!
You can even use compound assignment:
local function say(message)
message ??= "The message was nil."
print(message)
end
say() --> The message was nil.
say(nil) --> The message was nil.
say("Hello, world!") --> Hello, world!
This operator does not implement any metamethods.
Walrus Operator
The Walrus operator allows you to perform assignments inside of conditional expresssions.
if a := get_value() then
-- 'a' was assigned a truthy value.
else
-- 'a' was assigned a falsy value.
end
You can imagine it like this, but note they're not always the same:
do
local a = get_value()
if a then
-- 'a' was assigned a truthy value.
else
-- 'a' was assigned a falsy value.
end
end
Note that for while-loops, it will be executed as many times as the condition:
while a := next_value() do
-- ...
end
while true do
local a = next_value()
if not a then break end
-- ...
end
Spaceship Operator
The spaceship operator, also known as the three-way comparison operator, allows you to quickly compare 2 values for equality and order.
local eq = 1 <=> 1
local lt = 3 <=> 42
local gt = 9 <=> 5
print(eq, lt, gt) --> 0, -1, 1
It works with any type that supports __eq
and __lt
, making it well-suited for usage in generic algorithms like sorting. The return values are designed such that you can compare them to 0
, e.g. with the values from above:
print(eq <= 0) --> true
print(lt <= 0) --> true
print(gt <= 0) --> false
Pipe Operator
The pipe operator allows you represent data pipelines more succinctly.
local { http, json } = require "pluto:*"
http.request("https://httpbin.org/get")
|> json.decode
|> dumpvar
|> print
--> {
--> ["args"] = {},
--> ["headers"] = {
--> ["Host"] = string(11) "httpbin.org",
--> ["User-Agent"] = string(56) "Mozilla/5.0 (compatible; Soup Library; +https://soup.do)",
--> ["X-Amzn-Trace-Id"] = string(40) "Root=1-65e05b66-6aa8b7c94e7580774a804c24",
--> ["Accept-Encoding"] = string(13) "deflate, gzip",
--> },
--> ["origin"] = string(13) "1.2.3.4",
--> ["url"] = string(23) "https://httpbin.org/get",
--> }
Try It Yourself
The HTTP-to-print pipeline here would otherwise be written like this:
print(dumpvar(json.decode((http.request("https://httpbin.org/get")))))
Note that the pipe operator only passes on the first return value, which is classically achieved by wrapping the expression in an extra pair of parentheses.
Additional Arguments
It is also possible to provide additional arguments for the righthand side of the pipe operator:
local producer = || -> "10"
producer()
|> tonumber|16|
|> print --> 16
Try It Yourself
Methods Calls
There is specialized syntax for method calls with the pipe operator, too:
local producer = || -> 21
local obj = {
function multiply(value)
return value * self.factor
end
}
obj.factor = 2
producer()
|> obj:multiply
|> print --> 42
Try It Yourself
Anonymous Functions
The righthand side of the pipe operator can also be an anonymous function, allowing for more advanced usage like this:
local producer = || -> 42
producer()
|> |res| -> print($"The result was {res}")
--> The result was 42