22
\$\begingroup\$

Polyglots are programs that are valid in multiple programming languages simultaneously. Most such polyglots are written in such a way that certain constructs of one language are interpreted as comments of another language (e.g. #define in C being interpreted as a comment in several scripting languages).

I am curious to see if it is possible to make a non-trivial polyglot which contains no comments, but also immediately changes when you remove any non-whitespace character, I therefore challenge you to come up with such a program.

The concrete rules are as follows:

  1. (Output). Your program must produce some output on the console under each of your languages. That is, your program is not permitted to simply exit without printing anything.
  2. (Variance). As a relaxation of the standard polyglot definition, the program's output may vary between languages.
  3. (Errors). Your program must not produce any errors (broadly defined) under any of your languages. For most languages, this is defined as returning a non-zero exit code from the compiler and/or interpreter.
  4. (Restriction). The removal of any single non-whitespace character from your code should cause your program to change its behaviour under every one of your languages. The program may "change" by becoming invalid for that language, or by changing the output that is produced.
  5. This is a code challenge. Winner is the program which is valid in the most programming languages. Ties will be broken in favor of shorter program length.

The restriction rule doesn't apply to the removal of several characters. That is, it is fine if removing several characters simultaneously results in no change for one of your languages.

Observe that the restriction rule implies that you cannot use Whitespace as one of your languages, as removing any non-whitespace character won't change the behaviour of the Whitespace program.

Here's a simple example of a program that fulfills all the above restrictions, for the languages Python 2 and Python 3:

print("Hello World!")

Removing any character in print will cause both languages to throw a NameError; removing any bracket or quote will throw a SyntaxError, and removing any of the string characters will change the output in both languages. (Note that print("hello", "world") is a more subtle, but still valid program under the above rules).

This example is a bit lame because Python 2 and Python 3 are very similar, so I won't accept any other solutions that only use different versions of the same language (especially Python 2 and Python 3).

\$\endgroup\$
4
  • \$\begingroup\$ @IngoBürk: The rule prevents you from writing a functional polyglot which involves Whitespace, unless somehow your other language is also whitespace-only. \$\endgroup\$
    – nneonneo
    Sep 28, 2014 at 0:49
  • 1
    \$\begingroup\$ FWIW your example, print("Hello World!") is also valid Ruby code \$\endgroup\$ Sep 28, 2014 at 12:38
  • \$\begingroup\$ It's a little annoying that the simple answers (like mine) to a [polyglot] tend to be able to have so many languages. \$\endgroup\$
    – Justin
    Sep 28, 2014 at 19:40
  • 6
    \$\begingroup\$ To avoid the myriad language variants or languages with similar syntax, it would be more interesting to require that two languages count as different only if the program produces different output. \$\endgroup\$ Sep 29, 2014 at 12:09

12 Answers 12

13
\$\begingroup\$

Bash + GolfScript + CJam

"echo" []
{ cat<&3;} \
3<""<("echo" 'p'~)

Output

Bash:

[]
p~

GolfScript:

"echo"
echo{ cat<&3;}0

CJam:

echo{ cat<&3;}-1echop

There is a \x7f in the end of output of CJam.

\$\endgroup\$
2
  • \$\begingroup\$ ...wait, how does this work in all three languages, without being redundant? \$\endgroup\$
    – nneonneo
    Sep 30, 2014 at 15:47
  • \$\begingroup\$ @nneonneo It simply prints all the unused code in other languages. \$\endgroup\$
    – jimmy23013
    Sep 30, 2014 at 21:40
9
\$\begingroup\$

Bash + Befunge

"echo" $,$,"ol":,,,@

prints 'hello' in befunge.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I can attest that every character (except the space) does something in Befunge. I can't do so for the Bash though. This is impressive. \$\endgroup\$
    – Justin
    Oct 1, 2014 at 5:33
7
\$\begingroup\$

GolfScript + PHP + CJam + Mathematica + bc + Pyth + /// + TI-Basic + R + Octave + Matlab + Scilab + Numeric Topline + ?Fueue + huh?

10

In Golscript, PHP, CJam, Mathematica, bc, Pyth, ///, and TI-Basic, it outputs 10.

In R, it outputs [1] 10

In Octave, it outputs ans = 10

In Matlab and Scilab, it outputs ans = 10.

In Numeric Topline, it outputs 0.

If I understand Fueue properly, it outputs a newline, then acts as a cat program.

In huh?, it outputs

What?
?
\$\endgroup\$
14
  • 1
    \$\begingroup\$ Also works in CJam \$\endgroup\$
    – August
    Sep 28, 2014 at 4:10
  • 5
    \$\begingroup\$ I don't think interactive interpreters should count. \$\endgroup\$
    – nneonneo
    Sep 28, 2014 at 4:12
  • 2
    \$\begingroup\$ This runs fine in a lot of languages, but doesn't provide output in that many... \$\endgroup\$
    – Justin
    Sep 28, 2014 at 4:15
  • 1
    \$\begingroup\$ This is also valid in HTML, bc, Matlab and Scilab. If you change 72 to 10, it should print 0 in Numeric Topline. \$\endgroup\$
    – Dennis
    Sep 28, 2014 at 5:33
  • \$\begingroup\$ HTML is not a programming language according to the meta discussion as it has no means of simple arithmetic or loops. \$\endgroup\$
    – Ingo Bürk
    Sep 28, 2014 at 8:34
7
\$\begingroup\$

bc, GolfScript, Homespring, huh, Octave, Scilab (0 bytes)

Guaranteed to comply with rule 4. Not a winner, but would do well in the tie break.

Output

bc

Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.

GolfScript


Homespring

In Homespring, the null program is not a quine.

huh

?

Octave

GNU Octave, version 3.6.4
Copyright (C) 2013 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type `warranty'.

Octave was configured for "x86_64-redhat-linux-gnu".

Additional information about Octave is available at http://www.octave.org.

Please contribute if you find this software useful.
For more information, visit http://www.octave.org/get-involved.html

Read http://www.octave.org/bugs.html to learn how to submit bug reports.

For information about changes from previous versions, type `news'.

Scilab

Startup execution:
  loading initial environment

-->
\$\endgroup\$
10
  • 2
    \$\begingroup\$ I know there's an esolang which specifically prevents 0 length quines by doing this sort of thing (oh wait, that's Homespring). I believe huh? outputs something. \$\endgroup\$
    – Justin
    Sep 30, 2014 at 5:02
  • 1
    \$\begingroup\$ All I needed was an extra package for mono. Your program prints What?\n?, by the way. \$\endgroup\$
    – Dennis
    Sep 30, 2014 at 6:39
  • 2
    \$\begingroup\$ Also works in GNU Make (if that's a programming language): make: *** No targets. Stop. \$\endgroup\$
    – jimmy23013
    Oct 5, 2014 at 13:18
  • 1
    \$\begingroup\$ @Dennis The correct way running a file called polyglot should be make -f polyglot. Or you can simply rename that file to Makefile and then make. \$\endgroup\$
    – jimmy23013
    Oct 5, 2014 at 13:54
  • 1
    \$\begingroup\$ @user23013: Right. In that case, it's not a valid entry, since make's exit code is 2. \$\endgroup\$
    – Dennis
    Oct 5, 2014 at 13:57
3
\$\begingroup\$

Seems like this answer is not fully correct.
I partially fixed it, and going to improve the other part in a few days.

C++ & Javascript

The idea is:

void eval(bool="main=function(){alert('Hi from Javascript!')};puts=function(){};int=0");
int
main()
{
puts("Hi from C++!");
}

C++: http://codepad.org/SK2wbIDL
Javascript: Just copy code to the browser console

And a set of fixes to make it satisfy

(Restriction). The removal of any single non-whitespace character from your code should cause your program to change its behaviour under every one of your languages. The program may "change" by becoming invalid for that language, or by changing the output that is produced.

From Javascript side:

Changing int, main or puts will crash with reading of undeclared variable. But bool and Hi from C++! can be safely changes. Let's fix it:

puts=function(){}
puts=function(s){s=='Hi from C++!'?bool:nope}

If strings are equal, it checks existance of bool, otherwice it crashes with undeclared nope.

Now, there are 2 trailing semicolons that can be removed. The first is fixed esyly - just remove newline before int:

void eval(bool="main=function(){alert('Hi from Javascript!')};puts=function(){};int=0");int

The second is before }, so I need some constriction, valid in both languages and not requiring semicolon at the end in C++ or forsing a semicolon in js. Fine:

