#๐Ÿช…-progaming

1 messages ยท Page 29 of 1

placid cape
#

like visitor interface where you have for example visit method?

valid jetty
#

(which is also recursive)

placid cape
#

And then for each node type you'll implement it

hoary sluice
#

yes

valid jetty
#

ive seen that approach used before but i dont personally like it

placid cape
#

well I don't have that "interface" but for each node I have different file with function that is called in the match

valid jetty
#

@hoary sluice is x = (x + 1) % y the same as x = (x + 1) & (y - 1)

hoary sluice
#

ur combining statements and expressions into 1 enum, that seems hard to maintain

placid cape
valid jetty
hoary sluice
#

that seems ugly

valid jetty
#

its a lot more reasonable than it looks

hoary sluice
#

im gonna make everything an expression

placid cape
#

yeaaa

valid jetty
#

how do you determine the return value of while true {}

hoary sluice
valid jetty
#

.

#

sounds like a lot of overhead when it could just be a jmp

hoary sluice
#

its an interpreter, im gonna make while a builtin function that just uses rust while in the background

#

u can return from it

placid cape
#

I wonder how to transpile something like

i32 a = if 4 == 7 { return 7; } else { return 9; }

into qbe

placid cape
#

I'm not gonna resolve if statements at compile time

#

at least not now

#

it's easy to do in interpreter

placid cape
#

hmm

#

okay

#

but first I'll have to implement blocks

#

btw Elle helps me a lot with qbe so thank you so much :D

valid jetty
#

if you dont create with addrs itll be like

type :ElleMeta = { l, l, w, l, l, w, w }
export function w $main() {
@start
    %tmp.7 =w ceqw 4, 7
    jnz %tmp.7, @ift.6, @iff.6
@ift.6
    %ternary.6 =w copy 7
    jmp @end.6
@iff.6
    %ternary.6 =w copy 9
    jmp @end.6
@end.6
    %a =w copy %ternary.6
    ret 0
}
#

:3

placid cape
#

I'm using it for compiling when I'm not sure how it should be

valid jetty
#

@hoary sluice opinions on a std/prelude.le module which just imports all of the common things like io, math, array, tuple, split, char types, etc

placid cape
#

since it uses namespaces then it's probably fine

hoary sluice
valid jetty
#

youre confusing prelude with util

#

lol

#

this is part of the stdlib not for aoc

hoary sluice
#

betaveros has his in prelude

valid jetty
#

should hashset and hashmap be part of it

hoary sluice
#

just import on demand without requiring keywords

valid jetty
#

what like you see HashMap::new() and you go and import std/collections/hashmap?

placid cape
#

instead std/prelude make LSP that'll automatically import things blobcatcozy

valid jetty
#

idk maybe that could work

valid jetty
hoary sluice
#

pretty sure lsps arent actually that hard

placid cape
#

I recommend tower lsp crate for rust

hoary sluice
#

at least add tree sitter support

#

elle-analyzer ๐Ÿฅฐ

valid jetty
#

they are lol

#

do i put vectors into the prelude

#

theres vector2 and vector3 structs with some like things

placid cape
#

You should have two variants, with doubles and floats

valid jetty
#

idk i have them only with floats

#

double precision is usually not needed when working with vectors

hoary sluice
#

my kotlin aoc points are i32, worst decision of my life

placid cape
#

idk I only know that Minecraft uses vectors with doubles

placid cape
#

is it possible to somehow make i128 in kotlin?

hoary sluice
#

this delta couldve been 10s

hoary sluice
hoary sluice
hoary sluice
# placid cape what

there are hundreds of solutions that use Point, entire grid system (2d, 3d, hex, arbitrary d), line, direction all need to be rewritten to long

valid jetty
#
struct Point {
    i32 x;
    i32 y;
}
struct Point {
    i64 x;
    i64 y;
}
#

oh horror

hoary sluice
#

i have longpoint but it has no support

placid cape
#

oh

valid jetty
#

just change Int to Long and follow the compilation errors from kt

#

unless it auto truncates and doesnt tell you

hoary sluice
#

there will literally be thousands and i cba

valid jetty
#

lmao i guess

placid cape
#

upload your project to chatgpt and tell it to do it ๐Ÿ˜

hoary sluice
#

so true!!!!

valid jetty
#

im thinking of converting ```rs
fn main(i32 argc, string *argv) {
io::dbg(argv[1]);
}

```rs
fn _main(string[] args) {
    io::dbg(args[1]);
}

fn main(i32 argc, string *argv) {
    string[] args = Array::with_capacity(argc);

    for let i = 0; i < argc; i += 1 {
        args.push(argv[i]);
    }

    return _main(args);
}
#

like internally

#

and all you write as the developer is

fn main(string[] args) {
    io::dbg(args[1]);
}
placid cape
#

that's good ig

placid cape
#

just for i < argc; i += 1

valid jetty
#

no lol

placid cape
#

why not

hushed pebble
#

that sounds dumb

#

for more complex code, that could leave one wondering where i is defined

#

or, in other cases, it might cause them to not see that i was actually defined as a variable earlier

hoary sluice
valid jetty
# placid cape why not

for loops can have any code, its just convention to have init, cond, step but you could make it like

for let foo = get(); foo != nil; foo = get_next() {}
#

and that too yeah

#
for i in 0..argc
placid cape
#

like for (;i<3;i++)

valid jetty
#

sorry this is evil actually

valid jetty
#

you just cant omit it and expect i to still be defined

hushed pebble
placid cape
#

so you can do for ;foo!=nil;foo = get_next(); {}

hushed pebble
#

:3

placid cape
#

yea, who needs while

#

its just for ;; {}

valid jetty
#

you can do this actually

hushed pebble
#

question

#

does for allow any statement as the initializer

valid jetty
#

yes

#

it just yields tokens until ; and runs the parser recursively on them

hushed pebble
#

even something as insane as for for ;; {} ;; {}

valid jetty
#

uh

#

nvm i read that wrong

#

i guess yes technically

hushed pebble
#

guh

valid jetty
#

but not specifically that because itll break on the first ;

hushed pebble
#

eh?

frosty obsidian
#

itll see for for ; and notice that its invalid syntax

valid jetty
#

so the initializer tokens will be [for] not [for, semicolon, semicolon, curly, curly]

#

yes

#

this is valid code lol

placid cape
#

xd

hushed pebble
valid jetty
#

yeah that works but thats also evil

#

have i shown you guys the approaching operator

#

i cant do it in elle but 1 sec

#

ok well im finally done refactoring all 15 of my solutions in elle to use actual tuples instead of the encoding into single numbers stuff lol

#

time to start day 16

#

how am i gonna do day 23 in elle

placid cape
#

bron kerbosch

valid jetty
#

ill have to write a pivoting bron kerbosch tho

