WarpScript best practices
WarpScript is a concatenative stack based language. Once you've read the basic concepts, you will get used to manage the stack state in your brain, while writing WarpScript. Without any kind of obfuscation, you can turn your code to brainfuck really easily...
Look carefully at the code below. What is this doing ?
Well, it outputs a map of numbers and their factorials, without any variable use.
And what does this WarpScript do?
The same thing with far less warpscript operations.
The common points of both scripts:
- You will not be able to understand them one week after writing them
- They seem to be highly optimized
- There is not a single comment
Do not over optimize
Warp 10 is written in Java. The JVM will optimize your code, especially if you run it several times (the Just In Time compiler will turn it in native machine code).
Do not try to over optimize your WarpScript from start. The best practice is to do something functional, easy to read a few days later (comments help).
You will optimize later the loops called several hundred of millions time.
If you do have performance problem, contact the Warp 10 core team.
Keep your stack clean
Mental visualization of the stack state when you are doing WarpScript is a gym you will get used pretty fast. But it is a waste of brain time to have to do the job each time you open a 200 lines WarpScript program.
To simplify, divide your code into blocks. Between each block, write a comment with the stack content, if any.
Code review:
On line 9, it would be great to store the resulting GTS in a variable, instead of leaving it on the stack and SWAP it later. On line 7, using PICK is not a good idea for readability. A few comments will help.
Use well documented macros
Writing custom functions is a basic reflex for every language. In WarpScript, you will do inline or server side macros.
You can document them with a few comments, or you can use the INFO function. INFO
will allow you to later generate a documentation from within WarpScript.
Code review:
Well, that's far more readable. It could be optimized later if needed. Between each block, the stack is empty You might do something to clearly separate arguments of the PUT function. Maybe adding spaces to understand $key @factorial is the value expected by PUT, for example: $result $key @factorial $key PUT
VSCode plugin allows you to develop your server side macros easily. See documentation here.
Macro skeleton
In VSCode, when you type "macro", a snippet will output the typical WarpScript macro skeleton:
<%
{
'name' '<macro name>'
'desc'
<'
Macro description
'>
'sig' [ [ [ 'input:TYPE' ] [ 'output:TYPE' ] ] ] // Signature
'params' {
// Signature params description
'input' 'TODO'
'output' 'TODO'
}
'examples' [
<'
Warpscript usage example
'>
]
} INFO
SAVE 'context' STORE
// Code of the actual macro
$context RESTORE
%>
'macro' STORE
// Unit tests
$macro
The content of /macros/maths/factorial.mc2 could be:
Unit tests will be called each time the macro is reloaded by Warp 10. Not every time the macro is called. When you execute a macro file itself, the output stack should contain only one element, and this element must be a MACRO (check that it is the case with TYPEOF).
Your unit tests must leave the stack clean. In a large project, you will end up with lots of macros.
INFO
andINFOMODE
will allow you to generate automatic documentation.
- Do not optimize too soon, prefer a clear style and keep your stack clean between code blocks.
- Use variables.
- Stack gym is brain consuming. It is absolutely necessary when you write WarpScript, but it should not be when you read your WarpScript a few week later.
- Custom function = macro.
- Macro documentation generation is possible.
- Include unit tests in your macros.
- There is no style rules for WarpScript yet. Craft your own!