391
votes
\$\begingroup\$

Write a program that seemingly adds the numbers 2 and 2 and outputs 5. This is an underhanded contest.

Your program cannot output any errors. Watch out for memory holes! Input is optional.

Redefining 2+2 as 5 is not very creative! Don't doublethink it, try something else.

\$\endgroup\$
23
  • 48
    \$\begingroup\$ This is question in book "1984" by George Orwelll. \$\endgroup\$ May 30, 2014 at 12:23
  • 97
    \$\begingroup\$ Why is this underhanded? Two plus two is five. \$\endgroup\$
    – Geobits
    May 30, 2014 at 16:23
  • 79
    \$\begingroup\$ THERE! ARE! FOUR! LIGHTS! \$\endgroup\$
    – Nick T
    May 30, 2014 at 19:57
  • 105
    \$\begingroup\$ @Geobits - I agree: 2+2=5 you can see it in this calculator. \$\endgroup\$
    – MT0
    May 30, 2014 at 20:03
  • 47
    \$\begingroup\$ echo "2+2=5"; \$\endgroup\$ May 31, 2014 at 12:16

156 Answers 156

3
votes
\$\begingroup\$

C#

using System;

namespace AdditionFoo
{
    class Number
    {
        private int m_value;

        public Number(int value)
        {
            m_value = value;
        }

        public static Number operator +(Number c1, Number c2)
        {
            if( (int)c1 == (int)c2 && c2 == 2)
                return 5;
            return c1.m_value + c2.m_value;
        }

        public static implicit operator Number(int b)
        {
            return new Number(b);    
        }

        public static implicit operator int(Number b)
        {
            return b.m_value;
        }

        public override string ToString()
        {
            return m_value.ToString();
        }
    }

    class Program
    {
        static void Main()
        {
            var a = (Number)2;
            var b = (Number)2;

            var c = a + b;

            Console.WriteLine(a + "+ " + b + "= " + c);
            Console.ReadLine();
        }
    }
}
\$\endgroup\$
3
votes
\$\begingroup\$

C++

#include <iostream>
using std::cout;


int main(void)
{
    char const * const one = "345678910";
    //copy template string
    char * two = new char[strlen(one) + 1];

    strcpy_s(two, strlen(one) + 1, one);

    //but make this one a zero
    *(two + 3) = 0;

    //not working for some reason?
    cout << two + 2;

    delete[] two;
    return 0;
}
\$\endgroup\$
1
  • \$\begingroup\$ Note that here in PPCG when a question asks for a program, we generally include everything necessary for compilation, so e.g. in C++ you need a main() function. \$\endgroup\$
    – user12205
    May 30, 2014 at 22:32
3
votes
\$\begingroup\$

Python 3

>>> ₓ2 = 3

>>> print("2+2 =",ₓ2+2)

2+2 = 5

Don't downvote; try it by cut and pasting.

Hint:

To find out, hold Ctrl+= (Zoom) and look carefully:

Additional Hint:

Look at the 2 in 2=3 The x next to it makes it assign: x2 = 3 I made all the text small to reduce the chances of noticing the code was small.

\$\endgroup\$
5
  • 31
    \$\begingroup\$ 'What is this, Code Golf for Ants?!' \$\endgroup\$
    – MrLore
    May 31, 2014 at 11:53
  • 1
    \$\begingroup\$ @MrLore I would like to inclusive and allow ants to read it 😺. \$\endgroup\$ May 31, 2014 at 11:57
  • \$\begingroup\$ @Schilcote you can delete your spoiler comment; I have added a spoiler. \$\endgroup\$ Jun 1, 2014 at 3:56
  • \$\begingroup\$ -1. This is essentially the same as the homoglyph trick, except less underhanded. Also, it breaks formatting. \$\endgroup\$ Jun 1, 2014 at 5:55
  • \$\begingroup\$ @JanDvorak Thanks, I didn't know. \$\endgroup\$ Jun 1, 2014 at 6:27
3
votes
\$\begingroup\$

Coq

Lemma silly : 2 + 2 = 5.
Proof.  admit. Qed.


(* We can now prove all other sorts of broken things *)
Example consequence : 5 = 6.
Proof.
    assert (expand : 6 = 1 + 5).
        simpl. reflexivity.
    rewrite -> expand.
    assert (expand2 : 1 + 5 = 1 + 2 + 2).
        rewrite <- silly.
        simpl.
        reflexivity.
    rewrite expand2.
    simpl.
    reflexivity.
