#🪅-progaming
1 messages · Page 85 of 1
when i said infix operators are clean i didn't mean i actually like them

i think languages should be more simple than that
@winged mantle use
What about Rust
pretty good in a practical sense
but it has too many features to be perfect
c has far too few features, so it's perfect
i mean in a "the perfect IDE is notepad kind of way"

C has named constants
named constants
I prefer useful things myself
Sum types are an indispensable feature whether you call them enums or something else
named constants are perfectly useful as... normal enums
They're usable as named constants, barely
well... for the purpose of just storing a set of static things they're ok enough
java style enums where you can attach data do make them a little nicer i guess
rust's solution is even more powerful, it's just I think it goes beyond what an enum traditionally needs to do
I guess this is an example where c enums can feel limited
public enum Color {
RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF);
Color(int hex) { this.hex = hex; }
public int hex;
}
but does rust really have this in the same way
don't you have to do match self
which is basically like c so 🤷
imagine if you're de/serialising something to binary
it's useful that enums are just numbers and you can write them directly as a byte 
you can do that in rust tho
like noone is stopping you from doing this
named constants
horror
you can even make them more named by making their names unqualified
horror
@valid jetty hii
hii
enum Color {
RED, GREEN, BLUE
}
int color_value(Color color) {
switch (color) {
case RED: return 0xFF0000;
case GREEN: return 0x00FF00;
case BLUE: return 0x0000FF;
}
}
this is what i was going for
who says you cant do that in rust tho 😭
it's basically the same thing though that's why i don't think c is much worse for using enums as constants
ulgy
enum Color {
RED, GREEN, BLUE
}
use Color::*;
fn color_value(color: Color) -> i32 {
match color {
RED => 0xFF0000,
GREEN => 0x00FF00,
BLUE => 0x0000FF
}
}
equivalent to your C code
though in any real codebase you would use the qualified names for the enum variants
use Color::* is cursed
but if you were doing it in a more rusty way wouldn't it be virtually the same too
that's what i mean
wha
passes 3 Nice ub bro
just make them constants smh
i mean yeah i guess
i mean like, i don't think this does much to make the c version cleaner
enum Color {
Red, Green, Blue
}
impl Color {
fn value(self) {
match self {
Red => 0xFF0000,
Green => 0x00FF00,
Blue => 0x0000FF
}
}
}
you are still doing a switch
i don't think you can do the same thing you can do in java
@fleet cedar is there a way i can impl PartialEq only for a specific variant of an enum otherwise call the derived Eq method???
without a wrapper or helper type because i dont want all of that boilerplate and implementing a proc macro for converting to it is also kinda annoying
is there anything cleaner
this is why you initialize the variants in-place
C lets you do this too, why not use it
but i mean sometimes you might want multiple different types of data
in which case rust wins because it has tagged unions i guess
mine can be literally any type of data lololol
but i mean even in C
enum ThingKind {
STRING, INT
};
struct Thing {
enum ThingKind tag;
union {
int i;
char *s;
} value;
};
struct Thing Thing_new(enum ThingKind tag, void *value) {
switch tag {
case INT: return (Thing) {
.tag = tag,
.value.i = *(int *)value
}
case STRING: return (Thing) {
.tag = tag,
.value.s = *(char **)value
}
default: UNREACHABLE; break;
}
}
you dont have type safety
but youre literally working in C
fun
95% of rust criticism is just "why is rust not (other language)"
"but what if i want to do it like this way like i do in (other language)"
"why not do it (better way)"
"but i wanna do it the shitty way like (other language)"
idk i if i particularly like this error message
maybe i can print them specially if theyre a lambda so it doesnt show that ugly ::23123 thing
can it state more info about why it can't convert
i can make it do that
can i open pr to elle adding 🖨️ operator
Only if you add emojis for other operators too
fair it is pretty well... designed compared to other languages
can i open pr to elle adding <?elle and ?> to allow for embedding elle inside html
Why not embedding elle inside elle
something actually really annoying though is needing to keep variables out of scope before doing await
like a.. quine? :3
fn main() {
x := "fn main() {
x := \"?\";
io::puts(x.replace(#[63], x.replace(#['\\\\', '\\\\'], #['\\\\', '\\\\', '\\\\', '\\\\']).replace(#['\"'], #['\\\\', '\"'])));
}";
io::puts(x.replace(#[63], x.replace(#['\\', '\\'], #['\\', '\\', '\\', '\\']).replace(#['"'], #['\\', '"'])));
}
``` the
No just <?elle ?>
what does that mean
the
its a quine
Literally this
if you run that program it will print itself
Yeah that is true
@valid jetty rosinga
i just ended up not implementing something and decided rust has to not fully be turing complete otherwise i would've been able to do it

i love how c has a header called ctype
do you do cctype in c++
you use the header within rust and then type your typeless rust
i wanted to add a fallback to requesting the channel from discord's api if it's not cached (for closed threads) and I can't even comprehend how you do that
it needs to be in the if block, and if you await inside the if block it gives an error
😭
serenity 😨
ignore the fact it does linear search that isn ecessary in the stable and current verersion

but fixed in next
i think i would need to move it out of that if block and instead do a check that the cache contains it without storing it in a var
so it would need to be duplicated...
i also wanted to use /discovery/{guild_id} route to look up server if the bot is not in it
but serenity's request handler requires passing in an enum for the route and it's not defined rip
(i think it's undocumented)
(it's used by @pearl stag)
i might try adding this @deep mulch
[1, 2, 3].map(fn(x) x * 2);
```right now you have to specify that x = i32, but it can be inferred
love
the working version atm is
[1, 2, 3].map(fn(i32 x) x * 2);
zoot only thinks in kotlin
yes
I only think in python
i would appreciate if anyone had ideas on how to please rustc with this though...
thanks though
map(lambda x: x * 2, [1, 2, 3])
are these documented
why is the lambda first
tbh idk
Fork serenity and add these manually? Whats the problem
map(fn(x)) { x * 2 }
At userdoccers sure
^^^
oh wait
map(Function x = {x * 2})
@deep mulch should i add a then function on every type
what would it do
i want it to happen in the case where the guild is cached, but it can't be found
if the guild isn't cached, it shouldn't bother
and rustc will complain that the future is not Send or something
@valid jetty pipe operator would be good
3941123
.then(fn(a) a + 1)
.then(i32::to_string)
.then(fn(a) a.split(""))
.then(fn(a) c - '0')
.then($println);
yeah thats basically pipe
hm
horror
3941123
|> $ + 1
|> i32::to_string
|> $.split(""))
|> $ - '0'
|> $println;
do 3941123 | $ + 1 | $.toString() | $.split("") | $ - '0' | println($)
Rosie loves $ everywhere
wait i ahd the same idea to do $
$ is actually common in cases like this
is this what functional langs normally do
lol that surprised me
id prefer it
i was just trying to think of bash
$ is overused in elle
and i know it uses $ in a lot of places
you're so obsessed with groovy...
$ is literally only used for stdlib aliases
no you use it for tuples I think
$(2, 3)
😭
hatred
I hate that
map(x |> fn(x) x * 2 |> fn(x) x + 1)
or
map(x |> x * 2 |> x + 1)
though you'd just use all the operators together in that specific example
it sucks
^ expected right hand side to infix operator `sucks`, got EOF
|_______|
where you could do something like sh`cd ${dirname}`
oops
3941123
|> add(_, 1)
|> i32::to_string
|> split(_, "")
|> sub(_, '0')
|> println;
bad
there is none
syntax sugar idk
I don't understand why kotlin has it
better than 500 layers of brackets
abusable
it doesnt
println((3941123 + 1).to_string().split("") - '0')
this case is kinda dumb because theres no actual foo($) methods
something like turning foo(bar(baz(qux))) into qux |> baz |> bar |> foo makes sense
insane
$0 obviously means first arg smh
every programming language should copy node.js and have 2 as the first arg
(process.argv[2])
let args = process.argv.slice(2)
you do know how argv works right
it gives you all the arguments from execvp
with node it is
node script_name <args>
the 0th argument is always the executable
the 1st is therefore the script name
so yeah, logically the actual args you want start at 2
idk

in a systems language they start at 1
@valid jetty wyd
the inferred types for lambdas
nop
i have access to the context type when compiling a function call
if you do foo(???), when compiling the ??? you know what foo expects that argument's type to be
as functions have strong types in the type system now, i can just use the callback's explicit types and backpatch untyped things to that type
what's ???
any expression
fn foo(fn(i32, string) x) { ... }
fn main() {
// when compiling `fn(x, y) x` the compiler knows `foo` expects `fn(i32, string)`
// at that place in the call (in this case 0th arg), so we can just extract the
// `i32` and `string and give them to `x` and `y`
foo(fn(x, y) x);
}
its not that hard
easy for a Rosie to say
nvim is done for
We all edit
what the horror
u are just a hater
its because there is no pre-installed tui editor on windows
so youd have to go out of your way to install nano/micro
oh is that gonna be inbuilt
yes
that's useful I guess
nooooo not my neovim
also its open source so thats always fun
(open source app made by microsoft!!! crazy)
just signed up for an iusevimbtw gmail adress 😦
made by a german so you know it's good
yeah but atp what isnt inbuilt into windows
its like they do everything they can to make windows bigger
oh yeah is there a discord tui app that wont get me banned for api spam? i really wanna move discord over to the terminal
a tui editor until now
with neovim keybindings
and thats even pre-installed on most linux distros!
so this is what the pro gamers are updating their windows for?
a tui editor
the 3 hour update for a tui editor
oh yippie
you are not the target audience for this
Awesome gjjj
i use arch btw
there's discordo but it sends weird ahh payloads and X-Super-Properties
weird ahh payloads
sure (missing bunch of properties, and nonce when sending a message)
youre so smart
@hoary sluice @hoary sluice aoc machine
literally can call mapping functions with no specifying of types anywhere
it infers everything
even the type of x
type inference is so cool
are you doing some specific algorithm like algorithm W or just figuring it out
i finished my first C project! a tiny stack based programming language (shown is 39th fibonacci number)
conclusion is i can't live without tagged unions and C is really annoying
and this is 16!
uiua if it was readable
cool
yes
i didn't think about the syntax a lot
the lexing is also pretty inconsistent with whitespacing
another language i have to stop myself from giving "helpful" suggestions for
lol go ahead

Yeah just call it dup
nahh i feel impressed that rosie has not blocked me yet
i suggested jsx support
and a 🖨️ operator
@valid jetty is Elle your first language youre developing
its funny lmao
im here to have fun
im not doing serious development
nop
hell yeah
And I know for a fact that I am
Doesn't stop me
TRUE
yeah, i'm gonna rename a bunch of stuff
not that youre annoying but
that you can be annoying without caring
i love being annoying and not caring about it
ive been working on this for like all of my free time all day every day for over a year atp if i didnt have progress it would be concerning
how do you have so much motivation
I find things fun and still lose motivation
make kotlin object notation
never
like my jon idea
john
parse syntax like
new Map() {{ put("key", "value"); }}
that would be so fire
wait can you do Map.of
jonathan blow
mapOf
do same thing but however you do it in kotlin
is it like mapOf {
"cheese" to "burger"
}
i can't remember
kotLin
HashMap::with_entries("cheese", "buffer");
``` !!!
cheese buffer
HOW DID I TYPE BUFFER
i bet you say in your whatsapp group yes i would like a cheese buffer
ches buffer
buffer
and your non programmer friends are confused
i said to non programmer friends byte instead of bye before
meson for building C has been so good for me
# meson.build
project('cazal', 'c')
src_files = run_command('sh', '-c', 'ls src/*.c', check: true).stdout().strip().split('\n')
executable('cazal',
src_files,
include_directories: include_directories('src')
)
meson is nice I just wish the docs were better and better ide support
How is that any more rust than any other language
gotta love my DSL for build systems
i know i was kidding
rust brainrot
Elle is the rustiest
zoot uses build.gradle.kts for C++
nop
zoot uses build.zig
cmake has something to build java
yop
every project is well documented if you can read source code
i take it back
i should do more code golf
@valid jetty
omg this still doesnt work if you try to access methods on the type in the cb
i think i know how youre meant to do it
or well
@valid jetty compile elle to malbolge
a way that would work
literally named after the eighth circle of hell is crazy
@valid jetty tomorrow you will get your first job
I got my first job at 16 or 17 @valid jetty
horror
how do you know you will get a job in almost 1 year excatly
oh i don't know if I will, i just have to
i dunno what i wanna have a job doing
it will probably be something i never expected
(which is exactly the thing i expected because i don't expect it)
my goal is to compile
fn foo<T, U>(T x, fn(T) -> U y) {
y(x);
}
fn main() {
foo(3, fn(x) x * 2);
}
during monomorphization:
- compile lambda once but only arguments, not the body, dont add the function, this gives me the link between the args and the generics
- compile again but this time, knowing the arguments, dont add the function, but compile including the body so you can get the generic for the return type
- compile last time knowing all generics and add the function
this is actually a complicated problem
because if you naively just compile twice, you end up not knowing T in one of the passes
nerddd!!!
Rosie will omit fn for passing in functions
(x) x * 2 is ambiguous
a function that takes T and U and returns void without fn would look like (T, U) which looks like a tuple
you can omit the return type if it returns void
that syntax is really unreadable though
wdym isn't that what's happening
fn foo<T, U>(T x, U(T)) {
y(x);
}
ivknow it's just an idea
no 😭
wha
Here is your php(8.2.3) output @lavish frigate
file0.code
/run
ls
Here is your bash(5.2.0) output @lavish frigate
file0.code
fn foo<T, U>(x: T, y: (T) -> U) {
y(x);
}
🔥 ?
it wouldn't work anyways
you'd still have to specify void
wait
actually
nvm
idk
kotlin
nop
@valid jetty continue with what you have
I stil think argument name preceding type is more natural to read
i like rhs idk
its rhs in structs too
but putting them on the left does not solve the problem at all lol
Arg name right of type im guessing
is it good practice to do this in a .c file 
so that you can override with compiler args
it's better
talloc
yes definitely
@valid jetty hiii
not unless youre planning to make this library work on embedded
for the sake of learning i should probably make this library work on a wide variety of platforms

*for the sake of pain
i have so much rust brain rot
you dont have enough
i am coding using sublime text
no lsp
no errors or autocomplete
(you can probably set it up but who needs that)
i can’t live without go to definition (it’s like marginally faster than grepping it)
i use grep all the time to find definitions
yop
most kodepilled setup
you love
i renamed macro
honetly i think sublime is the best minimal text editor

it feels very performant
did zed really do anything groundbreaking
@winged mantle uses edit
zed has voice chat
use ed
just like nintendo acting as though they invented discord
is this micro
We all edit.
We all Elle.
remember when microsoft open sources something it's because they determine that it is commercially viable

uncle bob level clean code right here
is it kinda awkward that you need to do builder = string_builder_append(builder, "obama")
it wouldn't be hard to make it just string_builder_append(builder, "obama") or string_builder_append(&builder, "obama") but the former would be less efficient and the latter would mean you could accidentally make unsafe copies
the latter is how i typically see that kind of api
not sure why youre not going with it
hm
what do you mean
oh i know what you mean i think
the fact you do &builder implies that you builder would not already be a pointer and would be on stack
oh wait
i am dumb anyway
surely you can just take a pointer
because with reallocing the builder it would be unsafe anyway
why does it matter if its on the stack
uhh yeah that too
you should be reallocing the buffer
@valid jetty you smell like flowers
yea...
Not really, it might be a struct strbuilder { strbuilder_impl* impl; }
Rosie rot
And then the functions take a strbuilder*
@valid jetty does Elle have proper heap and stack
@deep mulch throws u on the heap
A stack is lifo while a heap can access smallest only
heap is dynamic
void string_builder_append(StringBuilder *builder, char *str) {
int old_length = builder->length;
builder->length += strlen(str);
if (builder->length >= builder->capacity) {
while (builder->length >= builder->capacity) builder->capacity *= 2;
builder->buffer = realloc(builder->buffer, builder->capacity);
}
memcpy(builder->buffer + old_length, str, strlen(str));
}
``` surely its just this @winged mantle
am i missing something
int main() {
StringBuilder builder = {0};
string_builder_append(&builder, "wow");
}
silly
wait it shouldn't be >=
it should
if the buffer is full it will reallocate the next time you push something
might aswell grow now
might as well start of as 1gb
i don't think it really makes a difference? apart from being slightly less memory efficient?
i guess so
I think people would be upset if ```c
StringBuilder builder = StringBuilder::with_capacity(4);
builder.append("four");
and how would it make anything more efficient?
lmao fair
it wouldnt
youre just doing the growing logic right now instead of offloading it to the next push
good idea
do you know how to do both in the same file
with #define STRING_BUILDER_IMPLEMENTATION and whatever
if you implement in header doesn't that mean it either has to be static or inline
oh wait
its just a different file extension but its still just C code
wha
The One Definition Rule (ODR) is an important rule of the C++ programming language that prescribes that classes/structs and non-inline functions cannot have more than one definition in the entire program and templates and types cannot have more than one definition by translation unit. It is defined in the ISO C++ Standard (ISO/IEC 14882) 2003, a...
seems like c ++ thing
In C you'd just get duplicate definition errors
yeaa
yeah
don't you have to make static so everything that imports it gets its own copy?
why not?
yeah but... how does that prevent the fact that you're potentially defining the function multiple times?
include guards?
If you put a normal function in a header and include it from two compilation units, you have now defined that function twice and will get a linker error
I said in different compilation units
well if this is a header only library, you would define the IMPLEMENTATION macro in one unit and not in the other one
but each c file is gonna be compiled separately?
if while one c file is being compiled something is defined i don't think that affects other c files?
so the other one will only compile the headers
i believe the include guards are just to prevent multiple extern declarations
So you mean make it not header-only at all, just the implementation is ifdef instead of a separate c file
That's gonna make things so much nicer to work with great job gold star for you ⭐
that is what header-only is though, the header and implementation in the same file
isn';t this gonna happen regardless of include guards
Yes
i mean in c++ pretty sure things are implicitly made inline
(You get a no-diagnostic ub if you violate it instead)
#ifdef STRING_BUILDER_IMPLEMENTATION
int foo(int x) {
return x * 2;
}
#else
int foo(int x);
#endif
#define STRING_BUILDER_IMPLEMENTATION
#include "string_builder.h"
int main() {
foo(3);
}
#include "string_builder.h"
int x() {
foo(3);
}
``` surely no issues
or am i missing something
That has exactly zero benefits compared to just putting the implementation in its own .c file
if that worked that would also mean if you included stdlib.h in one unit it would be available in another
oh wiait what
the benefit of this is that you can copy around a single file instead of multiple lol
nothing's stb libraries work like this afaik
how could this possibly work
git clone doesn't give a fuck if the repo contains one file or multiple
it doesnt, but if youre vendoring you dont git clone you just copy paste the file into your repo
And if you're vendoring, you also do not care about whether you have multiple files
this wouldn't work, would it?
cc filea.c fileb.c
filea.c
#define A "aaaa"
fileb.c
#include <stdio.h>
int main() {
puts(A);
}
Not unless you #include <filea.c>, yes
no
so how does this... achieve anything lol
Compilation units are compiled separately
if you include the header in one unit... it's not gonna be defined... and if you include it in another it's gonna be defined either lol
ohh
so you just do it only in the main file
yes
when you said include guard i thought you meant like pragma once
that is what i meant originally
that won't stop multiple implementations 😭
this is not an include guard its called something else
but... but ... how
if i have a.c include a file defining func1 and b.c including a file defining func1 too that would not work
nope it wouldnt
even with a traditional include guard
i am confused... did you realise you were wrong
impossible
yes lol i was wrong from the start i wasnt sure what you meant
but that doesnt change the fact that you can do this
well then what did you mean earlier by single header library 😭
why doesn't rust have headers that would be cool
this is typically what you refer to a "single header library" https://github.com/nothings/stb/blob/master/stb_leakcheck.h
i swear i've seen header only libraries where you don't need that
but for c++
well yeah its completely different for c++
i have done more C++ than c
so many words.. so many just to say quit and use serde_json
use serde_json::json;
let data = json!({
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
});
println!("first phone number: {}", john["phones"][0]);
Rust is just so cool
wdym can't you overload operators
Idk how it works exactly I just know that serde and by extension serde_json is peak
what is js
serde reference
@deep mulch finally it works
you can do this
use std/prelude;
fn main() {
$dbg([1, 2, 3].map(fn(x) "{}".format(x)));
}
and it properly infers what T is, then whatx is, then what U is
this feels a bit dirty lol
delete
nvm it still doesnt work properly
if more generics are found after the function, the function wont be re-monomorphized with what we now know
fn Array::map_with<T, U, V>(T[] self, fn(T, V, u64, T[]) -> U mapping, V arg) -> U[] {
let new_self = Array::with_capacity<U>(self.len());
for u64 i = 0; i < self.len(); i += 1 {
new_self.push(mapping(self[i], arg, i, self));
}
return new_self;
}
V is deduced after the mapping is compiled
implicit self implicit self implicit
nop
yop
ok i know how to do this
i need to generate into a stub module
then that means the third compilation is actually necessary
unfortunate
how should i handle the size of a string growing larger than the largest 64-bit integer

imagine giving a server a quintillion bytes to abuse use after free
or something like that
add built in ui
assert
but it should catch it in non debug
well youre working in C
you cant exactly return a Result
@deep mulch i was right it worked
there's also problems like malloc/calloc/realloc returning NULL
they will only do that if you ran out of memory
but you can return a bool from the function
false if it fails
so you can do if (!json_read(...)) return 1
or whatever
i don't think i have a single void function
nvm
i have one
wait can you not just do return { .name = "joe" } in c
this is c99 tbf
im pretty sure you can
oh no you cant
this is the best you can do
#include <stdio.h>
typedef struct {
int x;
} Foo;
Foo Foo_new() {
return (Foo) {
.x = 39
};
}
int main() {
Foo foo = Foo_new();
printf("%d\n", foo.x);
}
@hoary sluice look at this js code
[1, 2, 3].map(fn(x) x * 2)
``` or ```rs
[1, 2, 3].map(fn(x, i) {
$dbg(i);
return x * x;
});
``` or ```rs
[1, 2, 3].map(fn(x, i, arr) {
$dbg(i, arr);
return x - 1;
});
make elle ui framework, elle compiler collection, elle os, elle browser, elle kernel, elle fan, elle sweatshirts, elle banana
@deep mulch
I don't understand
strong typing in Result::resolve
the resolve function is supposed to let you ""match"" on a result
but the first branch is returning an i32
the second branch is returning a string
so its throwing an error
sounds cursed
in rust its like
fn main() {
let x = Ok(39);
let y = match x {
Ok(val) => val,
Err(_) => "a"
};
}
``` and this will throw an error
what is val => val
oops
this makes me so happy
https://wiki.osdev.org/Expanded_Main_Page my beloved
typescript is just pedantic javascript
@hoary sluice @deep mulch @placid cape iterators
use std/prelude;
struct Iterator<T, Env> {
Box<Env> env,
fn(Env *) -> Option<T> cb
}
fn Iterator::next<T, Env>(Iterator<T, Env> self) {
cb := self.cb;
return cb(self.env.to_ptr());
}
fn Array::iter<T>(T[] self) -> Iterator<T, (i32, T[])> {
return Iterator {
env = Box::new($(0, self)),
cb = fn(env) {
i, self := env;
if i < self.len() {
env.x += 1;
return Option::Some(self[i]);
} else {
return Option::None<T>();
}
}
};
}
fn main() {
x := [1, 2, 3].iter();
while _, val := x.next() {
$dbg(val);
}
}
i genuinely cant believe this works
what a difference 
wsl is open source now!
why is it staring into my soul
You have one?
i hope so
Best commit
lazy ranges and stuff
women's super league
oh my god it still doesnt fully work
thoughts on delegation stuff @solemn ravine @woven mesa
this feels so blegh but i dont know how else to do it, especially in a delegate pattern
notification summary is just anything atp 😭
OKAY i do it in a saner way now
@formal belfry first roadblock
i offload the monomorphization of function defs that contain generics to after everything else is monomorphized
that way everything is inferred for functions right at the end
no but similar
o
@deep mulch
@formal belfry i got it compiling and working and authenticating
@deep mulch is this comment small enough
// offload lambda monomorphization until after everything else is monomorphized
// because the lambda's return type may depend on generics which arent known yet
//
// consider:
//
// fn foo<T, U>(fn(T) -> U x, T b) {
// $dbg(x(b));
// }
//
// foo(fn(x) "{}".format(x), 5);
//
// in this, the return type requires that we know x's type, but this is deduced after
// the lambda definition (T = i32 is deduced from `T b`[5])
//
// if we try to generate the body without knowing T, we will call `T::__fmt__`, which
// we can't guarantee will have a definition, so the compiler will throw an error
//
// instead, we don't do this right away, and just defer it.
//
// after all other generics are deduced, we now know T, so we can now generate the body
// as this is monomorphized with T = i32, and we know that `i32::__fmt__` exists so
// we can confidently generate that U = string, monomorphizing everything as a result.
if ty.is_function() {
deferred_generics.push((i, param_ty.clone(), parameter.1));
}
I overslept by 2 hours
WHERE IS MY SYNTAX HIGHLIGHTING
nop
this also means you can use the return type to deduce the inner type of the lambda
HOW
im magic
interesting
love
h?
Tho i use oauth2 api directly so no need for native interop
ofc !
no ofc you can ask lol
wow this is so cool
but seriously does anyone know how to get token using the webpack things?
@lucid trail look at how complicated this is starting to look lmao
my code doesn't work anymore 😢
there's no token grabber code in #📜-js-snippets
and I'm probably dead just by asking it lol
yeah lemme install an app for opening text files rq
@royal nymph do you know how nowadays
I am not trying to commit any crime I swear I just need a more simpler way to get the token
😭
nvm i actually
just figured it out on my own
its just Vencord.Webpack.findByProps('getToken').getToken() lol
who couldve guessed
I think the last time I asked about anything related to tokens I got banned
@deep mulch look at this file 😭
if Rosie says complicated then it's impossible for me
true
is cb() telling it its a pointer to a callback
@valid jetty is genius
yes
no, it infers the type of cb to make it callable
you just cant call fields in structs inline
because it thinks its a struct method
when you do self.next() it doesnt know whether you mean (self.next)() or Self::next(self)
arr1.extend(arr2)
makes sense
extend isn't a good choice I think
its what rust uses
Elle is rust
in 4 years im gonna write a borrow checker
Oh yeah what gc method do you use
single threaded mark&sweep stop the world
ill need to rewrite the gc eventually because its slightly wrong right now
@valid jetty @valid jetty @valid jetty @valid jetty @valid jetty
@deep mulch have you made any progress
do
guhhh motivation
@valid jetty
@valid jetty you sap my motivation away to work on Elle
you will return it
Rosie feeds on my motivation and energy
that's why I'm so eepy all the time
Like a vampire?
yes
I knew it
what next
works in xrpc
io
oi
i thought you just used polling there
this doesnt work at all and idk why
nothing is ever printed
i could never
oh actually idk if i did or not
pretty sure you did
yeah
can you push ur changes on a branch or something so i can take a look
if you mean by reading the code of axswift yeah cos theres no docs xd
in a moment
you make a compelling argument
i accidentally airdropped my dad axswift
truee
does discord have an api for checking if an rpc asset exists
probably for apps that dynamically pick assets
probably GET https://discord.com/api/v9/oauth2/applications/<app_id>/assets or something that
OH MY GOD ive just found out the entire reason my code felt jank was because more than half of the backend had a synchronous macro on the function.
im never using sync functions again
everything async or threaded from now on
its so smooth now!!!!
tysm
upcoming project readme
Based on football concepts, so it should be easy to understand even if you're really stupid.
what if you know nothing about football
@frosty obsidian doesnt know what football is
@frosty obsidian has never played sports
that's mostly true
@frosty obsidian doesnt know how to run
@hoary sluice i just had the most genius idea to impose compile-time restrictions on reversing an iterator which may not have a next_back
instead of returning a Result<T, E>
i can have a phantom generic on the iterator struct
namespace SingleEnded;
namespace DoubleEnded;
struct Iterator<T, Env, Kind> {
Box<Env> env,
fn(Env *) -> Option<T> next,
fn(Env *) -> Option<T> next_back
}
then i can make rev only allow DoubleEnded iterators
fn Iterator::rev<T, Env>(Iterator<T, Env, DoubleEnded> self) -> Iterator<T, Env, DoubleEnded> {
return Iterator {
env = self.env,
next = self.next_back,
next_back = self.next
};
}
which throws a compile time error if the iterator is not double ended
and this too
ofc array iterators should be reversible
but as an idea
wtf is this function signature 🥀 💔
yeah ok this is getting out of hand 😭
works tho?? literally slay
clean code?? pfft
fn Iterator::map<T, U, Env, Kind>(
Iterator<T, Env, Kind> self,
fn(T) -> U cb
) -> Iterator<U, (Iterator<T, Env, Kind>, fn(T) -> U), Kind> {
return Iterator {
env = Box::new($(self, cb)),
next = fn(env) {
self, cb := env;
return self.next().map(cb);
},
next_back = self.next_back ? fn(env) {
self, cb := env;
return self.next_back().map(cb);
} : nil
};
}
@valid jetty hiii
hii
i thought i was onto something with this function
(this is literally just a redefinition of Option::map)
@hoary sluice ever wanted type hell?
beautiful
LMAOOOOOOO
WHAT THE FUCK IS THIS
im crying
%tmp.2267 =:Tuple.0.Iterator.0.11.Tuple.0.Iterator.0.11.Tuple.0.Iterator.0.11.Tuple.0.Tuple.0.11.7.1.2.Array.0.11.1.1.DoubleEnded.1.98.0.11.11.1.1.DoubleEnded.1.98.0.11.11.1.1.DoubleEnded.1.98.0.11.11.1.1 call $Tuple.__tuple__.0.Iterator.0.11.Tuple.0.Iterator.0.11.Tuple.0.Iterator.0.11.Tuple.0.Tuple.0.11.7.1.2.Array.0.11.1.1.DoubleEnded.1.98.0.11.11.1.1.DoubleEnded.1.98.0.11.11.1.1.DoubleEnded.1.98.0.11.11.1.1(:Tuple.0.Iterator.0.11.Tuple.0.Iterator.0.11.Tuple.0.Iterator.0.11.Tuple.0.Tuple.0.11.7.1.2.Array.0.11.1.1.DoubleEnded.1.98.0.11.11.1.1.DoubleEnded.1.98.0.11.11.1.1.DoubleEnded.1.98.0.11.11.1.1 %env.2264)```
this is a single assignment
i just realized this is completely untypeable by hand
lol
good luck explicitly declaring your variable with that type
@valid jetty SLEEP
Repent for thy sins
you love monomorphization !!!
you can reverse single ended iterators
No you can't
for whom
How would you reverse an iterator that only has one end
create a double ended iter, pop from the single ended and push them to the front of the double ended
So you mean collect into a vec and iterate that?
does rosie have infinite iterators
well yea basically
In other words, not reversing the iterator
how is that not reversing it
You are traversing the iterator and then reversing the result
reversing an iterator means the front turns into the back
You are throwing away the laziness of the iterator
And potentially wasting shitloads of memory
better than crashing
ok its a compile time error you can just make it double ended
the error message should be more descriptive thought maybe
you clearly can reverse a single ended iterator, its just slow, so it should tell you that and not "cannot cast to doubleended"
You can not
You can reverse its results
Which is a very different thing
Sure, adding a "note: you can collect to a vec and reverse that" sounds harmless enough
Error: cannot convert from SingleEnded to DoubleEnded
note: reversing a single ended iterator is inefficient, make it double ended instead
whats the overhead of a double ended iterator
Zero for things that support it, infinite for things that don't
what if you have a single ended where you insert a billion items, pop a billion items, add 3 items and reverse it
would that be faster with double ended
You seem to have a very strange idea of what an iterator is
You do not insert things in an iterator
An iterator is a traversal
Some traversals (such as over vec) can be done in both directions, others (such as over lines of stdin) can not
make an iterator with a billion items, traverse it 999999997 times, then reverse it
oh i thought single ended was somehow somewhere more efficient than doubleended, not that double ended doesnt make sense with stdin
you cannot always reverse the iterator
the iterator may be infinite
yeah
@hoary sluice this is what an iterator is
there may never be a case when the iterator ends
i didnt know if elle had infinite iterators
What language requires iterators to be finite
it doesn’t, that doesn’t have to be a language construct you just need state and lambdas
An iterator is just a function that gives the next value
yeah
Please provide a valid message ID: `!test [messageId] code
Please provide a valid message ID: `!test [messageId] code
iterators couldve existed in elle before but they would’ve been awkward to use because you couldn’t specify the prototype of function parameters (which means you couldn’t infer like, anything, among other issues of the fact that you need to cast void to your real return type which means void had a size of 8 bytes)
now that i wrote all these qol things (function signatures in the type system, much higher quality generic inference/deduction, lambda arg type inference) iterators become so silly and useful
a bad one
im just used to iterators being something that is made from collections
infinite ones in my lingo (kotlin lingo) are sequences
They commonly are, yes
so i assumed that iterators can be finite
They sure can
well kotlin has sequences, which generate new values on the fly using a function that is passed the index, and it also has iterators, im not sure if sequences are a subclass of iterators or if iterators are finite
any language can have finite or infinite iterators if it can take in functions into other functions and can mutate a struct lol
iterators are just an interface with hasNext and next so theyre infinite
well you can obviously implement them in any language
so then what were you saying earlier about whether elle iterators can be infinite
an iterator by definition can be infinite because it just yields the next value which may never have an end
but as a language construct or stdlib impl im sure theres at least one language that doesnt have infinite iterators and has a good reason for it
true