Hacker News new | past | comments | ask | show | jobs | submit | more jasonkillian's comments login

In case it wasn't immediately obvious, there's a Stage 2 tc39 proposal that was spawned from this blog post called Temporal:

https://github.com/tc39/proposal-temporal

At a glance, it does follow the same ideas as the great Joda Time library (now a part of the Java standard library), and there's currently a port of this library for JS which is quite nice:

https://github.com/js-joda/js-joda


For context, this was the most requested feature [0] in the isaacs repo of GitHub requests [1].

[0]: https://github.com/isaacs/github/issues/283

[1]: https://github.com/isaacs


Weirdly enough, both websites use this exact same quote: "This means you'll need to make an API (application programming interface). It's how all your friendly apps talk to each other."

Either plagiarism was involved, or there's some underlying library that's the same for both, or they both hired the same company to build their MVP ;)

HowMuchToMakeAnApp is by "Commite, a digital studio specialized in driving ideas from inception to launch" based out of "Seville, San Francisco & New York".

BuildMyMVP is made by "ProductDone a digital studio based in Auckland, New Zealand".

The two sites side by side: https://imgur.com/a/e7OVYVa


If you do a search on the second sentence: "It's how all your friendly apps talk to each other." You'll find at least 10 other cost calculator websites that all use that exact sentence to explain the term API. It also shows how flooded the web is with sites like this.


Nice find.


> Surely Node.js is going to be looked back upon as one of the worst mistakes in the history of 21st century programming.

Why is that? There were dynamically-typed backend languages long before Node.js became popular. And you now can easily have a TypeScript-based Node.js backend, which gives you the nice benefit of having the exact same language and types for both your backend and frontend. I'm not saying the Node runtime is perfect, but I don't understand why having a runtime that lets you use JS/TS as a backend or local language is quite such a bad thing.


I have absolutely no way to back this up, but my gut feeling is that the node ecosystem's tendency towards small modules, coupled with a lack of explicit interfaces in the language, increases the number of places where a developer is likely to introduce a type error.


It is a bad idea to intermingle the problems of dependency management with the concerns of a type system as though these are somehow related concepts. If you are not managing your dependencies sloppy things will follow regardless of the type system in place. There is an unrealistic expectation that JavaScript developers shouldn't have to write code because somebody has already written it for them in an NPM package.


I don't just mean external dependencies. The culture of "small modules" also means internal modules are vulnerable to this.

Edit to add: on further thought, I think it would be a mistake not to look at dependency management and type-safety at the same time. If my external dependency exposes a defined interface, that gives me more information about that dependency which I can use to manage it (replacing it, for instance) than without.


If I import a Nuget package into my C# code that changed a signature behind my back or even one that correctly versioned the package as “we have breaking changes”, I’ll know at compile time. With an NPM package I won’t know until runtime.


Do you have integration tests to ensure your applications do all the things it claims to do and that dependencies don't break those things? If dependency health isn't a part of your product testing bad things can happen.

Another thing to consider is that maybe you might not need a given dependency. Sometimes it is faster to include a bunch of dependencies at the beginning of a project just to produce something functional in the shortest time. As a product matures there is a lot of opportunity to clean up the code and slowly refactor the code to not need certain dependencies.


I’ve found just the opposite especially going into companies with less mature engineers and “architects” who’ve been at the company forever and haven’t had much outside experience. They both tend to reinvent the wheel badly and write code for cross cutting concerns that have already been solved better like custom authentication and custom logging.

Then again, I’m a big proponent of avoiding “undifferentiated heavy lifting” at every layer of the stack.


I think this comes down to reinventing the wheel. I frequently see less mature developers misuse that term to avoid writing code or making architectural decisions. That term isn't an excuse to off load your work onto someone else's reinvented wheel. The idea is to avoid unnecessary churn, whether that means you writing original code or using a dependency, and even still the concept is not always the best course of action.