#

in elle

#

thatll be interesting

placid cape
valid jetty
#

can you use cartesian product instead of combinations there

placid cape
#

well it would include duplicates, e. g. (a, b, c) and also (c, b, a)

#

so if you sort it and add to set then you can

valid jetty
#

yeah ok

#

oh god defaultdict

#

oh god heappush heappop

#

oh well i think i know how

#

i dont really have to implement heappush i can just push normally but i can just write a specialized heappop for this heap specifically

#

LMAOOO

#

im so glad i implemented let

valid jetty
#

yeah but i didnt implement Ord overloading yet

#

so itll sort by the pointer lol

#

i can just find the min value and remove that index

#

HashMap.0.2.Triple.0.11.11.11.1.11.1

translates to

Hashmap( 2.Triple(11, 11, 11), 11 )

where 11 is int and 2.x is x*

#

but its not catching the parts after the first nested struct

#

wtf is this signature

#

i should just make a struct atp

hoary sluice
#

u should make vararg generic

#

omg thats so smart

valid jetty
#

that would be so hard ๐Ÿ˜ญ

#

i thought i would need to do that when i first made tuples

#

do i allow you to do (i32, i32) -> Tuple<i32, i32> * and (i32, i32, i32) -> Triple<i32, i32, i32> *

#

i can do that its not that hard

#

just count the number of commas

#

im gonna make a HashMap.get_or_insert(k, v)

#

so you can do dist.get_or_insert($$(y, x, ndir), i32::max())

placid cape
#

beautiful

valid jetty
#

how do you differentiate between returning from the function and returning from the if statement

#

btw optimization goes as far as -O3 why are you doing O2 lol

#

is there a specific reason

placid cape
#

i was just trying something

placid cape
#

i need to fix it

valid jetty
placid cape
#

looool

valid jetty
#

this doesnt seem right that line just isnt long

#

this is 4419

placid cape
#

i think qbe sometimes doesnt show correct locations

#

happened to me few times

valid jetty
#

found it

#

