26
\$\begingroup\$

Task

Write a polyglot in two languages that when run, outputs the name of the language it is run in. Additionally, this program must also output the other language's name if the source code is reversed

Example:

Program ABC in language foo outputs foo. ABC in language bar outputs bar. CBA in language foo outputs bar, and CBA in language bar outputs foo.

This is code-golf, so the shortest code wins

\$\endgroup\$
2
  • \$\begingroup\$ Does anyone see how to use Haskell in an answer? \$\endgroup\$
    – Simd
    Commented Feb 13, 2023 at 7:29
  • \$\begingroup\$ Please add a comment here if anyone had an implementation of txeT before this question posted. :) \$\endgroup\$
    – tsh
    Commented Feb 23, 2023 at 8:11

15 Answers 15

16
\$\begingroup\$

JavaScript, HTML, 68 bytes

HTML JavaScript
Normal
<!---->HTML<!--!<tpircSavaJ>--
alert`JavaScript`//`LMTH`trela
<!--!<
<!---->HTML<!--!<tpircSavaJ>--
alert`JavaScript`//`LMTH`trela
<!--!<
Reversed
<!--!<
alert`HTML`//`tpircSavaJ`trela
-->JavaScript<!--!<LMTH>----!<
<!--!<
alert`HTML`//`tpircSavaJ`trela
-->JavaScript<!--!<LMTH>----!<

JavaScript is a strange language that support 5 kinds of comment and 5 kinds of link breaks.

Comment:

  • Multi line comment /* ... */ Ref
  • Single line comment // ... Ref
  • Hashbang comment #! ... Ref
    • Must at the beginning of source code
    • Some script host support an extra BOM in front of hashbang
  • Single line HTML open comment <!-- ... Ref
  • Single line HTML close comment --> ... Ref

Line breaks: Ref

  • <LF>
  • <CR>
  • <LS>
  • <PS>
  • <CR> <LF>
\$\endgroup\$
14
\$\begingroup\$

Python + ><>, 49 bytes

#o<"><>"
print("python")#)"><>"(tnirp
"nohtyp"<o#

Try it:

\$\endgroup\$
12
\$\begingroup\$

Java and Whitespace, 175 bytes

v->"Java"//"ecapsetihW">-vSSTTN
SSTTTN
SSTTSTN
SSSTSTSN
SSSTTSTN
SSTTN
SSSTTTSN
SSSTTN
SSSTSN
SSTTTTTN
N
SSN
SSSTTSSTTSN
TSSSTN
SSN
SN
N
N
N
SN
SSN
TSSSTN
SSSSSTTSSSN
SSN
N
STTSTTSSN
TSSSN
STTSTSSSN
TSSS

Above, the spaces, tabs, and newlines are indicated with S; T; and N respectively for readability only. The TIO-links below contain the actual spaces/tabs/newlines.

Explanation:

In Java:

v->                        // Method with empty unused parameter & String return-type
   "Java"                  //  Return "Java"
         //"ecapsetihW">-v //  No-op comment
                           //  No-op spaces/tabs/newlines

In Java reversed:

                           // No-op spaces/tabs/newlines
v->                        // Method with empty unused parameter & String return-type
   "Whitespace"            //  Return "Whitespace"
               //"avaJ">-v //  No-op comment

In Whitespace:

v->"Java"//"ecapsetihW">-v // No-ops
SSTTN                      // Push -1 (e)
SSTTTN                     // Push -3 (c)
SSTTSTN                    // Push -5 (a)
SSSTSTSN                   // Push 10 (p)
SSSTTSTN                   // Push 13 (s)
SSTTN                      // Push -1 (e)
SSSTTTSN                   // Push 14 (t)
SSSTTN                     // Push 3 (i)
SSSTSN                     // Push 2 (h)
SSTTTTTN                   // Push -15 (W)
NSSN                       // Create Label LOOP
 SSSTTSSTTSN               //  Push 102
 TSSS                      //  Add the top two integers together
                           //  (which will implicitly stop the program with an error if
                           //  there is just a single value on the stack)
 TNSS                      //  Print the top as character to STDOUT
 NSNN                      //  Jump to Label LOOP
NNSNSSNTSSSTNSSSSSTTSSSNSSNNSTTSTTSSNTSSSNSTTSTSSSNTSSS
                           // No-op whitespaces

In Whitespace reversed:

SSSTN                      // Push 1 (a)
SSSTSTTSN                  // Push 22 (v)
SSSTN                      // Push 1 (a)
SSTTSTTSN                  // Push -22 (J)
NSSN                       // Create Label LOOP
 SSSTTSSSSSN               //  Push 96
 TSSS                      //  Add the top two integers together
                           //  (which will implicitly stop the program with an error if
                           //  there is just a single value on the stack)
 TNSS                      //  Print the top as character to STDOUT
 NSNN                      //  Jump to Label LOOP
