Live data from Hacker News

'Do' More with 'Run'

maxgreenwald.me

21–30 of 33 posts

Re: 'Do' More with 'Run'

#21
I appreciate the sentiment, but i do not agree with the solution.

The actual solution is to extract a function. What is the legitimate excuse for not extracting a function (other than being lazy, which i will not accept as an argument)

Edit: Just to enhance my comment, having a separate function with a distinct name enhances readability and maintainability. Readability is enhanced because a clear name lets the reader understand what is happening in the function (this attribute is lost with self calling nameless functions). Also, less lines need to be read to understand the wider context. Maintainability is enhanced because 1) more readable code is easier to reason about and change and 2) extracting a function means it can be reused

Re: 'Do' More with 'Run'

#22
post #21

I appreciate the sentiment, but i do not agree with the solution. The actual solution is to extract a function. What is the legitimate excuse for not extracting a function (other than being lazy, which i will not accept as an argument) Edit: Just to enhance my comment, having a separate function with a distinct name enhances readability and maintainability. Readability is enhanced because a clear name lets the reader…

Extracting to a function means you need to give it a name. There is a middleground where you might want a function for control-flow purposes, but giving it a name makes the code look more complicated than it needs to be. Personally I just use an IIFE in those situations - and I don't see much benefit from run() as compared to an IIFE.

Re: 'Do' More with 'Run'

#23
post #21

I appreciate the sentiment, but i do not agree with the solution. The actual solution is to extract a function. What is the legitimate excuse for not extracting a function (other than being lazy, which i will not accept as an argument) Edit: Just to enhance my comment, having a separate function with a distinct name enhances readability and maintainability. Readability is enhanced because a clear name lets the reader…

Try using `run` in the return of a React (or similar) component and you'll never go back ;)

There is always a balance here. I'm not saying to never extract a named function, and there is certainly good reason to do that, especially if the function is called elsewhere or is quite complex.

But, in many cases, the inline logic is more readable because it's right there, and the function really doesn't need a name.

Re: 'Do' More with 'Run'

#24
post #23
post #21

I appreciate the sentiment, but i do not agree with the solution. The actual solution is to extract a function. What is the legitimate excuse for not extracting a function (other than being lazy, which i will not accept as an argument) Edit: Just to enhance my comment, having a separate function with a distinct name enhances readability and maintainability. Readability is enhanced because a clear name lets the reader…

Try using `run` in the return of a React (or similar) component and you'll never go back ;) There is always a balance here. I'm not saying to never extract a named function, and there is certainly good reason to do that, especially if the function is called elsewhere or is quite complex. But, in many cases, the inline logic is more readable because it's right there , and the function really doesn't need a name.

I will once more agree with the reasoning on the high level, but:

From my experience working in big react+ts codebases devs are nesting components and logic way to much, resulting in unmaintainable messes that neeed hours to refactor. This kind of utility enhances this mental model of nesting stuff instead of extracting. I am not suggesting the run utility will break the world, and maybe there are quite a lot legit usecases. But it is the equivalent (exaggerating a bit here) of giving every untrained person a bazooka. They're lack of proper use will cause caos

Re: 'Do' More with 'Run'

#25
post #21

I appreciate the sentiment, but i do not agree with the solution. The actual solution is to extract a function. What is the legitimate excuse for not extracting a function (other than being lazy, which i will not accept as an argument) Edit: Just to enhance my comment, having a separate function with a distinct name enhances readability and maintainability. Readability is enhanced because a clear name lets the reader…

Extracting to a function means you need to give it a name. There is a middleground where you might want a function for control-flow purposes, but giving it a name makes the code look more complicated than it needs to be. Personally I just use an IIFE in those situations - and I don't see much benefit from run() as compared to an IIFE.

I do not see anything wrong with what you are describing, but in my experience, going into that excercise of extracting a function and giving it a name is an insightfull process. It gives you time to reason about what you are building instead of going full coding-monkey mode. Instead, you pause a bit and reflect. To this day I have never regreted doing that.

Re: 'Do' More with 'Run'

#26
post #16
post #6

Earlier quoted context omitted.

