#🪅-progaming
1 messages · Page 104 of 1
i got demoted.
oh yea there's stuff like static where linking actually is relevant to the programmer
just add a uuid to the end of the name
Oh, neat!
deserved
whats the actual difference between JIT and interpreted? Every damn "explaination video" I see tells me "Its the computer reading the code" or the "computer directly executing instructions" but last I checked computers didnt just "read code". My other thought was that it could be translating source code into another language to be executed as the program runs, however is this not transpiling?
interpreted languages don't get compiled
jit compiles as its executed rather than beforehand
Interpreted iterates over the list of instructions as it runs, jit generates code that runs each instruction
But there's certainly some gray zones
jit is a mix of interpreted and aot
wing detected
Modern cpus have builtin jits
yeah im asking how this is possible, since computers dont just "read code" and translating it is just transpiling no?
The processor itself iterates over each instruction as it runs and generates micro-ops that it then runs
the interpreter does the actual execution
and im guessing I must build my own interpreter to understand this?
It is very educational, yes
or how this is done?
you can look into existing interpreters
I dont wanna read pythons code 😭
then read Ruby's interpreter code
i love interpreters
ruby the language where random amounts of periods is valid syntax ```
irb(main):001> ..
irb(main):002> ...
irb(main):003* ....
(irb):2: warning: ... at EOL, should be parenthesized?
internal:kernel:168:in 'Kernel#loop': (irb):3: syntax errors found (SyntaxError)
1 | ..
2 | ...
3 | ....
| ^ unexpected '.'; expected an expression after the operator
| ^ unexpected end-of-input; expecting a message to send to the receiver
from /usr/lib/ruby/gems/3.4.0/gems/irb-1.14.3/exe/irb:9:in '<top (required)>'
from /usr/bin/irb:25:in 'Kernel#load'
from /usr/bin/irb:25:in '<main>'
irb(main):004> .....
irb(main):005> ......
irb(main):006* .......
(irb):5: warning: ... at EOL, should be parenthesized?
internal:kernel:168:in 'Kernel#loop': (irb):6: syntax errors found (SyntaxError)
4 | .....
5 | ......
6 | .......
| ^ unexpected '.'; expected an expression after the operator
| ^ unexpected end-of-input; expecting a message to send to the receiver
from /usr/lib/ruby/gems/3.4.0/gems/irb-1.14.3/exe/irb:9:in '<top (required)>'
from /usr/bin/irb:25:in 'Kernel#load'
from /usr/bin/irb:25:in '<main>'
irb(main):007>
unexpected .
.
these are Ranges
zeet loves kotlin partially being interpreted
range my ranges
@frosty obsidian
3.4.4
python is better than ruby because they have the bigger 3.x version
go is the worst because they're still on 1.x
and said there wont be a 2.x
sorry i went
you went
greaaaaaaaat
chrome introduced a regression in ffmpeg in v136
which is still in all active stable chromium versions
and it fucks seeking and loading
does this effectively
and its been like this for MONTHS
and they only fixed it in 140.0.7299.0
which is a dev build released a week ago

mmmmmm thank you
over half a year of this shit being fucked
compiled -> a compiled compiler translates source into machine code that is able to be directly run
interpreted -> a compiled runtime reads source code, parses it into it's own bytecode, and virtually runs it (hence, a "virtual machine")
JIT -> an addition to a an interpreter in a runtime, that transforms the parsed bytecode into real machine code, which provides a marginal performance boost as it can be directly run by the cpu, instead of being virtually run by the interpreter
AOT -> a loose combination of compiled and JIT, where portions of the bytecode is transformed into machine code ahead of time, just like compiled, but run from the context of a runtime (like in GraalVM, or .NET with AOT on)
the point is that either the cpu directly can run instructions it supports, or it can run the instructions of an interpreter, which will virtually "run" custom bytecode (aka. a VM), and accomplish the same thing
So much to nitpick here. I'll settle for yeeting the word "marginal" onto a collision course with pluto
I wouldn't call several orders of magnitude marginal
well I guess it really depends on the situation but yeah JIT can be really good
Yeah what
I worded that as dumbed down as I could and it ended up being husk
JIT is the difference between a cool and good or warm and bad interpreted lang

Try running Minecraft world gen with JIT disabled and come back saying "marginal"
Prolly the best example
it really matters for performance critical areas but not so much for other stuff
which is why android does profiling before JITing methods to not waste resources on compiling methods that won't yield a significant performance increase

Not doing JIT means you're getting the worst-case
Which makes a lot of sense for Android UIs, where the code paths need to be fast IMMEDIATELY
And the compiled caches prolly won't last as soon as the user switches to another app
i believe it's persisted
TL;DR it matters anywhere where you're gonna be doing the same thing a lot, over and over for some period of time
Even a very simple jit that basically compiles each bytecode into an asm call instruction gets 5-15% perf over an interpreter loop https://v8.dev/blog/sparkplug
In V8 v9.1 we’re improving V8 performance by 5–15% with Sparkplug: a new, non-optimizing JavaScript compiler.
The real power of JIT is that you have all the context in the world at runtime
You know with certainty what code path is hot or cold
You're the other half then
May I offer an unhelpful compromise? I think stacks don't grow
Don't care what direction the stack goes
In memory or otherwise
It's a stack.
When I stack things the stack grows taller.
They should have called it the mineshaft
If it needed to go down
Anyway who the hell visualizes the stack as going down lmao
You love memory
How do you feel knowing that Java is more memory safe than Rust?

It's true.
i visualize it as a long rope
the stack and heap are sort of touching
and the stack grows downwards towards one end of the rope while the heap grows upwards towards the other end
OK tbh i was lying in bed thinking of ideas for Unicorn so maybe I should work on that instead
(Unicorn was the name I thought of for a scripting language but i didn't think of many actual features
)
this is probably a wrong way to think about it
but it works for me
(and that pivoting point in the middle changes as the stack requires more memory)
compiler or interpreter
interpreter
😭
Quite wrong indeed
Most importantly, heap is not necessarily consecutive
well yeah because of fragmentation
And I think stack is usually closer to the end of the address space, with heap below it
But I'm not sure about that
but i was thinking more about how one grows to one end and the other grows to the other
Especially since with threading or whatever there can be multiple stacks
with virtual memory you can't really reason about any of this in real code but yeah
Yeah
in an ideal world my model would work i think
In the grand scheme of things, the stack itself is just another heap allocation
Kinda yeah
Compiler has a bit more control over it than a typical bump, but conceptually yeah
hey i am NOT a plate
so good
entrypoint {
println("hello world")
entry := ScoreboardEntry.make({ name: "joe", score: 10000 })
println(entry.toString())
}
type ScoreboardEntry {
name
score
meth toString() {
return f"Name: {{name}}; Score: {{score.toString()}}"
}
}
why don't any languages use the meth keyword to declare methods
dynamic typing 😭
yes you are
entrpt {}
main {}
start {}
why is there a meth keyword anyway
you can use the left parenthesis to differentiate properties and methods
Same reason as they don't use lsd to declare fields
yeah just have no keyword
use the fact that there is a left paren after the identifier to tell you that it’s a method rather than a property
I've sent you a DM with more info!
8 spaces
if i make an editor i will make it so that multiple spaces always render as one to force you to use tabs
yes officer, this man right here
reactive frameworks hate this one simple trick! see how this hacky developer avoided installing 50gb of dependencies for reactivity using web components!
okay
i have reached the point of insanity in language design
??? what do you mean name of the type
is that not the thing next to the type keyword
crazy
it's genius
i mean go and java have the ability to inspect types too
add reflection to elle @valid jetty
the icing on the case is this is a word document that i am typing code into
you have some reflection
@valid jetty make elle library for generating elle code
thats just macros
RTTI
is it viable to support method chaining with automatic semicolon insertion
you can do a little more
if you take in a generic value to ElleMeta you can not only get the type's name but also its expression as a string
thats how $dbg works
thats also how type_of works btw :3
asi seems generally kinda bad
but it does look clean
i thought kotlin might do it well but apparently this breaks

"""
line 1
line 2
line 3
""".trimIndent()
?
Both
no im saying thats what it currently is
@valid jetty rosinga
every time I see people working on langs I want to try making my own only to end up remaking kotlin
i have managed to design a language that doesn't resemble anything i've used that much
but it is kinda cursed
also i need to impl it
and i haven't really designed that much
it doesn't even have switch statements... first things first though
oh yeah it's a scripting language
my instincts kicked in and i added a rune type
maybe that's a bit weird?
thats becuase its almost perfect
lolll
so true
honestly the two improvements I'd want to see:
- static extension methods
- C++ interop in KNative (somehow)
- If we can't have that, at least the ability to use any given toolchain so I can develop switch mods with it
technically you can extend the companion object but that would only work if the target actually has one
C++ ABI is still unstable
and its different between multiple compilers (although clang tries to be same as gcc)
also collection literals and destructuring
Exactly, if there is no companion there's nothing you can do and that needs fixing (even if it's just a synthetic companion object)
theres a proposal for it
@frosty obsidian will make it get merged faster
you did the same url twice
guhhh
https://github.com/Kotlin/KEEP/discussions/442 i dont like this KEEP @frosty obsidian
they never heard of a linter before
i also don't like that
i don't see it seriously solving a problem
would just be a new thing libraries force on you
@frosty obsidian hi
terrible
idk how anyone could think this is a good idea
Apple moment
yop
I love when libraries decide how I'm supposed to write my code
YES I NEED STATIC EXTENSION METHODS
this is literally my biggest gripe with kotlin
the support for statics is shit
Why do you need static extension methods
i was doing some fancy syntax stuff a while back
related to dsl for patching and I needed static extension methods but there was literally no way to accomplish what i was trying to do
actually so bad
How
Same :( ended up making a TExt object for T and ended up putting them there
funniest thing is you can't even translate a java api into kotlin without breaking backwards compatibility
because you can only make statics on singletons for some fucking reason
Can c++ interop even work given kotlin doesn't have destructors
Knative uses destructors all the time to handle refcounts
the jvm kinda has destructors, it's the finalize method on the Object class
but it's never guaranteed to be called, as that could only happen during GC I think
not the same thing but still interesting
Phantom refs can get u destructors
does that work in jvm tho
Well for JVM you can just write JNI/JNA
The JVM equivalent is the Cleaner
Cleaner manages a set of object references and corresponding cleaning actions.
Cleaning actions are registered to run after the cleaner is notified that the object has become phantom reachable. The cleaner uses PhantomReference and ReferenceQueue to be notified when the reachability changes.
ooo I had no idea about this
I might could use this for ffmpegkt
I just use javacpp bindings tbh
that's what I'm doing
works good
recently I added hardware accel encoding
how have I never heard of cleaner before guhh
isn't the whole advantage of having named parameters as a proper language feature that they're optional
in javascript it would be really annoying to make it optional as you literally implement it by accepting an object
why have a lexer when you can have a grokker
aren't Closables essentially destructors
you have to explicitly close them but still
I prefer AutoCloseable over cleaners
like
In C++, a destructor is called when that thing goes out of scope
aka; you know WHEN it will happen for that exact resource
For cleaners, the GC will run whenever it wants.
in Java/Kotlin you have to explicitly close via a statement akin to C# using
try (var thing = new CloseableThing()) {
thing.explode();
}
CloseableThing().use {
it.explode()
}
the try syntax is so cursed lmao
ya
with Lombok it ends up being:
{
@Cleanup var thing = new CloseableThing();
thing.explode();
}
And it will do the whole try(){...} for you
Very useful when you have more than one closeable
Well, you can try-with-resources with multiple things
But not if you want to do other things between
you can make a closeablemanager for this
lmaooo
try (var closeables = new CloseableManager()) {
var foo = closeables.add(new Foo());
var bar = closeables.add(new Bar());
}
idk i prefer java syntax
the try syntax is so cursed... followed by more cursed syntax
epsecially if you name the var
CloseableThing().use { thing ->
thing.explode()
}
ig that's the unfamiliar lambda syntax
https://light-theme-hurts.my-ey.es/2U5xZLf.mp4
Made a funky thing that works with vanilla clients to emulate a zelda hookshot
works fine for me
it's literally the most basic conversion of ```bash
owo_video () {
FILE=$(ls -Art1 "/home/mart/Videos" | tail -n 1) # most recent file
TMP=$(mktemp --suffix .mp4) # file to write to
ffmpeg -y -i "/home/mart/Videos/$FILE" $TMP >/dev/null # convert to mp4 with ffmpeg
owo -u $TMP # upload to owo
}
probably cause image host
does seeking mean moving to a different time in the vid
yes
love?
real gaymers use potplayer
Whats potplayer 🐟
unfortunately the only actually functional video players in the world are mpv and kodi
everything else falls short
potplayer lacks support for a bunch of formats, vlc doesnt do color mapping correctly
and most other players dont do hdr or dv correctly
chromium patched with extra codecs like ac3 and dts is third when it comes to accuracy and featureset
but it lacks subittle format support since it only has VTT
I love mpv
i hate mpv @deep mulch
mpv sucks for users
gotta write 200 lines of config before its usable
and import like 14 luas
from a usability standpoint its fucking rancid
I use without config
which means HDR and DV doesnt work correctly
because mpv fucks hdr and dv out of the box
I just use jellyfin for content with HDR
evil
i unironically use my own build of chromium for playing videos
because it lets me make my own video player with the shit i want
with the least cancer and fuckery with color spaces, formats, codecs and weird features
but ofc chromium manages to fuck it up for me too
love
is this insane
my lexer is overengineered but i like how it has methods named peek and seek
peek 'n' seek
peekin' and seekin'
are you cheating and using a library for your lexer..
no
you dont really need a trie for a lexer, whats the point?
to make it cleaner
what..
avoid giant switch case
ok but you do know you made a giant switch case with different syntax right
my trie impl is cursed
for my ichigo lexer i have this
fn Lexer::next_token(Lexer *self) -> Option<Token> {
if self.is_eof() {
return None();
}
self.skip_whitespace();
c := self.current_char();
if _, op := c.to_operator() {
self.advance();
return Some(Token::new(
TokenKind::Operator,
TokenValue::Operator(op)
));
}
if c.is_letter() {
return Some(Token::new(
TokenKind::Identifier,
TokenValue::String(self.consume_identifier())
));
}
if c.encode() == "「" {
return Some(Token::new(
TokenKind::String,
TokenValue::String(self.consume_string_literal())
));
}
if c.encode() == "※" {
return Some(Token::new(
TokenKind::Comment,
TokenValue::String(self.consume_comment())
));
}
if c.is_number() {
return Some(Token::new(
TokenKind::Number,
TokenValue::Number(self.consume_number_literal())
));
}
if c.is_punctuation() {
punct := self.current_char();
self.advance();
return Some(Token::new(
TokenKind::Punctuation,
TokenValue::String(punct.encode())
));
}
return None();
}
oh spam
whatever
but my point is, collect all punctuation into a generic "punct" token
then compare on particular strings
instead of having a seperate token for each punctuation type
i even did this sorta thing for matching binary
with a trie??
Koda toda crazy
idk but what youre doing seems a little overkill to me
@valid jetty
i would just have a few basic token kinds and then match on their value
opcodes.go: Lines 17-52
var opcodes = [...]opcode{
{"00E0", clearScreen},
{"00EE", returnFromCall},
{"1---", jump},
{"2---", call},
{"3---", skipIfVarEqualsByte},
{"4---", skipIfVarNotEqualsByte},
{"5--0", skipIfVar1EqualsVar2},
{"6---", setVarToByte},
{"7---", incVarByByte},
{"8--0", setVar1ToVar2},
{"8--1", setVar1ToORVar2},
{"8--2", setVar1ToANDVar2},
{"8--3", setVar1ToXORVar2},
{"8--4", incVar1ByVar2},
{"8--5", decVar1ByVar2},
{"8--6", shiftVarRight},
{"8--7", setVar1ToVar2MinusVar1},
{"8--E", shiftVarLeft},
{"9--0", skipIfVar1NotEqualsVar2},
{"A---", setIndexToByte},
{"B---", jumpWithOffset},
{"C---", setVarToRandom},
{"D---", drawToScreen},
{"E-9E", skipIfKeyHeld},
{"E-A1", skipIfKeyNotHeld},
{"F-0A", awaitKey},
{"F-07", setVarToDelayTimer},
{"F-15", setDelayTimerToVar},
{"F-18", setSoundTimerToVar},
{"F-1E", incIndexByVar},
{"F-29", setIndexToFontFromVar},
{"F-33", splitVarDigits},
{"F-55", copyFromVarsUntil},
{"F-65", copyToVarsUntil},
}
i mean if you say so
youre not grouping by prefix
youre grouping by class
oh you meant the opcode thing
im dumb
no you are not
@valid jetty
@valid jetty @valid jetty @valid jetty
you are world smartest person
@deep mulch minklang progress when
im gonna get nin0chat working in elle before you get your first hello world running
soon
good
@valid jetty hiiii
hiiiii
look at this beautifully formatted code
fn Token::precedence(Token self) {
$assert(self.kind == TokenKind::Operator);
op := self.value.as_op;
if op == Operator::Mul
|| op == Operator::Div
|| op == Operator::Rem { return 2; }
if op == Operator::Add
|| op == Operator::Sub { return 1; }
}
with switch case i was doing
case '=':
if lexer.match("=") {
// Equals Equals (comparison)
} else {
// Equals (assignment)
}
i wasn't a fan of needing to group unrelated opreators
what if you could do
if op == (Operator::Mul | Operator::Div | Operator::Rem)
bitwise or
yes
..or you can group together all punctuation into a single token kind and a string value, then match on the token's string rather than giving every operator its own distinct token kind
rosie could mke some insane syntax like |||
^^^
then if you have bool = !bool it will read =! as a single token even though it's meaningless
look at specifically the last if statement
oh wait
oh rosie my rosie
what, no it won't
each char is an individual token
well that's also not that useful
but i want == to be a different token type to =
this is too much for my small brain...
i'm pretty sure there is a way to collect tokens into a single token kind while their string value represents their actual semantic meaning
(including multi char ones)
hold on lemme consult stb c lever
hmm
but a token for any punctuation is just a character with extra steps
well yeah
so you're back to square one
even if you do totally insane things it should still process @!|||===:=!!= as @ ! || | == = := ! !=
you need a greedy match... but not too greedy
hmmm i'll sit on this overnight i think
i'm pretty sure there's a better way
elle does the approach you didn't wanna do lmao
aka this
maybe you can have a function similar to match_keyword kinda, but instead of matching a particular keyword you match any punctuation tokens
so the function internally would match against "==", then "=" , etc, and if none match then it's not a punct token
rosinga
i'll model this in the morning
None()??????
stop
horrible
None needs to be the same size as Some so that it can be represented the same in memory
hence it needs to be generic
hence it needs to be a function
@winged mantle ```rs
use std/prelude;
enum TokenKind {
Punctuation // we only support punctuation in our lexer :)
}
struct Token {
TokenKind kind,
string value
}
fn Token::match_punct(Token self, string punct) {
return self.kind == TokenKind::Punctuation && self.value == punct;
}
struct Lexer {
string input,
u64 position
}
fn Lexer::consume_string(Lexer *self, string value) -> Option<string> {
for i, c in value.iter().enumerate() {
if self.input[self.position + i] != c {
return None();
}
}
self.position += value.len();
return Some(value);
}
fn Lexer::consume_punct(Lexer *self) -> Option<string> {
if _, v := self.consume_string("@") { return Some(v); }
if _, v := self.consume_string("||") { return Some(v); }
if _, v := self.consume_string("|") { return Some(v); }
if _, v := self.consume_string("!=") { return Some(v); }
if _, v := self.consume_string("!") { return Some(v); }
if _, v := self.consume_string("==") { return Some(v); }
if _, v := self.consume_string(":=") { return Some(v); }
if _, v := self.consume_string("=") { return Some(v); }
return None();
}
fn Lexer::next_token(Lexer *self) -> Option<Token> {
if _, punct := self.consume_punct() {
return Some(Token { kind = TokenKind::Punctuation, value = punct });
}
return None();
}
fn Lexer::iter(Lexer self) -> Iterator<Token, SingleEnded> {
return Iterator {
env = Box::new(self).to_ptr(),
next = Lexer::next_token,
next_back = nil
};
}
fn main() {
lexer := Lexer {
input = "@!|||===:=!!=",
position = 0
};
res := lexer.iter().collect();
$dbg(res);
// now we can do things like:
token := res.remove(0).unwrap();
if token.match_punct("==") {
// do things here
}
}
just, as long as || is before | itll be matched first
and you dont need seperate tokens for each punctuation
and you dont need to make each punctuation a single character
win-win
this is the token stream from the $dbg call
which is correct
or well, i think you actually wanted != to be a seperate punct
but i didnt add it to the list
but you can see hopefully how that would work
you just add != before normal = and it gets matched first
there
technically all of these consume functions should be called try_consume because they can potentially not return a valid punct
but again you get the idea lmao
ok good night
ok i cleaned it up a bit
REAL good night
@woven mesa I gotta redo the cells in the clipboard manager to look like this T_T
im so lazyy
o
uh thanks but this is what i was trying to avoid because i'm weird 😭
😭 stayed up until 1:00 i'm sorry....
try not to make code look like cannibalism challenge
a go developers idea of clean code
Won't second case always be true
Either second case is always true, or third case is always false, or the syntax is doing something very fishy
, is effectively the same as ||
Then second case is always true
|| would be better but this is a go developers idea of clean code 
All chars are either >= A, <= Z, or both
No all chars are U+0 through U+10FFFF
10FFFF is >= A
i also have average go developer iq
the code was correct before
i will just use normal operators
less confusing
what why
hold on i came up with a better solution while i was pondering
The correct implementation to this function is unicode_ident::is_xid_start/continue
ehh
Trie seems like it'd be a lot of overhead
i mean... is anyone going to use my toy language
No

it's an excercise in futility
parsing performance can matter sometimes
i'm just trying to learn
@winged mantle look at this
fn Lexer::try_consume_punct(Lexer *self) -> Option<string> {
original_position := self.position;
puncts := ["==", "!=", ":=", "||", "|", "@", "!", "="];
best_match := None<string>();
i := 0;
while self.position + i < self.input.len() {
current := self.input.slice(self.position, self.position + (i += 1));
for p in puncts {
if p.len() == current.len() && p == current
&& best_match.is_none_or_with(
fn(value, p) p.len() > value.len(), p
)
{
best_match = Some(p);
}
}
}
if best_match.is_some() {
self.position += best_match.unwrap().len();
} else {
self.position = original_position;
}
return best_match;
}
``` pattern matching on the puncts :]
this might be a little overkill
that's was the idea i started with but i felt a trie was a better structure
hm
but you cant have a string value if you do it like that aaaa
needing a token kind for every single punct feels so..
idk
i'm sorry...
isn't that what you do in elle though
you have a separate token for Comma and Equal
maybe i should copy you and use consume instead of eat too
eatDigits