NNSNSSNTSSSTNSTTSSTTSSSNSSNNTTTTTSSNSTSSSNTTSSSNSTTTSSSNTTSSNTSTTSSSNSTSTSSSNTSTTSSNTTTSSNTTSS
                           // No-op whitespaces
v->"Whitespace"//"avaJ">-v // No-ops

The constants 102 and 96 are generated by this Java program based on this Whitespace tip of mine.

\$\endgroup\$
11
\$\begingroup\$

05AB1E and Y, 15 bytes

"Y"gxg"E1BA50"R

Explanation:

In 05AB1E:

"Y"              # Push string "Y"
                 #  STACK: "Y"
   g             # Pop and push its length
                 #  STACK: 1
    x            # Double it (without popping)
                 #  STACK: 1,2
     g           # Pop and push its length
                 #  STACK: 1,1
      "E1BA50"   # Push string "E1BA50"
                 #  STACK: 1,1,"E1BA50"
              R  # Reverse it
                 #  STACK: 1,1,"05AB1E"
                 # (after which the top of the stack is output implicitly)

In 05AB1E reversed:

R                # Reverse (without input, it'll push an empty string)
                 #  STACK: ""
 "05AB1E"        # Push string "05AB1E"
                 #  STACK: "","05AB1E"
         g       # Pop and push its length
                 #  STACK: "",6
          x      # Double it (without popping)
                 #  STACK: "",6,12
           g     # Pop and push its length
                 #  STACK: "",6,2
            "Y"  # Push string "Y"
                 #  STACK: "",6,2,"Y"
                 # (after which the top of the stack is output implicitly)

In Y:

"Y"              # Push string "Y"
   g             # Pop and print it
    x            # Stop the program
     g"E1BA50"R  # No-ops

In Y reversed:

R                # No-op character
 "05AB1E"        # Push string "05AB1E"
         g       # Pop and print it
          x      # Stop the program
           g"Y"  # No-ops
\$\endgroup\$
1
  • 1
    \$\begingroup\$ There's a minor mistake in the explanation for the 05AB1E reverse program. When the program is reversed, the string literal reads 05AB1E, not E1BA50. \$\endgroup\$ Commented Nov 22, 2023 at 0:45
9
\$\begingroup\$

Python + Javascript(Node.js) 150 bytes

Uses the differences between javascript objects and python dicts to change code passed to eval in both languages. Uses both quoting styles with escaping to evaluate different code when reversed

"'\",)]'0'[}')'\nohtyP'\(gol.elosnoc':0,')'\tpircsavaJ'\(tnirp':'0'{(lave,'",eval({"0":"print(\"Python\")",0:"console.log(\"Javascript\")"}["0"]),'\"'

Python normal

Javascript normal

Python reversed

Javascript reversed

\$\endgroup\$
3
  • 3
    \$\begingroup\$ 96 bytes if you use SpiderMonkey: Try it online! \$\endgroup\$
    – Neil
    Commented Feb 6, 2023 at 21:56
  • 1
    \$\begingroup\$ @Neil Can you reverse the quotey \$\endgroup\$
    – l4m2
    Commented Feb 10, 2023 at 2:58
  • \$\begingroup\$ @l4m2 Nice, and you can do it in the reversed program too for 92! "'\",)]0[}'nohtyP':'0','tpircsavaJ':0{(tnirp,'",print({0:"Python","0":"Javascript"}[0]),'\"' \$\endgroup\$
    – Neil
    Commented Feb 10, 2023 at 8:36
8
\$\begingroup\$

C/C++, 119 bytes

#include<stdio.h>//
int main(){puts(sizeof!0-1?"C":"C++");}//};)"++C+0\C0"+0!foezis(stup{)(niam tni
//>h.oidts<edulcni#

Try it online!

Reference

Old: C/C++, 167 bytes

#include<stdio.h>//
int main(){puts("C"//
#ifdef __cplusplus//
"++"//
#endif//
);}//};)
//fidne#
//"++"
//sulpsulpc__ fednfi#
//"C"(stup{)(niam tni
//>h.oidts<edulcni#

Try it online!

Not that elegant due to #ifdef but resolving it also save bytes done

\$\endgroup\$
7
\$\begingroup\$

PHP Perl 4 or 5, 45 43 41 bytes

print-true?php:perl;#;php:lrep?eurt-tnirp

Try it online PHP

Try it online Perl

A simple take at it, I assumed it was not mandatory to specify the Perl version as it is not a polyglot between different versions of perl (though I could do one). Works in Perl 4 or 5

Takes advantage of the fact that PHP converts true to 1 for numerical operations while Perl 4/5 ignores it

EDIT: saved 2 bytes by removing 1, -true is enough (with swaped languages names)