while(0);

It's impossible to omit semicolon in js as while needs the body.

So the program at the moment is:

void eval(bool="main=function(){alert('Hi from Javascript!')};puts=function(s){s=='Hi from C++!'?bool:nope};int=0");int
main()
{
puts("Hi from C++!");while(0);
}

From C++ side:

There are 2 problems: eval can have any name and all js code can be changed.

I'll try to fix them in a few days.

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

CJam + Golfscript

Okay, this is somewhat boring, but it's a start.

1,

Prints "0" in both languages. Removal of the 1 causes an error, removing the , prints "1" instead.

The same can be done with 1) or 1(. There are many alternatives.

(Yes, I know this isn't code-golf)

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

C and C++

#include <stdio.h>
int main() { puts("Hello!"); return 0; }

C and C++ are different languages that are almost compatible with each other - contrary to what you might hear C++ is not a superset of C. Look at http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B for some differences. The example above is not idiomatic C++ but it does work and produces the same output in both C and C++.

\$\endgroup\$
5
  • \$\begingroup\$ You can remove the 0 for C. \$\endgroup\$
    – Dennis
    Sep 29, 2014 at 1:18
  • \$\begingroup\$ @Dennis Not in C89. \$\endgroup\$ Sep 29, 2014 at 12:11
  • \$\begingroup\$ @Gilles: If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined. (The C89 Draft - 2.1.2.2 Hosted environment) That doesn't make the program invalid nor does it change its output, so for the purposes of this question, the 0 can be removed. \$\endgroup\$
    – Dennis
    Sep 29, 2014 at 13:37
  • \$\begingroup\$ @Dennis I think an unspecified exit code counts as making the program invalid as per the rules of this question. If it doesn't, make that a C89 implementation where this program returns a nonzero exit code, such as gcc -ansi on x86 (or many other architectures: what happens is that the return value of puts ends up being in the register where the runtime reads the value to return from the main function). \$\endgroup\$ Sep 29, 2014 at 17:18
  • \$\begingroup\$ @Gilles: My interpretation of rule 3 is that the compiler must return 0, not the program. \$\endgroup\$
    – Dennis
    Sep 29, 2014 at 17:24
2
\$\begingroup\$

JavaScipt, Lua, R and Python 3 - 24 bytes

May work on some other languages, I'll test latter.

alert=print;alert(1)

JavaScript was tested on Firefox's console and the other languages here, here and here

\$\endgroup\$
1
  • \$\begingroup\$ This does not work in Javascript. It shows the print dialog. \$\endgroup\$
    – emanresu A
    Aug 5, 2021 at 8:58
1
\$\begingroup\$

Perl + Ruby + Python

I think in PHP this would need a semicolon if you are running with -R.

print "Hello World!"
\$\endgroup\$
2
  • \$\begingroup\$ This works in Python as well. \$\endgroup\$
    – August
    Sep 28, 2014 at 1:35
  • 1
    \$\begingroup\$ Also works with Lua. \$\endgroup\$ Sep 4, 2015 at 17:10
1
\$\begingroup\$

Bash + sh + zsh + ksh, 4 bytes:

echo

Really simple and satisfies every rule:

  1. Outputs a newline in each of the languages.
  2. Output currently does not vary in any way between the languages.
  3. Does not produce an error in any of the languages...
  4. ...except when any of the characters are removed/changed.
\$\endgroup\$
0
\$\begingroup\$

Bash + sh + zsh + ksh + Windows Batch, 4 bytes:

echo

Really simple and satisfies every rule:

Outputs a newline which doesn't vary in each of the languages (but Windows Batch, which outputs ECHO is on, on the language you use), doesn't error, except when any letter is removed or changed.

\$\endgroup\$
1
0
\$\begingroup\$

Every single flavor of HQ9+, 1 byte

9

Including but not limited to HQ9+, FishQ9+, BrainfishQ9+, CHIQRSX9+, Unified HQ9+, H9+, HQ9++,HQ9+-, FHQ9+-, HQ9F+, HQ9+B, HQ9+~, HQ9+2D, HI9+, and probably some more that I've missed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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