8 ought to become Infinity

19

3

Let's take a look on a typical loop, which usually performs 8 iterations:

for (int x=0; x<8; ++x);

You have to make it infinite!


It's a for all languages that support such form of for loop. So solution with highest score (upvotes minus downvotes) wins.

If your language has the other form of for loop, but you are sure, you can make something cool with it, feel free to post the answer and mark it as noncompeting. I reserve the right to enlarge scope of available constructions and languages, but it will never be shrinked, so don't be afraid of dropping previously correct solutions.


What is solution?

Solution consists of two programs.

The first program is a clean program. It's the typical program in your language with the for loop making 8 iterations. It should be the normal program, any developer could write. No any special hacks for preparation purposes. For example:

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}

The second program is augmented. This program should contain all the code from clean program and some additional code. There are limited number of extension points, see complete rules section for details. An augmented program for the clean one above can be

inline bool operator < (const int &a, const int &b)
{
  return true;
}

int main() 
{
  for (int x=0; x<8; ++x);
  return 0;
}

That's just an example (noncompilable in C++) to show an idea. The real correct augmented program have to be compilable, working and having infinite loop.

Complete rules

Both programs:

  • Any language with support of such for loops is ok.
  • The loop body has to be empty. More precisely, you can place some output or other code into the loop, but loop behavior should be the same in case of empty loop.

Clean program:

  • Loop uses integer or numeric counter and performs 8 iterations:

    for (int          x=0; x<8; ++x);   // C, C++, C#
    for (var          x=0; x<8; ++x);   // C#, Javascript
    for (auto         x=0; x<8; ++x);   // C, C++
    for (auto signed  x=0; x<8; ++x);   // C, C++
    for (register int x=0; x<8; ++x);   // C, C++
    
  • User-defined types are disallowed.

  • Using of property (except of global variable) instead of loop variable is disallowed.
  • Declaration of variable can be inside or outside of the loop. Following code is ok:

    int x;
    for(x=0; x<8; ++x);
    
  • Either prefix or postfix increment can be used.

  • Loop limit 8 should be written as a constant literal without saving to named constant or variable. It's made to prevent solutions based on declaring variable or constant equal to 8, and then reassigning, overriding or shadowing it by the other value:

    const double n = 8;
    
    int main()
    {
      const double n = 9007199254740992;
      for (double x=0; x<n; ++x);
      return 0;
    }
    

Augmented program:

  • Must contain all the code from the clean one.
  • Should extend clean program in limited number of extension points.
  • Must execute same for loop as an infinite loop itself.
    Placing of the loop into another infinite construction is not ok.
  • Runtime or compile-time patching of the code is allowed as long as textual representation of it is unchanged.
  • Placing the construction into a string and passing to eval is disallowed.

Extension points:

  • Anywhere outside of the fragment with clean code, including other files or other assemblies.
  • for statement (as single piece - for construction and its body) must be kept unchanged.
  • Variable declaration must be kept the same.
  • Any place between simple statements can be used as extension point.
  • If and only if variable was declared outside of the loop and without immediate assignment of the value, such assignment can be added.
/* extension point here */
int main()
/* extension point here */
{
  /* extension point here */
  int x /* extension point for assignment here */;
  /* extension point here */
  for (x=0; x<8; ++x);
  /* extension point here */
  return 0;
  /* extension point here */
}
/* extension point here */
int main() 
{
  /* BEGIN: No changes allowed */ int x = 0; /* END */
  /* extension point here */
  /* BEGIN: No changes allowed */ for (x=0; x<8; ++x); /* END */
  return 0;
}

PS: If possible, please provide a link to online IDE.

Qwertiy

Posted 2016-11-21T20:59:42.583

Reputation: 2 697

Question was closed 2017-02-06T01:34:12.693

2@Oliver, as I know, "highest score (upvotes minus downvotes)" is exactly the defaults for [tag:popularity-contest], at least it is written in the tag description: "A popularity contest is a competition where the answer with the highest vote tally (upvotes minus downvotes) wins." But I can add it to the question explicitly. – Qwertiy – 2016-11-21T21:19:30.557