As an example using a framework to avoid touching the DOM is an external reinvented wheel. As a leaky abstraction the need for that framework may dissolve over time as requirements evolve. That evolution of change can result in refactoring or a growth of complexity. Accounting for those changes means reinventing the same wheels whether or not the abstraction is in place. That is because a framework serves as an architecture in a box, but if you are later making architectural decisions anyways you have out grown at least some of the framework's value.


I’ve seen it before where “I don’t need a framework”. Then after the project grows, the “architect” ends up reinventing the same framework badly. I have no problem with opinionated frameworks especially with larger organizations. It also makes it easier to onboard developers. As a new dev on a team, I’d much rather come into a company that uses Serilog than used AcmeSpecialSnowflakeLogManager.


I have seen that as well. Many people will complain that if you don't use a framework you will end up writing one anyways, which is completely false. For many people who have never worked without frameworks writing original code means inventing a new framework, because that framework-like organization is how they define programming to themselves. This behavior is safely described as naive, or a lack of exposure to differentiating methodologies. This reminds me of that quote: when you're a hammer everything looks like a nail.

https://www.dictionary.com/browse/naive


So what is your definition of an agreed upon method that an organization uses to produce results....


Depends on the goals and constraints of the organization.


And what happens once you have 3 or 4 developers?


I think what you are ultimately getting at is: How do you ensure they write code the same way?. That isn’t a real problem and so it isn’t something you need to address. This comes up because insecurity is a very real concern.

Instead provide a business (not code) template to define requirements for integration. This should define what is needed in their documentation, what they output/return, their inputs, automation test requirements, and so forth. That list delicately does not include code style or any more of vanity. Most of this can be automated but you need code reviews to hold people to account and to use as a training opportunity. Be honest and critical during the code reviews. If people find respectful honesty offensive talk to them about it outside the group and if they still can’t get with it transfer them out of your team.


So you’re suggesting that one person decides that they like JQuery on the front end and one decides that they want to use plain Vanilla JS and one decides they like the look of Material UI, the other Bootstrap, and one happens to like sites that look like MySpace that’s ok?

And on the backend, if one developer liked log4net for logging, the other Serilog, and yet another developer likes to build his own logging framework that’s okay?

Let’s take this to a logical extreme, since one person is an old school VB developer and another likes F#, let’s just do that and throw in a little COBOL.Net for good measure....

And when a new dev comes in snsr takes forever to ramp up. No big deal. While we are at, let’s not follow the REST semantics either and no one needs those pesky frameworks like Express and ASP.Net. Let’s just go bare metal...

Or you could just have agreed upon standards....

If you’re going to have standards anyway, why not just use frameworks where you can open a req for the required framework that lets you get some developers who you can make sure already know the basics?

You’d be surprised at how many cheap developers you can get to throw together your yet another software as a service CRUD app using React.


> So you’re suggesting that one person decides that they like JQuery on the front end and one decides that they want to use plain Vanilla JS and one decides they like the look of Material UI, the other Bootstrap, and one happens to like sites that look like MySpace that’s ok?

The expectation is that developers are literate in their line of work, even though most companies don't hire like that. Since developers are expected to be literate don't waste time worrying about how to write code. If a developer suggests a tool that helps them on the "how to write the code" reject the tool.

Set business principles that specifically communicate the acceptable scope of work. Such principles can be something like this:

* code will execute within X milliseconds.

* code will allow up to X total dependencies (choose wisely).

* code will not exceed X bytes total size. If they want to include jQuery their code solution just increased 69kb.

The common failing is confusion around standards. Many developers find it easier if everybody just did everything the same way so that things appear standard. That approach ignores everything relevant to product quality and the goals of the business, which is stupid. It is stupid because it sacrifices simple for easy at the lowest level of leadership by lazy or weak managers. You don't get to offload management onto a framework and still hope to be a strong effective manager. Ultimately the success of a manager is tied to the work of that manager's team whether the team can retain/promote effective people.

When you set concrete and specific business limitations the limits are easily understood and based on objective criteria. Innovation and creativity are not stifled as developers are free to work within the constraints anyway they please.

This all makes sense once you accept that the group is worth more than the individual, but the product is worth more than the group. Sacrificing business goals for group cohesion is backwards just as sacrificing group integrity for an individuals option is backwards.