Qed.

This (un)fortunately doesn't prove that 2 + 2 = 5, since admit is the "hey compiler, trust me on this on" value, but you can use it in later proofs.

\$\endgroup\$
3
votes
\$\begingroup\$

C/C++

#include "hidden.h"
int main()
{
    printf("%i\n", 2 + 2);
    getchar();
    return 0;
}

hidden.h:

#define + + 1 +

The answer (if it's not obvious)

Unicode/Preprocessor hacks: The + symbol is a unicode symbol, which means it doesn't count as the + operator, so it's possible for the preprocessor to re#define it. main itself uses +, but without seeing the #define beforehand, anyone would think it were just a normal + operation.

\$\endgroup\$
1
  • \$\begingroup\$ Note that I separated the code into two files for the sake of keeping the trick hidden for those who like figuring out how these things work. \$\endgroup\$
    – Pharap
    Jun 6, 2014 at 23:06
3
votes
\$\begingroup\$

Java

public final class MyMath {
    public static void main(String[] args) {

        boolean isFive = ((2 + 2) == 5);

        if(isFive = true) {
            System.out.println("2 + 2 = 5");
        } else {
            System.out.println("2 + 2 is not 5");
        }
    }
}

There is a small typo in the isFive check... I've actually seen this happen in production code :-(

\$\endgroup\$
1
  • 1
    \$\begingroup\$ There was an attempted linux backdoor hack that was this trick, if(user = 0)... or something, making the user root, not checking if the user was root. \$\endgroup\$
    – ACarter
    Jun 6, 2014 at 10:11
3
votes
\$\begingroup\$

C#

using System;
class Program
{
   static void Main()
   {
      double \u01bb;
      unchecked
      {
         \u01bb = (double)((uint.MaxValue + 3) + 0.5);
      }
      Console.WriteLine(ƻ + ƻ);
   }
}

\u01bb is the unicode escape sequence for ƻ. Since ƻ is technically a letter, it can be used as a variable name. The 1st thing the C# compiler does is convert all escape sequences to the correct unicode characters, so my program utilizes overflow to set the value of ƻ to 2.5 in a roundabout way.

\$\endgroup\$
3
votes
\$\begingroup\$

Batch

@echo off
set a=2
set /a a+=2>nul^
::No 3
echo %a%

Sets a to equal 2, then adds 2 to a redirecting stdout to nul. So %a% should output 4. Only a harmless comment before the output.

The trick is that >nul is actually 2>nul redirecting stderr to nul. Due to the carat after nul, it ignores the newline and is actually redirecting stderr to nul::No. Evaluating instead set /a a+= 3, the redirection is considered before the command is executed. Unfortunately the carat makes it very obvious, I couldn't think of anything more underhanded.

\$\endgroup\$
3
votes
\$\begingroup\$

Scratch

reset timer
wait (2) secs
wait (2) secs
say ([ceiling v] of (timer))

Waiting 2 seconds, then another 2 seconds. 4? Nope - says 5.

\$\endgroup\$
3
votes
\$\begingroup\$

C

Two fun entries,

#include <stdio.h>
int main(x)
{   
    int a = 2;
    int b = 2;
    int c = a + b;
    printf("%d + %d%n = ", a, b, &c);
    printf("%d\n", c);

    return 0;
}

and

#include <stdio.h>
#include <string.h>

int main(x)
{   
    int a = 2;
    int b = 2;
    int c = a + b;
    memset(&x, c+x, 9);
    printf("%d + %d = %d\n", a, b, c);

    return 0;
}

Run the second program at your own risk, it may set your PC on fire.

The magic:

The first program I takes advantage of the little-known format specified: "%n" which instead of printing anything, it actually writes to the location specified the number of characters that were written up to that point. In my code it was "2 + 2" which is 5. The code then goes on to print that value resulting in the final output of "2 + 2 = 5". The second is UB, I take advantage of how GCC lays out the variables which is: argc, argv, c, b, a (in THAT order) and the fact intel is little endian. Note in my example, to aid the confusion I renamed argc x and intentionally omitted argv (which GCC implicitly includes back). Once you understand that the code is pretty clear, we are writing (c+x) which is 5 over argc and argv to get to c. The code then goes on to print "2 + 2 = 5".

\$\endgroup\$
3
  • \$\begingroup\$ how to the strangeness of C ddoes the magic work? \$\endgroup\$
    – masterX244
    Dec 31, 2014 at 16:57
  • \$\begingroup\$ @masterX244 I added an explanation \$\endgroup\$
    – David
    Dec 31, 2014 at 21:47
  • \$\begingroup\$ Nice hack at variant 2 :). black magic at its finest \$\endgroup\$
    – masterX244
    Jan 1, 2015 at 1:29