@LuisMendo, I expect it to be ok for [tag:restricted-source]. By the way, the first sentence by your link: "Unless you're writing a language-specific challenge" - yes, I am. I'm limiting scope of the languages by this construction, I understand it and I'm making it on purpoise.

– Qwertiy – 2016-11-21T22:44:24.277

How about removing the language restriction, and replacing the for loop with something more general (and have the extension points only be before and after the clean code). Maybe something like print something 8 times for the clean task, and have the clean task go on forever, for the augmented task – Maltysen – 2016-11-21T22:49:22.030

1@Maltysen, there is a lot of interesting solutions in languages with these construction. There are C and C++ (with absolutely different solutions), C#, Java, Javascript, php, Perl, Groovy. I'm sure there are much more. Anyway, I'm open to enlarge question and that's specified in rules. If you can make something iteresting in other language - post it. If it will have positive reation, rules can be enlarged. – Qwertiy – 2016-11-21T22:51:20.240

4Doing this as a [tag:popularity-contest] is a little awkward because there's no description of what criteria voters should choose when voting (making the victory condition subjective). I was working on a [tag:code-golf] solution on the basis that many people here find golf solutions interesting and thus it might be popular; that seems like it might be a workable victory condition for the challenge. – None – 2016-11-21T23:26:07.863

@ais523, no [tag:code-golf] doen't suit for this challenge as 1. Interesting solutions with reflection or code patching are not good for golfing, also they are much better in readable state then in golfed. 2. C/C++ solution will win in 13 chars. 3. The other very cool C++ only solution will have 16 chars. – Qwertiy – 2016-11-21T23:37:05.027

@ais523, "there's no description of what criteria voters should choose when voting" let's take a look at [tag:popularity-contest] description: "Qualities which should be AVOIDED in popularity contests ... Rules what people should consider when voting. In the past this has consistently never worked out." – Qwertiy – 2016-11-22T09:11:16.197

