r/ProgrammerHumor 3d ago

Meme whenDoesThisWillEnd

Post image
758 Upvotes

68 comments sorted by

302

u/malsomnus 3d ago

That's the neat part, it doesn't!

173

u/FuerstAgus50 3d ago

It will end really quickly probably because most runtimes have a maximum recursion depth

82

u/LauraTFem 3d ago

Yea, computer will quickly say, “You’re pulling some bullshit.”

27

u/-Ambriae- 3d ago

Even without a runtime, you’ll pop the stack

3

u/MaybeADragon 3d ago

I can't remember the conditions to do so since I normally just compile to check, but could this be tail call recursion thus completely fine?

8

u/Qwertycube10 3d ago

This is not tail recursion. A tail call is a function call that is the last thing you need to do in your current function, so you don't need to keep around a stack frame with all your locals. Here it is not a tail call because you need to multiply the result by n after the function call finishes.

3

u/Tidemor 3d ago

could do tail recursion if you passed an accumulator, but at that point you have a overcomplicated for-loop

1

u/MaybeADragon 3d ago

Yeah I don't really use recursion often tbh. It doesn't (typically) get optimised by the compiler as well AND it is sometimes harder to read.

1

u/geek-49 2d ago

you’ll pop the stack

Actually, you'll keep pushing the stack until it overflows (unless, as someone pointed out, the compiler tests for the left-hand operand of * being zero and doesn't bother to compute the right-hand operand -- and in that case it will return zero which is the wrong answer).

2

u/AdamWayne04 2d ago

unless your compiler is really smart and optimizes that into tail-recursion!

0

u/atanasius 3d ago

It's stacks all the way down.

4

u/Any-Bobcat2370 3d ago

The function gets a stack overflow though. Sisyphus doesn't!

121

u/Axman6 3d ago

IF you have a lazy *, then this will end when n is zero, and return zero. 

83

u/torsten_dev 3d ago edited 3d ago

If you have a smart enough optimizing compiler it will compile to a constant 0.

28

u/-Redstoneboi- 3d ago

took me a moment to recognize "amaet" as "smart"

24

u/torsten_dev 3d ago edited 3d ago

Shhh, you saw nothing. I am very amaet.

5

u/Axman6 3d ago edited 3d ago

I am so smart

A. M. A. E. T.

  • Homer Simpson

6

u/Makefile_dot_in 3d ago

what if n is negative?

15

u/torsten_dev 3d ago

Inevitable UB, so might as well return 0 too?

1

u/da_Aresinger 2d ago edited 2d ago

(Edit: From the syntax I am assuming this is JS)

Actually since Number.MIN_SAFE_INTEGER - 1 === Number.MIN_SAFE_INTEGER it'll get stuck eternally looping/recursing on Number.MIN_SAFE_INTEGER while the output automatically gets converted to BigInt (I think).

JS ... a *= Number.MIN_SAFE_INTEGER -1.8768792072011717e+255 a *= Number.MIN_SAFE_INTEGER 1.6905424996341256e+271 a *= Number.MIN_SAFE_INTEGER -1.5227053142812468e+287 a < Number.MIN_VALUE true typeof a 'number'

This is what chrome console gave me.

1

u/chuch1234 3d ago edited 3d ago

The compiler never do that because it will recognize that the function could be passed a negative number.

My bad, i was /r/confidentlyincorrect

5

u/torsten_dev 3d ago edited 3d ago

Function can only halt with 0 or trap on underflow. Depends on if you have exceptions or not.

If you have tail-calls and the compiler isn't very smart you might have an infinite loop instead, yes.

1

u/Nightmoon26 3d ago

Although... If you're using a fixed-width integer without underflow checking, it'll still wrap around from its minimum value to its maximum, and then reach zero eventually, even if it has to go through all possible values to do so

8

u/Brilliant_Year9161 3d ago

Always those lazy Haskell developers /s

2

u/Axman6 3d ago

Lazy and proud 🫡 

2

u/AdamWayne04 2d ago

a lazy asterisk? you mean my anus?

0

u/chuch1234 3d ago edited 3d ago

Don't forget negatives.

Edit: just like my karma haha

4

u/Axman6 3d ago

If it’s a fixed size integer, it’ll eventually underflow and reach zero anyway (because stack overflows are for loser languages). 

If you have arbitrary sized integers like Haskell and Python, then it’ll never terminate, so the compiler is basically free to whatever it wants. 

