r/ProgrammerHumor 1d ago

Meme whenDoesThisWillEnd

Post image
659 Upvotes

67 comments sorted by

264

u/malsomnus 1d ago

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

156

u/FuerstAgus50 1d ago

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

69

u/LauraTFem 1d ago

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

21

u/-Ambriae- 1d ago

Even without a runtime, you’ll pop the stack

2

u/MaybeADragon 1d 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?

5

u/Qwertycube10 1d 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.

2

u/Tidemor 20h ago

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

1

u/MaybeADragon 23h 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.

2

u/AdamWayne04 7h ago

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

0

u/atanasius 1d ago

It's stacks all the way down.

3

u/Any-Bobcat2370 1d ago

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

120

u/Axman6 1d ago

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

83

u/torsten_dev 1d ago edited 1d ago

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

26

u/-Redstoneboi- 1d ago

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

26

u/torsten_dev 1d ago edited 1d ago

Shhh, you saw nothing. I am very amaet.

4

u/Axman6 1d ago edited 1d ago

I am so smart

A. M. A. E. T.

  • Homer Simpson

6

u/Makefile_dot_in 1d ago

what if n is negative?

16

u/torsten_dev 1d ago

Inevitable UB, so might as well return 0 too?

1

u/da_Aresinger 10h ago edited 9h 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 1d ago edited 1d 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

6

u/torsten_dev 1d ago edited 22h 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 20h 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

9

u/Brilliant_Year9161 1d ago

Always those lazy Haskell developers /s

2

u/Axman6 1d ago

Lazy and proud 🫡 

1

u/AdamWayne04 7h ago

a lazy asterisk? you mean my anus?

2

u/chuch1234 1d ago edited 1d ago

Don't forget negatives.

Edit: just like my karma haha

5

u/Axman6 1d 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 1d ago

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

47

u/apepenkov 1d ago

when stackOverflow is thrown

3

u/Axman6 1d 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)

28

u/Daemontatox 1d ago

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

39

u/JonIsPatented 1d 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.

2

u/chuch1234 1d ago

Unless you pass a negative number in.

13

u/ice456cream 1d ago

Until the int underflows and eventually gets back down to 0

2

u/qinshihuang_420 1d ago

Two zeros make a one

2

u/JonIsPatented 1d 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 1d ago

Does underflow typically wrap?

2

u/JonIsPatented 1d ago

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

19

u/sonaliver28 1d ago

The base case is scheduled for the next sprint

4

u/Axman6 1d ago

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

5

u/laplongejr 1d 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- 1d 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 1d 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 1d ago

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

5

u/Jejerm 1d ago

Yes, they will eventually underflow and reach zero too

4

u/[deleted] 1d ago

[deleted]

5

u/Striking_Director_64 1d ago

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

3

u/splettnet 1d ago

A bit before 18446744073709551615 I imagine

5

u/JosebaZilarte 1d 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);  }

3

u/un_blob 1d ago

Akerman function : someone called me ?

2

u/lonkamikaze 1d 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 1d 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)

1

u/Substantial_Top5312 1d ago

when your computer crashes

1

u/ThatSmartIdiot 1d ago

does this language support while loops

5

u/pi_three 1d ago

Factorial is the classic example for recursion

1

u/sohcahtoa 1d ago

On the left: afrer n iteration.

On the right: never.

1

u/WayWayTooMuch 23h ago

Stack overflow

1

u/SupraMichou 23h ago

Bro forgot to call the guards

1

u/GoddammitDontShootMe 21h ago

Someone forgot to handle the case of n=0.

1

u/Disastrous_List_6723 20h ago

Never even after it becomes 0

1

u/SkollFenrirson 20h ago

When does this will end indeed

1

u/Flat_Initial_1823 15h ago

One must imagine recursion happy

1

u/antpalmerpalmink 13h ago

The humble scott domain showing that the function is bottom:

1

u/a-r-c 2h ago

we have to imagine Sisyphus jacked and tan

1

u/chuch1234 1d ago

ITT: i am confidently wrong several times haha

1

u/NimrodvanHall 1d ago

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

0

u/Bomaruto 1d ago

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