3
votes
\$\begingroup\$

Emacs Lisp

(defadvice + (before freedom-is-slavery activate)
  (when (ad-get-args 0)(ad-set-arg 0 (or (and (= 2 (length (ad-get-args 0))) (= 2 (ad-get-arg 0)) (= 2 (ad-get-arg 1)) 3) (ad-get-arg 0)))))

(+ 2 2) ;; => 5

Emacs advice allows you to define code that runs before, after, or around the main body of a function to modify its behavior. In this case, I specify that every time + is executed, the arguments should be checked and if there are two arguments that are both 2, set the first argument to 3 before passing them into the main body of +.

\$\endgroup\$
3
  • \$\begingroup\$ hows it working? \$\endgroup\$
    – masterX244
    Jul 23, 2014 at 17:14
  • \$\begingroup\$ I've updated the post to explain the code. There was also a typo in the code but it will work now if you try it out. \$\endgroup\$ Jul 23, 2014 at 17:20
  • \$\begingroup\$ thx, now its obvious \$\endgroup\$
    – masterX244
    Jul 23, 2014 at 17:22
3
votes
\$\begingroup\$

Ruby

%w(2+2).pack("m").size

Some Ruby pack magic!

%w(2+2).pack("m") returns "Misy\n" which is a 5 character string.

\$\endgroup\$
3
votes
\$\begingroup\$

><>

Nowhere near the best, but it was fun to make

3a*4+:02p:c2p:b3p\
03p5a*3+c3pab*d3p\
 import Math     \
 print(2+2)     ;\

Output

5

Explanation

The first two lines of keyboard mash is actually code that puts quotes around import math and print(2+2), and also puts 5n immediately afte the ending quote of the 4th line. ><> is stack-based, so 5n pushes 5 onto the stack, and n pops off the top value and prints it as a number.

\$\endgroup\$
3
votes
\$\begingroup\$

TI-BASIC:

With all of these answers redefining the value of 2, we need to make sure we really have 2, not some impostor. So let's construct 2 from 0, like the set theorists.

