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).

  • @IngoBürk: The rule prevents you from writing a functional polyglot which involves Whitespace, unless somehow your other language is also whitespace-only. – nneonneo Sep 28 '14 at 0:49
  • 1
    FWIW your example, print("Hello World!") is also valid Ruby code – GolfWolf Sep 28 '14 at 12:38
  • It's a little annoying that the simple answers (like mine) to a [polyglot] tend to be able to have so many languages. – Justin Sep 28 '14 at 19:40
  • 5
    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. – Gilles Sep 29 '14 at 12:09

11 Answers 11

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.

  • ...wait, how does this work in all three languages, without being redundant? – nneonneo Sep 30 '14 at 15:47
  • @nneonneo It simply prints all the unused code in other languages. – jimmy23013 Sep 30 '14 at 21:40

Bash + Befunge

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

prints 'hello' in befunge.

  • 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. – Justin Oct 1 '14 at 5:33

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

-->
  • 2
    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. – Justin Sep 30 '14 at 5:02
  • Thanks! Sadly, I can't convince huh? to run on Linux... – Dennis Sep 30 '14 at 5:15
  • 1
    All I needed was an extra package for mono. Your program prints What?\n?, by the way. – Dennis Sep 30 '14 at 6:39
  • 1
    Also works in GNU Make (if that's a programming language): make: *** No targets. Stop. – jimmy23013 Oct 5 '14 at 13:18
  • 1
    @user23013: Right. In that case, it's not a valid entry, since make's exit code is 2. – Dennis Oct 5 '14 at 13:57

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

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.

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)

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++.

  • You can remove the 0 for C. – Dennis Sep 29 '14 at 1:18
  • @Dennis Not in C89. – Gilles Sep 29 '14 at 12:11
  • @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. – Dennis Sep 29 '14 at 13:37
  • @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). – Gilles Sep 29 '14 at 17:18
  • @Gilles: My interpretation of rule 3 is that the compiler must return 0, not the program. – Dennis Sep 29 '14 at 17:24

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

Perl + Ruby + Python

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

print "Hello World!"
  • This works in Python as well. – August Sep 28 '14 at 1:35
  • 1
    Also works with Lua. – Trebuchette Sep 4 '15 at 17:10

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.

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.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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