# Shortest auto-destructive loop [closed]

Your task is to write a full program or function that takes no input and runs any type of loop (while, for, foreach, do, do-while, do-loop, goto, recursion, etc) that will end in causing an error, which means that the program must stop itself running and exit.

Rules:

1. The error must be a run-time error, unhandled exception, or anything that makes the program end itself.
2. The error must produce the stop and exit from the program without calling explicitly exit; (or equivalent) at some point.
3. Messages like Warning:, Notice:, etc, that do not cause the program to end itself are not valid. For example in PHP divisions by zero produces a Warning message but the program will not stop and will still run, this is not a valid answer.
4. The loop must run at least one full cycle. In other words the error can happen starting at the second cycle and further. This is to avoid to cause the error using incorrect code syntax: the code must be syntactically correct.
5. The loop can be even infinite (example for(;;);) if it respects the above said rules, but must take no longer than 2 minutes to end itself in a run-time error.
6. Recursion without Tail Call Optimization is invalid (1,2).
7. This is so the shortest code wins.
8. Standard loopholes are forbidden.

C# example (test online):

using System;
public class Program {
public static void Main() {
int i;
int[] n;
n = new int[5];
for(i=0; i<7; i++) {
n[i] = i;
Console.WriteLine(n[i]);
}
}
}

Output:

0
1
2
3
4
Run-time exception (line 9): Index was outside the bounds of the array.

Stack Trace:

[System.IndexOutOfRangeException: Index was outside the bounds of the array.]
at Program.Main(): line 9


var QUESTION_ID=104323,OVERRIDE_USER=59718;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important;font-family:Arial,Helvetica; font-size:12px}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

Thanks to Martin Ender for the Leaderboard Snippet

• Just to be clear, recursion without TCO can be used as long as the error does not have to do with too much recursion, correct? (For example, a recursive function that errors on the second recursion) Dec 23, 2016 at 22:06
• @ETHproductions It was suggested by Dennis in chat: "It might be difficult to decide if a full cycle has completed in this case [of recursion]. Tail recursion kinda fits the bill, but only TCO does actually complete a cycle if execution is aborted by an error. [...] I'd say recursion without TCO is invalid." Dec 23, 2016 at 22:13
• @Hedi Here's my humble opinion (not the OP): All entries must complete one full cycle, meaning they must enter a second cycle; this means that at least one statement is run a second time. Since the order of execution in your example is a, b, d, c, b, d, c, ..., b is the start of the cycle, and must be run at least a second time. Dec 24, 2016 at 1:20
• I don't want to start any trouble but since the program (of function for that matter) is not supposed to be taking any input, all recursive solutions that have a parameter are invalid because a parameter is input. Dec 25, 2016 at 11:43
• Voting to close because the requirements for what counts as a loop and what counts as what part of the loop are unobservable. This could sort of go either way, but I think it's vague enough that it could (and from what I've seen, has) cause disagreement about the correct interpretation. Jun 16, 2021 at 3:22

# Commodore BASIC (C64Mini, C64, VIC-20, C128 etc..) 3227 25 tonekized BASIC bytes

0FORI=9TO0STEP-1:PRINTI/I*I:NEXT


As it counts down, it will produce a ?DIVISION BY ZERO ERROR IN 0 error before it hits 0 as is intended (old 32 byte solution shown in associated image).

### CBM BASIC (Direct mode) 9 bytes used on stack, 31 PETSCII characters

FORI=9TO0STEP-1:PRINTI/I*I:NEXT


It's a bit difficult to determine the amount of memory used in direct mode as no program is stored so that saves on those BASIC tonkenized bytes, also it executes by calling via the Kernal so that's ROM not RAM; the BASIC screen is default to 1000 bytes and direct mode outputs 1 8-bit character per line + white space + carriage return. When I request the free bytes, it tells me that I've used 9 so I'll go with that (I think that includes some memory pointers as well).

# x86 Machine Code, 3 bytes

Same size on both 64 or 32 bit. 2 instructions.

