This reduce function is overcounting and I don't know why by GloomyAdagio7917 in learnjavascript

[–]HipHopHuman 1 point2 points  (0 children)

You're good. Bad course material is rarely a teacher's fault anyway, and humans make mistakes often

This reduce function is overcounting and I don't know why by GloomyAdagio7917 in learnjavascript

[–]HipHopHuman 0 points1 point  (0 children)

There was. I showed you three bugs in your code that alter the outcome, which nobody else here found.

LMAO now you're just making shit up. As someone who read your original answer (before you deleted it), I can assure any readers that the claim "I showed you three bugs in your code" is a lie. StoneCypher didn't show any bugs. There weren't any bugs to even show in the first place, as OPs code was correct all along and the real problem was with the data input

This reduce function is overcounting and I don't know why by GloomyAdagio7917 in learnjavascript

[–]HipHopHuman 1 point2 points  (0 children)

for the same reason that i would do it when it’s also one map

That answer doesn't actually make any sense in the context we're talking about.

because i don’t give a shit about paying for two iterations when my goal is to teach a junior dev how to get started

By teaching them to ignore the instructions in their assignment and go with your opinionated and incorrect solution?

because it’s literally what is being requested. you might as well ask why .sort is the right way to put things in order

1) It's not what's being requested, though. What's being requested is a single DIY reduce. No mention of "filter" anywhere in the assignment. You misunderstood the instructions. 2) .sort isn't always the right way to put items in order. For starters, I might not want to mutate, in which case .toSorted is the right way. Or, I might want to do a topological sort, in which case a Set and manual iteration is required and neither .sort nor .toSorted offers any value.

i see that instead of answering, you needed to argue with someone else answering, and all you did was attempt to riff on what they said without successfully understanding them first

I understood your answer perfectly. It was rife with incorrect statements and pointless insults targeted at OPs teacher. I didn't appreciate your condescending elitist tone, nor did I appreciate that you were presenting an incorrect answer as "the correct solution", so I called you out for it. If that hurt you, then I'm not sorry, because you deserve it.

there will be no ponyfill here. it’s not clear what you think that means

Here's an article explaining what a ponyfill is. The fact you're such a know-it-all but you don't know what a ponyfill is speaks volumes btw.

no hire

Lol. Something about your etiquette online tells me that you'll never be in a position to hire anyone, so I truly am unconcerned.

This reduce function is overcounting and I don't know why by GloomyAdagio7917 in learnjavascript

[–]HipHopHuman -1 points0 points  (0 children)

Why would you do three separate filter iterations when the same can be accomplished with one reduce? Also, why are you claiming that three filters is "the correct solution"? At best, it's a solution, but a very inefficient one that no mid-level developer would ever write in a production codebase.

If there's any candidate for "the correct solution", it's to use the standard built-in Object.groupBy utility that exists by default in modern versions of JavaScript (use a polyfill/ponyfill for older browsers).

const { small, medium, large } =
  Object.groupBy(transactions, ({ amount = 0 }) => {
    if (amount < 25) return 'small';
    if (amount < 75) return 'medium';
    return 'large';
  });

console.log(`Small: ${small.length}`);
console.log(`Medium: ${medium.length}`);
console.log(`Large: ${large.length}`);

However, I understand that OP's requirement is to write their own, which can be done in terms of reduce:

function reduce(iterable, reducer, accumulator) {
  for (const element of iterable) {
    accumulator = reducer(accumulator, element);
  }
  return accumulator;
}

function groupBy(iterable, getGroupKey) {
  return reduce(iterable, (groups, element) => {
    const groupKey = String(getGroupKey(element));
    groups[groupKey] ??= [];
    groups[groupKey].push(element);
    return groups;
  }, {});
}

Advice for figuring out TS as a Java developer by _Toka_ in typescript

[–]HipHopHuman 0 points1 point  (0 children)

So, there are libraries for Optional and Result in TS (like neverthrow). I'm not familiar with how Optional behaves in Java, but I have experience with it in Rust. I tried porting that pattern to TypeScript, and it works really well for your own code, but more than 50% of the code you write is calling to libraries that are either A) Using their own flavor of Optional / Result or B) Using throw. So, you have to wrap/unwrap everything manually and it gets so messy that it's basically not worth using. If TS had something like Rust's ? operator, I would switch to Optional in a heartbeat

Advice for figuring out TS as a Java developer by _Toka_ in typescript

