Syntax
Comments
Single Line Comments
Single-line comments begin with #.
Example:
# This is a single-line comment
Multi Line Comments
Multi-line comments begin with // and end with \\.
Example:
//
This is a
multi-line
comment
\\
Imports
Hachi imports modules with >@.
Example:
>@ "fmt"
>@ "so"
>@ "data/map"
Imports are typically written near the top of a file and do not include the file extension.
Primitive and Core Types
Int - Integer
Holds positive or negative whole numbers.
69
420
-86
Flt - Floating Point Number
Stores positive or negative decimal values.
69.420
-867.5309
Bool - Boolean
Boolean values are represented as tru and fls.
tru
fls
Byte
Represents a single byte value.
65.Byte
String
Strings are enclosed in double quotes.
"This is a string"
"This is another one"
Void
Used for functions or operations that do not return a value.
AnyT
AnyT is Hachi’s generic-like catch-all type for values that may vary in type.
printThing:: {AnyT}:(
print: Ri
)
printThing: 69
printThing: 69.420
printThing: "Goodbye World!"
printThing: tru
General Syntax Philosophy
Hachi is designed to be lightweight and deductive. Many constructs intentionally share syntax so the language feels compact and flexible rather than heavily ceremonial.
Hachi also does not use indentation as syntax. Newlines usually terminate statements, but structure is driven by parentheses, braces, operators, and context.
Vars, Functions, and Constants
Accessing Vars and Calling Functions
Accessing a variable and calling a function with no arguments look the same.
# A variable
myVar
# A function with no input
myFunc
Assignment and Single-Input Calls
Assignment and function calls with one input also share syntax.
# Variable assignment
myVar: "This is my variable."
# Function call with one input
myFunc: "Input goes here"
# Assigning the result of a call
result: myFunc: "Input goes here"
Tuples and Multi-Input Calls
Creating a tuple and calling a function with multiple inputs also use the same form.
# Tuple creation
myTuple: 69, -4.20, fls
# Function call with multiple inputs
myFunc: input1, input2, input3
Constants
Constants are declared with ::.
a :: 3
print: b
b :: a + c
c :: 2
Constants may be defined before or after where they are used, as long as they can be resolved at compile time.
Structures and Tuples
Structures are constant type definitions.
Defined Structure
Named elements can be assigned in a struct definition.
DefinedStructure :: {
thing1: Int
thing2: Bool
thing3: String
}
Positional Structure
If field names are omitted, Hachi treats the structure as positional.
Positional elements can be accessed in two equivalent ways:
- by letter alias:
.a,.b,.c, and so on - by zero-based index:
.0,.1,.2, and so on
The letter form is kept for backwards compatibility and remains fully supported. The numeric form is useful for newer code and scales more naturally for larger tuples.
TupleExample :: {
Int
Bool
String
}
otherTuple :: {Int, Bool, String}
Example access:
pair: 7, fls, "doggo"
print: pair.a
print: pair.b
print: pair.c
print: pair.0
print: pair.1
print: pair.2
Both styles refer to the same positional elements:
pair.a==pair.0pair.b==pair.1pair.c==pair.2
Functions
Functions are commonly declared with ::, though they may also be assigned with : when you want function-valued expressions.
Function Signature
Define as Constant
<function-name> :: <input-parameters> -> <return-values> : (
<function-body>
)
Define as Variable
<function-name> : <input-parameters> -> <return-values> : (
<function-body>
)
Return Values
Hachi returns the final expression in the function body.
Some Input and Some Output
echoThing:: {String} -> {String}:(
text: Ri.a
text
)
Some Input and No Output
announce:: {String}:(
print: Ri.a
)
No Input and Some Output
getNumber:: {} -> {Int}:(
6 + 9
)
No Input and No Output
showOS:: {}:(
hcmd: "cat /etc/os-release"
)
Parameters
Function parameters may be written as plain types, named typed elements, or struct-like grouped inputs.
Multiple parameters may be separated by commas, spaces, semicolons, or newlines.
Input Parameters as Types
Right-Side Input
showRight:: {String}:(
print: Ri.a
)
Left-Side Input
showLeft:: {String}.{}:(
print: Li.a
)
Both Left-Side and Right-Side Input
showBoth:: {String}.{String}:(
print: Li.a
print: Ri.a
)
Input Parameters as Named Elements
personInfo:: {name:String, age:Int}:(
print: Ri.name
print: Ri.age.String
)
Input Parameters Using a Struct Shape
MyStruct :: {
str1: String
str2: String
int1: Int
}
showStruct:: {MyStruct}:(
print: Ri.str1
print: Ri.str2
print: Ri.int1.String
)
Left and Right Input Style
Hachi supports passing input from the left side, the right side, or both.
sumBoth:: {Int}.{Int} -> {Int}:(
Li + Ri
)
2.sumBoth: 3
Anonymous Functions
Hachi supports anonymous functions for inline use.
testFunc:: {Int}:(
print: Ri
)
testFunc: ({} -> {Int}:(4 - 2)) * 6
Type Conversion Syntax
Many conversions are written in method-style form.
count: "123".Int
ratio: "2.5".Flt
flag: 1.Bool
letter: 65.Byte
text: 42.String
Some conversions also work well in assignment-style expressions:
myBool: Bool: 0
myByte: Byte: 65
Arrays
Hachi includes built-in integer and string arrays.
Integer Array
numbers: IntArray: 5
numbers.set: 0, 42
numbers.set: 1, 99
print: numbers.get: 0
print: numbers.len
String Array
words: StringArray: 3
words.set: 0, "Hello"
words.set: 1, "World"
print: words.get: 1
print: words.len
Conditionals
Hachi uses ? for conditionals and | to separate branches.
age: 21
age >= 21 ?
(
print: "You may enter."
) | age >= 18 ?
(
print: "Give me your hands so I can use a permanent marker to draw giant X's on them."
) | (
print: "GTFO."
)
A simple conditional can also be very compact:
tru ? print: "Yep"
Loops
Hachi uses @ for looping.
While-Style Loop
i: 0
i < 5 @ (
print: i
i: i + 1
)
C-Style Loop
i: 0 | i < 5 | i: i + 1 @ (
print: i
)
Operators
Common operators include:
+-*/%=!=<><=>=&&||!.?|@
Important Notes
=is equality comparison, not assignment:is assignment and function-call syntax::defines constants and constant functions.is used for field access and method-style calls
Interoperability with C++
Hachi can embed raw C++ directly when needed.
innerCPP
C++ code inside innerCPP is injected inside the transpiled main.
innerCPP: "std::cout << \"Hello from C++\" << std::endl;"
outerCPP
C++ code inside outerCPP is injected outside the transpiled main.
outerCPP:"
#include <fstream>
#include <string>
"
One-Liner Example
Statements and expressions can often be written very compactly on one line.
oneLinerFunction:: {} -> {String}: (pair: 1, 2 sum: pair.a + pair.b sum.String)
print: oneLinerFunction