Restricted Polyglot

20

1

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

nneonneo

Posted 2014-09-27T23:28:32.337

Reputation: 11 445

@IngoBürk: The rule prevents you from writing a functional polyglot which involves Whitespace, unless somehow your other language is also whitespace-only. – nneonneo – 2014-09-28T00:49:59.660

1FWIW your example, print("Hello World!") is also valid Ruby code – Cristian Lupascu – 2014-09-28T12:38:58.153

It's a little annoying that the simple answers (like mine) to a [polyglot] tend to be able to have so many languages. – Justin – 2014-09-28T19:40:20.823

5To 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 'SO- stop being evil' – 2014-09-29T12:09:35.093

Answers

13

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.

jimmy23013

Posted 2014-09-27T23:28:32.337

Reputation: 34 042

...wait, how does this work in all three languages, without being redundant? – nneonneo – 2014-09-30T15:47:47.793

@nneonneo It simply prints all the unused code in other languages. – jimmy23013 – 2014-09-30T21:40:54.233

8

Bash + Befunge

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

prints 'hello' in befunge.

saeedn

Posted 2014-09-27T23:28:32.337

Reputation: 1 241

1I 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 – 2014-10-01T05:33:14.630

7

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

-->

Dennis

Posted 2014-09-27T23:28:32.337

Reputation: 196 637

Also works in Guile, at least if you pipe it in on standard input; my version prints a prompt and then exits. Apparently it can't tell that it isn't being used interactively. – None – 2016-11-24T13:31:43.037

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 – 2014-09-30T05:02:56.793

Thanks! Sadly, I can't convince huh? to run on Linux... – Dennis – 2014-09-30T05:15:55.267

Sadly, I deleted the interpreter from my computer, and I can't download the interpreter on this network. – Justin – 2014-09-30T05:43:10.153

1All I needed was an extra package for mono. Your program prints What?\n?, by the way. – Dennis – 2014-09-30T06:39:53.650

1Also works in GNU Make (if that's a programming language): make: *** No targets. Stop. – jimmy23013 – 2014-10-05T13:18:29.877

@user23013: Makefiles are Turing complete, so I'd say yes. Thanks! (The output is entirely different on my system.) – Dennis – 2014-10-05T13:48:51.820

@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. – jimmy23013 – 2014-10-05T13:54:37.783

1@user23013: Right. In that case, it's not a valid entry, since make's exit code is 2. – Dennis – 2014-10-05T13:57:00.793

@Dennis Ah... make -f polyglot some_existed_file works, but I don't think that should qualify... – jimmy23013 – 2014-10-05T14:03:29.107

6

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?
?

Justin

Posted 2014-09-27T23:28:32.337

Reputation: 19 757

@IngoBürk HTML + CSS is turing complete and therefore can perform arithmetic, (it essentially can emulate rule 110) – Rohan Jhunjhunwala – 2017-04-18T20:57:57.887

1Also works in CJam – August – 2014-09-28T04:10:54.950

5I don't think interactive interpreters should count. – nneonneo – 2014-09-28T04:12:11.603

2This runs fine in a lot of languages, but doesn't provide output in that many... – Justin – 2014-09-28T04:15:46.313

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 – 2014-09-28T05:33:58.550

HTML is not a programming language according to the meta discussion as it has no means of simple arithmetic or loops. – Ingo Bürk – 2014-09-28T08:34:35.893

bc prints 10 on my machine. Matlab and Scilab prints ans = 10 (and possibly some whitespace). – Dennis – 2014-09-28T19:45:39.987

And in mathematica it should output 10 – Tally – 2014-09-28T19:52:56.650

Outputs 10 in Pyth – isaacg – 2014-09-29T07:44:20.813

It also seems to be valid in ///.

– Dennis – 2014-09-29T17:45:35.347

Should work in Javascript too.. – Tejas Kale – 2014-09-30T05:08:25.420

@TejasKale That only works in a JavaScript interpreter, such as the Chrome Console. But the standard for this website is that JavaScript needs to be wrapped in alert for it to be valid. Same with Python, we aren't allowed to simply post 10 as a quine in Python. – Justin – 2014-09-30T05:09:39.640

This does "work" in nodejs, but prints nothing(same for python). Reading the rules again, I see why these languages were not included. – Tejas Kale – 2014-09-30T05:14:55.540

TI-BASIC it outputs 10. – Timtech – 2014-09-30T23:55:17.190

3

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.

Qwertiy

Posted 2014-09-27T23:28:32.337

Reputation: 2 697

2

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)

Ingo Bürk

Posted 2014-09-27T23:28:32.337

Reputation: 2 674

2

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

Jerry Jeremiah

Posted 2014-09-27T23:28:32.337

Reputation: 1 217

You can remove the 0 for C. – Dennis – 2014-09-29T01:18:05.533

@Dennis Not in C89. – Gilles 'SO- stop being evil' – 2014-09-29T12:11:31.567

@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 – 2014-09-29T13:37:32.040

@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 'SO- stop being evil' – 2014-09-29T17:18:39.163

@Gilles: My interpretation of rule 3 is that the compiler must return 0, not the program. – Dennis – 2014-09-29T17:24:40.197

2

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

William Barbosa

Posted 2014-09-27T23:28:32.337

Reputation: 3 269

1

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.

R. Kap

Posted 2014-09-27T23:28:32.337

Reputation: 4 730

1

Perl + Ruby + Python

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

print "Hello World!"

hmatt1

Posted 2014-09-27T23:28:32.337

Reputation: 3 356

1Also works with Lua. – Trebuchette – 2015-09-04T17:10:58.483

This works in Python as well. – August – 2014-09-28T01:35:05.010

0

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.

user75200

Posted 2014-09-27T23:28:32.337

Reputation: 141

1

Your answer appears to be almost identical to this one: https://codegolf.stackexchange.com/a/100654/65326

– Uriel – 2017-10-24T10:58:53.583