a:pushf
jmp a


In 64-bit or 32-bit:

Dump of assembler code for function a:
0x0000000000001000 <+0>: 9c  pushfq
0x0000000000001001 <+1>: eb fd   jmp    0x1000 <a>
End of assembler dump.


Same machine code. Obviously, the 32-bit version won't have the extra 0's in front of the address or the q suffix.

It just runs out of stack space.

# Mornington Crescent, 238 215 bytes

Take Northern Line to Bank
Take Circle Line to Temple
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take District Line to Mile End
Take District Line to Bank
Take Northern Line to Angel


Executing the final line of the program jumps the program back to the second line, thus constituting the only way to loop in Mornington Crescent. After a few swaps of the accumulator and various stations, in the second iteration of the loop, the program attempts to find the last -1 characters of the empty string "". Since -1 is clearly out of range, a runtime error is thrown.

There are other runtime errors that could beget a shorter solution, such as not ending at Mornington Crescent, but I decided those were too trivial to really count.

EDIT: Fiddling around with the order yields a slightly shorter solution.

Try it online!

– null
Jul 28, 2020 at 13:14
• @HighlyRadioactive Wouldn't say that -- the cat program is only one line ;) Aug 4, 2020 at 19:29
• Ah right, forgot that one. It's still suspiciously short compared to the Hello, World! one and a lot of others.
– null
Aug 5, 2020 at 5:02

# Rust, 25 bytes

||for i in 0..{&""[i..];}


Try it online

This tries to slice the empty string "" by the current loop index. The first iteration is successful, but the second panics because the string is empty.

# 1+, 7 bytes

1(|:())


1+ answer delivery service, sign here.

## Explaination

1 pushes 1 onto the stack. The rest of the program (which looked like a fancy emoticon) defines a recursive function with an empty name that repeatedly pop and output the stack top, so you'll pop an empty stack the second time, which is invalid. 1+ functions are executed while defined.

## Ruby, 17 bytes

2.times{|i|i/~-i}


# Python 3, 35 Bytes

x=lambda a:1/0if a<1 else x(0);x(2)


I am not totally sure, but I think this works like you'd expect. Does that count as an true answer?

# Factor, 19 bytes

1 iota [ 0 / ] each


Fails with 0 division error after 1 run.

## awk 18 bytes

{while(++i/i)i-=2}


or using for:

{for(;++i/i;)i-=2}


Test it (added print for iteration proof):

$awk '{while(++i/i){print i; i-=2}}' /dev/urandom 1 awk: cmd. line:1: (FILENAME=/dev/urandom FNR=1) fatal: division by zero attempted  ## Go, 28 bytes func f(){i:=1;for{i/=i;i--}}  Simple divide by zero • You did yourself a nice go-around the rules, pretty impressed. Dec 25, 2016 at 22:37 # Turtlèd, 6 bytes runs one cycle before crashing. however it produces no output, because the interpreter does the crash before it prints the grid. [|(*r]  Tryitonline can show you the error in debug, but won't really show you whether it runs the loop one cycle and a half, but if you want, you could download the interpreter, modify command ] to print howdy or something, and see that it prints howdy prior to crashing. yes, the parentheses is usually in pairs for ifs. looks like a syntax error, but my language checks no syntax ## How it works: So this is a turtle based language, moving around on an infinite grid of cells with chars in Firstly, there is the infinite loop [| ]  this loop runs while the cell does not have a |. There is no way that a cell will contain a |, since no code in this writes it or user input down, so this would run forever (except error) The code inside: (*r  the (* would usually starts an if block. essentially, if the current cell is a *, do nothing and continue running, otherwise skip ahead to the matching ), and the r just makes the pointer move right. on the first cycle, the turtle starts in the centre cell, which unlike other cells, begins as an *. here are the steps of execution from there • the infinite loop starts running. • checks the current cell to see if it is an asterisk, sees it is • moves right, off the asterisk cell • loops back to the start of loop • checks if cell is an asterisk. it is a space, so it tries to skip ahead • interpreter throws IndexError, because it tried to look past the end of the loop for the closing ) # Valve Scripting Language, 21 bytes alias a "alias a b;a"  This creates a function that will recurse when called. You can call the function just by typing 'a' into the console. Since this challenge wants an error to be thrown, b is sufficient. This will just error with undefined function. However, you can also replace b with quit to fully quit the application. Explanation for those who don't immediately understand: it re-aliases the function to something that doesn't exist. # Bash, 21 bytes alias a="alias a=c;a"  Same logic as my VSL answer, posted for completeness. # Mathematica, 22 19 bytes 3 bytes saved due to Martin Ender. #>0&&Throw@#&/@{0,}  Uses Throw@# to throw an exception when looping over the second element. I can't think of anything else that would cause the program to immediately stop. # bash (No recursion), 20 bytes for((;;)){ x=x$x$x;}  This one crashes on my machine in just over a minute, due to running out of memory. If you get rid of the 2-minute rule, presumably for((;;)){ x=x$x;}