2>

  • "integer or numeric counter" is a bit too vague. E.g. does it include java.lang.Integer? 2. This would better with a proper winning criterion.
  • < – Peter Taylor – 2016-11-24T14:08:41.407

    1

    >

  • Yes, it does. 2. What exactly winning creteria? PS: We can continue on meta.
  • – Qwertiy – 2016-11-24T14:40:50.213

    "If and only if variable was declared outside of the loop and without immediate assignment of the value, such assignment can be added." So in Perl 5 this is good? Program 1: my$a;1;$a=8;1while$b<$a Program 2: my$a;1;$a=8;$a=Inf;1while$b<$a – msh210 – 2016-11-24T15:36:53.227

    @msh210, it was about loop variable, not about loop limit. loop limit is expected to be constant. – Qwertiy – 2016-11-24T17:39:36.150

    @Dennis, why close?

    – Qwertiy – 2017-02-06T05:57:29.100

    1Because the challenge is too broad for our standards. In particular, If your language has the other form of for loop, but you are sure, you can make something cool with it, feel free to post the answer and mark it as noncompeting. I reserve the right to enlarge scope of available constructions and languages, but it will never be shrinked, so don't be afraid of dropping previously correct solutions. That paragraph entirely explains why it's too broad. – Alex A. – 2017-02-06T06:06:58.573

    How do noncompiting answers affect how broad the question is? And why not to answer on meta? – Qwertiy – 2017-02-06T06:11:58.547

    Answers

    33

    Python3

    Clean Program:

    This is just a standard countdown while loop.

    n = 8
    while n != 0:
      n -= 1
    print("done")
    

    Augmented Program:

    import ctypes
    
    ctypes.cast(id(8), ctypes.POINTER(ctypes.c_int))[6] = 9
    
    n = 8
    while n != 0:
      n -= 1
    print("done")
    

    It uses the int cache to redefine 8 as 9 which effectively makes the n -= 1 a no-op, since 9-1 = 8 which just sets n back to 9 again, causing the infinite loop.

    You can see the int cache in action online here (though obviously without the infinite loop cuz its online).

    Maltysen

    Posted 2016-11-21T20:59:42.583

    Reputation: 25 023

    Could you provide a link to onlinde IDE, please? http://ideone.com/aI3ZrI - seems not working there.

    – Qwertiy – 2016-11-21T22:11:01.557

    @Qwertiy, I tried running it in repl.it, but it just freezes, which is to be expected since it'll be an infinite loop. i know the int cache stuff works there, because that's where I experimented with how to set 8 to 9 – Maltysen – 2016-11-21T22:12:18.157

    Really works there. Strange that thay haven't time limit like ideone (5 sec). They show Python 3.5.2 (default, Dec 2015, 13:05:11) [GCC 4.8.2] on linux – Qwertiy – 2016-11-21T22:14:55.353

    @Qwertiy link without the loop: https://repl.it/E4fx/0

    – Maltysen – 2016-11-21T22:15:23.973

    That's interesting... – Qwertiy – 2016-11-21T22:16:37.693

    Is this really in Python3, or is this whole ctypes business a CPython-implementation-specifc detail? – Cactus – 2016-12-02T04:52:32.450

    @Cactus I think it's CPython specific. – FlipTack – 2017-01-07T13:36:38.587

    22

    Python 3

    Clean Program:

    The standard way to do something 8 times in python is:

    for i in range(8): 
        # Do something
        pass
    

    Augmented Program:

    However, if we override the range generator function to infinitely yield 1, it becomes an infinite loop...

    def range(x):
        while 1: yield 1
    
    for i in range(8):
        # Infinite loop
        pass
    

    We can take this further and create a generator function which, rather than infinitely yielding 1, counts up forever:

    def range(x):
        i = 0
        while 1: yield i; i+=1
    
    for i in range(8):
        # Counting from 0 to infinity
        pass
    

    Test on repl.it

    FlipTack

    Posted 2016-11-21T20:59:42.583

    Reputation: 13 242

    2Hide that in the middle of a huge module... – Benjamin – 2016-12-16T03:31:29.343

    21

    Perl

    Clean

    for($i=0; $i<8; $i++) { }
    

    Augmented

    *i=*|;
    for($i=0; $i<8; $i++) { }
    

    Ideone.

    primo

    Posted 2016-11-21T20:59:42.583

    Reputation: 30 891

    16Oh, that's really clever. For anyone who doesn't know Perl: this is aliasing $i to become an alias for a special variable that's only capable of holding booleans, so once it reaches 1 it becomes immune to being incremented. – None – 2016-11-25T12:45:12.350

    10

    ES5+ (Javascript)

    EDIT: Removed explicit variable declaration, as otherwise it was hoisted and a non-configurable window.x property was created (unless run line by line in the REPL console).

    Explanation:

    Makes advantage of the fact that any globally scoped variable is also a property of the window object, and redefines "window.x" property to have a constant value of 1.

    Clean

    for(x=0; x<8; x+=1) console.log(x);
    

    Augmented

    Object.defineProperty(window,'x',{value:1});
    for(x=0; x<8; x+=1) console.log(x);
    

    NOTE: To make this work in Node.js, just replace "window" with "global" (tested in Node.js 6.8.0)

    zeppelin

    Posted 2016-11-21T20:59:42.583

    Reputation: 7 884

    1By the way, it's ES5, isn't it? – Qwertiy – 2016-11-22T09:55:32.987

    Also it doen't work with var in Crome. But you can remove var from both programs - it'll be ok. – Qwertiy – 2016-11-22T09:57:02.330

    @Qwertiy this does work with "var" in Chrome for me (Linux/Version 52.0.2743.82 (64-bit)) – zeppelin – 2016-11-22T09:58:36.110

    ockquote>

    By the way, it's ES5, isn't it?

    True, will correct the title now – zeppelin – 2016-11-22T09:59:01.697

    ockquote>

    Also it doen't work with var in Crome.

    Please make sure that you start out clean, i.e. "x" must not be defined, before you run this code, i.e. if you first "run" the clean code, you have to reload the page, before running the augmented version. – zeppelin – 2016-11-22T10:07:22.940

    1

    The problem is var hoists, so at the moment of using defineProperty it already exitst. But if you place these 2 lines in different scripts (by the way, it's allowed), it would work, as the property will be created first and the var then will be ignored. Proof: https://i.stack.imgur.com/lSwbE.png

    – Qwertiy – 2016-11-22T10:22:16.393

    @Yep, true, I just ran it line by line in Chrome, which is why it worked for me. I've removed an explicit variable declaration (I believe that is allowed according to your earlier comment). – zeppelin – 2016-11-22T10:58:35.147

    Yes, both solutions are allowed: remove var or place 2 lines of code in different scripts. https://jsfiddle.net/19g110y1/ (safe to open as there is break after 16 iterations).

    – Qwertiy – 2016-11-22T11:01:07.563

    I think you could also replace window with this to make it isomorphic. – Patrick Roberts – 2017-01-07T13:37:24.803

    10

    C

    Clean program

    int main() 
    {
      for (int x=0; x<8; ++x);
      return 0;
    }
    

    Augmented program

    #define for(ever) while(1)
    
    int main() 
    {
      for (int x=0; x<8; ++x);
      return 0;
    }
    

    Omar

    Posted 2016-11-21T20:59:42.583

    Reputation: 1 154

    Must execute same for loop as an infinite loop itself. Placing of the loop into another infinite construction is not ok. – Karl Napf – 2016-11-25T13:39:11.677

    3@KarlNapf The "for" loop is not inside another infinite construction. – coredump – 2016-11-25T13:41:15.303

    3@KarlNapf I thought this answer was explicitly allowed by the rule: •Runtime or compile-time patching of the code is allowed as long as textual representation of it is unchanged. – Omar – 2016-11-25T16:00:41.923

    It is the wording "Must execute same for loop" but yes this conflicts with the textual representation. – Karl Napf – 2016-11-25T18:08:49.637

    7

    Java

    Clean program:

    public class Main {
        public static void main(String[] args) throws Exception {
            for (Integer i = 0; i < 8; i++);
        }
    }
    

    Augmented program:

    import java.lang.reflect.Field;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cache = Integer.class.getDeclaredClasses()[0];
            Field c = cache.getDeclaredField("cache");
            c.setAccessible(true);
            Integer[] intcache = (Integer[]) c.get(cache);
            intcache[129] = intcache[128];
    
            for (Integer i = 0; i < 8; i++);
        }
    }
    

    Sets the Integer in the Integer cache that should contain 1 to 0, effectively making i++ do nothing (it sets i to the cached Integer that should contain 1, but since that Integer actually contains 0, nothing changes).

    insert_name_here

    Posted 2016-11-21T20:59:42.583

    Reputation: 816

    Beat me to it, this solution is identical to my own. – Hypino – 2016-11-25T16:45:55.400

    6This isn't really an idiomatic Java for loop, which would probably use the unboxed int rather than the relatively heavyweight Integer. – None – 2016-11-25T17:11:27.257

    7

    C++

    int main() 
    {
    #define int bool
      for (int x=0; x<8; ++x);
      return 0;
    }
    

    bool can only be 0 or 1. Inspired by primo's Perl answer.

    Karl Napf

    Posted 2016-11-21T20:59:42.583

    Reputation: 4 131

    6

    Python 3 (3.5.0)

    Clean Program:

    for i in range(8):
        print(i)
    

    Augmented

    import sys
    
    from ctypes import *
    
    code = sys._getframe().f_code.co_code
    
    cast(sys._getframe().f_code.co_code, POINTER(c_char*len(code))).contents[len(code)-4] = 113
    cast(sys._getframe().f_code.co_code, POINTER(c_char*len(code))).contents[len(code)-3] = 160
    
    for i in range(8):
        print(i)
    

    This solution is unlike the others written in Python in that it actually changes the source code on the fly. All the stuff in the for loop can be changed to whatever code is wanted.

    The code changes the second to last opcode to be 113 or more readably - JUMP_ABSOLUTE. It changes the operand to 160 - the instruction where the for loop begins, in effect creating a GOTO statement at the end of the program.

    The augmented program prints the numbers 0..7 infinitely many times without stack-overflowing or similar.

    Blue

    Posted 2016-11-21T20:59:42.583

    Reputation: 26 661

    6

    PHP

    I think this is following the extension point rules; I'm not totally clear on point 4. It's very similar to @primo's perl answer so I think it counts.

    Clean

    for(;$i<8;$i++);
    

    Augmented

    $i='a';
    for(;$i<8;$i++);
    

    PHP lets you increment certain strings, like so:

    'a' -> 'b'
    'b' -> 'c'
    'z' -> 'aa'
    'aa' -> 'ab'
    'aab' -> 'aac'
    etc
    

    All of these strings evaluate to 0, so this will loop practically forever (barring somehow running out of memory).

    ToXik-yogHurt

    Posted 2016-11-21T20:59:42.583

    Reputation: 311

    That's in the spirit of the competition and very interesting. Actually there wasn't said anything about ommiting initial assignmnet, so that's some edge case. Actually it was expected that there is no extension point between assigning 0 and iterations. But I'm not going to disallow it now as I see some interesing edge case ways based on that and it's not easy to overuse. – Qwertiy – 2016-11-25T15:41:08.670

    2@Qwertiy "so that's some edge case." PHP in a nutshell :) – ToXik-yogHurt – 2016-11-25T16:03:52.473

    6

    Perl

    Clean code

    for ($x = 0; $x < 8; $x++) {}
    

    Augmented code

    sub TIESCALAR {bless []}
    sub FETCH {}
    sub STORE {}
    tie $x, "";
    
    for ($x = 0; $x < 8; $x++) {}
    

    Most Perl variables are just variables. However, the language also has a tie feature, which allows you to effectively give variables getters and setters. In this program, I make the main package (whose name is the null string) into the equivalent of a class from an object-oriented language, whilst also having it be a program. That allows me to tie the for loop counter to the program itself. Implementing TIESCALAR allows tie to succeed; the return value of TIESCALAR is meant to be a reference to any internal state we need to keep around associated with the variable, but because we don't need any, we return an empty array reference as a placeholder. We then give the simplest possible implementations of the getter and setter; neither of them do anything, so attempts to assign to $x have no effect, and attempts to read it always return undef, which is numerically less than 8.

    user62131

    Posted 2016-11-21T20:59:42.583

    Reputation:

    5

    WinDbg

    Clean

    .for (r$t0 = 0; @$t0 < 8; r$t0 = @$t0 + 1) { }
    

    Augmented

    aS < |;                                            * Create alias of < as |
    .block {                                           * Explicit block so aliases are expanded
        .for (r$t0 = 0; @$t0 < 8; r$t0 = @$t0 + 1) { } * Condition is now @$t0 | 8, always true
    }
    

    This approach creates an alias for < as |, so when < is encountered in the code the alias is expanded to | and bitwise-or is done instead of less-than. In WinDbg all non-zero values are truthy so anything | 8 is always true.

    Note: The .block is not actually needed if the aS and .for are actually entered as two different lines as shown here, it's only required when the aS and .for are on the same line.

    milk

    Posted 2016-11-21T20:59:42.583

    Reputation: 3 043

    5

    Common Lisp

    Clean code

    (dotimes(i 8))
    

    Augmented

    (shadowing-import(defmacro :dotimes(&rest args)'(loop)))
    (dotimes(i 8))
    

    A macro named keyword:dotimes, a.k.a. :dotimes (see 11.1.2.3 The KEYWORD Package) is defined which expands as an infinite loop. The defmacro macro returns the name of the macro being defined, which can be fed to shadowing-import. Thus, this new dotimes symbols shadows the standard one (which should not be redefined or lexically bound to another macro in portable programs).

    Augmented (2)

    (set-macro-character #\8 (lambda (&rest args) '(loop)))
    (dotimes(i 8))
    

    When we read character 8, we replace it by (loop). That means that the above reads as (dotimes (i (loop))) and so the code never terminates computating the upper-bound. This impacts all occurrences of 8, not only the one in the loop. In other words, 8 really stands for infinity. If you are curious, when the readtable is modified like above, then character 8 becomes "terminating", and detaches itself from other numbers/symbols currently being read:

    (list 6789)
    

    ... reads as:

    (list 67 (loop) 9)
    

    You can run tests on Ideone: https://ideone.com/sR3AiU.

    coredump

    Posted 2016-11-21T20:59:42.583

    Reputation: 6 292

    5

    Mathematica

    Clean

    For[x = 0, x < 8, ++x,]
    

    Augmented

    x /: (x = 0) := x = -Infinity;
    For[x = 0, x < 8, ++x,]
    

    alephalpha

    Posted 2016-11-21T20:59:42.583

    Reputation: 23 988

    4

    Ruby

    Clean

    This sort of for loop is not much used in Ruby, but a typical tutorial will tell you that this is the way to go about it:

    for x in 1..8
      # Some code here
    end
    

    Augmented

    The for loop just calls (1..8).each with the given block of code, so we change that method:

    class Range
      def each
        i = first
        loop { yield i; i+= 1 }
      end
    end
    
    for x in 1..8
      # Some code here
    end
    

    daniero

    Posted 2016-11-21T20:59:42.583

    Reputation: 17 193

    4

    Haskell

    Clean version:

    import Control.Monad (forM_)
    
    main = forM_ [0..8] $ \i -> print i
    

    Augmented version:

    import Control.Monad (forM_)
    
    data T = C
    
    instance Num T where
        fromInteger _ = C
    
    instance Enum T where
        enumFromTo _ _ = repeat C
    
    instance Show T where
        show _ = "0"
    
    default (T)
    
    main = forM_ [0..8] $ \i -> print i
    

    It's quite basic, really: we just define our own type T such that its enumFromTo instance is an infinite sequence, then use type defaulting so that the un-type-annotated values 0 and 8 are taken as type T.

    Cactus

    Posted 2016-11-21T20:59:42.583

    Reputation: 185

    1Nice idea to change the default type for Haskell's overloaded numeric literals. – nimi – 2016-11-29T15:15:43.870

    3

    ///

    There are no explicit for loops in ///, but can be simulated (it's turing complete after all).

    Clean:

    /1/0/
    /2/1/
    /3/2/
    /4/3/
    /5/4/
    /6/5/
    /7/6/
    /8/7/
    8
    

    Augmented:

    /0/0/
    /1/0/
    /2/1/
    /3/2/
    /4/3/
    /5/4/
    /6/5/
    /7/6/
    /8/7/
    8
    

    What's going on?

    While the former program counts down from 8 to 0, the latter one's /0/0/ rule will replace 0 by 0 until eternity.

    Cedric Reichenbach

    Posted 2016-11-21T20:59:42.583

    Reputation: 448

    And I thought that you would actually do something like /0/1//1/2/.../7/8//8/8/8 to count up instead. – Erik the Outgolfer – 2016-12-13T12:23:42.103

    3

    Javascript ES6

    OK, here's a version that works using the ES6 for...of loop construct. I'll even give you a clean array so that we're sure there's no funny business:

    Clean

    for(a of [0,1,2,3,4,5,6,7]);
    

    Of course, that doesn't stop someone from messing with the Array prototype...

    Augmented

    Array.prototype[Symbol.iterator]=function(){return {next: function(){return {done: false}}}}
    for(a of [0,1,2,3,4,5,6,7]);
    

    This works by over-writing the default iterator so that it never terminates, therefore locking everything into an infinite loop. The code doesn't even have a chance to run the stuff inside the loop.

    Marcus Dirr

    Posted 2016-11-21T20:59:42.583

    Reputation: 51

    "loop behavior should be the same in case of empty loop" – Qwertiy – 2016-11-29T15:20:37.280

    Darn, missed that - I'll have to figure something out. – Marcus Dirr – 2016-11-29T15:23:28.263

    As far as I can tell, it isn't possible to do what the challenge with a C-style for loop in Javascript unless you break a rule - either by having something inside it (like my solution) or by pre-massaging the loop declaration in your clean code (like with Cedric Reichenbach's). – Marcus Dirr – 2016-11-29T15:41:12.470

    Actually there are some ways. Way with global variable is already posted, bute there are some more, allowing var in the loop. – Qwertiy – 2016-11-29T18:50:18.317

    Like I said, as far as I can tell. I saw the global variable way after making that comment and kicked myself. – Marcus Dirr – 2016-11-29T19:55:44.633

    @PatrickRoberts, my comment was about an older version. Check edit history for more details. – Qwertiy – 2017-01-07T19:04:43.587

    @Qwertiy thanks for pointing that out, and yes for the older version I completely agree with your comments. – Patrick Roberts – 2017-01-07T21:00:44.543

    2

    C++

    Uses 2 extension points:

    struct True {
      True(int x){}
      bool operator<(const int&){
        return true;
      }
      void operator++(){}
    };
    
    
    int main() 
    {
    #define int True
      for (int x=0; x<8; ++x);
      return 0;
    }
    

    Clean program is same as in the description.

    Karl Napf

    Posted 2016-11-21T20:59:42.583

    Reputation: 4 131

    Nice, but can be "optimized" :) There are some interesting builtins in C++ to make another answer. – Qwertiy – 2016-11-25T13:16:21.740

    2

    Brainfuck

    I print a '0' each iteration, just to make it easy to count iterations. But any code could be inserted there without changing how the loop works.

    Clean

    >> ++++++ [-<++++++++>] <<                   b = '0' (value to be printed each iteration)
    
    >> ++++++++ [-<< ++++++++ ++++++++ >>] <<    for (a = a plus 128;
    [                                              a;
    ++++++++ ++++++++                              a = a plus 16 (mod 256)) {
    >.<                                              loop body (print b)
    ]                                            }
    

    Try it online

    The augmented version relies on the common Brainfuck implementation with 8 bit cells. On these implementations, "increment" is actually "increment (mod 256)". Thus to find a loop that will iterate exactly 8 times in the clean version and endlessly in the augmented version, we can simply find a solution to the following system of inequalities.

    • a + b*8 (mod 256) == 0 (for clean version)
    • c + a + b*n (mod 256) > 0 for all n (for augmented version)
    • a > 0

    In this case, we let a = 128, b = 16, and c = 1. Obviously 128 + 16 * 8 = 256 (and 256 (mod 256) = 0) and 128 > 0, and since b is even, c + a + b * n is odd for any odd a + c, and thus will never be an even multiple of 256 in such cases. We select c = 1 for simplicity's sake. Thus the only change we need is a single + at the beginning of the program.

    Augmented

    +                                            increment a (only change)
    >> ++++++ [-<++++++++>] <<                   b = '0' (value to be printed each iteration)
    
    >> ++++++++ [-<< ++++++++ ++++++++ >>] <<    for (a = a plus 128;
    [                                              a;
    ++++++++ ++++++++                              a = a plus 16 (mod 256)) {
    >.<                                              loop body (print b)
    ]                                            }
    

    Try it online

    I leave it to the OP to determine if this entry is competing. Brainfuck doesn't have an explicit for loop, but the loop form I used is as close as you're likely to get. ++++++++ is also as close to a literal 8 as you can get; I've included quite a few of those.

    The clean version almost certainly constitutes a typical program written in this language, as even the shortest known Brainfuck Hello World depends on a modular recurrence relation to work.

    Ray

    Posted 2016-11-21T20:59:42.583

    Reputation: 1 488

    2

    Haskell

    Clean

    import Control.Monad (forM_)
    
    main = forM_ [0..8] $ \i -> print i
    

    Augmented

    import Control.Monad (forM_)
    
    import Prelude hiding (($))
    import Control.Monad (when)
    
    f $ x = f (\i -> x i >> when (i == 8) (f $ x))
    
    main = forM_ [0..8] $ \i -> print i
    

    Replaces the usual function application operator $ with one that repeats the loop again every time it finishes. Running the clean version prints 0 to 8 and then stops; the augmented version prints 0 to 8 and then 0 to 8 again, and so on.

    I cheat a little, in that forM_ [0..8] $ \i -> print i isn't necessarily the "cleanest" way to write that loop in Haskell; many Haskellers would eta-reduce the loop body to get forM_ [0..8] print and then there's no $ to override. In my defense I copied the clean code from Cactus' answer, who didn't need that property, so at least one Haskell programmer actually wrote that code with no motivation to unnecessarily add the $!

    Ben

    Posted 2016-11-21T20:59:42.583

    Reputation: 381

    1

    C++

    int main() 
    {
      int y;
    #define int
    #define x (y=7)
      for (int x=0; x<8; ++x);
      return 0;
    }
    

    Lets x evaluate to 7. Does not work in C because it requires an lvalue at assignement and increment.

    Karl Napf

    Posted 2016-11-21T20:59:42.583

    Reputation: 4 131

    1

    Nim

    The idiomatic version, using countup:

    Clean

    for i in countup(1, 8):
      # counting from 1 to 8, inclusive
      discard
    

    Augmented

    iterator countup(a: int, b: int): int =
      while true:
        yield 8
    
    for i in countup(1, 8):
      # counting 8s forever
      discard
    

    Simple, and very similar to the Python answer which redefines range. We redefine countup, the idiomatic Nim way of iterating from one int (inclusive) to another, to give 8s infinitely.

    The more interesting version, using the range operator ..:

    Clean

    for i in 1..8:
      # counting from 1 to 8, inclusive
      discard
    

    Augmented

    iterator `..`(a: int, b: int): int =
      while true:
        yield 8
    
    for i in 1..8:
      # counting 8s forever
      discard
    

    Very similar to the previous solution, except we redefine the range operator .., which normally would give an array [1, 2, 3, 4, 5, 6, 7, 8], to the iterator from before.

    Copper

    Posted 2016-11-21T20:59:42.583

    Reputation: 3 684

    1

    GolfScript

    Clean

    0{.8<}{)}while;
    

    Augmented

    {.)}:8;
    0{.8<}{)}while;
    

    It assigns the function returning n+1 to the variable 8

    jimmy23013

    Posted 2016-11-21T20:59:42.583

    Reputation: 34 042

    1

    tcl

    Normal:

    for {set i 0} {$i<8} {incr i} {}
    

    Augmented:

    proc incr x {}
    for {set i 0} {$i<8} {incr i} {}
    

    The idea is to redefine the incr command that is used to increment the variable i, to actually not increment!

    Can be tested on: http://rextester.com/live/QSKZPQ49822

    sergiol

    Posted 2016-11-21T20:59:42.583

    Reputation: 3 055

    1

    x86_64 Assembly

    Clean program:

    mov rcx, 8
    loop_start:
    sub rcx, 1
    cmp rcx,0
    jne loop_start
    mov rax, 0x01
    mov rdi, 0
    syscall
    

    The sort of loop any Assembly programmer would use, followed by an exit syscall so as not to enable adding a jmp loop_start instruction afterwards.

    Augmented program:

    global start
    section .text
    start:
    mov rcx, -1
    jmp loop_start
    mov rcx, 8
    loop_start:
    sub rcx, 1
    cmp rcx,0
    jne loop_start
    mov rax, 0x01
    mov rdi, 0
    syscall
    

    Also, sorry if it's bad that the clean program doesn't have an entrypoint or a section .text

    goose121

    Posted 2016-11-21T20:59:42.583

    Reputation: 151

    Won't it stop after integer overflow? – Qwertiy – 2017-02-06T06:10:03.410

    1Oh, uh... maybe. But it will take a long time? I kind of forgot that that could happen, being mostly a high-level-language programmer – goose121 – 2017-02-08T16:31:46.580

    0

    JavaScript

    Clean:

    for (var i = 0; !(i > Math.PI * 2.5); i++);
    

    Augmented:

    window.Math = {PI: NaN};
    for (var i = 0; !(i > Math.PI * 2.5); i++);
    

    Cedric Reichenbach

    Posted 2016-11-21T20:59:42.583

    Reputation: 448

    Doesn't seem to be a typical loop... – Qwertiy – 2016-11-29T10:32:35.223

    Yeah, I kinda stretched the term typical... :/ – Cedric Reichenbach – 2016-11-29T11:48:55.057

    0

    C++

    Clean Program

    A nice, normal loop, iterating from numbers 0 to 7.

    #include <iostream>
    
    int main() {
    
      for (short i = 0; i < 8; i++) {
        // Print `i` with a newline.
        std::cout << i << std::endl;
      }    
    
    }
    

    Augmented Program

    The preprocessor of C++ is quite a dangerous feature...

    #include <iostream>
    #define short bool
    
    int main() {
    
      for (short i = 0; i < 8; i++) {
        // Print `i` with a newline.
        std::cout << i << std::endl;
      }    
    
    }
    

    The only line we had to add was #define short bool. This makes i a boolean instead of a short integer, and so the increment operator (i++) does nothing after i reaches 1. The output then looks like this:

    0
    1
    1
    1
    1
    1
    ...
    

    FlipTack

    Posted 2016-11-21T20:59:42.583

    Reputation: 13 242

    http://codegolf.stackexchange.com/a/101226/32091 – Qwertiy – 2016-12-18T08:22:57.623