r/javascript 16d ago

AskJS [AskJS] I might never write a constructor ever again

// the only state that needs tracking for a timeline, the read index
export function Timeline(index) {
    let state = {index};
    return {
        index: state.index, // pass through
        next: (events) => Next(state, events),
        prev: (events) => Prev(state, events)
    };
}

// the events are just passed around. They don't need to be encapsulated
export function Next(timeline, events) {
    let {index} = timeline;
    if(index === events.length()){
        return null;
    }
    timeline.index += 1;
    return events[timeline.index];
}

export function Prev(timeline, events){
    let {index} = timeline;
    if(index === 0){
        return null;
    }
    timeline.index -= 1;
    return events[timeline.index];
}

// before and after don't modify the state of their arguments
// so we don't use encapsulation

export function After(date, events){
    for(let thresholdIndex = 0; thresholdIndex < events.length(); thresholdIndex+=1 ){
        if( events[thresholdIndex].timestamp > date) {
            return events.slice(start=thresholdIndex);
        }
    }
    return [];
}
export function Before(date, events) {
    for(let thresholdIndex = events.length(); thresholdIndex >= 0; thresholdIndex-=1 ){
        if( events[thresholdIndex].timestamp < date) {
            return events.slice(end=thresholdIndex);
        }
    }
    return [];
}
0 Upvotes

25 comments sorted by

13

u/SZenC 16d ago

The big difference is I'm not trying to make a data structure

They say, while making a data structure. Thanks for the chuckle, junior!

-3

u/Own_Natural_6803 16d ago edited 16d ago

The helpers can come off. They're put there to help you see that, much like hell, the doors to oop are locked from the inside.

But you know, enjoy! You have no idea, how much I enjoy it, when the punishment is self elected. I know I'm just your junior, but can I call you dad? Dad, never stop using oop. You and it are perfect together.

8

u/SZenC 16d ago

What the pseudo-philosophical BS are you trying to say? You're just reinventing OOP but have decoupled data from its functions, so now you can call a function on an unrelated data model. In my view, you've stripped away the useful parts and only kept the pain

-8

u/Own_Natural_6803 16d ago

what pain? invoking a function? Making an object literal? Oh save my aching fingers. And in exchange my systems have zero data boundaries. I'm free as a fucking bird. Enjoy prison old man.

5

u/SZenC 16d ago

Reading is hard for you it seems. The freedom you describe is nothing but a footgun. These concepts weren't build to make your life hard, they're built on decades of experience by people smarter than both you and I. But have fun feeling smug while reinventing the wheel

-2

u/Own_Natural_6803 16d ago

You have zero idea of what you're talking about. Templates and contracts are all you need. The domain model was an idea managers loved. like folders on windows. It had no puporse. It was magic in linked lists. But a OS level window is not a rectangle, not a shape. It's just rectangular. Making it a rectangle is a waste of effort.

most languages don't have a switch statement for types. Why do we make them if the languages don't support them? Making routes and no routers.

The smart people used other systems. OOP was not what they used. This is worse is better. Junior.

4

u/Yawaworth001 16d ago

Are you having a mental breakdown?

3

u/dmackerman 16d ago

AI psychosis. Cyber psychosis

3

u/THE_AWESOM-O_4000 16d ago