EDIT 2: thanks to Neil for saving another 2 bytes removing the spaces

\$\endgroup\$
2
  • \$\begingroup\$ Now that you no longer have the 1, do you still need the spaces? \$\endgroup\$
    – Neil
    Commented Feb 7, 2023 at 22:26
  • \$\begingroup\$ @Neil good catch, I don't indeed, thanks \$\endgroup\$
    – Kaddath
    Commented Feb 8, 2023 at 8:08
6
\$\begingroup\$

C and Python, 163 119 bytes

p=0//1;print("Python")#//#
#define p;main(){puts("C");}//#
p
#//};)"nohtyP"(stup{)(niam;p enifed#
#//#)"C"(tnirp;1//0=p

Try it online!


warning-less & C99 compliant version, 235 bytes

#include<stdio.h>//#
#define p int main(void){puts("C");}//#
#if 0//fidne#
print("Python");p=0//1#//#
#endif//0 fi#
p
#if 0//fidne#
#//#1//0=p;)"C"(tnirp
#endif//0 fi#
#//};)"nohtyP"(stup{)diov(niam tni p enifed#
#//>h.oidts<edulcni#

Try it online!

Turns out, since C99, main() does implicitly return 0 which indicates successful termination. A single # (with optional whitespaces and/or comments after it) followed by a new line is also allowed; The standard calls it "Null directive".

\$\endgroup\$
2
  • \$\begingroup\$ Is it possible to make a version without C warnings? \$\endgroup\$
    – Simd
    Commented Feb 13, 2023 at 7:27
  • 1
    \$\begingroup\$ @Simd Yes. You have to add an #include <stdio.h> for puts() and the int type specifier for main(). Since it's C, the empty parameter list must also be (void), and you must explicitly return 0 (or EXIT_SUCCESS by also #including <stdlib.h>. Some compilers might not accept #), #//, )#. I had a version that (ab)used the #line directive and some extra Python boilerplate to workaround this. \$\endgroup\$
    – pan
    Commented Feb 14, 2023 at 13:34
2
\$\begingroup\$

Python 3.8 (pre-release) + JavaScript (Node.js), 95 bytes

1//print("Python")#1//)"nohtyP"(gol.elosnoc
console.log("JavaScript")//1#)"tpircSavaJ"(tnirp//1

Try it online! (Python)

1//print("Python")#1//)"nohtyP"(gol.elosnoc
console.log("JavaScript")//1#)"tpircSavaJ"(tnirp//1

Try it online! (JavaScript)

The python programs error after printing

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

dc and Fission, 35 bytes