(18 bytes) will eventually crash due to running out of memory, but it will take a long time.

I had originally posted a recursive solution in 10 bytes:

f()(f;:);f


This 10-byte program crashes on my MacBook in about half a second with a "fork: Resource temporarily unavailable" error. There's no tail-recursion to optimize away, since the last thing done in each call is the ":" command, not the recursive subcall.

But @Dennis pointed out that this doesn't satisfy Rule 4 (the program must complete one full cycle), since none of the recursive calls actually get a chance to complete before the program crashes.

I think this same problem invalidates other recursive programs that have been posted as answers.

By the way, if you allow tail recursion, you can do it in 8 bytes:

f()(f);f


[This version doesn't satisfy the tail-call-optimization requirement, and it's arguable whether it satisfies the one-complete-cycle rule. The function calls (except for the last) execute all of the code in their body, but they don't ever return. So if "one complete cycle" means one complete body, not including the return at the end, it's OK for Rule 4. If "one complete cycle" is taken to include the return at the end, then Rule 4 is not satisfied.]

• I think you missed the point regarding tail recursion. Tail call optimization is mandatory in this challenge if you use any kind of recursion. This is because rule 4 dictates that the iteration has to complete at least one cycle. In both of your recursive solutions, the outmost function never finishes because the function it calls never returns. Dec 24, 2016 at 21:56
• @Dennis You may be right, but I think it's a bit unclear. The tail-call-optimization rule (Rule #6) is separate from the one-full-cycle rule (Rule #4). Rule #6 is followed: there is no tail recursion, so tail-call-optimization isn't a question. Rule #4 may be an issue though. It's true that no recursive subcall gets a chance to return. But it's not clear that that's the right way to count loop iterations in a recursive program. OP allowed recursive programs; how did he intend for a recursive program to qualify? (OP's stated reason for Rule #4 is just to avoid errors due to incorrect syntax.) Dec 25, 2016 at 3:41
• @Dennis I'll be rewriting my answer to take the issues into account -- thanks for the input. Dec 25, 2016 at 3:49

# Ruby, 11 bytes

loop{$.*=2}  $. needs to be a long, so it will throw after a couple cycles.

# DUP, 10 bytes (8 chars)

Conor O'Brien already wrote the shortest possible solution in FALSE which is also a valid DUP program. DUP is a direct descendant of FALSE and FALSE is almost a complete subset of DUP, with a few exceptions. I won’t just simply rip off his solution but add a slightly bigger (in bytes, not chars) but specific DUP solution just for the fun of it:

1[.A]⇒AA


In contrast to FALSE, DUP can define/redefine operators with the (3 UTF-8 byte) ⇒ operator. Operator names are not bound to the lowercase ASCII range of variables but can use the whole Unicode range of characters.

This solution is a recursive operator call that throws an error after the first recursive call of itself:

1[.A]⇒AA     data   return
stack  stack