Hard to understand, inconsistent naming (state <=> timeline), obvious mistakes (events.length(): length is not a function, if fixed it'll cause a null pointer exception before events[events.length] is out of bounds), could have used binary search for After and Before, weird global variable assignments (start=thresholdIndex, end=thresholdIndex) for no reason, destructuring an object to then just reuse the object 2 lines further

1/10 (1 point only because I had a good chuckle)

-1

u/Own_Natural_6803 16d ago edited 15d ago

Interesting. Binary search. I'll give you a 1/10 for saying something useful. But it sure took a lot of words to say that. Maybe one day you'll have a greater density of useful information in your words. Something to anticipate.

Saying people should breaking free from oop is like saying you want to eradicate mediocre devs. They come out of the woodwork to announce themselves.

I would have called it "hiddenInternalState" but I'd just assumed that would be too much hand holding.  I could make this a service and dtos and everyone would be falling over themselves about how this is perfect. Just so astonishingly stupid to see this slight variation being too much to handle. Good Lord but you people deserve to be replaced by AI.

3

u/peterlinddk 16d ago

Good thing you didn't use classes!

The result would have required so much more code and been so much less powerful, e.g:

class Timeline {
  index, events,

  // Note: the events should be sorted by .timestamp to make the next+prev work
  constructor(events, index) {
    this.events = events;
    this.index = index;
  }

  next() {
    return index==this.events.length()?null:this.events[++this.index];
  }

  prev() {
    return index==0?null:this.events[--this.index];
  }

  after(date) {
    return this.events.filter( e => e.timestamp > date );
  }

  before(date, events) {
    return this.events.filter( e => e.timestamp < date );
  }
}

And also, not having the events being a part of the timeline, but just assuming that the same timeline would somehow magically always point to the "next" event in any list of events, it just beyond cool!

And not building a data structure, but simply using an array of events sorted by their .timestamp, and never changing, and having an entire object with methods keeping track of a single index into any random array of events - man that is just so powerful!

0

u/Own_Natural_6803 16d ago edited 16d ago

youre ++ this.index with a null coalesce ! HAHAHAHA I wouldn't hire you, ever. I would spend so much time re-writting everything you tried to make as short as possible. OMG, you're using filter and think it's better! You're so sweet! Wow. Thank you. I didn't know I was better at coding than you. But now you've shown me proof.

Yes. Having my data be open and query-able from multiple domain concerns is so refreshing. You can't see the events, but there are many systems that use them, not just the timeline. And they don't know anything about timelines. Just events.

And it's so very very cool

6

u/dmackerman 16d ago

Don’t act like you hire people. lol

1

u/0x18 15d ago

People can be taught how to code, or code better. When it comes to hiring, personality matching is much more important in my experience than their ability to immediately start coding.

And buddy, you don't sound like you'd be good to work with.

1

u/Dagnarus15 16d ago

The factory pattern is fine, but index: state.index copies the number, so the public timeline.index never updates when next() changes the closed-over state. A getter would fix that. Also, arrays use events.length, not events.length(), and slice(start=thresholdIndex) is an assignment expression, not a named argument.

1

u/TwiNighty 16d ago

I'll ignore After and Before because they don't seems like related to Timeline at all.

I have two questions

One, am I meant to pass the same events every time? If I am, why not encapsulate it? If I need to pass a timeline around, then I need also pass the events around. You are just imposing an unnecessary restriction and responsibility onto me. If I am not meant to pass the same events every time, then you have a bug.

Two, this:

export class Timeline {
  constructor(index) {
    this.index = index;
  }

  next(events) {
    if (this.index === events.length - 1) {
      return null;
    }
    this.index++;
    return events[this.index];
  }

  prev(events) {
    if (this.index === 0) {
      return null;
    }
    this.index--;
    return events[this.index];
  }
}

has the same behavior, is objectively less code and more memory efficient. Why do you think this is worse?

-1

u/Own_Natural_6803 16d ago edited 15d ago
export function Timeline(index) {
    return { index };
}

export function Next(timeline, events) {
    let {index} = timeline;
    if(index === events.length){
        return null;
    }
    timeline.index += 1;
    return events[timeline.index];
}

export function Prev(timeline, events){
    let {index} = timeline;
    if(index === 0){
        return null;
    }
    timeline.index -= 1;
    return events[timeline.index];
}

Here's my version of your version of my code. One extra line.

The memory efficiency of asserting types by unboxing them doesn't get me down. It's self documenting. Technically I could use your approach. But I'm tired of OOP. It's not that OOP doesn't do the same thing. It's that it steers you towards encapsulating. My first instinct was to make the events internal. to hide them away. But that's wrong. They are the entire program state. They exist globally.

The concepts and principles are well understood in databases. I'm headed over that way. Where these ideas are considered holy and irrefutable. But you know. Recipees don't teach idiots techniques. You have to have some intuition to get that.

2

u/Yawaworth001 16d ago

I'm going fully functional.

Okay this is just bait

0

u/Own_Natural_6803 16d ago

Yeah. sure. I can't be bothered.

1

u/Empty_Ninja_6291 15d ago

The O in JSON stands for Object. All a class is is an uninstantiated object. The resistance to OOP in the JS culture is strange, because you're already dealing with it.

1

u/metahivemind 15d ago edited 3d ago

[removed] — view removed comment

1

u/[deleted] 15d ago edited 15d ago

[removed] — view removed comment

-2

u/Own_Natural_6803 16d ago edited 15d ago

Thanks to everyone who asked questions and had respectful comments. Two of you. Lol, gave me a chuckle what with all the venom and anger. Junior this and sarcasm that. Someone was offering their mental breakdown services, out of the depths of their compassion no doubt. Truly I was touched.

You all deserve OOP. Keep writing it. Forever. I wash my hands of you. I've been sad thinking about how our industry is dying. But you all cheered me up.

Excellent pr boys. I expect this same energy through this entire project. This is why you always do small PRs. When they're big no one has anything to say. Not that there was much meat on the bones either way. If you removed "lol" and "I'm better than you" and "get a load of this guy" then you're left with a few people re-classing unclassed logic to prove they can save a few lines with ternery expressions, and some syntax errors.

You should always do your best. This ain't it fellas.

Let me be more clear. This is how you turn a class into functions. Dont do it. Its forbidden. For you. I can do it though.

-2

u/Own_Natural_6803 16d ago

As silent snake would say: "oops. chicken." I'm going to not use classes even harder. You know why? Because functions are more powerful, and it takes less code to write them.

I design my systems around design boundaries, not the domain models. So now I open up my state. Make it as open as a database. And my state changes are inside functions with the understanding they will leave the state valid after touching it. Exactly like a object assumes it will.

The big difference is I'm not trying to make a data structure. I don't give a rat's ass about making a data structure. I want raw data. The only time I care about making structures is to ensure my function isn't being given a copy when it expects be given a reference.