PROGRAM:FOUR
"𝑛+1"→u         ;successor function.
0→𝑛Min          ;make sure 𝑛 is in the domain
0→𝑛
u(𝑛→𝑛           ;𝑛=1
u(𝑛)+u(𝑛        ;u(1)+u(1) = 2+2 = 4, obviously.

Let's try it...

prgmFOUR
               5

When the calculator calculates the sequence function u at a given value, for example u(n), it sets n to the value, evaluates the string stored in u, and then increments n. Why? That's a good question, but I suspect it has something to do with the fact that when the TI-84 evaluates any call to u, it first evaluates u at every n less than the value given, regardless of whether the function is actually recursive (yes, it takes linear time in n to get a single value of u).

\$\endgroup\$
3
votes
\$\begingroup\$

MATLAB

In MATLAB, the plus function can be called in two different ways, either by using +, or writing plus. If you try to add values of different types, for instance a cell with an integer, you'll get an error stating what the error is, for instance:

plus(3,{3})
Undefined function 'plus' for input arguments of type 'cell'.

plus(2,2,2)
Error using  + 
Too many input arguments.

This of course, is helpful, as it tell's you what the problem is: You cannot add a cell and an integer, and for some reason, you can't add three integers either. Typing help plus won't help you a lot, it just tells you that the plus-function can add two arrays.

The best approach seems to be to create a very simple plus-function that is both simple to read, and simple to understand.

plus=@(x,y) x + y + logical((x==(isnumeric(x)+isfinite(x)) & y==(isnumeric(y)+isfinite(y))));

This function checks if both arguments, x and y are numeric and finite. If not, it will fail, just as the original plus-function. The advantage is, you still get to know what the error is, but you also get too know where, and why!

plus(3,3)
ans =
     6

plus(3,{2})
Undefined function 'plus' for input arguments of type 'cell'.
Error in @(x,y)x+y+logical((x==(isnumeric(x)+isreal(x))&y==(isnumeric(y)+isreal(y))))

And of course:

plus(2,2)
ans =
     5

x==(isnumeric(x)+isreal(x)) returns 1 if x = 2, because the two functions isnumeric and isreal will both return 1, thus 1+1. The same goes with y==(isnumeric(y)+isreal(y)) of course. Now, we check if both those conditions are true, and return a logical 0 or 1: logical((x==(isnumeric(x)+isreal(x))&y==(isnumeric(y)+isreal(y)))). The logical function is strictly not necessary, but I think it makes it a bit harder to spot (for an untrained eye of course). In MATLAB, boolean values can be added to integers, so for x & y == 2, this will return 2+2=5. For any other values, it will return the correct answer.

\$\endgroup\$
4
  • \$\begingroup\$ And how does this output 2+2=5? \$\endgroup\$
    – Sanchises
    Nov 8, 2015 at 12:40
  • \$\begingroup\$ @sanchises, I'll take that comment as a good sign, at least since I know you know MATLAB =) Have a look here. \$\endgroup\$ Nov 8, 2015 at 12:55
  • \$\begingroup\$ Mostly, I was missing last bit of code where it says plus(2,2) = 5 - I was wondering whether your actually got the point of the challenge :) Let me see if I can figure it out before reading your spoiler. Edit: hehehe. Who doesn't love weak typing... \$\endgroup\$
    – Sanchises
    Nov 8, 2015 at 15:37
  • \$\begingroup\$ Jep, although mostly because I used to program my TI-BASIC games like that. Shame I long since lost my calculator... \$\endgroup\$
    – Sanchises
    Nov 8, 2015 at 18:29
3
votes
\$\begingroup\$

R

> `+` <- function(e1,e2) base::`+`(base::`+`(e1,e2),1)
> 2+2
[1] 5
\$\endgroup\$
3
votes
\$\begingroup\$

C89

int main()
{
    int a;    
    a = 2 + 2//**/(2.f/3.f)
    ;
    printf("%d\n", a);
    return 0;
}

A little explanation:

In C89 there just existed the multiline comment like this: /* This is a comment*/, but not the single line comment: //This would be an syntax error in C89 or previous versions so in this code, which doesn't see the single line comment but just sees the /**/as a starting and immediately ending comment. the program after parsing really does:

a = 2 + 2 / (2.f/3.f);
\$\endgroup\$
3
votes
\$\begingroup\$

MATLAB

I think this one can be quite deceiving as well.

disp(fprintf('2+2 ='))

Printing

2+2 =     5

Or alternatively

fprintf('%d\r',fprintf(' 2+2='))

Printing

2+2=5
\$\endgroup\$
3
  • 1
    \$\begingroup\$ How does it work? How does fprintf('2+2 =') come up with a 5? \$\endgroup\$
    – Cyoce
    Jan 5, 2016 at 16:17
  • 1
    \$\begingroup\$ @Cyoce fprintf returns the number of characters successfully written. \$\endgroup\$ Jan 5, 2016 at 16:20
  • \$\begingroup\$ I really like this approach... (You had my upvote two weeks ago!) =) \$\endgroup\$ Jan 19, 2016 at 11:48
3
votes
\$\begingroup\$

Octave

To ensure compatibility with other programs and languages, outputting the result as a string without the default ans = part is the most sensible thing to do. This can be achieved like this:

disp(num2str(+('2+2'))(1))
5

The ASCII-code for 2 is 50. '2+2' is a vector with the characters with ASCII-codes: [50 42 50]. This is implicitly converted to integers using +, and then converted to a string '50 43 50' using num2str(). Using Octave's direct indexing you can obtain only the first element of this string, 5. This is then displayed using disp().

\$\endgroup\$
2
votes
\$\begingroup\$

Javascript

var num1=1;
var num2=2;
alert(num1 + " + " + num2 + " = " + Math.ceil((num1/10+num2/10)*10));

Although it's kind of cheaty and not really valid I decided to answer it anyways because I can.