yeah i do but elle is my first attempt at writing a language
i didnt use good practices i just wrote whatever i first thought of
why not make a punk token type
punk
what the hell is a punct meant to be
punk is cooler
lol
feels like when you see a bsod at an airport
the go compiler falling apart because my code is just too good and vomiting out its internals
but hey it compiles really quickly
the compiler crashes within less than half a second
ok in all seriousness how 😭
i should just riir 🚀
rust would unironically be more suited for this but i wanted to write in a gc language first
write in java like the interpreter guide i was reading did
or just work out what the hell is going on
is this a common go issue
or did i just trigger an edgecase
ah i'm using go dnf package
i will try official distribution
@winged mantle what do you expect this to print
use std/prelude;
fn main() {
xs := [1, 2, 3];
it := xs.iter().map(fn(x) x * 10);
xs.push(4);
$dbg(it.collect());
}
10, 20, 30, 40
I'd say error, but if not, yeah that
no idea what happens in rust
why would it error
ah
/run
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
// java 8 based just in case
List<Integer> myInts = new ArrayList<>(Arrays.asList(1, 2, 3));
Stream<Integer> stream = myInts.stream().map(x -> x * 10);
myInts.add(4);
System.out.println(stream.collect(Collectors.toList()));
}
}
Here is your java(15.0.2) output @winged mantle
[10, 20, 30, 40]
yeah i know this is expected behavior
yeah it'd be weird if it didn't work like this
but theoretically you could make it throw
store crc with list