1                            push 1 on data stack
[           1               push [ location on data stack, move behind matching ]
⇒A       1,1            pop data stack, assign value (function location) to function A
A      1              call function A, push current ip location on return stack,
move ip 1 behind stored address in A (1)
.           1      7       pop data stack, print value to STDOUT
A                         call function A, move ip 1 behind stored address
.                          pop data stack... throws error because the data stack is empty.


Try it out in the online DUP interpreter on quirkster.com or clone my DUP interpreter repository on GitHub (written in Julia).

# Julia, 19 bytes

for i=1:2 "a"[i]end


The first loop accesses string "a" at index [1], which is char 'a', the second loop tries to access string "a" at index [2] and throws a BoundsError:

julia> for i=1:2 "a"[i]end
ERROR: BoundsError: attempt to access 1-element Array{UInt8,1} at index [2]
in next at .\strings\string.jl:88 [inlined]
in getindex(::String, ::Int64) at .\strings\basic.jl:70
in macro expansion; at .\REPL[40]:1 [inlined]
in anonymous at .\<missing>:?


# Kotlin, 19 bytes

{for(x in-1..0)1/x}


A simple lambda expression that does one iteration of the for loop and then throws with a division by zero exception.

## Euphoria - 53 bytes

atom i
i=1
while 1 do
puts(i,i)
i-=1
end while


Did it in a different way so we dont get full of "division by 0" errors.

Explanation:

"puts" first argument is the device to output argument two. There are three pre-defined devices:

0 is STDIN, 1 is STDOUT, and 2 is STDERR

After decreasing i (with i-=1) once, on the second cycle we will get

Wrong file mode for attempted operation

which is the exception/error.

# Swift, 22 bytes

for i in 0...1{[0][i]}


Pretty self-explanatory, crashes with sigill on second iteration. You can do the exact same thing in Python with 2 less bytes, but I really wanted to do a Swift submission.

Try it online!

## Clojure, 21 bytes

Quite odd challenge, I hope I understood this correctly. On first iteration i is the + function which can be called with zero arguments and it returns zero, on second iteration (0) is evaluated and you get ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn.

(loop[i +](recur(i)))


Confirmation that loop is executed twice:

(loop[i +](do(print{:i i})(recur(i))))
{:i #object[clojure.core$_PLUS_ 0x7e72f43f clojure.core$_PLUS_@7e72f43f]}
{:i 0}

• @Carcigenicate what do you think? Jan 11, 2017 at 1:07

# Dart, 20 bytes

_ i=1;for(;;)0~/i--;


Since Dart discards static type information at runtime, declaring a variable with an unknown type ( _ ) gives a warning but doesn't stop the code from running. Then we just trigger an exception by doing integer divide by 0.

### Bonus 1, 23 bytes

_ x;for(;;)x=x?.a??"x";


Same thing as above, but it doesn't utilize a floating point exception. It uses the "null operator" on x to access member a, which evaluates to null when x is null and throws a runtime error when x is not null but doesn't have the property x. We also use the "??" operator to coerce the null value from x?.a to "x". Strings don't have a property named "a", so it errors.

### Bonus 2, 22 bytes

_ x=(){};for(;;)x=x();


This declares an anonymous function that returns void, which actually return null (since everything is nullable in Dart). The first loop iteration gets a successful call and sets x to null. The second loop iteration errors because the Null type doesn't have a call method.

Edit: To clarify, the warning given above is not from Dart but from Dart's analyzer (so its a pre-runtime warning).

# C#, 23 bytes

### Out of range (23 bytes):

()=>{while(""[1]>'a');}


### Divide by zero (25 bytes):

()=>{for(int i=0;;i/=i);}


### Runtime binder exception (33 bytes):

()=>{for(;;){dynamic d=1;d.D();}}


### Null reference (36 bytes):

()=>{string x=null;while(x[1]>'a');}


### Stackoverflow (C# 7 local function) (37 bytes):

()=>{while(true){bool b()=>b();b();}}


### Argument exception (48 bytes):

()=>{while(System.IO.File.ReadAllText("")=="");}


### Invalid operation (77 bytes):

()=>{var v=new System.Collections.Generic.List<int>{1};v.ForEach(V=>v[0]=0);}


# HQ9+-, 2 bytes

Q-

The program consists of two parts:

• Q- Prints out the source code (which, in this case, is Q-).
• - Behavior changes based on the previous character(s) in the program. Since Q came before -, the program enters into a recursive loop and finally quits, raising the error:

[1] 1979 segmentation fault ./hq9+-i test.hq9

(!a(:^)*^)::^


Try it online!

Stack trace:

(...)   | (!a(:^)*^)
:       | (!a(:^)*^)(!a(:^)*^)
:       | (!a(:^)*^)(!a(:^)*^)(!a(:^)*^)
^       | (!a(:^)*^)(!a(:^)*^)
!      | (!a(:^)*^)
a      | ((!a(:^)*^))
(...)  | ((!a(:^)*^))(:^)
*      | ((!a(:^)*^):^)
^      |
(...) | (!a(:^)*^)
:     | (!a(:^)*^)(!a(:^)*^)
^     | (!a(:^)*^)
!    |
a    | <error>


Underload is interesting. The only way to loop is to create a sort of quine. The basic idea is this:

• Push a block containing the loop body to the stack: (...)
• Duplicate it, and then execute it. This means the loop body will be run with the loop body string at the bottom of the stack: (...):^
• In the loop body, immediately "uneval" with the a command: (a...):^
• Append :^ to the end: (a(:^)*...):^. This recovers the original program (and in fact, if we output right here, we would have a quine.)
• Execute this stack value to loop: (a(:^)*^):^. This is the basic structure of our loop program.

I've made a few changes to this idea. The first is that we duplicate twice rather than once before entering the loop. Normally, this would not be significant (as we would just have an unused value at the bottom of the stack) but I also add a ! (delete) at the beginning of the loop body, which means that the stack will be gradually "worn down." After two iterations of the loop, the stack is empty, so running a causes a segfault in the TIO interpreter.

This shouldn't violate rule 6, because any competent Underload interpreter would do TCO.

## REXX, 14 bytes

do i=0
i=j
end


This creates an infinite for-loop with i as a counter, but during the loop, i is reassigned from 0 to j, which, as an unassigned symbol, contains the string J.

The result:

     1 +++ do i=0
Error 41 running "test.rexx", line 1: Bad arithmetic conversion
[Finished in 0.1s with exit code 215]


Another option is to drop i, but that is three bytes longer.

# Whitespace, 16 bytes

[S S S N
_Push_0][N
S S N
_Create_Label_LOOP][T   N
S T _Print_top_as_integer][N
S N
N
_Jump_to_Label_LOOP]


Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Probably my shortest Whitespace answer thus far. :)

Explanation in pseudo-code:

Push 0 to the top of the stack
Start LOOP:
Pop and print the top of the stack as integer to STDOUT
Go to next iteration of LOOP


Run process

Command    Explanation             Stack    STDOUT    STDERR

SSSN       Push 0                  [0]
NSSN       Create Label_LOOP       [0]
TNST      Print top as integer    []       0

TNST      Print top as integer    []                 Error: Can't do OutputNum


Stops with an error because it tries to output the top of the stack, which isn't there anymore.

func o[]
while[true]
o: //Recursive call to o
end
end
o: //Call o the first time


This just calls itself infinitely, resulting in a System.StackOverflowExceptionafter ~300ms.

# SMBF, 5 bytes

Runs the loop once, then modifies the source code, exiting the loop. The instructions reached, in order, are: +[-<][-<\.

+[-<]


The test runs on the TIO interpreter, but you can't really check what happens. Visit the first hyperlink, which is my Python interpreter. Change the code on the data = bytearray(... line. The interpreter used to take code from STDIN, but I found that I needed non-printable input so often that changing the input in the source is easier. I also just added an option for recording what instructions were executed, which you can enable by changing debug=True.