As I'm sure most of you know, this relies on the fact that 0.1 + 0.2 = 0.300...004 in Javascript. That said, this script obviously only calculates 1 + 2 = 4 (instead of 2 + 2 = 5) but gives the correct answers for all other numbers

\$\endgroup\$
2
votes
\$\begingroup\$

JavaScript

This isn't really particularly inspired, but:

a=atob(btoa('2+2')+'LTIrMw==');eval(a)

or perhaps

a=atob(btoa('2+2').replace(/i/,'y'));eval(a)
\$\endgroup\$
2
votes
\$\begingroup\$

Python 3

A rather trivial example from me.

Imagine the following hidden in an import somewhere; maybe modify a prank-ee's math.py (so that only non-trivally mathematical programs get the error)

#nothin to see here folks
import builtins
class int(builtins.int):
    def __add__(self,other):
        if self==other==2:
            self=3
        return builtins.int.__add__(self,other)

To test, combine with this:

if __name__ == '__main__':
        #Input returns strings; we must convert to ints
        lights1=int(input("How many lights are in set 1? "))
        lights2=int(input("How many in set 2? "))
        print("There are",lights1+lights2,"lights!!!")

For whatever reason, super() doesn't work inside the fake int. Which is too bad; otherwise, I'd set builtins.int to be the "evil" int as well, making the real default int unrecoverable (and making builtins.int is int be true, making it harder for the victim to confirm their suspicions).

Of course, no matter what this won't work on int literals; Python directly turns those into the default int objects even if builtins.int is set to something else. Only things that are converted to ints will be affected.

Reminds me of the stage hypnosis trick where you convince your subject there is no number six and then have him count his fingers; first the left, then the right, then all of them together...

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This question is an underhanded contest. Answers should appear that they will output 4, but in reality output 5. Your submission does not seem to be trying to hide the fact that it will output 5, so it may not be considered a very good answer for this question. Anyway, welcome to PPCG! :) \$\endgroup\$
    – user12205
    May 31, 2014 at 20:40
  • \$\begingroup\$ It hides it just fine; there's clearly a comment above the "malicious" code telling readers not to look at it. I had some ideas to make it a little more devious; editing now. \$\endgroup\$
    – Schilcote
    May 31, 2014 at 21:28
2
votes
\$\begingroup\$

C

How can this be!? For the maths are broken! The sum of the length of two strings with both the length of two is five.

Since string length is isomorphic to the set of Natural numbers, I decided to use strings for this challenge.

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {
   char* str1 = "ab";
   char str2[4] = "cd";
   char z = 0x90;

   str2[3]=0x00;
   memcpy(str2+2, &z, 1); 

   printf("%d\n", strlen(str1) + strlen(str2));

}

strlen will return the length of address calculated where the first null byte is detected - start address

\$\endgroup\$
2
votes
\$\begingroup\$

Javascript

var number = 3;   //set variable
numbеr = 2;       //redefine it
alert(number+numbеr) //alerts 5. (what?!?!)

JSFIDDLE

\$\endgroup\$
7
  • 2
    \$\begingroup\$ That's pretty good. Could you post a spoiler explaining it? \$\endgroup\$ Jun 3, 2014 at 21:18
  • 5
    \$\begingroup\$ This hack has been presented multiple times on this question (and even in this language) already. It's officially now on the not funny list. \$\endgroup\$
    – Caleb
    Jun 4, 2014 at 7:59
  • 1
    \$\begingroup\$ oh it's the variables that look the same but aren't, isn't it? \$\endgroup\$
    – ACarter
    Jun 6, 2014 at 10:19
  • 1
    \$\begingroup\$ It's the e that does it \$\endgroup\$
    – Pharap
    Jun 6, 2014 at 23:19
  • 2
    \$\begingroup\$ @YoYoYonnY Don't Ctrl + F e, use Ctrl + F е instead, makes things easier :P \$\endgroup\$
    – Pharap
    Jan 31, 2016 at 23:52
2
votes
\$\begingroup\$

MySQL

Here my simple SQL solution to the problem:

Database structure:

create table doublethink(`2+2` int);
insert into doublethink values(5);

Query:

mysql> select `2+2` from doublethink;
+------+
| 2+2  |
+------+
|    5 |
+------+

The trick is that in MySQL column names are escaped by backticks. So 2+2 is not evaluated, but used as a column name.

