this post was submitted on 24 Sep 2023
210 points (93.0% liked)

Programmer Humor

31998 readers
705 users here now

Post funny things about programming here! (Or just rant about your favourite programming language.)

Rules:

founded 5 years ago
MODERATORS
all 40 comments
sorted by: hot top controversial new old
[–] emerald@lemmy.place 56 points 11 months ago (3 children)

If your code is that deeply nested, surely something has gone horribly wrong, yes?

[–] yogthos@lemmy.ml 12 points 11 months ago (1 children)

Problem is that Js kind of encourages this being single threaded and using callbacks for anything blocking. To be fair, the new async syntax sugar helps in modern Js, but nesting a bunch of callbacks or promises was basically the way you did stuff for the longest time.

[–] Tartas1995@discuss.tchncs.de 14 points 11 months ago (1 children)

Yes and no. Any programming language encourages nesting as in the end the computer does nest your code. So it is only normal and predictable that languages would reflect that. BUT! Nest logic can often be inverted and by doing so, reduce how much nesting you need to do.

If (data is not null) {
    If (data has field x) {
         Return data x
    } else return null
} else return null

Can be

If (data is null) return null
If (data hasn't field x) return null
Return data x
[–] yogthos@lemmy.ml -1 points 11 months ago (1 children)

I'm not arguing that avoiding deep nesting is a good idea, or that techniques foe doing that don't exist. I'm just pointing out that Js style programming naturally leads you to nesting things because of the nature of callbacks. Notice how your example isn't using callbacks.

[–] Tartas1995@discuss.tchncs.de 4 points 11 months ago (1 children)

Yeah and you can void nesting there just as easily and you have the same issues in any other programming language. You just need to create functions. Also JavaScript is not single threaded... you only have access to the dom on one thread, for obvious reasons.

Please explain to me how you do e.g. file downloads without a callback in your favorite language. If you solution involves having the main thread being stuck in a while loop, I am not sure if your complain about nested code can be taken seriously.

[–] h_a_r_u_k_i@programming.dev 10 points 11 months ago

Code aesthetic: If your code looks like a triangle, you're seriously doing something wrong.

[–] Blackmist@feddit.uk 5 points 11 months ago (1 children)

I prefer a bunch of

if (fucked_up) {return(error_code);}

for checking common errors.

[–] DWin@sh.itjust.works 2 points 11 months ago

Yup, never nest.

All the conditions should be checked and returned if they failed as you go through the function with the successful response being the last line.

[–] vettnerk@lemmy.ml 35 points 11 months ago (1 children)
[–] bdonvr@thelemmy.club 18 points 11 months ago (2 children)

Directly linking the file of an XKCD should be illegal

https://xkcd.com/297/

[–] lukas@lemmy.haigner.me 8 points 11 months ago

Linking to images should be illegal

[–] vettnerk@lemmy.ml 6 points 11 months ago* (last edited 11 months ago) (1 children)

I'll let Randall Munroe decide that himself, considering the fact that he provides URLs for hotlinking below the comics

[–] bdonvr@thelemmy.club 6 points 11 months ago (1 children)

I don't mean the act of embedding or direct linking in general, but in link aggregators these comics are well known for their alt text, which cannot be seen from the direct link.

I think a good practice might be embedding the comic directly in your comment along with a "source" link.

[–] cnx@slrpnk.net 2 points 11 months ago* (last edited 11 months ago) (1 children)

these comics are well known for their alt text

It's title text, or in web comic circles, hover text. The linked comic's alt is simply Lisp Cycles.

[–] thejevans@lemmy.ml 24 points 11 months ago (2 children)

I know it's not nearly as nested as this, but nesting in Rust annoys the hell out of me.

impl {
    fn {
        for {
            match {
                case => {
                }
            }
        }
    }
}

is something I've run into a few times

[–] darcy@sh.itjust.works 1 points 11 months ago

the loop or match statement could possibly be extracted to another function, depending on the situation. rustc will most likely inline it so its zero cost

[–] DWin@sh.itjust.works 1 points 11 months ago* (last edited 11 months ago) (1 children)

Just use this syntax

let myResultObject = getResult() 
let item = match myResultObject {
	Ok(item) => item, 
	Err(error) => {
		return;
	} 
};
[–] thejevans@lemmy.ml 2 points 11 months ago (1 children)

How does that change anything? Sorry if it wasn't clear, this was assuming a function call in the for loop that returns either a Result or enum.

[–] DWin@sh.itjust.works 1 points 11 months ago (1 children)

Oh sorry, I misread what you typed and went on a tangent and just idly typed that in.

One thing you could do for your situation if you're planning on iterating over some array or vector of items is to use the inbuilt iterators and the chaining syntax. It could look like this

let output_array = array.into_iter()
    .map(|single_item| {
        // match here if you want to handle exceptions
    })
    .collect();

The collect also only collects results that are Ok(()) leaving you to match errors specifically within the map.

This chaining syntax also allows you to write code that transverses downwards as you perform each operation, rather than transversing to the right via indentation.

It's not perfect and sometimes it's felt a bit confusing to know exactly what's happening at each stage, particularly if you're trying to debug with something mid way through a chain, but it's prettier than having say 10 levels of nesting due to iterators, matching results, matching options, ect.

[–] thejevans@lemmy.ml 1 points 11 months ago (1 children)

I definitely use that syntax whenever I can. One of the situations where I get stuck with the nested syntax that I shared is when the result of the function call in the for loop affects the inputs for that function call for the next item in the loop. Another is when I am using a heuristic to sort the iterator that I'm looping over such that most of the time I can break from the loop early, which is helpful if the function in the loop is heavy.

[–] DWin@sh.itjust.works 2 points 11 months ago* (last edited 11 months ago) (1 children)

It feels like maybe this could be a code structure issue, but within your example what about something like this?

fn main(){
    let mut counter = 0;
    let output_array = array.into_iter()
        .map(|single_item| {
            // breaks the map if the array when trying to access an item past 5
            if single_item > 5 {
                break;
            }
        })
        .collect()
        .map(|single_item| {
            // increment a variable outside of this scope that's mutable that can be changed by the previous run
            counter += 1;
            single_item.function(counter);
        })
        .collect();
}

Does that kinda syntax work for your workflow? Maybe it'll require you to either pollute a single map (or similar) with a bunch of checks that you can use to trigger a break though.

Most of the time I've been able to find ways to re-write them in this syntax, but I also think that rusts borrowing system although fantastic for confidence in your code makes refactoring an absolute nightmare so often it's too much of a hassle to rewrite my code with a better syntax.

[–] thejevans@lemmy.ml 2 points 11 months ago

Thanks for this! I'll see if I can work something like this in.

[–] wim@lemmy.sdf.org 12 points 11 months ago

Back when I was still in school, I ran a few tests on real world LISP and Java (the then dominant language, this was in the late days of Sun Microsystems succes).

Turns out most LISP programs had fewer parentheses then Java had braces, parens and brackets.

[–] TheBlue22@lemmy.blahaj.zone 7 points 11 months ago

If your code looks like this, you seriously need to reconsider your code

[–] HumanBehaviorByBjork@hexbear.net 6 points 11 months ago (3 children)

are there any JS fans who argue that it's elegant? i thought the supposed advantage was that it's flexible and universal.

[–] Tartas1995@discuss.tchncs.de 2 points 11 months ago

Well my Js isn't looking like that and it is really easy not too. But bad people write bad code.

[–] david@feddit.uk 2 points 11 months ago

Well, universal, anyway.

[–] yogthos@lemmy.ml -2 points 11 months ago

Weirdly, I've seen plenty of people who appear to genuinely like Js and Ts.

[–] YurkshireLad@lemmy.ca 2 points 11 months ago (1 children)

I learned Lisp at uni and hated it. Thankfully that was long enough ago that I’ve forgotten everything I learned about it.

[–] davel@lemmy.ml 29 points 11 months ago (1 children)

I’m sorry to hear you learned nothing.

[–] addie@feddit.uk 12 points 11 months ago (1 children)

Yeah - pure functions and immutable data aren't always the right answer, but appreciating that they're damn good most of the time is a good first step. Writing obvious code that does exactly what it appears to do at first glance and not one thing more? Your colleagues will thank you when they have to work with your stuff.

[–] davel@lemmy.ml 9 points 11 months ago

And metaprogramming and tail call optimization and and…. At least other languages are starting to catch up with this 60 year old language, by for instance implementing lambda expressions.