And a step further into the past, no need for a lambda - I find this clearer: function doWork() { function calcX() { if (foo()) return f(); if (bar()) return g(); return h(); } return calcX() * 10; } Where "calc" can be "gen[erate]" or "find" or at least more descriptive.

Well you definitely can do that to my somewhat contrived example that is loosely based off of an example from the `do` expression proposal, but I'm not sure its better. Part of the beauty of `run` is that you don't have to declare and name a function `calcX`. In longer and more complex examples, declaring a function inline like this is potentially confusing because you don't get to see where it is used, whereas with…

But then there's mental overhead figuring out / remembering what the function does every time you go through the parent function. Once you have it in your head, may as well just label it so you don't have to do that every time.

> In longer and more complex examples, declaring a function inline like this is potentially confusing because you don't get to see where it is used

It only exists in the scope of the parent function, the only place it can be used is right next to where is declared. Unless you're in the habit of making functions hundreds of lines long, I guess...

Re: 'Do' More with 'Run'

#27
post #21

I appreciate the sentiment, but i do not agree with the solution. The actual solution is to extract a function. What is the legitimate excuse for not extracting a function (other than being lazy, which i will not accept as an argument) Edit: Just to enhance my comment, having a separate function with a distinct name enhances readability and maintainability. Readability is enhanced because a clear name lets the reader…

Extracting to a function means you need to give it a name. There is a middleground where you might want a function for control-flow purposes, but giving it a name makes the code look more complicated than it needs to be. Personally I just use an IIFE in those situations - and I don't see much benefit from run() as compared to an IIFE.

It already has a name, even in the contrived example OP named it "x".

The extracted function can simply be getX() or calcX() or generateX() - which verb chosen can tell the reader roughly the origin/complexity of X without having to read the function body: Does it already exist or are we creating it here? If we're creating it, is it internal or is it likely to require other resources like an API call?

In a more concrete example I'm sure it can get a better name than that, too.

Re: 'Do' More with 'Run'

#28
post #27

Earlier quoted context omitted.

Extracting to a function means you need to give it a name. There is a middleground where you might want a function for control-flow purposes, but giving it a name makes the code look more complicated than it needs to be. Personally I just use an IIFE in those situations - and I don't see much benefit from run() as compared to an IIFE.

It already has a name, even in the contrived example OP named it "x". The extracted function can simply be getX() or calcX() or generateX() - which verb chosen can tell the reader roughly the origin/complexity of X without having to read the function body: Does it already exist or are we creating it here? If we're creating it, is it internal or is it likely to require other resources like an API call? In a more concr…

That's true when you're assigning the result of the function to a variable, but what about the use case where you're replacing a ternary within JSX code? You could extract the evaluation to an assignment of a variable outside of the JSX, but that's the kind of unnecessary complexity that IMO is sometimes worth avoiding.

Re: 'Do' More with 'Run'

#29

Feels like code golf. The two run examples are basically the same, but now I have to reason about what ‘run’ is and I’ve made my stack trace more complicated. I am in love with “everything is an expression” from my time with Rust. I regularly use a ‘let’ and wish I could just have the entire conditional feed into a ‘const’ given it’s never going to change after the block of code responsible for assignment. I wish the…

What some people call "code golf," others call "syntactic sugar." :-)

Re: 'Do' More with 'Run'

#30
post #11
post #7

Parentheses phobia strikes again. This is 1 character longer than an IIFE (since you replace "()" with "run"

i'd say that it's a bit more readable: run(() => { return foo }) looks better than, and assuming pre-existing knowledge of what `run` does, is more understandable than (() => { return foo })() but this is also a fairly contrived example

I agree that `run()` is more readable than an IIFE if you remove all context and history from the analysis. But the IIFE is a well-known idiom to JavaScript programmers, so readers will not have to pay a cognitive "what is `run()` do?" penalty in order to understand the code.

New abstractions have a cost, and "clever" abstractions tend to confuse the average developer more than the benefit they provide.

If there's a problem with an IIFE (yes, they can be abused), the usual approach is to replace it with a named function definition. This works in their React example as well--rather than (necessarily) creating a new component as they suggest, the standard approach is to add a named rendering helper in the function closure that returns JSX.

Post reply on HN