1,716 karma · joined March 3, 2017
I'd put the blame on React and poor Web APIs in this case. Both are way too complicated for mere mortals to understand fully, and even simplest things like maintaining 100% container height through nested elements, can become a ridiculous time-sink for something completely unrelated to what is your main objective.
I am more excited about making things rather than fetishizing about some language paradigms so, I acknowledge that Gleam just isn't for me. I did give me the insight that for me, it might be the best to stick with the common denominator languages for the foreseeable future.
Whose to judge if it works and ships on time? Well, the fool later down the road who has to maintain it probably. But I've never believed in gate-keeping or preaching without pragmatism - I rather put my energy in teaching what little i can and hope that joy of seeing things improve for better will motivate them towards learning. If not, well it's waste of time either way.
But it is funny that humans put a great lot of weight on social contracts and being given explicit orders, maybe even publicly, must help pursuing action instead of rumination. Especially in a world where things seemed to happen randomly anyway.
And then you still can end up with stale closures.
The fact they are over-engineering the server-side rendering is a cherry on top. React used to prize itself as the minimalistic solution but now they invent abstractions just to feel smart it seems.
But the fact is your complete PR commit history gives most people a headache unless it's multiple important fixes in one PR for conveniency's sake. Happens at least for me very rarely. Important things should be documented in say a separate markdown file.
Base64:ing the images into strings, like one could do with html, would probably not be ideal for compression. As a matter of fact, text-files as such would not be ideal compression-wise.
So I suppose if binary-format cant be avoided, SQLite would be as good as any other compression format. But without built-in collaboration protocol support, like CRDT, with history truncation (and diverged histories can always fall back to diff) I dont think it'd be good enough to justify the migration.
It's just corporate propaganda that all hell would break loose, you could just offer installing baby mode at Apple physical store that can only be removed at said places. Yeah some people would still climb the fence and touch the power lines but look, can we save them all? Should we? In this world of merciless exploitation, wouldnt it be just fair we stopped pretending it never was about anything else but money?
And look, I'm first to admit that TS type system isn't perfect (and it can cause some devs to go overboard) but I have read my share of Python scripts that were read-only from the minute they were born.
It sounds like you’re really trying to justify something and that’s great for you. I’m really happy for you. Keep it up. May you soar where no junior dev has dared to soar before. God speed.
And please, your condescension just sounds insecurity to me. It's highly amusing though that you try to play me down as a silly junior dev, I'm quite satisfied that my original assessment was correct.Sure, the nature of Elixir probably makes it easier but I find little joy in dynamic whack-a-mole and mental gymnastics to infer types instead of fricking actually being able to see them immediately.
I could go commando in TS as well and switch to JS and JSDoc, leaving everything gradually typed and probably be fine but I'd feel terribly sorry for anyone else reading that code afterwards. It'd be especially silly since I can now just infer my auto-generated Postgres zod schemas with little effort. Moreover, a good type system basically eliminates typing-related bugs which you guys apparently still have.
So please, don't over-generalize just because you think you got it figured out.
Be it React or Svelte or whatever. With serverless backend if you want to keep costs down. Although a server from Hetzner isn't that expensive and you can host multiple APIs there.
export interface AsyncQueueOptions {
timeoutSeconds?: number
}
export class AsyncQueue<T> {
private readonly queue: Promise<T | undefined>[] = []
readonly timeoutSeconds: number
private timeout: ReturnType<typeof setTimeout> | undefined
private reject = () => {}
private resolve = (value: T | PromiseLike<T>) => {}
/**
* @param timeoutSeconds @default 25
*/
constructor({ timeoutSeconds = 25 }: AsyncQueueOptions = {}) {
this.timeoutSeconds = timeoutSeconds
if (timeoutSeconds > 100) {
console.warn(`You are initializing AsyncQueue with over 100s timeout: ${timeoutSeconds}`)
}
this.queue.push(
new Promise<T | undefined>((resolve, reject) => {
this.resolve = resolve
this.reject = reject
this.timeout = setTimeout(() => resolve(undefined), timeoutSeconds * 1000)
})
)
}
next(): Promise<T | undefined> | undefined {
return this.queue.shift()
}
push(msg: T) {
this.resolve(msg)
this.queue.push(
new Promise<T | undefined>((resolve, reject) => {
this.resolve = resolve
this.reject = reject
clearTimeout(this.timeout)
this.timeout = setTimeout(() => resolve(undefined), this.timeoutSeconds * 1000)
})
)
}
close(msg?: T) {
if (msg) {
this.resolve(msg)
}
clearTimeout(this.timeout)
}
}Although my implementation doesnt have any sequencing as never had need for it but, more importantly, it has retrying and timeouts. Well retrying I might have implemented on level higher.
Maybe I'm just one of the rare few who actually would have enjoyed this type of question as a chance to brag about my version. Kinda neat as I've never been interested in programming challenges to, for once, know exactly the solution.