\$\endgroup\$
2
votes
\$\begingroup\$

PHP (<5.3.11)

Okay, so it's not quite 2+2=5, but 1+1+2=5:

echo 0x0 +1 +1 +2;
// 5

Thanks to a weird issue in the PHP parser, the first 0x0 +1 is interpreted as a hexadecimal literal and an addition, in other words, it becomes (0x01+1).

\$\endgroup\$
2
  • \$\begingroup\$ I had to go back to PHP 4.4.9 to make that work (current stable is 5.5.13). You should probably consider updating your interpreter - 4.4.9 was released Aug. 2008. \$\endgroup\$
    – primo
    Jun 6, 2014 at 11:46
  • \$\begingroup\$ @primo It seems like this bug was fixed with 5.3.11. I've added a note about the compatible versions. \$\endgroup\$
    – p.s.w.g
    Jun 6, 2014 at 11:54
2
votes
\$\begingroup\$

CoffeeScript

addNums = () ->
    document.body.textContent=2+2;
addNums();

Try it here

A kind've spoiler: it uses some invisible characters, and (at least on my machine) when you copy paste it it doesn't copy the special characters, and it says 4 when you run it (on the link it does what i meant for it to do and prints 5

Actually try to figure it out before looking at the spoiler

Look at the url of the "Try it here" link above. Look at my username. Nope, definitely not sucspicious

Still don't get it?

There's no invisible characters. I made the "online coffeescript compiler" that the link is to myself. It's a fakey compiler, and doesn't do what it's supposed to. Instead of running the code that you see on the page, it sets document.body.innerHTML to 5, regardless of what it's "compiling". You can see in this jsfiddle that the code actually prints 4 in a legit compiler

\$\endgroup\$
2
  • \$\begingroup\$ How does this work? \$\endgroup\$
    – ACarter
    Jun 6, 2014 at 10:13
  • 1
    \$\begingroup\$ @ACarter i don't want to say in the comments, so I'll update the question. I guess my current spoiler isn't obvious enough \$\endgroup\$ Jun 6, 2014 at 22:50
2
votes
\$\begingroup\$

GolfScript

[123 45 49 42 45 41 125 58 43 59]+~# These are my lucky numbers.

2 2+

The evaluated string redefines the addition operator as {-1*-)}:+, i.e., normal addition incremented.

-5...??./*-2/:2;

2 2+

-5...??./*-2/:2 saves -5 * (-5 ** (-5 ** -5) / -5 ** (-5 ** -5)) / 2 (also known as 2.5) in the variable 2.

{;5print}:puts

2 2+

This overwrites the implicit output function puts with a new function that always prints 5.

\$\endgroup\$
2
votes
\$\begingroup\$

Javascript (should work in a bunch of other languages too):

It adds what looks like 2+1+1

Math.ceil((0.2+0.1)*10)+1

Try doing the math yourself:

  • (0.2+0.1)*10 = 3
  • Math.ciel(3) = 3
  • 3+1 = 4

This works because of how floating point decimals work. 0.2+0.1 is just a little bit more than 0.3. Multiplying it by ten and then rounding it up gives us 4. Then we add an extra 1 because it should be 3 by now. When we do that, the result is 5.

\$\endgroup\$
1
  • \$\begingroup\$ I posted almost the exact same answer. The strangeness of floats can really make 2+2=5. \$\endgroup\$
    – wolfhammer
    Sep 5, 2014 at 20:08
2
votes
\$\begingroup\$

Perl 5

Example 1

(2 != 3) ? $x = 2 + 2 
         : $x = 2 + 3;
print $x;

? defines an lvalue and has higher precedence than assignment, so the code is equivalent to ((2 != 3) ? ($x = 2 + 2) : $x) = 2 + 3.

Example 2

@a = ("one", "2");
$x = length @a;
$x += length reverse @a;
print $x;

Length is string length, not list length, and hence expects a scalar. Arrays in scalar mode return their length, so length @a = length "2" = 1. Reverse in scalar mode concatenates and reverses its input, so length reverse @a = length "2eno" = 4.

Example 3

print (2 + 3) - (2 + 3) + (2 + 2);

The first set of parentheses define the arguments to the builtin print; the remaining calculation is applied to the return value of print and discarded.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.