Merge pull request #4 from mist-go/memory-proposition

Memory proposition
This commit is contained in:
2026-05-14 01:34:14 +02:00
committed by GitHub
16 changed files with 394 additions and 83 deletions
@@ -0,0 +1,66 @@
---
title: New Memory System Proposition
author: Klesti Selimaj
date: 2026-05-14
---
First of all i want to thank anyone who used or tried Mist, it's a literal dream project of mine that i attempted many times, years ago.
And i also released the syntax highlighting VSCode extension: https://marketplace.visualstudio.com/items?itemName=selimaj-dev.mist-syntax
## Current problem
As i'm developing this language for Rust, i keep noticing the amount of posts of frustration i see online, just like the ones i would make, and i impulsively check out other languages, maybe it's not worth using Rust after all?
The pattern is clear:
- Lifetimes have terrible syntax, and they are hard to understand, even for experienced Rust developers.
- Lifetimes are limiting, making it difficult to express certain patterns where in other languages this would be straightforward.
- The borrow checker can be frustrating, especially for newcomers, and it can lead to a lot of trial and error to get the code to compile.
## New proposition (Scope Counting)
I want to propose a new memory system (to my understanding), Scope Counting, which you have to see in action to understand it.
```mist
{
var x = new Box(10); // sc = 0
// sc is 0, drop it
}
```
```mist
var r; // sc = 0
{
// sc of r = -1 (relative to current scope)
var x = new Box(10); // sc = 0
r = &x; // sc of x = -(sc of r) aka 1
// sc is 1, don't drop it, decrement by 1
}
// sc is 0, drop it
```
This system fixes what Rust couldn't, that is maintaining the same level of safety, without compromising performance and ergonomics, because it's still at the compiler level.
What makes this better is that it can still live with Rust's lifetime model when needed.
## More examples
In rust this is a very limiting issue, but with SC, it goes how it's supposed to go
```mist
str* longest(str* x, str* y) {
if (x.len() > y.len()) return x;
else return y;
}
```
Why? because both x and y are already a level higher.
if x is an outer scope of y (generally means lives longer), y would actually push it's sc to live as long as x, a better example is this:
```mist
str* greet() {
return "hello, world!"; // Impossible in Rust
}
```
By default, any refrence/allocation is a sc of 0, meaning it's going to last until the current scope ends, but it detected that we are returning it, therefore it increased the sc by 1.
+9 -9
View File
@@ -10,11 +10,11 @@ Classes in Mist bridge the gap between Java's organizational structure and Rust'
A class groups fields and methods together. Fields follow the `type name` convention, and methods define their logic directly within the class body.
```cpp
public class Logger {
```mist
pub class Logger {
String prefix;
public void info(self*, str* message) {
pub void info(self*, str* message) {
self.log(LogLevel::Info, message);
}
@@ -28,8 +28,8 @@ public class Logger {
Unlike languages that use the class name for initialization, Mist uses the explicit `constructor` keyword. This makes the entry point of the class unmistakable.
```cpp
public constructor(str* prefix) {
```mist
pub constructor(str* prefix) {
self.prefix = prefix.to_string();
}
```
@@ -38,8 +38,8 @@ public constructor(str* prefix) {
Mist maintains Rust's explicit context handling. Any method that needs to access or modify class data must include `self*` (or `self mut*` for mutations) as its first parameter.
```cpp
public void warning(self*, str* message) {
```mist
pub void warning(self*, str* message) {
self.log(LogLevel::Warning, message);
}
```
@@ -48,7 +48,7 @@ public void warning(self*, str* message) {
One of Mist's most powerful features is the ability to nest trait implementations directly within the class block. This keeps the logic for how a type behaves (e.g., how it is displayed) physically coupled with the type definition.
```cpp
```mist
impl fmt::Display {
std::fmt::Result fmt(self*, std::fmt::Formatter<'_> mut* f) {
return write!(f, "logger ({})", self.prefix);
@@ -60,5 +60,5 @@ impl fmt::Display {
- **Unified Scope**: Data, behavior, and trait logic live in one place, eliminating the friction of jumping between `struct` and `impl` blocks.
- **Explicit Context**: The use of `self*` ensures that the relationship between a method and its instance is always transparent.
- **Encapsulation**: Visibility modifiers (`public`) allow you to expose a clean API while keeping internal helper methods and state private to the class.
- **Encapsulation**: Visibility modifiers (`pub`) allow you to expose a clean API while keeping internal helper methods and state private to the class.
- **Zero-Cost Classes**: Under the hood, Mist desugars these into idiomatic Rust structs and implementation blocks, ensuring no runtime overhead compared to raw Rust.
+6 -6
View File
@@ -10,8 +10,8 @@ Enums in Mist serve as powerful algebraic data types (ADTs), maintaining the exa
An enum can contain unit variants, tuple variants, or struct-like variants. Following Mist's core philosophy, struct-like variants place the type before the identifier.
```rust
public enum TaskState {
```mist
pub enum TaskState {
Pending,
InProgress,
Completed,
@@ -26,7 +26,7 @@ public enum TaskState {
Mist supports all standard variant shapes, ensuring a 1:1 mapping to the underlying Rust execution model.
```rust
```mist
enum Message {
Quit, // Unit
Move(i32, i32), // Tuple
@@ -40,8 +40,8 @@ enum Message {
Just like structs and functions, enums declare generics and lifetimes in a unified block. This is particularly useful for defining custom Result or Option types that handle references.
```rust
public enum Validation<'a, T> {
```mist
pub enum Validation<'a, T> {
Valid(T),
Invalid {
str'a* message,
@@ -53,5 +53,5 @@ public enum Validation<'a, T> {
- **Consistent Member Declaration**: Struct-like variants maintain the `type name` order, ensuring that data modeling feels identical whether you are defining a top-level `struct` or an `enum` variant.
- **Rust-Native ADTs**: Enums compile directly to Rust enums, allowing for exhaustive pattern matching and zero-cost abstraction.
- **Shared Visibility**: The `public` modifier at the enum level exports all variants for use in other modules, matching Rust's visibility rules for enums.
- **Shared Visibility**: The `pub` modifier at the enum level exports all variants for use in other modules, matching Rust's visibility rules for enums.
- **Comma-Separated Members**: Fields within struct-like variants are separated by commas, mirroring the syntax used in standard Mist structs.
+9 -9
View File
@@ -10,7 +10,7 @@ Functions are the primary unit of execution in Mist. They prioritize a tradition
A standard function requires a return type, a name, and a body. Use the `void` keyword for functions that do not return a value.
```cpp
```mist
i32 add(i32 a, i32 b) {
return a + b;
}
@@ -22,10 +22,10 @@ void log_status(str* message) {
## Visibility & Exports
Functions are private to their module by default. The `public` modifier exports the function for cross-module access.
Functions are private to their module by default. The `pub` modifier exports the function for cross-module access.
```cpp
public i32 get_version() {
```mist
pub i32 get_version() {
return 1;
}
```
@@ -34,7 +34,7 @@ public i32 get_version() {
Parameters follow Rust’s ownership rules but use Mist’s local variable syntax. Use `mut` to allow a function to modify its local binding of a value.
```cpp
```mist
void update_score(i32 mut current_score, i32 bonus) {
current_score = current_score + bonus;
}
@@ -44,8 +44,8 @@ void update_score(i32 mut current_score, i32 bonus) {
Mist integrates type abstraction and memory management into a single generic block. Lifetimes and type parameters share the `< >` bracket following the identifier.
```rust
public str'a* choose_longer<'a, T: Display>(str'a* s1, str'a* s2, T meta) {
```mist
pub str'a* choose_longer<'a, T: Display>(str'a* s1, str'a* s2, T meta) {
println!("Metadata: {}", meta);
return if (s1.len() > s2.len()) { s1 } else { s2 };
}
@@ -55,9 +55,9 @@ public str'a* choose_longer<'a, T: Display>(str'a* s1, str'a* s2, T meta) {
Metadata is applied via the `#[attr]` syntax directly above the declaration for compiler hints or testing.
```cpp
```mist
#[inline]
public bool is_active(u32 id) {
pub bool is_active(u32 id) {
return id > 0;
}
```
@@ -10,7 +10,7 @@ Mist simplifies Rust’s reference system by using a pointer-style syntax. While
References are defined by placing a `*` after the type. By default, pointers are immutable (shared). To allow modification of the underlying data, use the `mut*` modifier.
```cpp
```mist
void increment(i32 mut* value, i32* limit) {
if (value < limit) {
value = value + 1;
@@ -22,10 +22,10 @@ void increment(i32 mut* value, i32* limit) {
Lifetimes are attached directly to the type before the pointer symbol. This maintains a clean visual flow where the "type-contract" (identity, duration, and mutability) is read from left to right.
```cpp
public struct Inspector<'a> {
public str'a* target,
public u32'a mut* counter,
```mist
pub struct Inspector<'a> {
pub str'a* target,
pub u32'a mut* counter,
}
```
+15 -15
View File
@@ -10,21 +10,21 @@ Structs in Mist follow the same structural logic as Rust, but apply the language
A struct is defined by its name followed by a block of fields. Each field follows the Mist convention of placing the type before the identifier, separated by commas.
```rust
public struct Task {
public String name,
public TaskState state,
public i32 executions,
```mist
pub struct Task {
pub String name,
pub TaskState state,
pub i32 executions,
}
```
## Visibility
Use the `public` modifier to make the struct or its individual fields accessible from other modules.
Use the `pub` modifier to make the struct or its individual fields accessible from other modules.
```cpp
public struct NetworkNode {
public u32 id,
```mist
pub struct NetworkNode {
pub u32 id,
str* address,
}
```
@@ -33,7 +33,7 @@ public struct NetworkNode {
Structs are instantiated using the standard brace syntax.
```cpp
```mist
var task = Task {
name: "Initialize".to_string(),
state: TaskState::Pending,
@@ -45,10 +45,10 @@ var task = Task {
Generics and lifetimes are declared in angle brackets after the struct name. Lifetimes are associated with the reference/pointer type within the field declarations.
```cpp
public struct Buffer<'a, T> {
public T'a* data,
public usize len,
```mist
pub struct Buffer<'a, T> {
pub T'a* data,
pub usize len,
}
```
@@ -57,4 +57,4 @@ public struct Buffer<'a, T> {
- **Type-First Declaration**: Fields use the `type name` order to match function parameters and variable declarations.
- **Comma-Separated Members**: Fields are separated by commas, maintaining a clean and consistent delimiter style.
- **Rust Compatibility**: Maps 1:1 to Rust structs, ensuring zero-cost abstraction and full ecosystem interoperability.
- **Direct Visibility**: The `public` keyword replaces `pub` for a more consistent modifier language across the codebase.
- **Direct Visibility**: The `pub` keyword replaces `pub` for a more consistent modifier language across the codebase.
+7 -7
View File
@@ -10,8 +10,8 @@ Traits in Mist define a set of methods that a type must implement, facilitating
A trait definition lists method signatures that implementing types must satisfy. Like functions, these signatures place the return type before the method name.
```rust
public trait Drawable {
```mist
pub trait Drawable {
void draw(self*);
str* metadata(self*);
}
@@ -20,7 +20,7 @@ public trait Drawable {
To implement a trait for a specific type, use the `impl` keyword followed by the trait name and the target type. This block must contain all required methods defined in the trait.
```rust
```mist
impl Drawable for Task {
void draw(self*) {
println!("Drawing task: {}", self.name);
@@ -35,8 +35,8 @@ impl Drawable for Task {
Traits can provide default behavior for methods. Types implementing the trait can choose to override these defaults or use the provided implementation.
```rust
public trait Identifiable {
```mist
pub trait Identifiable {
u32 get_id(self*);
bool is_valid(self*) {
@@ -48,8 +48,8 @@ public trait Identifiable {
Traits can build upon other traits. If a trait requires another trait to be implemented first, use the colon `:` syntax.
```rust
public trait Animated : Drawable {
```mist
pub trait Animated : Drawable {
void animate(self*, f32 delta_time);
}
```
+1 -1
View File
@@ -64,7 +64,7 @@ path = "build/main.rs"
Now for the fun part! Create a new file at `src/main.mist` and add the following code:
```cpp title="src/main.mist"
```mist title="src/main.mist"
void main() {
println!("Hello World!");
}
+1 -1
View File
@@ -53,7 +53,7 @@ Inheritance is a major planned feature but is currently **not implemented**.
Be aware that because we are focusing on syntax, keywords and structures may change between minor versions. Currently:
* **Access Modifiers:** `public` and private defaults are being tested for various contexts (classes vs. structs, or `public(crate)`).
* **Access Modifiers:** `pub` and private defaults are being tested for various contexts (classes vs. structs, or `pub(crate)`).
* **Pointers vs. References:** The `*` syntax for references (e.g., `self mut*`) is the current standard but is subject to refinement based on ecosystem feedback.
+5 -5
View File
@@ -10,7 +10,7 @@ Control flow in Mist provides a bridge between C-style procedural logic and Rust
The `if` statement evaluates a boolean expression. It supports multiple `else if` branches and an optional `else` block.
```cpp
```mist
if (score > 50) {
println!("Pass");
} else if (score == 50) {
@@ -24,7 +24,7 @@ if (score > 50) {
The `match` statement provides exhaustive pattern matching. Currently, every match arm requires a block `{}` following the `=>` operator.
```cpp
```mist
match (task_state) {
TaskState::Pending => {
println!("Queued");
@@ -46,7 +46,7 @@ Mist supports both functional iteration and traditional low-level loop control.
For manual iteration control, Mist supports the standard three-part `for` loop: initialization, condition, and post-iteration statement.
```cpp
```mist
for (var mut i = 0; i < 10; i = i + 1;) {
println!("Index: {}", i);
}
@@ -56,7 +56,7 @@ for (var mut i = 0; i < 10; i = i + 1;) {
The `for-in` loop iterates over collections or iterators using Mist's pattern matching system.
```cpp
```mist
for (var item in collection) {
process(item);
}
@@ -71,7 +71,7 @@ for ((i32 x, i32 y) in coordinates) {
The `while` loop continues execution as long as the parenthesized expression evaluates to `true`.
```cpp
```mist
while (active) {
wait_for_event();
}
+4 -4
View File
@@ -10,7 +10,7 @@ Expressions in Mist are the fundamental units that evaluate to a value. The synt
Primary expressions are the starting point of any logic chain. These include literal values, paths to static members, or grouped expressions in tuples.
```java
```mist
// Literals and paths
var x = 42;
var y = Math::PI;
@@ -24,7 +24,7 @@ var coordinates = (10, 20, 30);
Postfix expressions allow you to build on a primary value. This includes calling functions, accessing fields, indexing arrays, or initializing structs.
```java
```mist
// Field access and method/function calls
var len = list.length();
@@ -44,7 +44,7 @@ println!("Value: {}", first); // Macro call via '!'
Prefixes modify the primary expression that follows them. Mist uses these for logical negation, dereferencing, and creating references.
```java
```mist
var mut value = 10;
var ref = &value; // Reference
@@ -58,7 +58,7 @@ var is_false = !true; // Logical NOT
Binary operations are applied as postfixes to an expression, following a `bin_op ~ expr` pattern. This supports all standard arithmetic, comparison, and logical operators.
```java
```mist
var sum = 10 + 20;
var is_equal = (x == y);
var complex = (a + b) * (c / d);
+5 -5
View File
@@ -10,7 +10,7 @@ In Mist, variables follow the language-wide `type name` convention. For local sc
Variables are declared using the `var` keyword for automatic type inference. Like Rust, variables are immutable by default.
```java
```mist
var message = "Hello Mist"; // Inferred as str*
var count = 42; // Inferred as i32
```
@@ -19,7 +19,7 @@ var count = 42; // Inferred as i32
To allow a variable to be reassigned, use the `mut` modifier after the `var` keyword or the explicit type.
```rust
```mist
var mut score = 0;
score = 100;
@@ -31,7 +31,7 @@ price = 14.99;
While `var` handles inference, you can explicitly define the type before the identifier. This is often used for clarity in complex logic or when the specific numeric width (e.g., `u8` vs `i32`) matters.
```rust
```mist
u64 large_id = 1000234;
bool is_active = true;
```
@@ -40,7 +40,7 @@ bool is_active = true;
Because variable declarations are patterns, you can destructure tuples or structures directly. This keeps data extraction clean and avoids manual indexing.
```rust
```mist
// Destructuring a tuple into local variables
(i32, i32) (x, y) = get_coordinates();
@@ -52,7 +52,7 @@ Because variable declarations are patterns, you can destructure tuples or struct
Constants are immutable values that are evaluated at compile time. They require an explicit type and follow the `const` keyword.
```rust
```mist
const i32 MAX_RETRIES = 5;
const str* VERSION = "1.0.4";
```
+231
View File
@@ -0,0 +1,231 @@
{
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
"name": "mist",
"scopeName": "source.mist",
"patterns": [
{
"include": "#comments"
},
{
"include": "#keywords"
},
{
"include": "#attributes"
},
{
"include": "#strings"
},
{
"include": "#macros"
},
{
"include": "#type_declarations"
},
{
"include": "#constants"
},
{
"include": "#lifetimes"
},
{
"include": "#generics"
},
{
"include": "#types"
},
{
"include": "#namespaces"
},
{
"include": "#functions"
},
{
"include": "#numbers"
},
{
"include": "#operators"
},
{
"include": "#punctuation"
}
],
"repository": {
"comments": {
"match": "//.*",
"name": "comment.line.double-slash.mist"
},
"attributes": {
"begin": "#!?\\[",
"beginCaptures": {
"0": {
"name": "punctuation.definition.attribute.begin.mist"
}
},
"end": "\\]",
"endCaptures": {
"0": {
"name": "punctuation.definition.attribute.end.mist"
}
},
"name": "meta.attribute.mist",
"patterns": [
{
"include": "$self"
}
]
},
"strings": {
"begin": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.mist"
}
},
"end": "\"",
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.mist"
}
},
"name": "string.quoted.double.mist",
"patterns": [
{
"match": "\\\\.",
"name": "constant.character.escape.mist"
}
]
},
"macros": {
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)(!)",
"captures": {
"1": {
"name": "entity.name.function.macro.mist"
},
"2": {
"name": "keyword.operator.macro.mist"
}
}
},
"type_declarations": {
"match": "\\b(struct|enum|class|trait)\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
"captures": {
"1": {
"name": "storage.type.mist"
},
"2": {
"name": "entity.name.type.mist"
}
}
},
"keywords": {
"patterns": [
{
"match": "\\b(if|else|while|for|in|return|break|continue|match)\\b",
"name": "keyword.control.mist"
},
{
"match": "\\b(struct|enum|class|trait|var)\\b",
"name": "storage.type.mist"
},
{
"match": "\\b(pub|mut|constructor)\\b",
"name": "storage.modifier.mist"
},
{
"match": "\\b(impl|use|mod|new|void|self)\\b",
"name": "keyword.other.mist"
}
]
},
"constants": {
"match": "\\b(true|false)\\b",
"name": "constant.language.boolean.mist"
},
"lifetimes": {
"match": "'[a-zA-Z_][a-zA-Z0-9_]*\\b",
"name": "storage.modifier.lifetime.mist"
},
"generics": {
"begin": "<",
"beginCaptures": {
"0": {
"name": "punctuation.brackets.angle.mist"
}
},
"end": ">",
"endCaptures": {
"0": {
"name": "punctuation.brackets.angle.mist"
}
},
"patterns": [
{
"include": "#lifetimes"
},
{
"match": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b",
"name": "entity.name.type.mist"
},
{
"match": ",",
"name": "punctuation.separator.mist"
},
{
"match": ":|\\+",
"name": "keyword.operator.mist"
},
{
"include": "#generics"
}
]
},
"types": {
"patterns": [
{
"match": "(?<![A-Za-z])(f32|f64|i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)\\b",
"name": "entity.name.type.numeric.mist"
},
{
"match": "(?<![A-Za-z])(str|char|bool)\\b",
"name": "entity.name.type.other.mist"
},
{
"match": "\\b_?[A-Z][A-Za-z0-9_]*\\b(?!!)",
"name": "entity.name.type.mist"
}
]
},
"namespaces": {
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)(?=\\s*::)",
"captures": {
"1": {
"name": "entity.name.namespace.mist"
}
}
},
"functions": {
"match": "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?=\\()",
"name": "entity.name.function.mist"
},
"numbers": {
"patterns": [
{
"match": "\\b\\d+\\.\\d+\\b",
"name": "constant.numeric.float.mist"
},
{
"match": "\\b\\d+\\b",
"name": "constant.numeric.integer.mist"
}
]
},
"operators": {
"match": "(<=|>=|==|!=|&&|\\|\\||\\+|-|\\*|/|%|<|>|=|=>|!)",
"name": "keyword.operator.mist"
},
"punctuation": {
"match": "::|:|;|,|\\.|\\{|\\}|\\(|\\)|\\[|\\]",
"name": "punctuation.mist"
}
}
}
+8 -1
View File
@@ -5,6 +5,7 @@ import {
} from "fumadocs-mdx/config";
import { metaSchema, pageSchema } from "fumadocs-core/source/schema";
import { z } from "zod";
import mist from "./public/mist.tmLanguage.json";
// You can customize Zod schemas for frontmatter and `meta.json` here
// see https://fumadocs.dev/docs/mdx/collections
@@ -33,6 +34,12 @@ export const blogPosts = defineCollections({
export default defineConfig({
mdxOptions: {
// MDX options
rehypeCodeOptions: {
langs: [mist],
themes: {
light: "github-light",
dark: "github-dark",
},
},
},
});
+9 -9
View File
@@ -21,7 +21,7 @@ export const mistShowcase = [
greet("Developer");
}
public void greet(str* name) {
pub void greet(str* name) {
// Familiar pointer ergonomics with Rust safety
String greeting = name.to_string();
println!("Hello, {}!", greeting);
@@ -46,19 +46,19 @@ void process_data() {
title: "Class and Type System",
description:
"Classes are syntactic sugar for Rust structs. Using 'extends' provides inheritance-style syntax over struct composition, compiling into the underlying Rust type system.",
code: `public struct PluginInfo {
public String name,
public String version,
code: `pub struct PluginInfo {
pub String name,
pub String version,
}
public class PluginRegistry<T> {
pub class PluginRegistry<T> {
T plugins;
public constructor(T plugins) {
pub constructor(T plugins) {
self.plugins = plugins;
}
public T plugins(self) {
pub T plugins(self) {
return self.plugins;
}
}`,
@@ -68,10 +68,10 @@ public class PluginRegistry<T> {
title: "Better Developer Experience",
description:
"While Rust can already be a great DX, Mist implements concepts that are proven to improve structure.",
code: `public class Logger {
code: `pub class Logger {
String prefix;
public constructor(str* prefix) {
pub constructor(str* prefix) {
self.prefix = prefix.to_string();
}
+13 -6
View File
@@ -1,21 +1,28 @@
"use client";
import { BundledLanguage, codeToTokens } from "shiki";
import { BundledLanguage, codeToTokens, createHighlighter } from "shiki";
import { motion, AnimatePresence } from "framer-motion";
import { useEffect, useState } from "react";
import mist from "../../public/mist.tmLanguage.json";
interface Props {
code: string;
lang?: BundledLanguage;
}
export default function MorphCode({ code, lang = "rust" }: Props) {
const highlighterPromise = createHighlighter({
themes: ["github-dark"],
langs: [mist],
});
export default function MorphCode({ code }: Props) {
const [lines, setLines] = useState<any[][]>([]);
useEffect(() => {
async function run() {
const result = await codeToTokens(code, {
lang,
const highlighter = await highlighterPromise;
const result = highlighter.codeToTokens(code, {
lang: "mist" as any,
theme: "github-dark",
});
@@ -36,7 +43,7 @@ export default function MorphCode({ code, lang = "rust" }: Props) {
}
run();
}, [code, lang]);
}, [code]);
return (
<pre className="text-sm overflow-x-scroll overflow-y-hidden">