1

u/Mateorabi 3d ago

I’ve heard of a lazy ass. Not a lazy asshole. 

45

u/apepenkov 3d ago

when stackOverflow is thrown

3

u/Axman6 3d ago

Only in pleb languages. 

(As written, Haskell would be a pleb language too, it won’t rewrite this to be tail recursive for you)

25

u/Daemontatox 3d ago

Wouldn't some compilers catch thats an infinite loop and give a warning or error?

39

u/JonIsPatented 3d ago

Some compilers can even note that it will multiply by 0 and optimize any call to it to just be the constant 0 instead.

3

u/chuch1234 3d ago

Unless you pass a negative number in.

13

u/ice456cream 3d ago

Until the int underflows and eventually gets back down to 0

2

u/qinshihuang_420 3d ago

Two zeros make a one

2

u/JonIsPatented 3d ago

Notably, if this function were actually typed, you'd use an integral type, and that type would have overflow and eventually reach 0 anyway.

1

u/chuch1234 3d ago

Does underflow typically wrap?

2

u/JonIsPatented 3d ago

Yup, and then it will keep going and eventually reach 0.

22

u/sonaliver28 3d ago

The base case is scheduled for the next sprint

4

u/Axman6 3d ago

Oh no, we can’t start the next sprint, the tests haven’t finished running 😰

6

u/laplongejr 3d ago

In some languages, it will stop with an infinite recursions. In others it would stop at "0 * factorial(-1)" and return 0 for all other cases as they call n0 at some point.  

3

u/-Redstoneboi- 3d ago

haskell? i don't know any language that knows to stop when multiplying by 0. imperative languages don't stop because there could be side effects when calling the factorial function, like a print statement, and optimizing out the call would result in different behavior

1

u/Axman6 3d ago

Haskell won’t do it unless you choose very specific types for n. The default Int and Integer types don’t lazily evaluate the second argument, but they could (adding an extra branch to every multiplication, which would generally be bad). 

If you used an inductive type

    data Nat = Z | S Nat

Multiplication would naturally be written as

Z     * _ = Z
(S Z) * n = n
(S m) * n = n + m * n

Which would always terminate (and also disallow negative numbers). 

0

u/chuch1234 3d ago

This doesn't guarantee zero -- it can be passed a negative number.

7

u/Jejerm 3d ago

Yes, they will eventually underflow and reach zero too

5

u/[deleted] 3d ago

[deleted]

5

u/Striking_Director_64 3d ago

Yes, why stop at saturating CPU, when we can saturate memory as well.

4

u/JosebaZilarte 3d ago

This is another reminder that you can turn (almost) every recursive solution into an iterative one:

while (n > 1) { result *= n--; console.log("Ends in: " +n);  }

4

u/un_blob 3d ago

Akerman function : someone called me ?

3

u/splettnet 3d ago

A bit before 18446744073709551615 I imagine

2

u/lonkamikaze 3d ago

This way it at least crashes. Imagine the code used a proper tail call, it would never run out of stack!

2

u/JebKermansBooster 3d ago

I'd like to see a language that allows factorials to continue for negative integers via the [gamma function](https://en.wikipedia.org/wiki/Gamma_function)

2

u/WayWayTooMuch 3d ago

Stack overflow

1

u/Substantial_Top5312 3d ago

when your computer crashes

1

u/ThatSmartIdiot 3d ago

does this language support while loops

4

u/pi_three 3d ago

Factorial is the classic example for recursion

1

u/sohcahtoa 3d ago

On the left: afrer n iteration.

On the right: never.

1

u/SupraMichou 3d ago

Bro forgot to call the guards

1

u/GoddammitDontShootMe 3d ago

Someone forgot to handle the case of n=0.

1

u/Disastrous_List_6723 3d ago

Never even after it becomes 0

1

u/SkollFenrirson 3d ago

When does this will end indeed

1

u/Flat_Initial_1823 3d ago

One must imagine recursion happy

1

u/antpalmerpalmink 3d ago

The humble scott domain showing that the function is bottom:

1

u/a-r-c 2d ago

we have to imagine Sisyphus jacked and tan

1

u/chuch1234 3d ago

ITT: i am confidently wrong several times haha

1

u/NimrodvanHall 3d ago

Depends on the type of n. Is it a signed or unsigned integer?

0

u/Bomaruto 3d ago

I took me way too long to notice it was missing the base condition as I just assumed it was there.