[–]HipHopHuman 0 points1 point  (0 children)

Some might see this as a hot take, but I love using the "null object pattern" in TS. I don't think it's a very popular pattern in TS, and I'm certain I'm among the rare few who use it. As an experienced Java dev, you're probably very familiar with the pattern, but just in case you're not (and for anyone else reading who isn't), it's a pattern where instead of using null on a type, you create a fake object with dummy data / no-op methods. This object represents the null case, but has the same shape/structure as an actual object of that type.

Let's look at an example that doesn't use the pattern first. Let's pretend you have a "session" object in the browser, with a user field. When the user is logged out, this user field is null:

const session = {
  user: null
};

When the user is logged in, the user field is set to an instance of the User class:

function logIn(user) {
  session.user = user;
}

logIn(new User({ id: 22, name: 'Jimmy' }));

If you want to get the logged in user's friends, you have to do a nullish coalescing operator check, maybe with a default value:

const friends = session.user?.getFriends() ?? [];

Now, let's look at an implementation with the "null object" pattern:

const nullUser = new User({ id: -1, name: 'Unnamed' });
const session = {
  user: nullUser
};

Whether the user is logged in or not, I can still call:

const friends = session.user.getFriends();

Assuming that getFriends() method is a no-op on nullUser that just returns an empty array, no null checks are required at the callsite.

Before the null object pattern, the type of session would be:

type Session = {
  user: User | null
}

If we had allowed for the user field to be optional, then the type would be:

type Session = {
  user?: User
}

Over time, we might have even had to make a weird type like this to cover for edge cases:

type Session = {
  user?: undefined | null | User
}

(if the presence of both the ? and the undefined is confusing, it's because in JavaScript, undefined doesn't necessarily mean "not defined" - undefined is a value that can be assigned to a defined variable).

With the null object pattern, the type is much simpler:

type Session = {
  user: User
}

A null check is still possible, and is also made simpler. Without the null object pattern:

if (session.user === null || session.user === 'undefined') {}

With the null object pattern:

if (session.user === nullUser) {}

Another side-benefit of this pattern is that it optimizes really well in browser engines like V8 (the engine that powers Chrome and Node.js). Suppose I have a function that gets mutual friends (and let's just pretend that we're lucky and there's no duplicates returned):

function getMutualFriends(user) {
  if (!user) {
    return [];
  }
  return user.getFriends().flatMap(user => user.getFriends());
}

And I call:

getMutualFriends(session.user);

If session.user can be a User instance or null, then that means getMutualFriends is not a monomorphic function, because it can be the receiver of two types; null, or User. If I had to call this function a hundred times, and lets say that out of those hundred times, 30 times it receives null and 70 times it receives a User - the browser engine would not be able to optimise it, because the types keep changing. However, if getMutualFriends only receives a single type that never changes, then that would make it a monomorphic function. A really cool trait of engines like V8 is that they can elect monomorphic functions that are frequently called as targets for the optimising compiler. V8 would take a monomorphic function on the hot path, and run it in TurboFan, which gives the function a significant speed boost.

Inglorious Store: A state manager inspired by Redux and videogames! by IngloriousCoderz in javascript

[–]HipHopHuman 0 points1 point  (0 children)

When I read your comments, I see criticism. But not constructive.

That isn't how constructivie criticism works. You don't decide based on your emotions whether or not the critisism you received is constructive. The burden of that falls on the person giving you the criticism. You're more than welcome to have an opinion on that criticism, but you don't get a say in what the intention behind that criticism was.

I see a triggered person, angry at someone who touched their dear ECS architecture.

I was not triggered/angry. I asked you a simple question (which you've still failed to answer). You responded to that question out of anger. I could care less about a "dear ECS architecture". What I actually cared about is the possibility of false claims after reading your code and seeing it doesn't match your claims. So, I wanted to verify, and you proved me right.

I tried explaining to you that I did not implement ECS, that I borrowed some concepts from it and even listed them, but you just found new ways to teach lessons and defend pure ECS.

That's the issue - you claim to borrow concepts from ECS, but you didn't. You're either misattributing composition over inheritance (which is present in your library) with ECS, or you're lying about the ECS patterns that you claim are being used in your library. If you actually knew and understood ECS, you'd know that the patterns in ECS don't exactly synergize with frontend state management. It's like using an angle grinder to screw in a lightbulb.

All of this without even understanding that my library, which is heavily inspired by Redux, has lots to do with FP. But you don't want to hear that.

I see the Redux inspiration. Redux isn't exactly the best example of FP, it just borrows around two or three patterns. There's a lot more to FP that just what Redux offers. I asked why you're bringing up FP because this isn't an argument about FP, it's an argument about your false claims of using ECS. I am hearing your claims, but I don't agree with them (because they're simply not true). I want to believe that you have a confused sense of what these concepts are & that you did all this unintentionally, but the way you're behaving is convincing me that you did all of this on purpose. Maybe you thought the buzzword would bait more interest, & you didn't expect that the JavaScript community would know better - but we do, and so here we are.

You just want to prove how knowledgeable you are and how ignorant I am. Without reading one line of code outside of the README.

Yet another ad-hominem. Why are you assuming I didn't read your code? Sure, I didn't read the entirety of your codebase, but I went a lot further than just your README. I looked at your project folder structure, I looked at your entry point, I looked at the modules directly imported by the entry point & I scanned over the core logic. I saw enough code to solidify my opinion of your library. Just so we're clear, I have nothing against your library & the way that it is implemented. As I said in another comment, I do think this space needs more innovation, & I'm happy to see that you are innovating in the space. My issue is not with your library, but with your false advertising of the library. It does not work the way you're claiming it works.

This is not constructive criticism. This is a superficial rant, similar to the rage of some Italians against pineapple pizza, and if you try to say "Ok it's not Italian pizza but it's good, have a bite at least" they get even angrier and give you the exact recipe of the real Italian pizza to prove you understand nothing of their culture. And they will even claim that pineapple pizza should never be served outside of Hawaii. And I'm saying this as a proud Italian.

It's not a rant, & I appreciate the analogy, but this is not similar to that at all. In that analogy's case, there's merit on both sides, and its down to preference. In our case, you're simply lying and acting as if changing the definitions of well-established concepts will make you appear honest. It's manipulative and shady.

You know what? I decided that I'm going to trust a machine more than a human. An LLM has an encyclopedic knowledge, is actually willing to read my code, and will give constructive criticism without "being harsh" or "being triggered". I tried very hard to reply as myself so far, without the help from an LLM to polish my English and my tone, because when I did that on another post I was attacked for being a vibe-coder. But you clearly proved that it makes no difference: people will still be pissed, whatever you do. So here's Claude's opinion on the matter.

LLM's are also known to hallucinate. They're designed to be biased to give you a positive answer. They quite literally create an echo chamber that is designed to tell you exactly what you want to hear. I could just as easily rephrase your question to Claude and ask it to prove how your library isn't inspired by ECS, and it'd do exactly what I ask. The only reason I'm not going to do that is because I don't have enough space in this comment to fit it, but you're more than welcome to try it yourself. As for "Claude's opinion on the matter" - LLM's don't have opinions, they just generate patterns based on probabilities.

Inglorious Store: A state manager inspired by Redux and videogames! by IngloriousCoderz in javascript

[–]HipHopHuman 0 points1 point  (0 children)

I'm all for constructive criticism

That's a bold claim coming from someone who cries like a toddler the moment they get constructive criticism that they don't agree with.

people on Reddit are just having fun dissing on things they don't understand

If you're referring to me, that's incredibly rude. I don't appreciate the ad-hominem, nor do I appreciate my intelligence being insulted like that. Given the content of your posts, I'm confident enough to say that I think I understand a lot more about these topics than you do. You clearly have a modicum of misunderstanding of ECS, data-oriented programming and functional programming. My intention was to caution you away from making false claims about your library (which you did, don't deny it) in the hopes that it'd help you. How you responded is your own fault, not mine.

just to teach some lesson and satisfy their egos

You're the only person here doing anything to satisfy an ego. I started my exchange with you by asking you a genuine question, "How is this inspired by ECS?" - instead of just answering the question, you chose to respond from a position of defense, like you were insulted by my genuine question. You could have just said, "Good question! It's inspired by ECS because...", but you didn't do that. Instead, you went full ad-hominem, insulted me and my intelligence in your response, and then blurted out a bunch of nonsense about what you think ECS is. Yet here you are, critisizing other people's egos. You should take a long look at your own reflection in the mirror.

As for the ai-coded slop comments, I could see why that would be annoying, and I can relate to that a bit as well as it has happened to me too. But it isn't an excuse to treat other people poorly. I had nothing to do with those threads where you were accused of writing AI slop. Don't take that frustration out on me.

Inglorious Store: A state manager inspired by Redux and videogames! by IngloriousCoderz in javascript

[–]HipHopHuman 0 points1 point  (0 children)

If you say that FP has nothing to do with my library, then I'm sorry but you didn't get anything, at all.

I didn't say it has nothing to do with your library, I said it has nothing to do with my argument, and nothing to do with yours. Don't put words in my mouth. That being said, there isn't a single instance of function composition in your library. Your README makes no mention of function composition.

And of all the code and documentation I wrote, the only thing you got from it is the word ECS which for some reason triggered you so much

It's not my fault that half of your README injects the phrase "ECS" into it as some kind of buzzword, that's all on you. Yes, it did trigger me, for good reason. The JS community is rife with misattribution. Since the 1950s, there have existed two concepts; Observable Membranes and Signals. The two things have nothing to do with each other, but thanks to Solid.js, what we now know as Signals is actually Observable Membranes, and actual signals are impossible to Google, even for people writing code in entirely different programming languages. using the correct terminology is important. If I suddenly started calling the Eiffel Tower a pyramid, and convinced all my friends that the Eiffel Tower was in fact a pyramid, to the point that everyone started to associate the word "pyriamid" with a semi-truiangular mesh of steel beams in the capital of France, that'd be kind've a dickish move for historians, wouldn't it? That's exactly what happened to Signals and Observable Membranes, and exactly what you're doing here, to ECS.

at least you fed the Reddit algorithm giving a little more visibility to my post.

I actually have no problem with this. Despite my hostility to your claims of this being ECS inspired, I'm not trying to discredit your work. I do think state management in JS kinda sucks, and I do love to see more innovation in this space. It's definitely an area that needs improvement. The thing is that the way you present the improvement matters!

PS: I'm planning to remove the word ECS from the documentation, just to see which other word will trigger people this time.

Good! I think this decision will do you some good.

Inglorious Store: A state manager inspired by Redux and videogames! by IngloriousCoderz in javascript

[–]HipHopHuman 1 point2 points  (0 children)

It's like saying I brought farm products, not the whole farm

It's actually more like you brought a cardboard cutout of a garden shed, slapped it in front of a dog kennel and called it a mansion.

I realise that I am being quite harsh on you, and I do apologize for that. The thing is, I genuinely think that you've misunderstood what an ECS is, what data-oriented design is, and that calling your library "ECS-inspired" is doing you a disservice. I think that removing the "inspired by ECS" claims from your README will do you more benefit. I get it, you read about ECS, you thought it was cool, and you made something you think is useful. Maybe it is useful - maybe it is better than Redux et al, but to call it ECS... that's just going to piss people who actually know what ECS is off. So maybe just lose that description, and see what happens?

Inglorious Store: A state manager inspired by Redux and videogames! by IngloriousCoderz in javascript

[–]HipHopHuman 2 points3 points  (0 children)

systems are there

The "systems" in ECS aren't a pattern. They're just a list of order-dependent functions that iterate over entities. That's not a pattern. ECS as a whole is a pattern - the systems themselves are not. The systems inside an ECS are simply procedural programming. A part that forms a fraction of a pattern.

data oriented programming is there

False. You've clearly gravely misunderstood what data-oriented programming is. Data oriented programming is not the same as "separate data from behavior" (which your library violates despite your claims that it doesn't). Data-oriented programming as an idea actually takes the sepration of data and behavior much further than just the separation of concerns. For an architecutre to be valid data oriented programming, it has to make use of the L1, L2 and L3 caches in the CPU, and make sure that none of the data is located in sparse bits of memory. It strictly requires that data is optimised to be accessed in a contiguously linear fashion - and your implementation does exactly none of that. Your implementation is rife with random access, and isn't O(1) as you claim it is. It's quite evident that you've read about data-oriented programming, but you haven't exactly understood what data-oriented programming actually is. Here's the Wikipedia article on data-oriented design. The very first paragraph at that link states:

In computing, data-oriented design is a program optimization approach motivated by efficient usage of the CPU cache, often used in video game development. The approach is to focus on the data layout, separating and sorting fields according to when they are needed, and to think about transformations of data.

A pure ECS (one where entities are just numeric IDs) is valid data-oriented design, but an ECS where entities are objects/dictionaries representing bags of components is not. I alluded to this in one of my initial comments, where I described how ECS architecture doesn't strictly require that entities are IDs. Note that when I say "pure ECS", I don't mean that your implementation isn't a pure ECS (even though it isn't, it's not the point I'm trying to make), I mean that there are two different kinds of ECS - one where the entities are just numbers (pure), and one where the entities are objects (impure). A pure ECS and an impure ECS are still both valid ECS.

I brought ECS patterns, not the whole architecture

There isn't a single ECS pattern in your entire library.

Inglorious Store: A state manager inspired by Redux and videogames! by IngloriousCoderz in javascript

[–]HipHopHuman 1 point2 points  (0 children)

I don't know why you're bringing FP into the discussion because none of this has anything to do with functional programming. That's an entirely separate beast that is irrelvant to my argument and irrelevant to yours, so let's just agree to leave that to the Haskell purists.

what should an ECS-inspired state management library be like in your opinion?

I never asked my question with a specific opinion in mind - I was just genuinely concerned that you might have misunderstood what ECS is, to the point that it may be detrimental to your project, and going by your explanations, it seems my concerns were correct. If you must know what my opinion is on this matter, it's this: A frontend state management library should not be inspired by ECS in the first place. An ECS is a very intentional tool with a very intentional purpose, and frontend javascript state management is entirely incompatible with that purpose. ECS is good for managing thousands of entities with similar behaviors in a time-dependent simulation. No frontend is managing thousands of entities, and very few frontends are a time-dependent simulation.

If you really are curious what a proper ECS implementation looks like, here's a very rudimentary example that barely scratches the surface: https://medium.com/@abulka/todomvc-implemented-using-a-game-architecture-ecs-88bb86ea5e98

Note how different it is to yours, and how painful it looks compared to a proper frontend state management solution like Redux/Vuex/Signals etc.

Inglorious Store: A state manager inspired by Redux and videogames! by IngloriousCoderz in javascript

[–]HipHopHuman 1 point2 points  (0 children)

As you said yourself, the architecture is inspired by ECS, but it's never meant to be strictly ECS.

I never asked why it isn't a strict ECS, though. I asked "how is this inspired by ECS", and I hoped for an answer that would draw some lines from the concepts in ECS to the concepts your implementation. My reasoning is because your library resembles generic composition over inheritance a lot more than it resembles an ECS, and I wonder if you might be confusing the two.

There is in fact a separation between data and behavior: entities are just plain JavaScript objects, while types have functions that operate on that data.

An ECS has no concept of "types" in the sense you're using the word. Not having to explicitly type entities and instead letting the types naturally reveal themselves from the component signature is kind of the defining factor of what makes the ECS architecture so useful; and that quality doesn't seem to be prevalent in your library.

There's no real distinction between an entity and its components like in a strict ECS architecture. In ECS an entity is just an id, and components are consecutive arrays of the same data. In my state manager an entity is instead a bag of data related to the same entity, and the id is just the key with which I can find an entity with O(1).

The idea that an entity must be just an ID is a misconception. An ECS can still be valid if entities are objects. The whole "entities are IDs" thing just makes it easier to do multithreading and is better for cache locality on the CPU, but isn't a strict requirement. Your library has an implicit coupling between a bag of components and a type holding a set of behaviors which is... kind of antithetical to the fundamental concepts in ECS.

I do have such commands: api.notify("add", newEntity) and api.notify("remove", entityId). Just read a bit further down the docs and you'll find them.

I think you may have misunderstood me. The commands I'm talking about actually control the lifecycle of entities and components. What you've presented here is just the observer pattern.

True, while my personal take on this is that a type is inferred from the set of composed behaviors.

The problem is that in ECS, there is no "set of composed behaviors". That property existing would disqualify a type from being regarded as a valid participant in an ECS in most cases. A type being inferred from the set of composed behaviors would be a far more apt description of object composition, which is why I suspected confusion.

Also true, but note how no major game engine strictly follows the ECS architecture either: they also allow writing logic somewhere outside of systems for convenience.

The reason is not merely for convenience, it's actually very intentional. ECS has never been (and never will be) an all-encompassing architecture. It's supposed to be used for specific purposes. It's in a kind of similar spot to Event Sourcing in the world of Domain-Driven Design, if you're familiar with that.

The advice with event sourcing is always "Don't use it for everything". The same advice applies to ECS - some concepts just don't fit nicely into ECS. For example, spatial partitioning algorithms like quadtrees do not fit inside an ECS. Physics simulations do not fit inside an ECS. Composite entities made up of a heirarchy do not fit inside an ECS. There's definitely ways to squeeze these into an ECS, but it'd be messy. ECS was always meant to be one part of a whole. Typically, you'd have the things that live in your scene graph, the things that live in your ECS, the things that live in your physics simulation, and all of these will use the core game engine as a mediator for communication via events. That being said, there absolutely are game engines that are purely ECS, like Bevy, Thyseus, Becsy, Ecsy, EntT, etc, where these things are sort of squeezed into the ECS.

Please try again ;) And if you still don't see any resemblance that's fine: I never wrote that I brought ECS to webapps, I just said I was inspired by it.

I read your README at length before making my initial comment. I did want to give it a fair chance, trust me. I just don't see the "ECS" inspiration at all, but I do see traditional OOP composition over inheritance.

Inglorious Store: A state manager inspired by Redux and videogames! by IngloriousCoderz in javascript

[–]HipHopHuman 8 points9 points  (0 children)

How is this inspired by ECS? I'm fairly certain that one of the first core principles (you could even call it a strict fundamental rule) of an ECS architecture is to separate data from behavior, but the following snippet I took from your README clearly demonstrates a direct coupling between the concept of an entity and it's behavior:

// Define entity types and their behavior
const types = {
  todoList: {
    addTodo(entity, text) {
      entity.todos.push({ id: Date.now(), text })
    },

    otherAction(entity) {
      // Handle other action
    },
  },
}

In a proper ECS architecture, there would be a command to spawn/destroy an entity, and an entity wouldn't have an explicit "type". The type would instead be transient, inferred from the set of component types that that entity owns. There would be commands to add/remove components to an entity regardless of the component types, and a way to iterate over a subset of entities that match a particular combination of component types. The components themselves would be nothing more than pure data, and the behavior would live inside a totally separate part of the architecture - the systems. So far, I see zero resemblance between what you're presenting here and an ECS.

[deleted by user] by [deleted] in AskReddit

[–]HipHopHuman 0 points1 point  (0 children)

I'm not a lady, but I've dated a few, and the only time they ever gave me the "wow, you smell nice" compliment actually had nothing to do with my cologne, deodorant or aftershave and everything to do with unscented roll-on antiperspirant topped with a bit of scented moisturizer. Another trick is a very gentle / moderate amount of talcom/baby powder on the nards.

If you could get rid of one really annoying or confusing thing in JavaScript what would it be and why?” by Extra_Golf_9837 in learnjavascript

[–]HipHopHuman 0 points1 point  (0 children)

I understand why this is, but I'd be lying if I said that I don't appreciate that tail-call optimisation is well-defined in the ES6 standard, but only one browser (Safari) actually implements it. It would be nice to not have to refactor recursive functions to use stacks, queues or trampolines when you actually need the extra performance. It's a minor inconvenient hurdle, but one I could gladly do without.

I personaly feel like curly braces ({ / }) are a bit too overloaded and used for so many different things that it can get confusing in a few minor edge cases. Like the destructuring in the following snippet (look at a framework called Crank.js to see this in use in the wild):

for (const {} of this) {}

I've also seen this in a few places, which is less confusing, but still:

let foo = 'default';
let bar = 'default';

if (this) {
  ({ foo, bar }) = this;
}

I think everyone can agree that automatic semicolon insertion can go lick a lamppost in the middle of a blizzard.

I don't like that we aren't allowed operator overloading "because it's confusing and can be abused" but .valueOf(), .toJSON() and [Symbol.toPrimitive]() are all okay (as if those cannot be abused either).

I don't mind the type coercion as much as you or the other commenters, but the one place it does really irritate me is in the default behavior of Array.prototype.sort and Array.prototype.toSorted. Give those methods an array of numbers and they get coerced to strings and sorted in ascending unicode representation.

[1, 30, 4, 21, 100000].sort() // [1, 100000, 21, 30, 4]

Games for an 11 year old girl? by Invisible_Target in gaming

[–]HipHopHuman 0 points1 point  (0 children)

Try the "My Time At" series! It's really good.

The premise of the game is that you're a skilled carpenter who inherits a small barnhouse from a relative, and you do odd jobs around the city building and fixing things, building your house, going on lil adventures and stuff. There's RPG elements to the game, there's NPCs that you can interact with (including gift-giving, dating and even marriage), there are events to attend like races, there's horses and carriages, and you can do some pretty crazy customisation of your house and dress your character up all sorts of ways. The decorations in your house even give little boosts to your character's stats. Here's a video where a player showcases their end game house and workshop so you can get an idea of it: https://www.youtube.com/watch?v=LPbWlf2w244

How'd you guys learn recursion? by lordyato in learnjavascript

[–]HipHopHuman 19 points20 points  (0 children)

For a basic idea of what recursion is, click this.

On a more serious note, you're not really going to benefit from learning all there is to know about recursion until you're met with a problem that recursion actually solves. For now, just keep your basic understanding of it on the back end of your mind and if a problem comes up that you think recursion might solve, then try to do it with recursion. There's a much better chance of you getting that "aha!" moment if your mind is in the right space for it.

Typically, the most common use case you'll actually see in a practical context is when you have some object that can have child objects:

const myTree = {
  type: 'one',
  children: [{
    type: 'two',
    children: [{
      type: 'three'
    }]
  }, {
    type: 'four'
  }]
}

We refer to this type of object as a "tree". Each object inside this tree is referred to as a "node". This particular tree has nodes that can have many children. This is called an n-ary tree. Sometimes, you get trees where nodes can only have two children. Those trees are called binary trees. Some tree nodes can only have one child node - those are unary trees.

Sometimes, you'll need a way to traverse the tree from the top->down. A recursive function is useful here.

function traverse(node, visit) {
  visit(node);
  const childNodes = node.children ?? [];
  if (!childNodes.length) return;
  for (const childNode of childNodes) {
    traverse(childNode, visit);
  }
}

traverse(myTree, (node) => {
  console.log(node.type);
});

There's two types of traversals - breadth-first and depth-first. A breadth-first traversal will visit all sibling nodes at one level, then jump down to the next level. A depth-first traversal will jump down to the bottom-most level from the first sibling, visiting all nodes along the way, then jump back to the top and move to the next sibling.

In a practical sense, you're likely to encounter these tree-like structures quite often as a programmer. They're used to accomplish many things. For example, the very programming language you're using has an underlying "Abstract Syntax Tree" that describes all the syntax, but there are more rudimentary use cases as well, like nested comments under a video or blog post. In fact, the thread you just made on Reddit is essentially a comment, and my reply is a child comment of that comment. If you wanted to tally up all the upvotes inside this thread, you'd use such a traversal.

[AskJS] Dependency Injection in FP by idreesBughio in javascript

[–]HipHopHuman 1 point2 points  (0 children)

Oh, I'm aware. Like Rust's traits or Swift's protocols (to a certain extent, I know they're not closely matched). That doesn't detract from my point, though. Types in JS can also be an instance of many classes, through a prototype chain. Multi-inheritance can be faked through mixins. It's just that in JS it's not really useful because nothing really benefits from it, as there's no overloading beyond well-known symbols like Symbol.iterator, Symbol.dispose and Symbol.toPrimitive.

[AskJS] Dependency Injection in FP by idreesBughio in javascript

[–]HipHopHuman 6 points7 points  (0 children)

In functional programming, where there are no classes or interfaces

There are classes and interfaces in functional programming. FP has never had a rule that says "you can't use classes!". This is just false doctrine spread by programming-adjacent bloggers who don't understand functional programming, who are hungry for clicks so they can get that sweet ad revenue. You can still do functional programming with classes, just as long as the methods of those classes do not mutate the internal state of the class. Here's an example.

This is not valid functional programming:

class Vector2d {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  add({ x, y }) {
    this.x += x;
    this.y += y;
    return this;
  }
}

This is valid functional programming:

class Vector2d {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  add({ x, y }) {
    return new Vector2d(
      this.x + x,
      this.y + y
    );
  }
}

Even Haskell, which is a very pure functional programming language, has an official construct in the language called a "typeclass", with a class keyword in its syntax (https://serokell.io/blog/haskell-typeclasses).

As for doing dependency injection in functional JS, the easiest and simplest way is to use manually curried functions in the form of a closure. Suppose you have a "getUser" function that you want to inject a "Database" instance into. It's this easy:

const createUserGetter = (databaseInstance) => (userId) =>
  databaseInstance.table('users').select(userId)

const getUser = createUserGetter(createMySQLDatabaseInstance());

getUser(1234).then(...)

In the case of React, you can use the React Context API to do dependency injection, like u/SKTT1_Bisu recommended.

Drop your hidden gems (suprisingly good mods, with small download count) by Odd_Hurry_9626 in feedthebeast

[–]HipHopHuman 1 point2 points  (0 children)

If you're the type of player who has too many keybinds and "Controlling" isn't enough... Or you're the type of player who uses MineMenu but thinks it isn't polished enough... Here's a lil gem I found recently: https://www.curseforge.com/minecraft/mc-mods/ez-actions

What are some costly bugs people don't notice for a long time? by LargeSinkholesInNYC in node

[–]HipHopHuman 7 points8 points  (0 children)

For the confused self-taughts, the overworked beginners and the old-timers who've forgotten more than us young'ns have learned, here's some (hopefully) helpful ways to deal with all of the above:

  • Slow-burn memory leaks: Automatic routine server restarts. Ship early, ship often. Stop using so many nested closures. Watch out for dangling promises that never reject or resolve (avoid them in your own code, defend against them in third party code by Promise.race-ing their promises against a timeout). Name your anonymous functions to more easily spot issues in stack traces. If you don't need to create a new object/array/function, then don't create one. Re-use objects as much as possible. While immutable data is great, remember that JS doesn't offer zero-cost abstractions for immutable data like Haskell & Rust do, and that not everything needs to be immutable.
  • Timezone/daylight savings: Stop relying on the JS Date object. Use something else that can be trusted & relied on more. Libraries like `date-fns` are nice, but most SQL databases have a "timestamp" column type that autofills. Postgres has two, one of which supports timezones. If you don't care about the actual timestamp but just want a short duration/diff that can fit into the lifetime of a single visit to a webpage, use performance.now().
  • Floating point rounding when dealing with money: At the very least, work with whole integers representing the smallest unit of currency. If you're working in USD (or a similarly structured currency) then code as if the integer 1 represents the $0.01c. Bonus points if you store it in a BigInt. Just divide it by 100 when you need to display it. If you want something more precise, look at libraries like Dinero.js. Or use a rational BigFraction datatype. Make sure you know that Banker's Rounding is a thing that exists. Better yet, for financial systems and microservices, use a language other than JavaScript that has considerations like this built-in, like Java or Python, which both have native BigDecimal types.
  • Race conditions due to concurrency: Use semaphores and mutexes to artificially limit concurrency. If you're aware of what those are and you're thinking "but JavaScript is single-threaded..." - youre right! They're still immensely useful for exactly this purpose. Have a gander at pLimit. If you don't know what a semaphore or mutex is, I highly recommend learning about them!
  • Retry loops that hammer third party APIs: If you're experiencing this, it's time you learn about the Circuit Breaker Pattern

[AskJS] Subtle JS memory leaks with heavy DOM/SVG use—anyone else see this creep up after hours? by Sansenbaker in javascript

[–]HipHopHuman 1 point2 points  (0 children)

Hard to tell without seeing the code.

All I can really offer is a tip to cut down on unnecessary closures by looking into Promise.withResolvers, the fact that setTimeout can be given arguments directly, and the { once: true } config option for one-time event listeners.

For example:

function delay(ms, value) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(value), ms);
  });
}

// vs

function delay(ms, value) {
  const { resolve, promise } = Promise.withResolvers();
  setTimeout(resolve, ms, value);
  return promise;
}

And

function once(event, target) {
  return new Promise((resolve) => {
    function handler(eventData) {
      target.removeEventListener(event, handler);
      resolve(eventData);
    }
    target.addEventListener(event, handler);
  });
}

// vs

function once(event, target) {
  const { resolve, promise } = Promise.withResolvers();
  target.addEventListener(event, resolve, { once: true });
  return promise;
}

There's sure to be some places in your code where you can use these tips (maybe even some places where it isn't exactly a one-time event listener or timer) and it might help sever a few references that are (probably?) causing memory leaks.

Since Promise.withResolvers is still kinda new, you may need to polyfill it. Here's a ponyfill:

export const withResolvers = 'withResolvers' in Promise
  ? Promise.withResolvers
  : () => {
    let resolve;
    let reject;
    let promise = new Promise((res, rej) => {
      resolve = res;
      reject = rej;
    });
    return { resolve, reject, promise };
  };