Common mistakes
Gotchas and frequent errors when learning Quadrate.
Using parameter names as variables
Parameter names in function signatures are documentation only. They don't create variables:
// WRONG - a and b are not defined
fn add(a:i64 b:i64 -- sum:i64) {
a b + // Error!
}
// RIGHT - use stack operations
fn add(a:i64 b:i64 -- sum:i64) {
+
}
// RIGHT - bind with ->
fn add(a:i64 b:i64 -- sum:i64) {
-> b -> a
a b +
}
Wrong argument order
In a stack-based language, argument order matters. The last value pushed is on top:
// Push 10 then 3: stack is [10, 3] with 3 on top
// The - operator does: second_from_top - top = 10 - 3 = 7
10 3 - print nl // 7, not -7
// If you want 3 - 10:
3 10 - print nl // -7
Forgetting -> when binding parameters
A common pattern is to forget binding parameters in reverse order:
// WRONG - parameters are in wrong order
fn distance(x1:f64 y1:f64 x2:f64 y2:f64 -- d:f64) {
-> x1 -> y1 -> x2 -> y2 // x1 gets the LAST pushed value (y2)!
}
// RIGHT - bind in reverse order (last pushed = first popped)
fn distance(x1:f64 y1:f64 x2:f64 y2:f64 -- d:f64) {
-> y2 -> x2 -> y1 -> x1 // Correct order
}
The last parameter in the signature is on top of the stack, so it gets popped first.
Stack underflow
Trying to use more values than are on the stack:
// WRONG - only one value on stack, but + needs two
fn main() {
5
+ // Error: stack underflow
}
Leaving values on the stack
Functions must leave exactly the number of values declared in their output signature:
// WRONG - leaves extra value on stack
fn double(x:i64 -- result:i64) {
-> x
x
x 2 * // Stack has [x, x*2] but signature says only 1 output
}
// RIGHT
fn double(x:i64 -- result:i64) {
-> x
x 2 * // Stack has [x*2], matches 1 output
}
Forgetting to handle errors
Fallible functions (marked with !) must have their errors handled:
use io
// WRONG - compiler error, must handle the error
fn main() {
"test.txt" io::read_file
}
// RIGHT - handle with switch
fn main() {
"test.txt" io::read_file switch {
Ok {
-> content
content print
}
_ {
"Could not read file" print nl
}
}
}
// RIGHT - abort on error with !
fn main() {
"test.txt" io::read_file! -> content
content print
}
Module not found
If use json gives an "unknown module" error, the module might be an external package that needs to be installed:
quadpm get https://github.com/quadrate-language/json
See External Packages for the full list.
Integer vs float confusion
2 is an integer, 2.0 is a float. Some functions accept both, but being explicit about types is good practice:
// Works, but implicit conversion
2 math::sqrt
// Better - explicit about the type
2.0 math::sqrt
Use cast for explicit conversion:
2 cast<f64> math::sqrt print nl // 1.41421