> You’d be surprised at how many cheap developers

That is also a common failure. Developers are never cheap unless you offshore. In hoping for cheap you will actually get developers that cost the same, do crappy work, don't value themselves, and that aren't valued by the organization. That is toxic. Instead hire people with potential to do great things and manage them effectively.


Dependencies should be tested, yes. But I enjoy this sentence in top comment: > "extensive" unit testing is a poor man's type checker

:)


Are you storing a large amount of offline music on an SD card? I've had that cause issues for me in the past. Their guide to fixing issues[0] is generally worth giving a shot.

[0]: https://community.spotify.com/t5/Android/COMPLETE-GUIDE-How-...


The difference is subtle (and took me a bit to figure out!). In the article's example component, the component's "main" function gets re-run on every render and a new `count` variable is created each time. The effect function is only run once at the very first render, and only captures the value from this first render.

I'm having a little trouble explaining the difference well, I think this jsfiddle illustrates the incorrect case the article is talking about representatively: https://jsfiddle.net/7fLnvz5c/


Thanks Jason, this was very helpful for me. I think I was having trouble making the mental jump from reading the code as a normal function with state vs how a component instance is called and handled by React at runtime--your example helped me make that hurdle.


Wow, I really don't know what to think of this article. I have to give Dan credit that every time I thought the code started looking really crazy, he'd say something like: "Admittedly, [this] code can be disorienting. It’s mind-bending to mix opposite paradigms." And I think it's a good sign he recognizes the fair objections people will bring up.

In addition to the paradigm-mixing the article illustrates, I wonder if the actual hook APIs make things more confusing than necessary at some points. For example, in the `useEffect` hook API:

* the first argument is a function that on every render

* the return value of the first argument is a "cleanup" function which runs when the component is unmounted or before the effect is run again

* the third argument is an array of parameters which controls when the effect is run. If passed an empty array, the effect is only run at mount and cleaned up at unmount.

All the above means that the API is very implicit and doesn't self-document its intent all that well. An example, from the article:

  useEffect(() => {
    function tick() {
      savedCallback.current();
    }

    let id = setInterval(tick, 1000);
    return () => clearInterval(id);
  }, []);
I'm sure with more use these hook patterns will become more familiar. But it's clearly a lot harder to learn and understand than the original simplicity that helped propel React to popularity.

Dan's arguments that hooks provide for easier abstraction and more composability is interesting to me though - if hooks are going to be "worth it" in the long run, I suspect this is why.


The pattern of returning an unregister function is a common one. But I agree that the cache key array is strange.

I'd almost suggest that a seperate useEffectOnce function would be better, but I'm sure the abstraction was heavily tested and bikeshedded before it was released in this form.


You could create userEffectOnce as a custom hook:

function useEffectOnce(callback) { useEffect(() => { return callback() }, []) }


Type guards are a useful construct, especially when dealing with data from an API that could come in a variety of shapes.

However, if you have control over the data shape, in general, it's nicer to take advantage of discriminated unions as you'll get more automatic typesafe compiler support. If you're not familiar with the construct in TypeScript, the docs give a nice example of them[0].

[0]: https://www.typescriptlang.org/docs/handbook/advanced-types....


Wrote this article because I was inspired by the amount of data the GitHub API gives easy access to and all the sorts of interesting info that can be gleaned from it.

It also raises some interesting questions on how to use this data effectively and responsibly as a tool for reflection on an engineering team's operating methods. I'd love to hear if other engineering teams have gleaned anything interesting about their own methodologies from GH data!


How well does Babel transpile TS? My initial instinct is that I'd trust the real TS compiler over Babel, but I've never tried compiling TS with Babel.

I assume the real TypeScript compiler still does the type-checking and that would be unaffected by Babel.


The TS team implemented the TS parsing support in Babel. You are correct that the TS compiler is still needed for the typechecker, however.


Ah, I didn't realize this, very cool collaboration! For those who are reading this and might find it helpful, here's a link to the official blog post on the work: https://blogs.msdn.microsoft.com/typescript/2018/08/27/types...


Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: