#🪅-progaming
1 messages · Page 81 of 1
@valid jetty maybe ill get started on io tomorrow
You don't necessarily need poker knowledge but it helps
OHHH MY AUTISTIC CLASSMATE PLAYED THIS ALL THE TIME
he was flexing his 1e347 all the time
looks interesting but needs some division 😭
like
add a newline between each test
or some color
or something
cba rn
Lua
i remember always getting weird e numbers in lua
funny stuff
its cool being able to just see the lua source code in balatro
makes modding 100x easier
i am never asking ai for a code review ever again
Roaches
ZOOT?????
nop
pub enum Unit @repr(u8) { _ };
pub const _ = Unit::_;
fn TcpConnection::close(TcpConnection self) -> Result<Unit, Errno> {
res := close(self.fd);
if res < 0 {
return Result::Err(#cast(Errno, errno));
}
return Result::Ok(_);
}
``` @hoary sluice is this sane
essentially a way to strongly type returning 0
zoot was here earlier i explained how to print a number in qbe ir
.
guh?
@deep mulch rosie is so powerful she can turn your brain off in seconds just by yapping about a simple programming concept
its true
Rosie tries explaining programming concept to ants
zoot sometimes spawns in vencord
yop
die
is it even a good idea to have a unit type
imo this is good other than calling the constant _
it was Unit::new() before but i dont like how long it is
Unit type is way better than having a big void-shaped hole in your type system
ty
true
but is it a good idea to always have a constant named _ in all contexts
Whether you name it _ or () or george is none of my business
@woven mesa @robust jackal you love the entirety of eqmac just being a webview for no rhyme or reason
its a standard swiftui app yet they made the entire interface a webview anyway and had the chance to just use swiftui but didnt
yeah but i just dont know whether its sane for when i eventually make "This function call's return value is not consumed. Try assigning it to a variable" warnings
I do think george is quite charming though
lmfao
technically
very technically
i can do this
pub const _ = #cast(void, nil);
``` lmao
and then you can do Result<void, Errno>
the thing with enums is that theyre entirely a 0 cost abstraction so doing it this way or with the Unit enum is going to have exactly the same output
Having different names for the unit type and its value is kinda ugly imo
yeah but i tried to do that and the parser doesnt allow it because its speculatively assuming that if the identifier is in the struct or enum pool at all its going to be a type no matter the context (because of struct literals)
Ah, C-style
yea but without needing to include struct X or enum Y, its just X or Y
its just kept track of by the compiler
Doesn't that require a system for forward declarations
Context-free languages are better
context is fun though, especially for things like return type inference
Type inference happens after parsing
yeah
Though it's not like rust is context-free either, considering macros
Rosie knows everything
however you need to compile the body to get the return type, therefore you have to compile function calls, which means you need to know their interface, and it becomes this big blob of context requirement
hence, forward declaration
@valid jetty explain the difference between a linear power supply and a switching power supply
idk lol
I guess the linear one is straight, which means the other is gay
true
I've heard of direct vs alternating current, which sounds like it might be somewhat related to this linear/switching thing, too
the biggest incentive i have to make function return type mandatory is this:
fn foo() {
return bar();
}
``` you have to compile foo and then that returns bar so you have to go find bar's interface, but if bar also has an implicit return type you need to also compile `bar`, then if this chain grows and any of the functions in this chain become recursive, you lose `foo`'s return value and any function higher up the chain until the recursive function (unless you explicitly set the return type of the recursive function)
its a real problem
Yep
Explicit return types enable local reasoning
And also catch implementation bugs
linear supplies use a transformer to step up or step down. they run hotter and are less efficient. they're also heavier but they have a cleaner waveform and less electromagnetic interference
switching uses buck / boost converters to step up and step down. they're much more efficient, lighter and run cooler. but due to the switching, they emit worse electromagnetic interference especially cheaply made units @valid jetty
but are also much more annoying for quick implementations of some function
yes
like if i wanna implement a function that returns a huge type Result<Foo<Bar[], Baz>, (Qux, Eep)[][]> i dont want to essentially need to define the same information in 2 places
being able to infer from the expression's type that this is what i want to return is nice
is (Qux, Eep) a tuple
You will add type aliases
yeah
i mean thats true but being able to infer return types for quick prototype work is useful
Languages should optimize for real code, not toy code
Though perhaps it's different for toy languages
@valid jetty add Elle coroutines
i mean yes but its also a real problem in rust that its verbosity makes it harder to prototype anything
elleroutines
have you not seen the things where people move to python to prototype and come back to rust to write the real implementation
this smells like inline assembly
Rosie hates easy to write code
no what
you physically cannot make coroutines without assembly
you need to save the registers when switching context
oh
I thought you meant you were just gonna make users use assembly instead of adding coroutines
lmao
Tell that to most modern languages
I've never needed to use asm!{} inside an async block, have you?
no i meant like, to create the abstraction
obviously when actually using it you just yield and jump or whatever
but internally you still need platform-specific assembly to save context before switching procedure
No you don't, that's just silly
wha
rosie smith go to sleep
how are you gonna save registers without inline assembly
Rosie doesn't know how to sleep
its like 10pm lol
State machine
I don't think you need assembly for coroutines
Registers exist at a way lower plane than coro desugaring
hmm i see
i was talking about this kind of thing https://github.com/tsoding/generators/blob/main/generator.c
Sure, if you want to implement coros without language support you're in for a hell of a ride
lmao
@valid jetty
you can’t even do threaded code at all nevertheless atomic abstractions
technically you can just leverage C libraries lol
noone is stopping you from using pthread or whatever
i did that when i was experimenting with my GC impl
Elle will run on esp32
@hoary sluice i think ill need to actually implement one of these https://en.wikipedia.org/wiki/Interval_tree
In computer science, an interval tree is a tree data structure to hold intervals. Specifically, it allows one to efficiently find all intervals that overlap with any given interval or point. It is often used for windowing queries, for instance, to find all roads on a computerized map inside a rectangular viewport, or to find all visible elements...
for GC allocations
my current impl uses a hashmap
which is fine for exact allocations but will cause a free if i do
fn main() {
x := #alloc(i32, 4);
y := x + #size(i32);
x = nil;
}
``` which is incorrect (because it only checks if the base pointer is set)
the benefit of this is that its O(1)
but its also wrong
i could do just an array of headers and check whether the ptr is within the interval of an allocation
but then it becomes O(n)
if i use an interval tree i think it becomes as good as O(logn) but is also correct for internal pointers within a buffer
So you're implementing your own allocator too?
Giving access to an allocator is a very different thing from implementing said allocator
its been the primary allocator since january
@valid jetty
allocators are hot-swappable, though
I'd just use jemalloc or similar
@deep mulch minkylang
soon
Or mimalloc or snmalloc, depending on what my benchmarks say
Definitely wouldn't implement one myself though
i dont think you need an interval tree for this
this implementation still uses malloc internally, but it allows for automatic cleanup (as per a gc)
i dont want to limit programs to a fixed memory capacity
i also have an arena allocator impl
i dont know if you count this as a custom allocator 😭 its more like a GC abstraction over malloc
as in, you call GCAllocator::alloc which keeps track of deallocating for you, but it still uses malloc to actually allocate the memory
That sounds vaguely like a no
you can be the judge https://github.com/acquitelol/elle/blob/rewrite/std/runtime/allocators/gc.le
If you are calling a different malloc, you are not implementing the allocator
i mean yeah
theres not really any way to make an allocator that doesnt use malloc internally other than a static memory region or manually doing mmap yourself
and a static memory region is quite limiting imo
Yes, it is not possible to make an allocator without doing the allocation stuff
Since that's literally what an allocator is
i might try to do it via mmap at some point
and like, maintain a free list or something
Enjoy quadrupling your runtime
lmao
Or who knows, maybe you manage to figure out a new super efficient scheme
do you love the heap allocator
use std/libc/mem;
global pub;
namespace HeapAllocator;
fn HeapAllocator::new() {
return #cast(HeapAllocator *, nil);
}
fn HeapAllocator::alloc(HeapAllocator *self, i32 size) {
return mem::malloc(size);
}
fn HeapAllocator::realloc(HeapAllocator *self, void *ptr, i32 new_size) {
return mem::realloc(ptr, new_size);
}
fn HeapAllocator::free(HeapAllocator *self, void *ptr) {
return mem::free(ptr);
}
m-elle-oc
explicit return types when
the HeapAllocator exists because #set_allocator expects you pass it something that has those methods defined on it (new, alloc, realloc, free, free_self)
idk if i want to do this
im still very torn on it
if they become mandatory i might just do the c3 look and do fn <return type> <name>() {}
like go
@valid jetty oh rosie my rosie
horror
how are we feeling on ECMAScript for XML
var sales = <sales vendor="John">
<item type="peas" price="4" quantity="6"/>
<item type="carrot" price="3" quantity="10"/>
<item type="chips" price="5" quantity="3"/>
</sales>;
alert( sales.item.(@type == "carrot").@quantity );
alert( sales.@vendor );
for each( var price in sales..@price ) {
alert( price );
}
delete sales.item[0];
sales.item += <item type="oranges" price="4"/>;
sales.item.(@type == "oranges").@quantity = 4;
is it fire
am i allowed to ask for help here or do i have to find out how to type in plugin-development
why are splines? well my god I have good news for you, here's why splines!
if you like my work, please consider supporting me 💖
https://www.patreon.com/acegikmo
This project grew much larger in scope than I had originally intended, and burnout made it impossible for me to do more with it. It was already getting incredibly unwieldy, so I apo...
@valid jetty i think youd find this interesting
super good
freya holmer mentioned !!
ya i saw this a while ago, such a good video 🎀🎀
all freya holmer videos are so good
yoppppp
@valid jetty can you write ellec -rei instead of ellec -r -e -i
but isnt that in the posix standard
nobody follows the posix standard for cli arguments tho
clang literally lets you pass -emit-llvm should that be parsed as -e -m -i -t -- -l -l -v -m
Most, but not all, follow de facto standards
i dont think its too difficult to do no?
x if x.starts_with('-') && !x.starts_with("--")
why shouldnt you
at least when you have a lot of 1 char args its useful to chain them that way
yeah but refactoring time
i can do it its not that hard
unsafe
Is Elle... not memory safe?
My dreams.
Shattered.
All those neatly arranged bits and bytes...
Overwritten.
I trusted her.
A language so elegant, so pure.
But behind the static types and lifetimes...
Undefined behavior lurked.
She let me dereference null.
She let me dance with use-after-free.
I thought we were compiling toward safety—
Instead, I’m compiling with fear.
Tell me, compiler,
Did the borrow checker lie too?
Was it all just syntactic sugar,
Masking the bitter truth of segmentation faults?
Say it ain’t so.
Tell me there's still hope—
That somewhere in the core of Elle,
Memory safety lives.
...Or was I just dreaming in C again?
i wrote the first four lines
😭
icypeas is memory safe (and blazingly fast 🚀 )
I thought we were compiling toward safety—
Instead, I’m compiling with fear.
so good
@valid jetty do you have any ci other than tests
nop
i will eventually add a ci so that prs must at least make the compiler compile and the tests should pass
then i can verify for correctness by hand
i mean like cargo fmt on commit
cargo clippy --fix --bin "elle" on commit

@valid jetty
#[derive(Debug)]
pub enum Argument {
Help,
Run,
Usage,
Version,
}
impl From<String> for Argument {
fn from(value: String) -> Self {
let value = value.to_lowercase();
if value.starts_with("--") {
match value.as_str().trim_start_matches('-') {
"help" => Self::Help,
"run" => Self::Run,
"version" => Self::Version,
_ => Self::Usage,
}
} else {
todo!()
}
}
}
fn main() -> ExitCode {
let mut args = std::env::args();
let program = args.next().expect("program name should exist");
let mut args = args.map(|arg| Argument::from(arg)).peekable();
dbg!(args.collect::<Vec<_>>());
test()
}
I'd usually give some library that responsibility
there is clap for that but i dont wanna have any deps if its not strictly required
Why
makes sense
NIH is a mental illness
arg parsing is easy enough to not need a dep
It is very much not
if i need async something im gonna depend on tokio, not make my own async runtime
i dont want this to take 3 minutes to compile
this is 3k loc and takes 3 minutes to compile https://github.com/eagely/voice-backend/blob/main/Cargo.toml
you're already writing one parser, why not write a second
@hoary sluice how are you gonna handle args which require a second thing like -p foo/bar with your system
if there are multiple and you do -puv how do you know which one wants the path
in that case you have to do it separately probably
afaik clap takes care of that for you
Yet another thing that is very nice to not have to implement yourself
clap takes 4.5s to compile clean
How often do you clean build
thats 4.5s i could be gambling
thats what im thinking but in the voice assistant it was getting really annoying having to wait minutes for it to compile, so often enough for it to matter
..why do you clean build??
i dont clean build
i probably clean build my stuff about once a day
but sometimes (when a dep updates?) it clean builds for you
clap is probably fine but if i add too much its gonna get annoying
i use quite a few and it doesnt take that long
[build-dependencies]
chrono = "0.4"
[dependencies]
levenshtein = "1.0.5"
codegen = { path = "codegen" }
tower-lsp = "0.20.0"
tokio = { version = "1.44.2", features = ["full"] }
anyhow = "1.0.98"
string-interner = "0.19.0"
tokio probably takes up 99.9% of your compilation time
Try calling it names or drawing ugly drawing on its locker
anyone know how could i pipe data to ffprobe?
i want to get duraiton of a track
cat song.mp3 | ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i
doesnt work
just gives n/a
cat your_file | ffprobe - or ffmpeg -i your_file -f ffmetadata pipe:
bloat
too handy
just a bunch of stuff i could easily write myself, but it's eaiser to just use lodash
like what
also only 24kb gzipped
things like this
i could easily write this, but its pretty handy
also this horror that i'm pretty sure there's a better way to do
that is just atrocious code bro
yeah, that's why i said it was horror 😭
yop, that's why i said that
lodash has the potential to be faster if it has actual pipelines tho
like you can do .reverse().chunk().map() in one single go
not 3
also being able to map to props with just a string is very nice
why do lodash and make it so you need to understand a library to understand th ecode

@jade stone try effect
insane
vercel design slop
guaranteed bad
astro which is based but still ew colours
I don't really like it, from a glance I prefer the lhs of their example
wow this looks awful
stop trying to turn js into rust it doesn't work
functional style typescript
also lol docs teaching you antipatterns
classes my beloved
@valid jetty how am i supposed to do anything while having a job
and going to uni
there are 168 hours in a week and somehow 40 are enough for you to not have free time
maybe its cause i sleep 14 hours
@valid jetty
:3
@hoary sluice i switched to using u64 for length of strings and arrays instead of i32 for arrays and i64 for strings, it never occured to me but now this ```rs
use std/prelude;
fn main() {
for let i = "hiii".len(); i >= 0; i -= 1 {
$dbg(i);
}
}
and i understand why but its still kinda funny
youll have >0, subtract 1, it will equal 0, you subtract 1 again but its unsigned so it becomes u64::MAX_VALUE and so its still >0
Most compilers warn about always-true comparisons
Yes
This is where the goes to operator --> comes in
🎉 Big news! CLion is now free for non-commercial use! Whether you're a student, hobbyist, open-source hero, or just in love with C or C++, you can now code your heart out – for free! https://t.co/1ExxItf7Wz
#cpp #cplusplus
everyone should ditch vs now 
GOOD
kinda funny how ppl in replies are crying over them forcing you to send anonymous statistics
like
they’re giving you a goated ide FOR FREE 😭😭😭
BASED
when free goland
i thought it was already
hold on
oh nvm 💔
is goland really that great though
yes
compared to like gopls
I mean it honestly makes sense to keep goland paid
it makes sense to make clion free because the alternative (visual studio) is also free
so if you really wanna compete you need to match that
meanwhile the go ide market isn't as saturated so you can make your go ide paid
they made rustrover free when in reality there is no rust ide either
I never even heard of rustrover
lol how
most people probably use vscode
Nov 26, 2023 ... That said, our intention is to keep the product in public preview until no later than September 2024. ".
go in vscode is pretty solid but goland is way better
How's rustrover compared to rust in vscode
vending
but like my point was that rust analyzer was good enough
so i don't really see any point in using rustrover 
r-a is so slow thoo
@valid jetty@valid jetty@valid jetty@valid jetty
it took me a while to understand what r-a was 
rust anal
though it felt like rustrover was even slower tbh
especially typing completeion or what's it called
on an unrelated note, i need a course for learning webdev 
i think you could get away with just building something and watching webdevsimplified for parts you dont understand
i think i kinda understand webdev but what confuses me the most are like different div layouts (flexbox and etc.) and adapting a site for mobile use
i guess i'll just watch these
I learned the CSS grid entirely from fixing better folders
@fleet cedar do you know if theres any way to get a list of values that env::consts::OS and env::consts::ARCH can be??? lika programatically i mean
i cant find anything online about this
A string describing the specific operating system in use. An example value may be: "linux", or "freebsd".
oh its std
is it different
is it not what you want?
friends, I want a notification to appear at the bottom right when a message is sent to a specific channel. is there a plugin for this or will it help me?
The list isn't constant in the first place I'm pretty sure
It's just what's currently supported
ok sorry
i know thats why i want to get a non-hardcoded list
i want to display it to the user in the help command
ok finally pushed everything
that was like 23 commits or something
Why
actually true
it should only support what qbe supports, i guess thats what i did
im pretty sure qbe also supports windows but elle doesnt because screw windows
In that case it doesn't matter much what rust supports does it
yeah
should --target and --arch also change what is passed to qbe???? right now it just changes what is passed to cfg
i suppose it should
i have to map those things into amd64_sysv, amd64_apple, arm64, arm64_apple, rv64 one of these
worth it
#[macro_export]
macro_rules! os_arch_to_qbe_target {
() => {
match unsafe { $crate::misc::constants::ARCH.unwrap() } {
"x86_64" => match unsafe { $crate::misc::constants::TARGET.unwrap() } {
"macos" => "amd64_apple",
"linux" => "amd64_sysv",
other => panic!("Invalid target {other}"),
},
"aarch64" => match unsafe { $crate::misc::constants::TARGET.unwrap() } {
"macos" => "arm64_apple",
"linux" => "arm64",
other => panic!("Invalid target {other}"),
},
"riscv64" => "rv64",
other => panic!("Invalid arch {other}"),
}
};
}
why is it unsafe 
because TARGET and ARCH are a static mut
because while theyre env::consts::OS and env::consts::ARCH by default they can be set by a flag
@valid jetty will go 1 day without programming
i think they will die
I will immediately make a PR to support Windows
Why are they static mut
There are zero use cases for static mut
because the alternative is passing the values down from the main function into every place that needs them
i will probably just refactor it into like a Context struct thats passed down
but for now this works
look
@valid jetty give me your motivation
@valid jetty
or 💀
i could use colored crate but that probabl works on all windows machines and i want to explicitly block windows
(im too lazy to change to colored now)
Modern windows supports ansi codes too
"probably works on all windows machines"
#![allow(unused_macros)]
use crate::global;
global!(RESET: &'static str = "\x1b[0m", get_RESET);
global!(BOLD: &'static str = "\x1b[1m", get_BOLD);
global!(UNDERLINE: &'static str = "\x1b[4m", get_UNDERLINE);
global!(RED: &'static str = "\x1b[31m", get_RED);
global!(GREEN: &'static str = "\x1b[32m", get_GREEN);
global!(YELLOW: &'static str = "\x1b[33m", get_YELLOW);
global!(BLUE: &'static str = "\x1b[34m", get_BLUE);
global!(MAGENTA: &'static str = "\x1b[35m", get_MAGENTA);
global!(CYAN: &'static str = "\x1b[36m", get_CYAN);
global!(WHITE: &'static str = "\x1b[37m", get_WHITE);
macro_rules! disable_colors {
() => {
unsafe {
RESET = Some("");
BOLD = Some("");
UNDERLINE = Some("");
RED = Some("");
GREEN = Some("");
YELLOW = Some("");
BLUE = Some("");
MAGENTA = Some("");
CYAN = Some("");
WHITE = Some("");
}
};
}
pub(crate) use disable_colors;

its so cursed
rosinga
writing a simple stack based programming language to teach myself C. I keep getting surprised by what C doesn't have
@cinder egret hi PROgrammer
@cinder egret hi PROgrammer
this is just evil
@cinder egret hi PROgrammer
no it’s not
you can do get_GREEN!() in a format string but if you disable colors at compile time that will return nothing
When the @valid jetty is immutable 
And how do you handle the safety?
Ub != segfault
or even how can it be undefined behavior considering the compiler itself is single threaded
Unsafe means can cause ub if used wrongly
well yeah, because there are static mut shared between threads there can be data races if used wrong, but the compiler is single threaded so that’s not a problem
..oh so that’s what i write in the SAFETY:
Streamed Live on Twitch: https://twitch.tv/tsoding
Enable Subtitles for Twitch Chat
Chapters:
- 00:00:00 - Day 1 - Intro
- 00:08:10 - Day 1 - Trying to compile B compiler on ARM
- 00:35:16 - Day 1 - Adding new target
- 00:46:21 - Day 1 - Studying the C Compiler Output
- 01:03:18 - Day 1 - External Declarations
- 01:09:30 - Day 1 - Data Section
...
@valid jetty hiiii
nop
Roieeeeeeeeeeeee
Roieeeee 😭
yfw NO_COLOR terminal:
oh no the ai garbage they let loose is coming back to bite them in the ass
@pseudo sierra pinguh
zootie patootie

I kinda wanna make my own bootloader
do
gonna have like 200 security issues but who cares
zooite especially won't notice the backdoor
fr tho making bootloader secure is very hard 
real
@deep mulch what if I throw security out of the window and allow arbitrary qml for theming
do
What's the new ratelimit
it doesnt tell in the blog
2
2
2
6 maybe 6.2
i hope you guys explode
The primary rate limit for unauthenticated requests is 60 requests per hour.
is this the old one or new one
TRUE
@valid jetty Elle will run on billions of devices
except android
love?
@maize.moe
my mink mode
she’s locked
@maize.moe will be locked away
goobachungo
@pseudo sierra
@lavish frigate might make a Minecraft launcher in rust
@maize.moe is rusty
I'm currently fucking losing it over the 300 shit decisions I've made on this so now I'm doing a refactor and the diff is like -2k +1.3k on the first commit 
Do it
gonna end up being fucking 10k by the time I'm done
rewrite Elle @valid jetty
purge history and push as "Initial Commit" 
insane
most if not all of my repos have had this done
i already did for the compiler

I have branch protection on main so not even I can force push 

do again
you do it
rewrite zoot
zoot-rs is blazingly fast and memory safe zootie patootie now with 200% more mink
oh wait I forgot the rockets
🚀 
@deep mulch hyperion-rs
@maize.moe
heroic hyperion with wither impact 
WHAT
its 2pm
you lack sleep
oh well
sleep is bloat
insane
nuh uh
@deep mulch zoop 
hiiii
i really should do tests
@hoary sluice theres a mismatch in how structs/enums/functions are defined
struct fields require semicolon delimeters, cannot have a trailing semicolon, and the struct def itself must end with a semicolon
enum variants require comma delimeters, can have a trailing comma, and the enum def itself must end with a semicolon
functions do not end with semicolons unless they are external definitions
im thinking to make structs use commas like enums, and to make enums and structs not require a semiclon at the end of their def, good idea???????
If they're terminated by a } anyway, no reason to have ; too
yeah thats what i was thinking
i mean since that message im already done with what i wanted to do
but the hard part is refactoring the whole stdlib and other things to use the new syntax
wtf was i thinking when i wrote this test 😭
How do those 42[x] even pass, aren't they out of bounds?
Or do you not have bounds checks
no bounds checks because static arrays arent a concrete type yet
static buffers decay to T*
I hate it so much
I love buffer overflows
i do want to make static arrays be a type soon though, doesnt sound too hard
that way you can make real padding in structs
@valid jetty rosinga
You needs bounds checks regardless of static size
padding without static arrays kinda sucks
there are runtime bounds checks
but only for dynamic arrays and hashmaps(/hashsets)
Clearly not, since the test passes
because thats a static buffer
Are arrays and buffers different
dynamic arrays are an operator overloaded struct
buffers are just pointers to stack memory
once stack-allocated buffers get a concrete type i will overload it to add runtime checks for accesses
but as of right now doing i32 x[4] just gives you a raw i32 * (though it does hold a bigger size if you do #size on it)
didnt i tell you about this like 2 months ago
why structs need a semicolon at the end
anyways yea do commas, trailing commas and no semicolons anywhere
also im gonna rewrite my parser almost from scratch
remember how i said i want everything to be an expression
that was a terrible idea
i dont wanna do that anymore
function declaration (types) and definition (bodies), imports, maybe io (not sure yet) => statement
ifs, lambdas, calls, unary, binary, literals, identifiers => expression
function definitions currently evaluate to None
like its cool that its an expression but its completely pointless
and it prevents me from writing a Pratt parser
i have pure recursive descent with no pratt loop and its unmaintainable
rewrite elle @hoary sluice
add 2 - 2 4 is parsed as add 2; -2 (4);, evaluating add 2 as a partially applied function call and -2 (4) as calling the function -2 with the argument 4
or smth like that
the elle parser will take 1 line in icypeas
yop
(parseElle "elle" "balls" 1 2 3) will return an elle parser)
but only with those arguments
i refuse to provide support for skill issues such as no color terminal or windows
oh yeah why do you depend on tokio and have an async main function in a compiler
Elle bloated
these woke windows and colorless terminals
Elle will require a license to use
yop
why would you ever use either
lsp??
the lsp does not use any of the static mut variables though
hello rosie pie
hello nex process identifier
elle requires the gpl v3
elle will only be available for women
misandry #cancelled
@hoary sluice cancelled
WOMEN License
Copyright (c) 2024 Rosie Johnson
Permission is hereby granted, free of charge, to any WOMAN obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Rosie last name is Acquite I think
Acquite LOL!!!! 🤣 🤣 😂
it most definitely is not
i found that name through a random name generator website maybe 4 years ago
Acquite LOL!!!! 🤣 🤣 😂
oh my god
Acquite LOL!!!! 🤣 🤣 😂
Acquite LOL!!!! 🤣 🤣 😂
same...
THE DOUBTERS
THE DOUBTERS
YOU ARE DONE FOR
SOMETHING ALWAYS HAPPENS
DIOXUS 0.7 IS REAL
ITS REAL
im crying
this is better than child birth
i was gonna rewrite my parser but now i have to rewrite my website in dioxus
lets gooooo istg this was scheduled for april
slaying i think
you can now make specific fields not throw a warning when theyre unused
useful for stuff like padding
when i use etc cuz i ran out of examples and not cuz theres more
@valid jetty hiii
hii

@deep mulch
@valid jetty i did this and it just works??????
it literally just worked first try
sometimes i really wonder how a language funded by google and built in C++ can be so slow
why is io a statement
cause it doesnt return a value
an expression has to evaluate to a value
so it can be used inline
a statement is just a statement, it states something, it doesnt evaluate to anything
a statement is impure
io usually does return a value tho
Why would io be anything but a function call
printf returns how many bytes it printed iirc
input returns the string
read returns a potential error
unless i misunderstand what you mean by io
if io in your case is just a crude builtin to print things it can probably be a statement
ok then o is a statement, i isnt
wongy
interesting
print should print and return nothing, input should return a string, read (im assuming read file?) should return a string
@frosty obsidian add issue viewing to gloom
just noticed i accidentally doubled up the top padding
this might not be a good idea actually
how would you make a wrapper function for print when its a statement
ok ur right
how else do i separate io from other functions tho
an lsp needs to know if a function is pure or not so it can evaluate it in the ide and show an inlay hint of the result like that one haskell tool
well then how can it be a statement lol
if read returns a string
i was gonna make print a statement
not other io ops
only output
but it doesnt make sense for print either because functions cant have multiline bodies
and function bodies are expressions
and you cant put a statement in an expression
@valid jetty is crazy
JAVA JAVA
holy shit the rabbit hole just goes deeper
@valid jetty is a bunny
- i try to make my ichigo codebase use plain structs instead of struct pointers
- i notice error in hashmap as a result (it uses nil to represent empty cells)
- i go to fix it by making arbitrary reinterpret casts to T and U from void *
- causes segfaults (as expected) because T and U are copy-by types so memory gets blit from nil when casting to a struct
- i go to fix the root of the problem (buckets dont hold generics because doing a generic
Foo<T> *[]will make it think that Array has unknown types and tries to fill them but the unknown is inFoo<T>) - now array methods will return T but T is
Foo<T>'s T so it unwraps T by accident 😭 - when parsing a generic type the known generics must change depending on the depth of the generic parsing and must also be cutoff at points because it can be partially monomorphized
- HELL.
i will vibe code you
@valid jetty vibe codes elle
yeah because ai could totally come up with this stupid convoluted chain of issues
even the commits are in yappanese 

nop
elle will soon need gradle
does elle not do recursive generics
what happens if you divide by zero in elle
recursive generics seem crazy with monomorphization
it does
but it specifically fails when monomorphizing another generic type that contains a half-monomorphized type
as in, this
struct Bar<T, U> {
T x,
U y
}
struct Foo<T, U> {
Bar<T, U> *[] x
}
turning it into regular types yeah
yeah
what is that
array of pointers?
@valid jetty make custom allocators for elle
rewrite in asm
horror
@valid jetty implement entire c stdlib in elle
write print implemention in raw assembly
i feel like i saw them do this
somewhere
rosie loves my genius ideas
yeah i did this recently
one day i will open massive PR to elle
+20000 -100
insane
and i dont even know how youre supposed to do this correctly
im doing monomorphization completely blind
i didnt do any research at all
i need to do like a contextual monomorphization
with a stack for context yeah
oh parser with state at each level, this is "just" type parameter scoping
rewrite elle in java
theres 2 states
Array's monomorphization with something, or Array's contents being monomorphized with something
if done recursively a stack isnt needed
monomorphization is done during codegen
well
partially
its done both at parsing and codegen level
what is this
a serialization/encoding/mangling of all types
what does . notate
seperator
0 indicates a new generic scope
1 indicates the end
2.??? indicates a ??? *
3.??? indicates an unknown with name ???
seems cursed
11 is an int
it is
ancient hieroglyphs
but it works
ooo you should do cross function optimizations after monomorphization
tomorrow it will mysteriously stop working and you wont be able to figure out why
this actually happened with my networking examples
it was an issue with the type of number returned when i did #size
it was being passed into bind and always returning EINVAL
whats that
oh god
fuck
how do you monomorphize a different kind of partial monomorphization
struct Foo<T> {
Bar<i32, T> x
}
monomorphization gets so complicated so fast
switch to dynamic dispatch
😭
now i have 2 smaller magic boxes inside my one general magic box instead of 2 specific magic boxes
rosie so smart
i dont understand what monomorphization is
actualyl like
half the things in this channel i dont get
I didn't know either, but I read about it this morning
I was reading on dynamic dispatch vs monomorphization
idk what dynamic dispatch is either
i still have no idea how monomorphization is actually done
literally like
struct Foo<T> {
T x
}
fn main() {
Foo<i32> a = Foo { x = 123 };
Foo<string> b = Foo { x = "hi" };
}
```into
```rs
struct Foo_with_i32 {
i32 x
}
struct Foo_with_string {
string x
}
fn main() {
Foo_with_i32 a = { x = 123 };
Foo_with_string b = { x = "hi" };
}
oversimplified but
this is the basic idea
Suppose I have a function called fn process<T: PartialOrd>(x: T). With monomorphization, the compiler writes a version of process for each concrete used, like process_i32 and process_f64.
Dynamic dispatch: Now lets say I have a magic box(fn process), and the box's trick is that it can do PartialOrd (compare yourself). With monomorphization, the compiler creates a f64 magic box and a i32 magic box.
With dynamic dispatch, the compiler writes down just one set of general instructions for how to use any magic box.
The magic box itself holds the actual thing (like i32 or f64), but it also has a tiny instruction booklet stuck to it.
When the general instructions need to do the specific trick ("compare yourself"), they look at the instruction booklet inside the box. This booklet has a list of pointers or addresses for the actual comparison code for whatever specific thing is currently in the box (e.g., the real i32 comparison code, or the real f64 comparison code)
(i found this very helpful)
but why
wdym why
why does it have to be converted
because if its not converted you cant know its size
and therefore cant do anything with it
like how do you allocate some memory with a size you dont know
Code that knows what it's doing can be optimized much better
that too
but thats more of an argument against dynamic dispatch than the reasons for monomorphization
i read about monomorphization contributing to binary bloat a lot but I don't think that's actually the case in general
In the dynamic case, that type is "any type plus a vtable"
In the static case, it's one function for each relevant type
yes it does
It does, but whether that is a problem varies
I was thinking this
because imagine you need to monomorphize a 1000 line function with i32 and string and f64, you now have 3000 lines of almost the same code

well yeah
and obviously thats gonna contribute to binary size
especially if youre monomorphizing many types or the function has a really big body
rust does its best in this regard
(but thats one of the contributing factors of why rust executables are so huge)
But on the other hand, what would be the alternative? Dynamic dispatch is significantly slower and can only cover a subset of cases
yep
why does it only cover a subset of cases?
theres no perfect solution other than monomorphizing only the parts that need to be monomorphized
Good luck writing ```rs
fn max<T: Ord>(a: T, b: T) -> T;
fn max(a: Box<dyn Ord>, b: Box<dyn Ord>) -> Box<dyn Ord>;
/run ```rs
fn max(a: Box<dyn Ord>, b: Box<dyn Ord>) -> Box<dyn Ord> { todo!() }
@fleet cedar I received rs(1.68.2) compile errors
error[E0038]: the trait `Ord` cannot be made into an object
--> file0.code:2:15
|
2 | fn max(a: Box<dyn Ord>, b: Box<dyn Ord>) -> Box<dyn Ord> { todo!() }
| ^^^^^^^ `Ord` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/cmp.rs:283:15
|
= note: the trait cannot be made into an object because it uses `Self` as a type parameter
::: /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/cmp.rs:764:21
|
= note: the trait cannot be made into an object because it uses `Self` as a type parameter
|
|
error[E0038]: the trait `Ord` cannot be made into an object
--> file0.code:2:15
|
2 | fn max(a: Box<dyn Ord>, b: Box<dyn Ord>) -> Box<dyn Ord> { todo!() }
| ^^^^^^^ `Ord` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/cmp.rs:283:15
|
= note: the trait cannot be made into an object because it uses `Self` as a type parameter
::: /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/cmp.rs:764:21
|```

im so confused to why it unwraps it
if i create this object standalone it works
waittttt i think i know why
yeah that makes sense
these known generics are T: i32 U: i32
but they should be the generics we just parsed
omg it still doesnt work 😭
YESSSSSSS
im
.................................................
oh
well i see why
the wonders of not running in pedantic mode
YESSSSSSSSSSSSS
im genuinely
amazed this worked
thats a pretty complex type lmao
@lucid trail IT WORKED
i me3an
yippieeeee
so what did you do
use std/prelude;
use std/collections/hashmap;
struct Bar<T, U> {
T x,
U y
}
struct Foo<T, U> {
Bar<T, U> *[] x
}
fn Bar::new<T, U>(T x, U y) {
self := #alloc(Bar<T, U>);
self.x = x;
self.y = y;
return self;
}
fn Foo::new<T, U>(T x, U y) {
self := #alloc(Foo<T, U>);
self.x = [Bar::new(x, y)];
return self;
}
fn main() {
x := HashMap::with_entries(
"hello everynyan",
Foo::new(1, 2)
);
$dbg(x);
}
you can do this
the Bar<T, U> *[] is an alias to Array<Bar<T, U> *>*
it now recognizes that Array<T>is being monomorphized with Bar<T, U> first and then Bar<T, U> is monomorphized with T and U
really cool
you still cant do ```rs
use std/prelude;
use std/collections/hashmap;
struct Bar<T, U> {
T x,
U y
}
struct Foo<T> {
Bar<i32, T> x
}
but the reason i needed to implement that was to do this
struct HashMap_Bucket<T, U> {
T key,
U value,
bool full
}
struct HashMap<T, U> {
HashMap_Bucket<T, U> *[] table,
i32 size,
i32 capacity
}
now that the bucket can be generic over T and U i dont need to do reinterpret casts between nil and the real values for comparisons
@valid jetty tomorrow you will wake up and youll try to work on elle but youll be unable to think
it will be because i stole your intellect
rosie defeated
@cinder egret not you
how did you know i was lurking @deep mulch
YES
@cinder egret nerd
IT WORKSSSSS
ive been trying to solve this for the last 4 hours
the output of this
関数 メイン()『
整数 値 = 乗算(
加算(
乗算(13、2)、
減算(23、10)
)、
乗算(5、2)
)。
整数 ミクの数 = 除算(値、剰余(100、90))。
プリント(「%d\n」、ミクの数)。
』
good thing you don’t mean me!
AWFUL
yappanese
@deep mulch wrong husk
i think this calls for a husk bomb
No more implicit boxing? Yippee
implement kanji for numbers like 10万
it's just 4 zeroes surely
Implement kanji for 不可説不可説転
It's just 37218383881977644441306597687849648128 zeroes
insanity
i did want to do this ya
@valid jetty elle for plan9 when
I just got a funny idea and now I wanna build an os based on plan9 shit instead of unix
android™️
emulator?
yes
explains why
i dont want to debug on my device
wifi im on blocks ports that wireless debugging uses for some reason
so i cant connect
same wifi network?
whats that
whats that
school wifi for high schools and universities
@deep mulch has never went to a school before
you can signin on any eduroam with your school credentials assuming your school is registered to the thing
zero education
probably a firewall blocking
probably a firewall blocking
@formal belfry@formal belfry
exactly
😭
easy way to identify a flutter app is the fonts
every single one ive ever used has had wrong fonts
true! It should all be SF Pro by Apple Computer Inc.
@formal belfry
no you should use jetbrains mono for everything
someone fix my fonts please
framework skill issue?
nop
my issue?
nop
but its my app 😭
you are so dumb
i hated it when i tried it aned im never using it again
go to sleep
omg finally normal fonts, but like why is it so low quality 😭
i think it renders to a canvas
i hope it will look better on real device
i started with flutter yesterday dont make me switch to compose 😭
do
what if it just doesn’t
and it looks worse
too bad its app for me
compose is fun flutter made me want to kill myself
it’ll look like Minecraft
@formal belfry
and you’ll have to use SwiftUI to fix
@formal belfry@formal belfry@formal belfry@formal belfry
@formal belfry you said you were gonna slepe
why doesnt nextjs target mobile 😭 i guess react native is the way
farming zeet husks
I will embed xml to java like jsx
It will be very cool
Fyi i WILL use regex to extract the xml
why do you not have an alias for compiling it
@frosty obsidian is a nerd
yeah
@frosty obsidian gloom done yet?
@frosty obsidian gloom done yet?
gloom is a nerd
flutter or not flutter...
@placid cape out of ~32 people in hardware, german and math matura there are a total of 15 fails
i was kinda expecting everyone to pass
cause its free
it was super low and easily triggerable but then ppl complained and it's been raised a little (someone mentioned smth about 20)
@valid jetty @formal belfry is this a
or
macro
Ok(expression!(
If,
location,
branches,
otherwise: Box::new(self.parse_expression()?),
))
macro_rules! expression {
($kind:ident, $location:expr, $($field:tt)*) => {{
Expression::new(
ExpressionKind::$kind { $($field)* },
$location,
)
}};
}
instead of ```rs
Expression::new(
ExpressionKind::If {
branches,
otherwise: Box::new(self.parse_expression()?),
},
location,
)
Is your Expression ```rs
struct Expression {
expr: ExpressionKind,
location: Location
}
I'd write that as ```rs
struct Located<T> {
node: T,
location: Location
}
Expression::If {
condition,
yes: body,
no: None,
}.at(location) // via extension trait
yea thats a great idea
i was considering renaming it to something else cause expressionkind isnt actually the kind its the whole expression
I usually call that type Spanned rather than Located, but naming is irrelevant
spanned is less intuitive imo
Not really, it's the ideal name for "has a span: Span"
its called location for me
and imo location makes more sense than span
span is some shakespeare ahh word
Location imo implies only one point in the file