[dc]P[;"cd"R"Fission";][[P]noissiF[

Try it online! dc in dc.

Try it online! Fission in Fission.

Try it online! Fission in dc reversed.

Try it online! dc in Fission reversed.

Explanations

dc → dc

[dc]P[;"cd"R"Fission";][[P]noissiF[
[dc]                                   push the string "dc"
    P                                  print without newline
     [;"cd"R"Fission";]                push the string (psuedo comment)
                       [               push the rest of the program as string (ditto)

Fission → Fission

[dc]P[;"cd"R"Fission";][[P]noissiF[
           R                           start an atom going right
            "Fission"                  print "Fission" and set the atom's mass to 7
                     ;                 destroy the atom

dc reversed → Fission

[Fission]P[[];"noissiF"R"dc";[P]cd[
[       ]                              push the string "Fission"
         P                             print without newline
          [                            push the rest of the program as string (psuedo comment)
                                       note that dc's [strings] nest
                                       and also doesn't complain with an unterminated string

Fission reversed → dc

[Fission]P[[];"noissiF"R"dc";[P]cd[
                       R               start an atom going right
                        "dc"           print "dc" and set the atom's mass to 2
                            ;          destroy the atom
\$\endgroup\$
2
\$\begingroup\$

Minecraft Function and C, 243 bytes

#include <stdio.h>//a fednu#
#define w int main(){printf("C");}//a fednu#
w
#undef a//>h.oidts< edulcni#
#undef a//};)"noitcnuF tfarceniM"(ftnirp{)(niam tni w enifed#
#if 0//fidne#
tellraw @a "Minecraft Function"#
#"C" a@ warllet
#endif//0 fi#

The C code is hidden behind preprocessor directives, which are interpreted as comments in the Minecraft function. The Minecraft code is hidden with #if 0 and #endif which is completely skipped by the compiler.

The code is written symmetrically with appropriate comments to comment out the reversed version. #undef a// (a comment in Minecraft and a no-op in C) is used to hide the reversed code.

The w, which is interpreted in C as int main(){printf("C");}, is also a valid Minecraft command. It has the wrong number of arguments, which causes a silent error, but the rest of the function still runs.

Try It Online:

(Minecraft Function not available on TIO)

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

Python, JavaScript (Node.js), 107 bytes

00000000: 2321 2f2f e280 a863 6f6e 736f 6c65 2e6c  #!//...console.l
00000010: 6f67 2822 4a61 7661 5363 7269 7074 2229  og("JavaScript")
00000020: 2f2f 2922 6e6f 6874 7950 2228 676f 6c2e  //)"nohtyP"(gol.
00000030: 656c 6f73 6e6f 63e2 80a8 3b60 230a 7072  elosnoc...;`#.pr
00000040: 696e 7428 2250 7974 686f 6e22 2923 2922  int("Python")#)"
00000050: 7470 6972 6353 6176 614a 2228 746e 6972  tpircSavaJ"(tnir
00000060: 700a 2360 e280 a82f 2f21 23              p.#`...//!#

No TIO link available...

All you need is comment out whatever you don't want...

\$\endgroup\$
5
  • \$\begingroup\$ on my machine the reversed javascript doesn't run \$\endgroup\$
    – emirps
    Commented Feb 7, 2023 at 13:31
  • \$\begingroup\$ @emirps I reversed the program using python -c 'open("2.js","w",encoding="utf-8").write(open("1.js",encoding="utf-8").read()[::-1])'. And execute it using node 2.js. Let me know any errors you will get after execute these commands. \$\endgroup\$
    – tsh
    Commented Feb 8, 2023 at 1:50
  • \$\begingroup\$ @emirps and the node version is v12.22.9 I'm using. As this program does not use any non-standard node features, it should work for any node version newer than 12.22.9. \$\endgroup\$
    – tsh
    Commented Feb 8, 2023 at 1:59
  • \$\begingroup\$ Note that those periods in the ASCII preview are not really periods. You may need to use a command like cat tsh_poly.xxd | xxd -r > tsh_poly.pyjs to create the file for testing. \$\endgroup\$
    – M Virts
    Commented Feb 8, 2023 at 20:08
  • 1
    \$\begingroup\$ @MVirts your command is about how to create 1.js described in above command \$\endgroup\$
    – tsh
    Commented Feb 9, 2023 at 1:35
1
\$\begingroup\$

Vyxal + 05AB1E, 39 bytes

"‛₴ŀ,Q,`E1BA50``"i0"laxyV"}"05AB1E"0i0`

Vyxal code

Vyxal code reversed

05AB1E code

05AB1E code reversed

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

Clip and Fission, 18 bytes

"Clip";"noissiF"L+

Try it online in Fission!

Try it online in Fission reversed!

No online link for Clip.

In Clip, most things after the first entity and its parameters recursively don't matter. (Some operators also wait for input, but not in this case.) Strings takes no parameters. L is an empty list. + is for concatenation.

In Fission, L emits an atom to the left and ; destroys the atom. Strings in double quotes on the path of the atom are printed. It wraps around on the edges like most 2D languages.

GolfScript and Fission, 25 bytes

"GolfScript"K}K"noissiF"L

Try it online in GolfScript!

Try it online in Fission!

Try it online in GolfScript reversed!

Try it online in Fission reversed!

In GolfScript, K is a no-op and } is a super comment.

In Fission, K works like ; but also does something else that doesn't matter. Using ; here would break GolfScript.

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

JavaScript (Node.js) and brainfuck, 2077 bytes

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>>.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/eval("console\56log('JavaScript')")//)")'kcufniarb'(gol65\elosnoc"(lave

Try it online - JavaScript

Try it online - brainfuck

Try it online - JavaScript (reversed)

Try it online - brainfuck (reversed)

Explanation:

In JavaScript, the main code looks like this - an eval statement with the bf code on the left inside /* */, and the reversed JS code on the right to the right of //

/* brainfuck code */ eval("console\56log('JavaScript')") //reversed JavaScript

Note that if I used . or [] to get the log property of console, then those characters would affect brainfuck, so I used eval, and replaced the . with it's octal escape sequence.

On the brainfuck side, the code looks like this (when broken onto separate lines):

++++++++++++++++++++++++++++++++++++++++++++++++.>    print 'b'  
+++++++++++++++++++++++++++++++++++++++++++++++++++.> print 'r'  
+++++++++++++++++++++++++++++++++++++++++++++.>       print 'a'  

>.+++++++++++++++++++++++++++++++++++++++++++++       print ascii(0)    
>.+++++++++++++++++++++++++++++++++++++++++++++++++++ print ascii(0)
>.++++++++++++++++++++++++++++++++++++++++++++++++    print ascii(0)

A purist may claim that I've cheated because I'm outputting ascii zeros, however the effect on TIO is that these chars don't appear or do anything to the output.

I couldn't use [], because when reversed it becomes ][ which are mismatched and will give rise to an error.

\$\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.