export function l $HashMap.with_capacity.0.2.Triple.0.11.11.11.1.2.Array.0.2.Triple.0.11.11.11.1.1.1(w %initial_capacity.6152) {

#

how tf do i solve this

placid cape
#

why it has identifier length limit lol

valid jetty
#

idk ๐Ÿ˜ญ

#

easy solution for now is to use void *????

placid cape
#

you can fork it and remove the limit maybe

valid jetty
#

true

#

i mean its there

#

i can get rid of it

#

that identifier isnt even that long

#

oh i see why

#

in the IR identifiers are statically sized 80 byte long arrays

#

i wonder if it would all explode if i just increase it to like 240

#

or like 320

#

i dont think its a good idea to just remove the check because all that would do is buffer overflow

placid cape
#

yeah you need to increase the size

valid jetty
#

ok well it compiles using a longer ident name

#

do i pr this now

placid cape
#

i dont think they'll accept it

valid jetty
#

im scared if i do theyll be like "the ident name should not be longer than 64 chars if it is youre doing something wrong"

placid cape
#

but you can try

valid jetty
#

yeah

placid cape
#

who wants to waste time with compressing names lol

#

i mean you could probably replace all names to integers but who wants to do it lol

valid jetty
#

void *[] it is

valid jetty
placid cape
#

yeah but the ir is at least readable rn

#

well it could be flag idk

valid jetty
#

the problem is even if i do

20.with_capacity.0.2.21.0.11.11.11.1.2.22.0.2.21.0.11.11.11.1.1.1
#

its still very long

placid cape
#

you would have to compress it into one number

valid jetty
placid cape
#

so you need some global counter

valid jetty
#

oh

placid cape
#

i have global counter for data things

#

so i dont even need the function name here

#

but i just added it for easier debugging

#

same with temp variables, i dont need anything else than number

valid jetty
#

that might be doable but it would ruin the philosophy of my monomorphism approach

valid jetty
#

you cant have %1 like in llvm the best you have is %.1

placid cape
#

okay then i would add dot at the beginning

#

not a big deal

valid jetty
#

ya

#

day 16 p1 done!!!

valid jetty
#

20 => HashMap
21 => Triple
22 => Array
11 => i32
2.x => pointer of x
0 => start of generic scope
1 => end of generic scope

valid jetty
hoary sluice
placid cape
#

Gj

hoary sluice
#

words 10 tho

#

hm not bad

#

lol that was such a good seed

#

i wonder if i could get 200 on it on qwerty

#

i started that at 84 wtf

ionic lake
#

here's mine

valid jetty
#
if dist.get_or_insert(prev, i32::max()) + (prev.z != current.z ? 1000 : 1) == dist.get_or_insert(current, i32::max()) {
                
}
``` horror
#

this is my time 15

#

and this is typing dbg 10 times

hoary sluice
valid jetty
hoary sluice
#

better like this

valid jetty
#

this shouldnt just work

let ecost = i32::max();
let estates = Array::new<Triple<i32, i32, i32> *>();
let tiles = HashSet::new<(i32, i32)>();

for i32 dir in 0..DIRS.len() {
    let tmp = $$(end.x, end.y, dir);

    if dist.get_or_insert(tmp, i32::max()) < ecost {
        ecost = dist[tmp];
        estates = [tmp];
    } else { if dist.get_or_insert(tmp, i32::max()) == ecost {
        estates.push(tmp);
    }}
}

while !estates.is_empty() {
    let current = estates.pop();
    let y = current.x;
    let x = current.y;
    tiles.add($(y, x));

    for Triple<i32, i32, i32> *prev in pre[current] {
        let cost = prev.z != current.z ? 1000 : 1;

        if dist.get_or_insert(prev, i32::max()) + cost == dist.get_or_insert(current, i32::max()) {
            estates.push(prev);
        }
    }
}

return tiles.size();
```` i refuse
valid jetty
hoary sluice
#

why is it getting so much more inconsitent

hoary sluice
#

i got the 178 on a laptop membrane keyboard in school ๐Ÿ˜ญ

valid jetty
#

ever since i got long nails i havent been able to type faster than 140 ๐Ÿ˜ญ

#

i could have 160 time 15 if i cut them

hoary sluice
#

@valid jetty isnt lazy evaluation super easy to implement

#

instead of storing a value u store a value and a list of functions

#

that sounds like its gonna take 5 mins to implement and then have an edge case that requires redesigning

valid jetty
#

why a list of functions

#

i already did lazy evaluation in 5 mins remember

#

or well specifically lazy range

use std/option;
use std/io;

struct Range {
    i32 current;
    i32 max;
    bool done;
};

fn Range::new(i32 low, i32 high, bool inclusive) {
    Range *range = malloc(#size(Range));
    *range = malloc(#size(Range));

    range.current = low;
    range.max = high + inclusive;
    range.done = false;

    return range;
}

fn Range::next(Range *self) -> Option<i32> {
    if !self.done {
        let res = Option::Some(self.current);
        self.current += 1;

        if self.current == self.max {
            self.done = true;
        }

        return res;
    }

    return Option::None();
}

fn main() {
    let range = Range::new(0, 10, true);

    while !range.done {
        io::dbg(range.next().unwrap());
    }

    io::dbg(range.next().unwrap());
}
#

in rust this would be like

fn main() {
    let range = Range::new(0, 10, true);

    while let Some(next) = range.next() {
        dbg!(next);
    }

    dbg!(range.next().unwrap());
}
``` but i dont have that semantic
#

or wait you said lazy evaluation

#

not lazy iteration

#

you could make lazy evaluation pretty easily by just making literally everything a function then when you wanna consume a value you call the function

dense sand
#

I genuinely want to see how much do yall sleep

#

Every time i look here yall are online

valid jetty
#

@hoary sluice do i allow for partial generic knowledge like this

#

where you can have a Foo<T, U> and declare a function like

fn foo<T>(Foo<i32, T> x) {}
placid cape
#

loops done ๐Ÿ”ฅ

valid jetty
valid jetty
placid cape
valid jetty
#

good

#

!!

placid cape
#

tomorrow i'll move a lot of things into analyzer

#

like adding default return type to functions, find missing types (e. g. when you're redeclaring variable), type checking

#

and then i can remove a lot of things from compiler and interpreter

hoary sluice
#

because io inherently cant be pure functional

#

so the goal is to be similar to noulith

#

maybe a little more on the functional side

#

allow sane io and variables

#

scala does it well

#

scala has a lazy keyword but its not default

hoary sluice
placid cape
#

thats good

hoary sluice
placid cape
#

because no aoc

hoary sluice
placid cape
#

yea it is

#

at least i think

hoary sluice
#

i need aoc in my life

placid cape
#

xddd

#

ahh i forgot to solve day 8 2015

#

nvm i'll do it tomorrow

#

and for 2019 ill implement intcode in blom ๐Ÿ˜Ž

hoary sluice
placid cape
#

nicee

valid jetty
#

how are you guys working so fast

#

it took me 8 months to get elle to a decent state where i could actually use it for most programs

placid cape
#

my current js transpiler transpiles:

i32 a = if 5 == 3 {
  return 7 + 5;
} else {
  return 8 + 5;
}

into something like

let a = (function() {
  if (5 == 3) {
    return 7 + 5;
  } else {
    return 8 + 5
  }
})();
#

not very efficient but who cares about js

placid cape
hoary sluice
placid cape
#

i had one prog language called frog which was basically monkey lang

#

if you know what monkey lang is

hoary sluice
placid cape
#

i did it in rust

#

and now im using go lol

hoary sluice
#

why go for blom

placid cape
#

i dont know tbh

#

i really miss

pub enum Asd {
  Something(i32),
  String(String),
  Int(i64)
}
#

enum with values is amazing feature

hoary sluice
#

gn

hoary sluice
placid cape
#

gnn

#

gonna sleep too

valid jetty
#

i wish i used a tutorial for elle lol

#

wouldve helped

#

good night tho guys

#

im gonna keep writing my solutions

valid jetty
#

i can actually just do this to parse lol

fn parse(string contents) {
    let lines = contents.split("\n");

    let a = lines[0].nums()[0];
    let b = lines[1].nums()[0];
    let c = lines[2].nums()[0];
    let instructions = lines[4].nums();

    return Program {
        a = a, b = b, c = c,
        instructions = instructions
    };
}
```i love
#
fn Array::slice<T>(T[] self, i32 _start, i32 _end) -> T[] {
    let start = _start;
    let end = _end;

    start = start < 0 ? self.len() - start : start;
    start = start < 0 ? 0 : start;
    start = start >= self.len() ? self.len() : start;

    end = end == -1 ? self.len() : end;
    end = end < 0 ? self.len() - end : end;
    end = end >= self.len() ? self.len() : end;
    end = end < start ? start : end;

    T[] result = Array::with_capacity(end - start);

    for i32 i = start; i < end; i += 1 {
        result.push(self[i]);
    }

    return result;
}
``` i think this is possibly the most cursed slice implementation ive ever written
fleet cedar
#

Slice making a copy is cursed

#

Though python does that too I guess

valid jetty
#

@hoary sluice ```rs
fn lists(string input) {
let parts = input.split("\n").map(string::nums);
let ls = parts.map(fn(i64[] nums) -> nums[0]);
let rs = parts.map(fn(i64[] nums) -> nums[1]);

return $(ls, rs);

}

valid jetty
#

can make it this

fn Array::slice<T>(T[] self, i32 start, i32 end) -> T[] {
    let temp = Array::with_capacity(math::next_power_of_2(end - start));

    temp.elements = self.elements + (start * #size(T));
    temp.size = end - start;
    temp.capacity = self.capacity;

    return temp;
}
stoic helm
lunar quail
#

Fortran supremacy

viscid grove
#

wtf is octave

#

and how whys it even slower than python

odd lake
valid jetty
#

does anyone know if ghostty can have transparent backgrounds

lunar quail
pseudo sierra
#

ngl I should give ghostty a shot when I get home

valid jetty
#

i figured it out

#

looks pretty nice

placid cape
#

zed ๐Ÿ”ฅ๐Ÿ”ฅ

runic sundial
#

I want Zed to be acquired by JetBrains

dense sand
#

why lol

runic sundial
#

Because they will make it usable

dense sand
#

they have fleet

runic sundial
#

Fleet is mid

dense sand
#

agreed

runic sundial
#

Only thing that makes Zed good is that it's fast

#

Literally it

#

So if I could have the other JetBrains tools be faster I would be happy

#

Shrimple as

dense sand
#

they would javaify it /s

runic sundial
#

Yes yes they would

#

A small price to pay

dense sand
#

performance down though

runic sundial
#

Java doesn't mean low perf tbh

dense sand
runic sundial
#

Really depends

dense sand
#

which to rust people means a lot

hoary sluice
dense sand
#

rust people will find every millisecond for a reason to switch to rust

#

(im a rust hater)

runic sundial
#

Rust people are rusting away by the millisecond

#

No worries

dense sand
#

oxidize yall

runic sundial
#

Now Zig

dense sand
#

havent tried zig

runic sundial
#

I am a real Zigger

dense sand
#

C is the best

#

"We will take away your need to manage memory and give you borrow checking which you need to worry about the same as memory management!"

hoary sluice
runic sundial
#

C and Zig let me to the same thing, not to mention the Zig tooling let's you use both in the same project

#

Like seamlessly

hoary sluice
dense sand
#

havent tried zig tbh

runic sundial
#

Zed is no good till it has IntelliJ tier plugin integration

dense sand
#

i mostly go after mainstream languages

#

like those enterprise ones

runic sundial
#

I do Java mostly

dense sand
runic sundial
#

But Zig has been a treat

dense sand
#

i do C mostly for osdev, i might try zig though

hoary sluice
dense sand
#

im pretty sure gcc has flags to detect possible segfaults

hoary sluice
#

i still use c++ sometimes but only for codeforces

dense sand
#

c++ is garbage

#

id rather use rust

hoary sluice
# dense sand c++ is garbage

yea ik it is, part of my diploma thesis is written in qt and i absolutely hate it, but its acceptable for competitive programming

#

i dont like c at all

hoary sluice
dense sand
#

I'm hoping my teachers will let me make my own OS as a hs diploma

#

or whatever is that called

#

i really dont want to make a fucking nextjs site

hoary sluice
#

i was gonna make a compiler but a diploma thesis requires a teammate for an A, otherwise its an F in teamwork and a B an total, and nobody in my class wanted to make a compiler, so now were making a voice assistant in kotlin

#

with a qt frontend

dense sand
#

๐Ÿ’€

#

WHY QT

#

why not kotlin mp?

hoary sluice
#

and i dont believe in kmp

#

kotlin should stay on the jvm

#

leave the native stuff to the fast languages

dense sand
hoary sluice
#

no

dense sand
#

well, you dont have to make multipaltform only apps with kmp

#

are you sure the desktop version compiles to native?

jade stone
hoary sluice
#

also qt might support xtensa/esp32

hoary sluice
#

im not using kmp

dense sand
#

well qt was the frontend, right?

hoary sluice
#

yes

dense sand
#

and the QT app was a dekstop app right

hoary sluice
#

qt widgets (c++)

hoary sluice
#

might work for mobile but i only need it for a raspberry pi and potentially for esp32

placid cape
#

But with hardware

#

So it's not only application

hoary sluice
placid cape
#

What are you gonna use?

hoary sluice
#

weve got the pcb ready (just some switches and leds lol) and hes making a case in fusion360 rn

#

im gonna give up on recording audio with qt

hoary sluice
#

just gonna make a python script do it and pipe the output to qt

placid cape
fleet cedar
#

What if the operator is overloaded and has side effects

placid cape
#

then i'll reconsider it

#

currently working on analyzing types

hoary sluice
placid cape
#

imagine overloading binary operators to send request to AI lmao

hoary sluice
placid cape
#

i have same font as @valid jetty

#

Maple Mono

hoary sluice
#

ik

#

but that font has both normal l and the silly one

#

at least their example used both

#

@placid cape whats the blom ast of (3 + 3)

#

also do i merge function and variable ast nodes

#

and just make

let x = 3

sugar for

fn x
x = 3
hoary sluice
#

ty

#

i think this is all i need

#

hm should i make else be an explicit ast node, be part of the if node or just parse an else as if !original_condition

#

ig option 3 would get difficult to maintain for else if chains

placid cape
#

I have else as part of if

#

if has condition, then, else

hoary sluice
#

yea i ended up doing that

If {
    condition: Box<Expression>,
    expression: Box<Expression>,
    otherwise: Option<Box<Expression>>,
},
#

time to define grammar husk

placid cape
hoary sluice
#

maker parsing much easier and i might wanna stick with it

fleet cedar
placid cape
#

I'm not sure if I understand how your functions really works

#

that's why I said nah

hoary sluice
#

this is the wip grammar

expression = function | definition | primary ;
function   = "fn" IDENTIFIER { TYPE } ;
definition = IDENTIFIER { PATTERN } = expression ;
primary    = "true" | "false" | "null" | "(" expression ")" | NUMBER | STRING | IDENTIFIER ;
placid cape
#

Is this some specific file format or you just made it

hoary sluice
#

so this is a function

fn add int int int
add x y = x + y

and this is a variable

fn x int
x = 3
hoary sluice
# placid cape Is this some specific file format or you just made it

In computer science, extended Backusโ€“Naur form (EBNF) is a family of metasyntax notations, any of which can be used to express a context-free grammar. EBNF is used to make a formal description of a formal language such as a computer programming language. They are extensions of the basic Backusโ€“Naur form (BNF) metastasis notation.
The earliest E...

placid cape
placid cape
#

In computer science, a parsing expression grammar (PEG) is a type of analytic formal grammar, i.e. it describes a formal language in terms of a set of rules for recognizing strings in the language. The formalism was introduced by Bryan Ford in 2004 and is closely related to the family of top-down parsing languages introduced in the early 1970s.
...

hoary sluice
#

im tryna figure out rn what it means for a function declaration to be an expression

placid cape
#

lambda?

#

maybe

hoary sluice
#

ig u can assing a function declaration to another function

hoary sluice
#
fn a int int
a x = x + fn b int b = 7
#

@placid cape

#

this is pointless tho

#

but itd be valid as a side effect

placid cape
#

can you show me more readable pseudo code please xd

#

I'm not sure if I know what's exactly going on

#

is it something like

hoary sluice
#
fn a int int
a x = x + fn b int b = 7

equivalent to

fn a int int
a x = x + 7

or

def a(x: int):
  return x + 7
placid cape
#

ohhhh understand

#

the last int in the signature is return type not argument

hoary sluice
#

just that ur gonna be able to use function declarations as expressions in order for everything to be an expression

placid cape
#

And a before the next statement means that's it's in the function body

hoary sluice
#

to allow currying

placid cape
#

Yea

#

Or what the a means at the start

hoary sluice
#

its like a switch case

#
fn a int int
a 0 = 1
a n = n * a n - 1
#

this is factorial i think

placid cape
#

ohhhh

hoary sluice
#

it uses the first one that the argument matches

placid cape
#

interesting

hoary sluice
#

its all stolen from haskell

placid cape
#

And how do you know which identifier is what

placid cape
#

but how do you know which identifier is it

hoary sluice
#

in the same order

placid cape
#

okay good luck with that

#

I would probably create some analyzer or something that can match the identifiers to arguments and then it'll be easier to do interpreter/compiler

hoary sluice
#
fn b string int point
b s i = point(0, i) + toint s

fn a int string int point
a x = b (tostring x) 0 
a x s i = point(x, i) + toint s

now u can call a either with 1 argument and or with 3 arguments

a "13" returns point(0, 0) + 13

a 7 "13" 5 returns point(7, 5) + 13
placid cape
#

and you put string

#

or it just skips the first arg?

hoary sluice
placid cape
#

yes but why a "13" is possible when first argument of function a must be int

hoary sluice
#

was looking at signature of b when i wrote that so i wrote "13"

placid cape
#

oh okay

valid jetty
#

holy shit @placid cape

#

closures are easier than i expected

placid cape
#

Interesting

valid jetty
#

literally so good

placid cape
#

I'll definitely use this

#
fun main() {
    i64 a = 18;

    {
        i64 a = 7;
        a = 9;

        {
            a = 8;
            a = 10;
        }
    }

    return a;
}
valid jetty
#

neat

hoary sluice
#

will a be 18

placid cape
#

yeah it should return 18

valid jetty
#

you can check with echo $?

#

shows you the return value of the last executed command

placid cape
#

Or echo $status if you have fish :D

valid jetty
#

oh

#

sure

placid cape
#

when you do echo $? in fish it'll say you that you have to use $status

valid jetty
#

lmfao

hoary sluice
#

i dont like fish

placid cape
#

I mean it's better than just saying it doesnt work, check docs

hoary sluice
#

i used it for a bit and it not being posix is so annoying

placid cape
#

do you use bash, zsh or something totally different?

#

time to make my own shell with blom blobcatcozy

#

terry davis moment

hoary sluice
#

zsh

valid jetty
#

i use zsh

placid cape
#

when elle shell

valid jetty
#

soon!!

hoary sluice
#

isnt zsh the mac default

valid jetty
#

ellsh

#

yes

placid cape
#

ellux

#

make own kernel

valid jetty
#

it does everything i want why change it

placid cape
#

I'm using voidlinux

valid jetty
#

how is it?

placid cape
#

Really good

#

I like it

#

fast pkg manager and everything what I want

valid jetty
#

xbps-query insane

placid cape
#

also like their docs, clean, simple, straightforward

valid jetty
hoary sluice
valid jetty
#

if you update specific dependencies and not pacman -Syu when you first install the OS

hoary sluice
#

its awesome but i missed the aur

valid jetty
#

iirc tsoding uses void lol

#

switched from debian

placid cape
#

they have pretty similar format

hoary sluice
placid cape
placid cape
valid jetty
#

last time i tried arch it was on my ipad

#

oh on that note have you guys ever tried alpine

hoary sluice
hoary sluice
valid jetty
placid cape
hoary sluice
placid cape
#

but I use wayland anyways heh

twilit sigil
#

It actually ran really well

valid jetty
hoary sluice
twilit sigil
#

Somehow got Firefox to open with like 512mb of ram

placid cape
#

idk i know they have open source drivers if you mean that

valid jetty
#

cursed or good

hoary sluice
placid cape
valid jetty
#

its not jailbroken

hoary sluice
valid jetty
#

if i could run asahi i probably would

hoary sluice
valid jetty
#

iSH

hoary sluice
#

does ios have vms

valid jetty
#
valid jetty
#

(because no JIT because apple sucks)

hoary sluice
#

so its just a vm

#

well

#

emulator

#

same thing

valid jetty
#

basically yes

pseudo sierra
valid jetty
#

and the interpreter is appropriately named asbestos

#

๐Ÿ˜ญ

placid cape
#

@valid jetty do you allow nested functions?

valid jetty
#

only lambdas

hoary sluice
#
expression = function | definition | op0 | if_expr ;

function = "fn" IDENTIFIER { TYPE } ;
definition = IDENTIFIER { PATTERN } "=" expression ;
if_expr = "if" expression expression "else" expression ;

op0 = op1 { IDENTIFIER op1 } ;
op1 = op2 { IDENTIFIER op2 } ;
op2 = op3 { IDENTIFIER op3 } ;
op3 = op4 { IDENTIFIER op4 } ;
op4 = op5 { IDENTIFIER op4 } ;
op5 = op6 { IDENTIFIER op6 } ;
op6 = op7 { IDENTIFIER op7 } ;
op7 = op8 { IDENTIFIER op8 } ;
op8 = op9 { IDENTIFIER op9 } ;
op9 = primary { IDENTIFIER primary } ;

primary = "true" | "false" | "null" 
       | "(" expression ")"
       | NUMBER | STRING | IDENTIFIER ;

TYPE = IDENTIFIER ;

PATTERN = "_"
       | "true" | "false"
       | NUMBER
       | STRING
       | IDENTIFIER ;
#

@valid jetty rate

#

@placid cape rate

#
0..100 map (if (%3) == 0 "fizz" else "" + if (%5) == 0 "buzz" else "") each print
#

partial application is so awesome, (%5) returns a function similar to this:

def s(arg: int) -> int:
  return arg % 5
#

overall equivalent to

def s5(arg: int) -> int:
  return arg % 5

def s3(arg: int) -> int:
  return arg % 3

def ss(arg: int) -> int:
  return if s3(arg) == 0 "fizz" else "" + if s5(arg) == 0 "buzz" else ""

map(0..100, ss)
valid jetty
fleet cedar
#

So you have that if some_fn ... turns into |x| if some_fn(x) ...?

fleet cedar
#

What if you also need x inside the cases, make an explicit lambda?

hoary sluice
#

yes

#

but when would u need that

#

ig if u do map (x, 91)

fleet cedar
#

Very often?

hoary sluice
#

to make tuples

fleet cedar
#

Often you do things like if x%2 then 3*x+1 else x/2

placid cape
#

push push push

#

I need to see how the env actually works xd

valid jetty
#

no lol it doesnt use env

#

im not gonna push that yet

#

im just refactoring all of my examples to use the new semantics

hoary sluice
valid jetty
#

for now ill make it just not free anything at all

hoary sluice
#

it is ugly so explicit lambdas will be allowed

valid jetty
#

bad but i dont wanna commit too much at once

placid cape
#

but it's better to commit more often than one large commit that changes a lot of things

#

you can create local commits and then push everything at once

valid jetty
#

this commit alone edits so much stuff

valid jetty
placid cape
#

so you'll still have nice git history and also the version on GitHub will really work

valid jetty
#

i just kinda edit things all over the place

hoary sluice
valid jetty
#

@placid cape if youve ever read my commit history

placid cape
#

yea I've seen that

valid jetty
#

its bad but its just how my brain works

#

oh and i also accidentally fixed the issue with struct names being written twice lol

#

in old code you had to write

Foo foo = Foo { x = 1, y = 1 };
#

i was gonna make it so you can do

Foo foo = { x = 1, y = 1 };
placid cape
#

that's nice

hoary sluice
#

c moment

valid jetty
#

but then let came along so you can just do

let foo = Foo { x = 1, y = 1 };
placid cape
#

Do you have support for function overloading?

valid jetty
#

nope

placid cape
#

I definitely want to do it

#

I love overloading

valid jetty
#

but there are varargs

#

you can technically write overloading

hoary sluice
placid cape
#

If it's not typescript overloading

#

Have you seen typescript's overloading?

valid jetty
valid jetty
placid cape
#
function add(a: number, b: number): number;
function add(a: string, b: string): number;

function add(a: unknown, b: unknown): number {
  if (typeof a === "string" && typeof b === "string") {
    return Number(a) + Number(b);
  } else if (typeof a === "number" && typeof b === "number") {
    return a + b;
  }
  return 0;
}
#

๐Ÿ˜

valid jetty
#

oh lol that

#

yeah thats pretty much what you can do in elle

placid cape
#

and if you have overloading with different amount of arguments you have to check for length of args as well

#

horrible

valid jetty
#

if you wanna call this overloading

#

i couldve used die actually

#

i forgot i have that function

#

but you dont get an error message with that

#

the meta struct is actually like super useful

#

i suppose this is an "env" of sorts

#

but its not passed to every function

#

only functions that ask for it

valid jetty
#

im so glad i have tests

#

i wouldnt have caught that lol

hoary sluice
#

i have an idea

#

if a function produces side effects its not allowed to return a value

valid jetty
#

revised i guess

use std/prelude;

fn add(ElleMeta meta, ...) {
    variadic args[meta.arity];

    if meta.arity != 2 {
        io::panic("Invalid number of arguments provided: {}", meta.arity);
    }

    let valid = ["string", "i32"];
    if !valid.contains(meta.types[0]) || !valid.contains(meta.types[1]) {
        io::panic("Invalid argument types provided: {} and {}", meta.types[0], meta.types[1]);
    }

    let a = meta.types[0] == "string" ? i32::parse(args.yield(string)) : args.yield(i32);
    let b = meta.types[1] == "string" ? i32::parse(args.yield(string)) : args.yield(i32);
    return a + b;
}

fn main() {
    io::dbg(add("13", "26")); // valid
    io::dbg(add(44, 6)); // valid
    io::dbg(add(1, "99")); // valid
    io::dbg(add("a", 13)); // valid because a would parse to 0
    io::dbg(add(1.0, 3)); // invalid because f32
    io::dbg(add(1, 2, 3)); // invalid because > 2 args
    io::dbg(add("1")); // invalid because < 2 args
}
hoary sluice
#

this is extremely cursed

hasty vessel
valid jetty
#

it lets you pass absolutely anything

#

technically this is a dynamic language now

placid cape
hoary sluice
#

its becoming closer and closer to js every day

#

i think i need to revise my function syntax

#

cause variables use the fn keyword

placid cape
#

oopsie

hasty vessel
#

way too long

valid jetty
#

๐Ÿ˜ญ

valid jetty
hasty vessel
#

hello world script

valid jetty
#

this looks like one of those "can you write a hello world script in the most convoluted way possible" things you get back from ai lmfao

hasty vessel
#

yeah lol i just asked chatgpt "make long hello world script now"

valid jetty
#

called it

hasty vessel
#

god damn is this taking long

hoary sluice
#
add int int = a b $ a + b

add int int
add a b = a + b

// variable:
x = 7
hoary sluice
#

now we get the := dilemma

valid jetty
#
fein fein;

fein fein(fein fein, fein *fein) {
    fein fein fein = fein; fein < fein; fein += fein {
        fein::fein("fein[%fein] = %fein", fein);
    }

    fein fein;
}
hoary sluice
#

is this valid elle

valid jetty
#

i wish

hoary sluice
#

omg i have an idea

#
// functions:
add int int = a b $ a + b

add int int
add a b = a + b

// variables:
x int = 7

x int
x = 7

placid cape
#

๐Ÿ˜

hoary sluice
#

this is literally perfect

hasty vessel
hoary sluice
#

x _ = is literally _ as the type

#

but x := is cleaner

valid jetty
#

_=?????????????

#

:= much better

#

what have i done

hasty vessel
#

const mitochondria = 'powerhouse of the cell'

hoary sluice
valid jetty
#

i guess

valid jetty
hoary sluice
#
x int = 7
x _ = 7

because x is technically a function

valid jetty
#

technically the behavior isnt exactly the same because in js all numbers are floats

placid cape
hoary sluice
valid jetty
#

im scared

#

soon theyre gonna fork elle and bring a 2gb elle_modules folder

hoary sluice
#

@valid jetty i think im gonna do _=

valid jetty
#

you can but it looks a little weird

hoary sluice
#

ik

#
x _ = 7
add int int _ = a b $ a + b

it matches functions

#

i cant use : for pattern matching/inference

valid jetty
#

you could always just interpret : as a different thing depending on the context

hoary sluice
valid jetty
#

are you planning to use rust for lists or implement the recursive tail lists with Pair(done, next)

#

(the fp way of lists)

hoary sluice
#

not sure yet

#

i dont really like x:xs lists

#

and they cant be indexed, right?

valid jetty
#

a list like [1, 2, 3] in fp would look like (1, (2, (3, nil)))

valid jetty
hoary sluice
#

how

fleet cedar
#

In linear time

valid jetty
#

it would be O(n) tho

#

yes

hoary sluice
#

that was my point

valid jetty
#

its basically just a glorified singly linked list lol

hoary sluice
#

id rather have [1, 2, 3]

fleet cedar
#

It's not even glorified

hoary sluice
#

or both, but first [1, 2, 3]

fleet cedar
#

It is a linked list, plain and simple

valid jetty
#

theres usually abstractions over it to make it look like a conventional list

#

but yeah

fleet cedar
valid jetty
#

yeah thats what i meant

hoary sluice
#

its sugar for a linked list

valid jetty
#

yep

fleet cedar
#

It would really be 1:2:3:[], but syntax sugar is nice

hoary sluice
#

but u cannot afford O(n) indexing when half of all problems are 2d grids

fleet cedar
#

Fair

valid jetty
#

@hoary sluice is this a good feature

use std/io;

fn main() {
    io::assert('a' == "a", nil); // Will use 'a' == "a"[0]
    io::assert("a" != 'b', nil); // Will use "a"[0] == 'b'
    io::assert("a" == 'a', nil); // Will use "a"[0] == 'a'
    io::assert('a' == "abc", nil); // Will use 'a' == "abc"[0]

    io::println("All string to character tests have passed!".color("green").reset());
}
``` i implemented this 3 months ago according to git blame
placid cape
#

why io::assert

valid jetty
#

wdym

hoary sluice
#

no

hoary sluice
#

dont cast implicitly

#

you are literally implementing js

placid cape
#

idk assert in io is weird

hoary sluice
#

when ===

placid cape
#

and yeah dont make JS lol

valid jetty
#

it was because i typed ":" not ':'

fleet cedar
#

Type errors, anyone?

valid jetty
#

sure

hoary sluice
#
fn equals(a: any, b: any) {
    if typeof a != typeof b return false
    return a == b
}
placid cape
#

now it passes analyzer and compiles

placid cape
#

java java java

fleet cedar
hoary sluice
#

sorry i meant operator fn ==

hoary sluice
#

wait what

fleet cedar
valid jetty
#

technically here you can use generics lol

hoary sluice
#

thats wrong

fleet cedar
placid cape
#

Object.requiresNonNull(a.equals(b))

valid jetty
#
fn equals<T, U>(ElleMeta meta, T x, U y) {
    return meta.types[0] == meta.types[1] || x == y;
}
fleet cedar
hoary sluice
placid cape
fleet cedar
valid jetty
hoary sluice
fleet cedar
#

But a close approximation

hoary sluice
placid cape
#

btw im ziggy so I have @cast() for casting blobcatcozy

#

(easier to parse)

valid jetty
#

its SO much easier to parse

#

i regret going with c style casts

placid cape
hoary sluice
valid jetty
#

it is

#

its promoting i32 to i64

hoary sluice
valid jetty
#

oh i know but i meant the compiler does that for you

hoary sluice
#

i meant dont cast inside the == at all

valid jetty
#

do you want the compiler to error when comparing i32 and i64

hoary sluice
#

yes

valid jetty
#

horror

placid cape
valid jetty
#

i32

placid cape
#

So i64 a = 5; is also an implicit cast

valid jetty
#

no actually

hoary sluice
#

default to usize ๐ŸงŒ

placid cape
#

don't cast in if statements

valid jetty
#

in i64 a = 5 the compiler tells the literal that the type is i64 and it actually directly creates the literal as an i64

hoary sluice
#

its what everyone besides js does

valid jetty
#

instead of creating it as i32 and promoting

#

hmmm ok

placid cape
#

that's what I'm gonna do too

hoary sluice
#

maybe stuff like ruby does casting in ==

valid jetty
#

its a bit cursd to read

ValueKind::Number(val) => {
    let num_ty = match kind {
        TokenKind::BoolLiteral => Type::Boolean,
        TokenKind::IntegerLiteral => Type::Word,
        TokenKind::FloatLiteral => Type::Single,
        TokenKind::LongLiteral => Type::Long,
        _ => Type::Word,
    };

    let mut final_ty = if ty.clone().is_some_and(|ty| !ty.is_string()) {
        ty.unwrap_or(num_ty)
    } else {
        num_ty
    };

    if is_return {
        final_ty = func.borrow_mut().return_type.clone().unwrap_or(final_ty);
    }

    Some((
        final_ty.clone(),
        Value::Const(
            if final_ty.clone() == Type::Double {
                "d_"
            } else if final_ty.clone() == Type::Single {
                "s_"
            } else {
                ""
            }
            .into(),
            val,
        ),
    ))
}
``` but yeah
hoary sluice
#
struct A {
  i32 a;
  Point b;
}

struct B {
  i32 a;
  Point b;
}

let a = A { 3, Point { 4, 6 } }
let b = B { 3, Point { 4, 6 } }
assert a == b
#

this should fail

valid jetty
hoary sluice
#

and so should i32 vs i64

valid jetty
#

uhhhhh

#

idk i quite like being able to do

for x in [[1, 2], [3, 4]] {
    if x == [1, 2] {
        io::println(":3");
    }
}
hoary sluice
fleet cedar
valid jetty
#

and thats how it behaves

hoary sluice
valid jetty
#

yes it is

hoary sluice
placid cape
#
valid jetty
#
fn Array::__equals__<T>(T[] self, T[] other) -> bool {
    if (void *)self == (void *)other {
        return true;
    }

    if ((void *)self == nil) || ((void *)other == nil) || self.len() != other.len() {
        return false;
    }

    for let i = 0; i < self.len(); i += 1 {
        if self[i] != other[i] {
            return false;
        }
    }

    return true;
}
hoary sluice
valid jetty
#

thats enforced by the generics

placid cape
#

because that should throw compilation error

#

since it's a different type

hoary sluice
#

just do it like java

bool ==(Object a, Object b) {
    return &a == &b
}
valid jetty
#

the reason it doesnt throw an error is because T[] is Array<T> *, theyre both ptrs

#

once it looks at T[] for self and sees T = i32 it stops searching because it found all the generics

#

so it doesnt assert that the T in other is the same as the the T in self

#

i need to fix that

hoary sluice
#

Array<reified T>

arr1.T.type == arr2.T.type

valid jetty
#

it basically interprets string[] as i32[] implicitly here but that is a huge issue lmfao

hoary sluice
#

u have reified generics right?

valid jetty
#

uhhh only with ellemeta

hoary sluice
#

fix that

valid jetty
#

eventually

placid cape
valid jetty
#

it does actually fail here but these arent structs

placid cape
#

I think you must

#

like you can't do

record Something<T>()

Something<Integer> a = new Something();
Something<Float> b = new Something();

a == b // error
valid jetty
#

oh yeah you deffo cant do that

#

i can actually technically do a little bit of a cursed thing

#
fn Array::__equals__<T, U>(ElleMeta meta, T[] self, U[] other) -> bool {
    if (void *)self == (void *)other {
        return true;
    }

    if ((void *)self == nil) 
        || ((void *)other == nil) 
        || self.len() != other.len() 
        || meta.types[0] != meta.types[1] 
    {
        return false;
    }

    for let i = 0; i < self.len(); i += 1 {
        if self[i] != other[i] {
            return false;
        }
    }

    return true;
}
#

oh and it actually fails at compile time now

#

ok good

hoary sluice
valid jetty
#

wdym self.meta

#

oh

#

the thing is that this wasnt designed to be used like this

placid cape
#

But what if you have meta in struct

valid jetty
#

yeah that

#

ok this is probably good

fn Array::__equals__<T, U>(T[] self, U[] other) -> bool {
    // If the pointers are the same (nil == nil)
    if (void *)self == (void *)other {
        return true;
    }

    // If one is nil
    if ((void *)self == nil) || ((void *)other == nil)
        || self.len() != other.len() // If lengths don't match
    {
        return false;
    }

    if !self.is_empty() && !other.is_empty() {
        if self[0] != other[0] {
            return false; // If the types don't match
        }
    }

    for let i = 0; i < self.len(); i += 1 {
        if self[i] != other[i] {
            return false; // Deep equality
        }
    }

    return true;
}
placid cape
#

making meta restricted keyword is too much tbh

valid jetty
#

yeah you can call the meta struct whatever you want

royal nymph
valid jetty
#

you actually dont need ElleMeta for this because itll fail at compile time if the types of the arrays dont match

hoary sluice
#

why are u panicking when hitting an error

valid jetty
#

thats a thing i meant to solve a while ago but never got to

hoary sluice
#

esp in lexer

#

without an lsp

#

u have to compile so many times to find syntax errors

royal nymph
#

inbuilt in nodejs

placid cape
#

is it actually faster than the npm pkg?

hoary sluice
#

im guessing fast deep equal is faster

placid cape
#

Just asking because last time when I implemented own reduce it was faster lol

royal nymph
#

in 99.99% of scenarios it doesnt matter if it's slightly slower

jade stone
hoary sluice
#

it does in aoc game of life

#

with huge grids

valid jetty
#

and the UInt8Array has 1,000,000,000 items inside

royal nymph
valid jetty
#

lmfao ok

royal nymph
#

you would compare the arrays

placid cape
valid jetty
#

?? discord is drunk again

#

รฅโ‚ฌยข

jade stone
valid jetty
#

@hoary sluice is this good

#

being able to do x || y and its not boolean

placid cape
#

NO

hoary sluice
royal nymph
#

then yes

placid cape
#

why you're changing your static typed language to dynamic husk husk husk

hoary sluice
#

oh x is a string

valid jetty
#

i remember spending so long trying to get that to work lol

hoary sluice
#

yea its file

hoary sluice
#

fine

royal nymph
#

wdym lol

valid jetty
royal nymph
#

good

#

then why add ||

valid jetty
#

equivalent to x ? x : "meep"

placid cape
#

|| is weird

valid jetty
#

|| was a feature longgggg before ?:

hoary sluice
valid jetty
#

what the hell was i doing 4 months ago

#

thank god that was fixed

hoary sluice
#

isnt that intended

placid cape
valid jetty
#

because it thought 1 was a char *

hoary sluice
#

huh lol

valid jetty
#

yeah it was weird

placid cape
#

I should implement && and ||

#

but I'll have it as and and or

valid jetty
#

its like when doing

fn foo(i32 c) {}

foo(bar(bar("a"));
``` it thought "a" is an i32 lol
placid cape
#

oh lol

valid jetty
#

thankfully that was fixed because wtf

valid jetty
#

because you have to implement short circuiting

#

like in x && y if x is false it shouldnt even evaluate y

hoary sluice
valid jetty
#

or in x || y if x is true it shouldnt evaluate y

placid cape
valid jetty
#

ok this error is actually very good

#

i was scared for a second

#

or vice versa

placid cape
#

I like your error messages

#

really nice

hoary sluice
#

add more context

#

Expected i32, got string

placid cape
#

it's in the first line

hoary sluice
#

oh

placid cape
#

Cannot implicitly convert 'i32' to 'string'

hoary sluice
#

the colored thing should have it too tho

valid jetty
#

yeah idk i can color in i32 and string to make it stand out more

#

@hoary sluice is stuff like this ever useful for aoc

use std/vectors;
use std/prelude;

fn Vector3::test() {
    let v = Vector3 { x = 1.0, y = 0.0, z = 0.0 };
    let axis = Vector3 { x = 0.0, y = 0.0, z = 1.0 };
    let angle = PI / 2.0;

    let rotated = v.rotate(axis, angle);
    io::dbg(rotated);

    let v1 = Vector3 { x = 1, y = 0, z = 0 };
    let v2 = Vector3 { x = 0, y = 1, z = 0 };
    io::dbg(v1.angle(v2));

    let zero = Vector3::zero();
    io::dbg(zero);
}

fn Vector2::test() {
    let v1 = Vector2 { x = 1.0, y = 0.0 };
    let rotated = v1.rotate(PI);
    io::dbg(rotated);

    let v1 = Vector2 { x = 1, y = 0 };
    let v2 = Vector2 { x = 0, y = 1 };
    io::dbg(v1.angle(v2));

    let zero = Vector2::zero();
    io::dbg(zero);
}

fn main() {
    Vector3::test();
    io::println();
    Vector2::test();
}
#

i swear ive asked about these vectors before actually

#

short term memory loss

placid cape
#

Most of time you just need point since we have 2d grids

#

Oh you have vector2

placid cape
#

do you have file api?

#

@valid jetty

#

Nvm you must have

valid jetty
valid jetty
#

theres only io::read_to_string() as a temporary thing for aoc

#
fn io::read_to_string(string path) -> string {
    FILE *file = io::fopen(path, "r");
    defer io::fclose(file);

    if !file {
        return nil;
    }

    io::fseek(file, 0, SEEK_END);
    i64 file_size = io::ftell(file);
    io::fseek(file, 0, SEEK_SET);
    i64 buf_size;

    if file_size > 0 {
        buf_size = file_size + 1;
    } else {
        buf_size = 4096;
    }

    string buf = (string)malloc(buf_size * #size(char));

    if !buf {
        return nil;
    }

    i64 pos = 0;
    i64 read_size;

    while (read_size = io::fread(buf + pos, #size(char), buf_size - pos - 1, file)) > 0 {
        pos += read_size;

        if pos >= buf_size - 1 {
            buf_size *= 2;
            buf = (string)realloc(buf, buf_size * #size(char));

            if !buf {
                return nil;
            }
        }
    }

    buf[pos] = '\0';
    return buf;
}
placid cape
valid jetty
placid cape
#

Make Vector2f and Vector2d

valid jetty
hoary sluice
#

it call them smth else

#

Point

#

Point3D

#

PointAD

valid jetty
#

idk they are vectors

hoary sluice
#

FPoint

placid cape
#

that's aoc specific thing

hoary sluice
#

or FloatPoint

valid jetty
#

like in math they are vectors

fn Vector3::zero() {
    return Vector3 {
        x = 0,
        y = 0,
        z = 0
    };
}

fn Vector3::clone(Vector3 self) {
    return Vector3 {
        x = self.x,
        y = self.y,
        z = self.z
    };
}

fn Vector3::dot(Vector3 self, Vector3 v2) {
    return self.x * v2.x + self.y * v2.y + self.z * v2.z;
}

fn Vector3::cross(Vector3 self, Vector3 v2) {
    return Vector3 {
        x = self.y * v2.z - self.z * v2.y,
        y = self.z * v2.x - self.x * v2.z,
        z = self.x * v2.y - self.y * v2.x,
    };
}

fn Vector3::length_sq(Vector3 self) {
    return self.dot(self);
}

fn Vector3::length(Vector3 self) {
    return math::sqrt(self.length_sq());
}

fn Vector3::add(Vector3 self, Vector3 v2) {
    return Vector3 {
        x = self.x + v2.x,
        y = self.y + v2.y,
        z = self.z + v2.z,
    };
}

fn Vector3::sub(Vector3 self, Vector3 v2) {
    return Vector3 {
        x = self.x - v2.x,
        y = self.y - v2.y,
        z = self.z - v2.z,
    };
}

fn Vector3::scale(Vector3 self, f32 scalar) {
    return Vector3 {
        x = self.x * scalar,
        y = self.y * scalar,
        z = self.z * scalar,
    };
}

fn Vector3::normalize(Vector3 self) {
    f32 length = self.length();
    return self.scale(1.0 / length);
}
#

they behave like vectors in math

placid cape
#

yea that's good keep it