i should learn c# and do linq everywhere
i don't even know how it works
probably like
List<String> myStrings = new List<String>();
List<String> aaa = SELECT item FROM myStrings WHERE position("aa", item) < 3;
wait it's literally pretty similar 😭
that is not how you do it in c#
var xs = new List<int> { 1, 2, 3 };
var it = xs.Select(x => x * 10);
xs.Add(4);
Console.WriteLine(string.Join(" ", it.ToArray()));
this is how i would do it
Select is like .map in any sane language
well yeah it is but thats not the "sane" way to write it
i fear nobody actually writes sql-style queries
you would've thought this would exist for a reason...
this code compiles
this code crashes the compiler
how??
fixed 14 hours ago
probably
i can also remove the equals
built-in SQL 👍👍
ahh macros, but its basically the same as rosie's method, so i have to place the 2 char ones first
i feel like my new method is actually more efficient than this
because you’re not doing as many comparisons
you instantly rule out some puncts based on their first characters
the pattern matching?
yes
linq so cool but in our codebase i was always told not to use it due to performance issues 🤷♂️
but yeah it looks really cool to do sql queries that way
i mean the way elle does it is also technically like that but not as nice
it checks for the = character then advances and checks if the next is also an =, if it is then the punct is == otherwise it’s =
so basically manual pattern matching
Why is discord's i18n key hash function so bad
It uses 36 bits (6 characters) from a 64 bit hash, but their base64 implementation is wrong so the last 4 bits are duplicate, effectively lowering the entropy to 32 bits
So like with their intl maps already having over 20k items, there's almost a 5% chance of a collision between all the keys
I tried bruteforcing it but there are just so many valid hashes, even with 37 characters (uppercase + numbers + underscore, I didn't even try lowercase letters)
impossible
@deep mulch is this a @cinder egret reference
yes
nin0 do you unironically listen to taylor swift
i'll let my lfm speak for itself ykyk
what the fuck
why am i in programming i thought this was regulars
what package manager? pnpm?
yes
you're a hater you need more
ykyk
Do this:
"pnpm": {
"overrides": {
"esbuild": "^0.25.0"
}
}
okay thaks
you're welcome champ
this is radiohead reference
true
whenever there's a collision they just change the string slightly 
(I have no idea)
That would be actually funny ngl 😭
Ik some of the keys have been misspelt for a long time
I might do a pr cuz it's kinda irking me that the code is clearly wrong
Hopefully it doesn't break any vencord patches
@nimble bone i'm working on vencord compnaion again
@crude star hii
zt
rini
@deep mulch my code was so bad, adding basic caching (which hits 99% of the time) makes it read 60x less data from disk every time it reloads
insane
you should pr a fix so that vencord needs to fix a load of patches
That wouldn't really change anything.
All we would need to do is change the one hash function.
technically it would look like an apocalypse with vencord reporter though and the scare would be funny
yeah
horrid types
export type AssertedType<
T extends Function,
E = any,
> = T extends (a: any) => a is infer R ? R extends E ? R : never : never;
export type CBAssertion<U = undefined, N = never> = <
F extends (n: Node) => n is Node,
R extends Node = AssertedType<F, Node>,
>(
node: Node | N,
func: F extends (n: Node) => n is R ? F : never
) => R | U;
TIL type assertions can be inferred
writes typescript
complains about rich type system
not complaining
just saying they're a bit cursed
you can do things like this which i loev
discrimination
In computer science, a tagged union, also called a variant, variant record, choice type, discriminated union, disjoint union, sum type, or coproduct, is a data structure used to hold a value that could take on several different, but fixed, types. Only one of the types can be in use at any one time, and a tag field explicitly indicates which type...
i love discriminated unions
i wish more languages had support for them
@deep mulch add discriminated unions to kotlin
Doesn't the type T also accept class objects since they're subtypes of the Function type
i mean if your class somehow has an assertion signature, then sure
otherwise user error
idk what that means
unions that know what element is currently active
@limpid mica hiii
This is just Extract<U, { [D]: K }> why do you need a whole new type utility for this 
to discriminate
no autocomplete
you also get errors on invalid variants
😭
saladinanity
javascript should get if let
HORROR
declare function foo(): string | undefined;
if (let bar = foo()) {
console.log(bar);
}
wouldn't that mean a whole scoped enum system for js
that would be insane
just to check type
yea
but i still think if let would be cool
do if walrus
i dont really care for walrus
like go
(i also hate go)
if myThing, err := doThing(); err != nil {
}
insaneeee
I would take this ```js
if (let bar = foo(); bar != null) {
}
its horrendously simply to implement in js tho
yeah, same thing
i considered refacoring all my code to use it
let being a condition is kinda weird
makes even less sense it being !== undefined
C++ has that syntax though 
(also go)
yeah, i use it often in c++
ever met the type of person to use thing !== null && thing !== undefined
insane
@winged mantle let's comprimise with != void 0
i always write void 0
async function err <T>(Promise<T>: v): T {
try {
return [null, await v]
} catch (e) {
return [e, null]
}
}
const [err, res] = await err(fetch(url))
or you could patch promise directly
bundler brainrot
do void new function(){}
why not reverse
res, err
because thats how go, and old nodejs callback style is
return ((function() {})(), undefined)
Promise.prototype[Symbol.iterator] = async function () {
try {
return [null, await this]
} catch (e) {
return [e, null]
}
}
but idk how to do typedefs for this
and then simply
const [err, res] = await fetch(url)
i think node had it as first so you didn't accidentally miss it out
@crude star @crude star
go deffo has it last though
wait this is wrong
😭
that cant work
would this fuck with async iterators
after you await its no longer a promise
yeah it patched then
does js support implicit conversion operators
im retarded, this is wrong
you need to patch then
but no
async iterators are symbol.asynciterator
or asynciterable
i dont remember
im fucked up
ah
XD
why doesn't this work in js
#include <node/console.h>
class CoolBool {
constructor(value) { this.value = value; }
operator bool () { return this.value; }
}
console::log(CoolBool{true});
at that point this is easier
but the point is to define it as a lang feature
uuuh
i think you can define how an object converts to asymbol
but idk if that works
i dont rly do rust
what
const object1 = {
[Symbol.toPrimitive](hint) {
if (hint === "number") {
return 42;
}
return null;
},
};
that's c++
no?
callbacks yes
but go nuh uh
very likely im wrong
!!{ [Symbol.toPrimitive]() { return false } } == !!{}
not a real go lover..
my go experience is limite
doesnt work
insane
except window.all

wait what was the
*document.all
insane
is that instances of HTMLAllCollection or just document.all
document.all is the only HTMLAllCollection
@royal nymph they should let Proxy create exotic objects like this
problem is, its a language feature really
not an object call
!obj doesnt read a property so u cant trap it
its kinda like ===
wonder if that would prevent a bunch of optimization
only all
lily faster than me
its probably some hardcoded backwards compatibility shit
where its meant to not exist
yes
the thing I linked answers it
if (document.all) {
// code that uses `document.all`, for ancient browsers
} else if (document.getElementById) {
// code that uses `document.getElementById`, for “modern” browsers
}
it's meant to make code like this use the getElementById but also still support websites that only use .all
vchars “
“ LEFT DOUBLE QUOTATION MARK
insane
mmmm, im happy that i understand js enough to be able to guess it
old code used to check if document.all exists to detect for ancient IE
new browsers implement document.all for legacy compat reasons but don't want to be detected as ancient IE
chromium: oh no our backwards compatibility to 2002 browsers
also chormium: yeah lets just break all video playback and make constructors randomly segfault on 32 bit systems

i think your usecases are a bit abnormal
new ImageData() is abnormal?
i assume 32-bit systems don't exist when writing software these days smh
ALL android TVs are 32 bit sir
well, actually there are like 3 exceptions from what i know
out of roughly 3k

ooooh 4 now not 3
china released a new atv box
it's about Websites not browsers 🤓
they want ancient websites to still work in latest chromium
nvidia shield, ugoos am6b+, and z9x pro
and new websites to not
if the website is new it means you will fix it 😉
i think its been 3 years since i reported that filters dont work on offscreen canvases when they were first introduced
still no dice
still need to piss performance away by computing colormaps in raw js, instead of using gpu accelerated svg filters
ur the kind of user every developer fears existing
hop on wasm or smth
const canvas = document.createElement('canvas')
document.body.append(canvas)
const ctrl = canvas.transferToOffscreen()
worker.sendCanvas(crtl) // do giga heavy stuff
i already do, its too slow
from what i calculated we'd need 9GHz single cpus for wasm to be as fast as native 2.5GHz cpus
for this specific task
aka text rasterization
correcting canvas rendered shit, to match the colorspace of a video thats playing under it
and the cheapest way by a LAAAAAAAAAAAAAAAND slide is to do it using SVG filters, as they support color matrixes
so you can pre-compute all possible combinations of color space conversions
map them to a color matrix
and simply apply that color matrix to an svg filter, and boom, you've got fully GPU accelerated color matrix conversion at 0 overhead for the thread the canvas is running in
be it the main thread or the worker thread
well, that is if chromium got off their ass and fixed it not working in worker threads

here @royal nymph enjoy https://github.com/ThaUnknown/jassub/blob/main/src/jassub.js#L3-L25
computed via https://github.com/ThaUnknown/colorspace
didnt do bt.2020 because... the math for it is black magic and i didnt understand it!
this._ctx.filter = `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${colorMatrixConversionMap[subtitleColorSpace][videoColorSpace]} 0 0 0 0 0 1 0'/></filter></svg>#f")`
self super react is crazy
wtf is it reacting to
cursed svg filters
bro has a plugin to selfbot react to jsslop
this._ctx.filter = url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${colorMatrixConversionMap[subtitleColorSpace][videoColorSpace]} 0 0 0 0 0 1 0'/></filter></svg>#f")
aw
sir its your plugin
its not auto
oh you mean the always super react
but yeah that filter is very not what it was made for
but chromium snuck url() as one of the options
and the flood gates opened
cuz the expected use case is
ctx.filter = "blur(4px)";
XD
does anyone actually notice their subtitle is in the wrong colorspace
insane
just write better code
????
sir do you understand how color spaces work?
you need to correct color spaces
like
what if the video is simply a different color space
you can apply subtitles to many videos, and they can be encoded differently with different color spaces
so you need to read the video color space, and the subtitle color space
and correct
programming chat
they are insane
you remind the teacher of homework
any vim motion enjoyers?
I'm making a calendar program for a school project. Should j be next month or previous month
next seems the most vim-y, but it's on the left so seems more previous to me
just use h and l
h and l will be for year
that feels so wrong to me
nop
should h and l be month and jk for year?
depends on ui
h and l seem more "extreme" to me since they're further on the outside
this depends on ui
yeah
this is the current ui that's barely functional that i just used for testing
i don't think i even have time to make the ui good
it's due tomorrow
well thanks
@deep mulch @nimble bone rate horrorcode
parseClassDeclaration(clazz: ClassDeclaration): RawExportMap {
const ret: RawExportMap = {};
for (const member of clazz.members) {
if (isMethodDeclaration(member)) {
if (!member.body)
continue;
ret[member.name.getText()] = [member.name];
} else if (isConstructorDeclaration(member)) {
// the ConstructoKeyword
ret[WebpackAstParser.SYM_CJS_DEFAULT] = [member.getChildAt(0)];
} else if (isPropertyDeclaration(member)) {
ret[member.name.getText()] = [member.name];
} else if (isAccessorDeclaration(member)) {
if (!member.body)
continue;
ret[member.name.getText()] = [member.name];
} else {
outputChannel.warn("Unhandled class member type. This should be handled");
}
}
// name ?? ClassKeyword
ret[WebpackAstParser.SYM_CJS_DEFAULT] ??= [clazz.name ?? clazz.getChildAt(0)];
return ret;
}
please never touch a keyboard again
horrorcode pt. 2
tryParseClassDeclaration(node: Identifier): RawExportMap | undefined {
const varInfo = this.getVarInfoFromUse(node);
if (!varInfo) {
return;
}
// classes should only have one decl.
// if someone proves me wrong on this (with an example in discord's code), ill support it
if (varInfo.declarations.length !== 1) {
return;
}
const [decl] = varInfo.declarations;
if (!isClassDeclaration(decl.parent)) {
return;
}
return this.parseClassDeclaration(decl.parent);
}
klass > clazz
@hoary sluice
you can attach colored ones
allow spaces in elle variable names
Ah
https://github.com/moonlight-mod/lunast knockoff ?

@nimble bone you use kotler compose for android right
Well im trying to decide if i should use flutter or kotlin
use that yeah
Use what
That is a switch 1 you cannot attach switch 1 joy cons to a switch 2 and switch 2 has only had one set of joy cons released yet (the grey ones with coloured accents)
not calibration, correction
still the wrong thing XD
cool
Its probably not aware of php 8/8.4 lol
Mine has been around for longer 😭
Also there’s like no code in that repo
Yeah, I'm doing all the parsing myself
Right now I'm working on Getting a UI for all the flux events so you can jump to where any one event is dispatched or handled.
salad vibe coded her parser
i admire it when people work on projects for a long time
I think this is the longest project I have going 😭
Only a year
(Unless you count my nix dotfiles)
I could never switch to go
i was really starting to like js but my js code looks like slop now
Module system is too confusing and I don't like the forced casing for variable names.
i think i probably just overengineered things
i love js
Forced casing is a good idea
and stuff like this isn't inherently a js problem but after writing a bunch of go i hate looking at this
just don't make a schema you know you know
Sometimes I wish typescript strayed farther away from js
With things like actual overloading (probably impossible)
overloading isn't that good
And runtime generics
I like it a lot for some things
have you never had that ambigious overload error in java and c++
I have in kotlin
Not Java or c++
anyway i'm kinda looking at my code and thinking how did i get here

tbf this is over a year
Real
I think the horrid tests I added a while back and the (somewhat sparse) comments are the only thing keeping me sane rn
i think maybe a good goal is to reduce lines of code
because the loc is probably an indication i made things more complex than they need to be
maybe i should just revert the last 100 commits it will probablybe much better
one thing good about my project is the largest file is 250 lines
Yeah
I can't really do that with that file
I'm not partial to OOP or more functions, but I think it works well for this file with the only downside being it's massive.
oop has been a curse on the programming community
i totally didn't just rewatch https://www.youtube.com/watch?v=QM1iUe6IofM for the 17th time
An explanation of why you should favor procedural programming over Object-Oriented Programming (OOP).
least half-baked youtube ui
how did you end up urlencoding your slashes
gh mobile urlencodes the filename
horror
i made an extension point system where plugins declare a set of "contributions" which modify the behaviour of other plugins
would it be better just to use functions

is there a good guide on making a nice plugin architecture with js/ts
are rust developers okay https://bsky.app/profile/orhun.dev/post/3lutxbgu23s2n
Tachyonfx brings web-level animations to the command line.
Then Ratzilla puts it back in browsers where it belongs 🤷♂️
Witness this beautiful chaos: junkdog.github.io/exabind
🦀 Powered by Rust & @ratatui.rs ecosystem
⭐ GitHub: github.com/junkdog/exab...
what is this
yeah honestly my code got worse 😭
best bet to revert before my rework and backport stuff
kode tode


