Troubleshooting & Common Mistakes
We have summarized errors that are easy to encounter while learning LuneScript and their solutions.
This focuses on points where experienced users of other languages (especially Lua, Go, Rust, etc.) are
likely to get stuck.
Character Literal Syntax
Mistake: Using single quotes
// Error
let c = 'a';
let c = ?'a';
Correct: Write the character immediately after ?
// Becomes character code (int)
let c = ?a;
let sp = ? ; // Same for space
let zero = ?0; // Character code for the digit
In LuneScript, character literals are treated as integer values (character codes).
Mutable Method Definition
Mistake: Prefixing with mut
class MyClass {
let mut val: int;
// Error: illegal field or method declaration
pub mut fn inc() {
self.val = self.val + 1;
}
}
Correct: Place mut after the argument list
class MyClass {
let mut val: int;
// Indicates that the method modifies itself (self)
pub fn inc() mut {
self.val = self.val + 1;
}
}
In method definitions, mut functions as a declaration of the side effect 'this method
modifies self', so it is written as part of the signature (on the trailing side).
Note that if there is a return value, it comes before the return type, like
pub fn func() mut : int.
Pattern Matching of ADTs
Mistake: Trying to use if let (Rust style)
// Error: illegal exp
if let .Val( v ) = val {
print( v );
}
Correct: Use the match statement
match val {
case .Val( v ) {
print( v );
}
default {
// Handling when no match is found
}
}
In the current version of LuneScript, using the match statement is the standard way to
decompose Algebraic Data Types (ADTs).
Manipulation of Nilable Types and unwrap
Mistake: Treating Nilable types as Non-nilable directly
let val: int! = 10;
// Error: type mismatch int! (nilable) to int
let num: int = val;
Correct: Use unwrap to extract values safely
let val: int! = 10;
// Specify a default value if it is nil
let num: int = unwrap val default 0;
// Or narrow it down with if let
if let v = val {
print( v ); // Here v is of type int
}
unwrap is used to either 'guarantee that the value is not nil' or 'provide an
alternative value if it is nil'.
Macro Syntax Errors
Mistake: Forgetting the expansion operator ,,
macro _dprint( val: __exp ) {
print( val ); // Error: val is of type __exp and cannot be used as is.
}
Correct: Use ,, to expand the expression
macro _dprint( val: __exp ) {
print( ,,val ); // OK: Expression is expanded
}
To use macro arguments (__exp, sym, __block, etc.) within the
code, they must always be expanded with ,,.
Mistake: Using Lua keywords as symbol names
macro _measure( block: __block ) {
{}
{
let start = os.clock();
,,block
let end = os.clock(); // Error: 'end' is a Lua keyword
print( end - start );
}
}
Correct: Use names that avoid keywords
Because LuneScript is converted to Lua, an error will occur if variable names in code expanded by
macros collide with Lua keywords (e.g., end, function,
repeat). Please change them to different names like endTime.
Mistake: Writing statements directly in a __block argument
_measure( print("hello") ); // Error: A block {} is required, not an expression
Correct: Pass it enclosed in {}
_measure( { print("hello"); } );
Also, in the latest LuneScript syntax, using the argument omission feature with ##
instead of __block may be recommended. Please adjust according to compiler warnings.
Mistake: Attempting to define or call normal functions within a macro-statement
macro _Test() {
{
fn createFunc( name: str ): stat { // Error
return `{ fn ,,,name() {} };
}
}
,,createFunc("hoge");
}
Correct: Understand that macro-statement is a restricted environment
Within a macro-statement block, the type system and user-defined functions are not fully
available. Basically, it's safer to stick to calculations using built-in types and built-in
functions, and code generation with `{}.
Mistake: Range of the ,,, operator is unclear
stats.insert( `{
let ,,, "v_%s"(name) = ,,i; // Error: Unclear where the name generation expression ends
} );
Correct: Explicitly indicate the termination with ~~
stats.insert( `{
let ,,, "v_%s"(name) ~~ = ,,i; // OK: Tell the end of the expression with ~~
} );
The ,,, operator, which generates symbols dynamically, often requires a ~~
delimiter to prevent it from being interpreted as combined with subsequent elements.