Printing
- Rockstar 2 introduced
print
, but you can still use say
to save two bytes.
- Both
print
or say
append a newline to the output. Rockstar 2 introduced write
, which is functionally equivalent, but doesn't append a newline to the output by default.
Assignment
Unlike Rockstar 1, you can do x=y
instead of x = y
.
Augmented assignment
In Rockstar 2, var'sXval
(short for var is X val
) is the equivalent of other languages' var X= val
, where X
is in +-*/
. While this often doesn't save a byte, it can still be useful, since you can't group expressions with ()
and, in general, it can save over using an auxiliary variable.
Pronouns
Rockstar 2 supports i
as a pronoun, even though it's documented obscurely.
Handling ARGV
This is undocumented, but i
's initial value is arguments
. It's shorter to assign another variable to i
if need be than use arguments
directly.
Comparisons
Rockstar 2 has undocumented <
, >
, <=
and >=
operators, as well as =
(=
+ space, ==
in other languages) and !=
(also with a space).
Printing \
\
now acts like any other character. There used to be an issue.
Whitespace
Usually, statements are separated by a newline (or punctuation within ;.!?
), and blocks are ended by 2 newlines, for example:
x=1
for n in 5
m=n*3
say m
say x
Top-level statements do not need newlines between them, and if one ends in [0-9"]
, it can be attached to the one after it with no whitespace at all:
x=1y="hello"z=3for n in 5
m=n*3
say n
Blocks with a single statement inside them can be collapsed into a single line, and doing so removes the need for multiple newlines after them:
for n in 5 say n
for x in 5 for y in 5 if x>y say x*y
say "done"
A single-line block, if at the top level, does not need a trailing whitespace at all:
for n in 5 say n+1say "done"
Nested blocks require multiple newlines to close them, for example:
for n in 5
if n>2
for y in 5
x=n<y
say n+x
say "done"
But you can collapse the block headers onto a single line, so that only 2 newlines are needed to close the block:
for n in 5 if n>2 for y in 5
x=n<y
say n+x
say "done"
If the code ends after a block, you don't have to close it, no matter how nested the block is.
An odd quirk of if-else
: Say you want to port this pseudocode to RS2:
n=10
if n<10 {
x=n*2
if x>10 { print x }
} else {
y=n*3
print y
}
You might try to port it like this, but it would fail because the else
would pair to the inner if
:
n=10
if n<10
x=n*2
if x>10 say x
else
y=n*3
say y
You can fix this by just adding a space before the else
. No idea why:
n=10
if n<10
x=n*2
if x>10 say x
else
y=n*3
say y
Precedence of ,
The ,
separator (to form expression lists) can sometimes be used to override precedence and create statements that otherwise wouldn't be possible without intermediate variables. For example, consider
say "Foo"+x at 0+"Baz"
vs
say "Foo"+x at 0,"Baz"
The first example tries to query x
for key "0Baz"
, since +
has higher precedence than at
. The second one doesn't, because at
doesn't accept expression lists, hence its operand is just 0
, with the ,
belonging to the outside expression.
Integer Division
You may be able to save a byte on floor division by using a loop (at the cost of probably a lot of speed).
x=50.y=7.z=x/y.turn down z.say z.
x=50.y=7.for z in 1+x/y 0.say z.
Rounding
Apart from using the built-in turn up
, you can round a positive number up by multiplying it with a string and then dividing it by the same string:
x=3.1
x=x*"."/"."
say x
For negative numbers, this will turn the number positive and round it up.
Built-ins
There's not a lot of built-ins, but acquaint yourself really well with the few there are. These include operators, mutations, at
, rock
/push
(push value at end), pop
(pop last element, mis-documented) and roll
(pop first element). Consider all types of arguments to these as well. Some very nifty tricks arise from their clever usage. Some of them are listed here.
- To get the length of a string, split it into an array with
cut
, and let the array evaluate to its length.
- Alternatively, you can get the length of a string using
str*"."/"."
(using a single character guaranteed not to be in the string for "."
)
- If the string is guaranteed not to have length 1,
cast
can also be used to get the codepoints of its characters instead, should they prove helpful.
- Since Rockstar doesn't have a (concise) integer division built in, it can be useful to check whether a number is an int. This can be done by checking if its string representation contains a
.
, using number/"."
.
- If your program's arguments can be considered as tuples joined with a delimiter, after you
cut
each argument, use pop
, roll
and at
on the resulting array to read them into variables. You can try to make the remaining array be useful in some form (or even get an empty array) by combining these carefully.
- If you have to pick an arbitrary delimiter, and you don't have a variable assigned to a good string, try to use a 1-digit number, as you won't need to wrap it in
""
within join
and cut
statements. In some cases, a 2-digit number, ok
or no
could also be better than a string literal.