g | x | w | all
Bytes Lang Time Link
180Python/Scratch240104T041811ZRhaixer
114Nim / Zsh250405T051431ZjanAkali
152AWK and JavaScript250404T103318Z鳴神裁四点一号
nan241217T234912ZRARE Kpo
150jBasher2 / 2let241217T173137Zmadeforl
122AutoHotkey v1 / AutoHotkey v2241214T104957ZXuesong
156Retina/JavaScript240103T151809ZJoao-3
103PHP 8.2.x and PHP 8.3.x240103T032807Z鳴神裁四点一号
104Jelly/Pyth180125T235424Zellie
114JavaScript V8 and Python 2220520T034217Zuser3604
150Lua/Python210726T203341ZJoseph W
053Vyxal V210724T122842Zemanresu
049Vyxal210725T150532ZAaroneou
233Assembly MIPS210102T103535ZEasyasPi
193ARM64/ARM32 Assembly201223T080823ZEasyasPi
091x86_64/i386 machine code with libc call210103T185341ZEasyasPi
117Python 2 and Zsh201222T194054Zpxeger
092Batch .cmd or .bat200507T125320ZScriptKi
1055Whitespace and Malbolge190830T101606ZKamila S
103Keg/><>191105T040701Zlyxal
308Go/Java 10+190818T064741ZPurple P
105sed190825T101037ZGammaFun
160Haskell and ink190819T133222ZSara J
086Bash/Zsh190818T080139ZGammaFun
106Perl 6 / Perl 5190602T204216Zbb94
nan190530T063541ZLegenDUS
812Brainfuck/PHP150903T164613ZPaper
089JavaScript 1.8/JavaScript 1.7150903T121207ZMario Tr
175Haskell/Standard ML MLton190305T022549Zdfeuer
203Hugs 98 Haskell/GHC Haskell190304T225130Zdfeuer
199Haskell GHC/Hugs98190306T034227Zdfeuer
112Python 3/Clojure190310T035055ZASCII-on
119Common Lisp / C170816T203936ZRenzo
166Racket/Standard ML190307T054316Zdfeuer
166Python/Clojure190305T084800Zsoweli N
230Java 7/Java 8190305T054947ZBenjamin
177Haskell/Racket190305T001619Zdfeuer
140Ruby/Crystal190304T171531ZCG One H
nanC89/C99150903T144607ZZaibis
163C++ gcc / R190113T090907ZdigEmAll
568Brainfuck/VBA immediate180712T141847ZDorian
130Yabasic / VBA180731T164939ZTaylor R
117VBScript/JScript180314T221138Zpeter fe
142Python/QBasic150903T201603ZDLosc
174C gcc / Processing.org Java mode180304T024825ZPrincePo
nanRuby/Python 3150905T231953ZPiccolo
144Python / CJam180125T173938ZEsolangi
140C and ecpp171121T020226ZMD XF
126Excel / Google Sheets170816T150016ZTaylor R
170Emoji/Emojicode170729T131836Zbetseg
201AWK/C++ gcc170423T180926ZRobert B
5342BF/SPL161127T230029Zclamchow
115Python / Retina150903T200849Zmbomb007
119JavaScript / Python3160908T052851Zstyfle
118PowerShell 2/PowerShell 3150903T150309ZAdmBorkB
195Haskell / Literate Haskell161027T082422Zuser6126
749brainfuck/C161026T214031ZIndiana
117Crystal / Ruby161026T212425ZZatherz
251sed / Hexagony 251 Bytes161026T154008ZRiley
179Python 2/C161026T123753ZErik the
168Emotinomicon/Python 2160925T160533Zacrolith
098JavaScript ES6 / Python2160901T171432Zstyfle
170JavaScript/Ruby150903T085823ZDom Hast
134QBasic / Javascript150911T154331Zsteenber
277C/Java160725T123959ZGiacomo
5127Javascript ES6160610T163902ZBál
112Fuzzy Octo Guacamole and Jolf160407T152311ZRiker
071Pyke/Foo160407T144107ZBlue
116MATLAB / Octave151030T221331ZStewie G
nan160202T170545Zusername
115Mathematica 9/Mathematica 10160201T221920ZLegionMa
192Mouse2002 / Factor151212T200403Zcat
157Mouse2002 / Python 2151210T221718Zcat
157Shells/Emacs Lisp151210T115411ZLord Yuu
110JavaScript / JavaScript ES6151210T044130ZDowngoat
189Ruby 2.1.5/JavaScript150903T193701ZNot that
164BASH/JavaScript150906T144502ZRK.
160Python 2.7/><>151030T135405ZSjoerdPe
158Python/Lisp151016T164116ZThe Fift
099Perl/PHP150904T020624Zprimo
127Python 2.7.9/Python 2.7.10150910T164110ZDLosc
nan150911T164643Zuser4486
151jq / Python 3150911T150458Zuser4486
128Scala/Groovy150911T002712ZEmil Lun
181Java/Groovy150910T095509ZEmil Lun
185Batch .BAT File / Batch .CMD File150909T144608ZAdmBorkB
238C / Python150903T085035Zugoren
171Perl/Tcl150910T110832Zjkb
nan/// and Retina150909T141154ZMartin E
169Commodore 64 Basic/QBasic150909T084406ZMark
130JavaScript/JavaScript ES6150903T122232Zfrikinsi
nanJavaScript/Haskell150903T183216ZCR Drost
829Brainf***/Thue150903T202906ZSuperJed
102Python/Boo150908T195456ZMason Wh
144MySQL 5 / Perl 5150908T175713Zmsh210
418Java/C150907T093401ZMarcDefi
185Haskell/Python 185 Bytes150907T061842ZCubic
219Haskell / C150907T002355ZCubic
192TeX / BASH150906T235153Zsheß
nan150906T213719Zuser5288
006Perl 5 / Perl150906T205716Zuser5288
217Fishing/><>150904T161225ZTheNumbe
113Perl 5 / Perl 6150904T124543ZLukStorm
105Ruby/Python150905T193700Zpreshing
096PHP/Perl150903T213803ZDLosc
115VB6 / ES6 –150904T201729ZToothbru
124JavaScript/CoffeeScript150903T154738Zkirbyfan
130Befunge/><>150903T164742ZPurkkaKo
070Foo/CJam150903T091053Zjimmy230
843Brainfuck/Bash 4.3150903T090124Zrpax
936Brainfuck/Javascript150903T163153ZPaper
164Lua/C150903T084536Zbenpop
078CJam/GolfScript150903T091344Zjimmy230
167Python 3/><>150903T230047Zcole
148Selectors Level 4/Selectors Level 3150904T040351ZOriol
568823/Malbolge150904T031553ZDennis
191PHP/JavascriptES6150903T204430ZIsmael M
092Python 2/Python 3150903T082351Zfeersum
087Ruby 1.8/Ruby 1.9150903T181456Zhistocra
178PHP/Javascript150903T162252ZPaper
103Python/Pip150903T154207ZDLosc
143Javascript / C150903T101640ZQwertiy
129Perl/Ruby150903T140118ZDom Hast
147PHP/MySQL150903T123530ZRazvan
170Perl/JavaScript ES6150903T120957ZDom Hast
136C/C++150903T115829Zgrc
156SWIProlog 6/SWIProlog 7150903T084044ZFatalize
769Brainfuck/Foo150903T082601ZFatalize

Python/Scratch, 181 180 bytes

In Python (and scratchblocks)

round(1)//3;print("This program wasn't written in Python, it was built for Scratch!");"""
when gf clicked
say[This program wasn't written in Scratch, it was built for Python!]//"""

Explanation (for Python):

round(1)//3 is evaluated, and then the print is run; then a multiline comment comments out the rest of the program.

In Scratch:

enter image description here

Explanation (for Scratch):

The orphaned block round(1) is ignored; only the script is executed, which is self-explanatory.

Nim / Zsh, 114 bytes

#[]#var
 s="This program wasn't written in zsh, it was built for Nim!"
#[]#s[31..33]="Nim";s[53..55]="zsh"
echo $s

Try it online! (Nim)
Try it online! (Zsh)

How it works:

what Nim sees:

var                                                            # variable block, next line must be indented
 s="This program wasn't written in zsh, it was built for Nim!"
s[31..33]="Nim";s[53..55]="zsh"                                # two range substitutions
echo $s                                                        # `$` - convert to string operator (noop)

what zsh sees:

 s="This program wasn't written in zsh, it was built for Nim!" # preceding whitespace is ignored
echo $s                                                        # `$` is for referencing variables

AWK and JavaScript, 152 bytes

AWK

Full program. Requires GNU extension because of /*/.

/*/;END{print"This program wasn't written in AWK, it was built for JavaScript!"}#*/_=>"This program wasn't written in JavaScript, it was built for AWK!"

Try it online!

JavaScript

An anonymous function to return a string.

/*/;END{print"This program wasn't written in AWK, it was built for JavaScript!"}#*/_=>"This program wasn't written in JavaScript, it was built for AWK!"

Try it online!

AWK and JavaScript, 167 bytes

Full program for both languages. No GNU extension.

//;END{print"This program wasn't written in AWK, it was built for JavaScript!"}{
console["log"]("This program wasn't written in JavaScript, it was built for AWK!");//}

Try it online! (Awk)

Try it online! (JavaScript)

awk + perl

It exploits the facts that (1) ^ operator means exponentiation in awk, but bitwise xor in perl, and (2) $_ in awk is a field accessor, despite awk not permitting the $ sigil prefix for generic variables ::

1 := zero-to-zeroth power

0 := anything xor the-same-thing
__='BEGIN{printf("This program isn\47t written in %s, it was built for %s!\n",
                ($_="Perl")^int($_)?"awk":$_,$_^$_?$_:"awk")}'

perl -e "$__"

This program isn't written in Perl, it was built for awk!

[m/g]awk "$__"

This program isn't written in awk, it was built for Perl!

Unlike a lot of other submissions, code duplication is nearly non-existent, except having to spell out "awk" twice.

jBasher2 / 2let, 150 bytes

ag 3
output "This program wasn't written in jBasher2, it was built for 2let!"
aa This program wasn't written in 2let%comma% it was built for jBasher2!

easy lol

AutoHotkey v1 / AutoHotkey v2, 122 bytes

v:=2,v=1,s:="This program wasn't written in AutoHotkey v" v ", it was built for AutoHotkey v" 3-v "!",m:=&s,m=s
MsgBox %m%

Explanation

Equals after a comma is assignment in v1, but an ineffectual comparison in v2 instead. After v:=2,v=1, the value of v is 2/1 in v2/v1.

For the same reason, after m:=&s,m=s, m becomes a reference to the string s in v2, but in v1, the value of s is then assigned to m.

In v1, MsgBox is a commands and its arguments are considered as literal strings; i.e., MsgBox m outputs "m" instead of the target string; only when enclosed in percent signs, m is considered as the variable name. In v2, all strings must be quoted, and the meaning of double percent signs changed to dereference. In both versions, MsgBox will output the target strings.

Retina/JavaScript, 156 bytes

1/console.log("This program wasn't written in JavaScript, it was built for Retina!")///K`This program wasn't written in Retina, it was built for JavaScript!

Explained (explanations here with #):

1 # This is here so the following slash becomes division in JavaScript
 / # Start Retina RegEx; JavaScript treats this as division
  console.log("This program wasn't written in JavaScript, it was built for Retina!") # Print the message in JavaScript; in Retina this is treated as a RegEx
                                                                                    /// # End Retina RegEx and start and end a blank one; in JavaScript the first two slashes treat the following code as a comment
                                                                                       K`This program wasn't written in Retina, it was built for JavaScript! # Output the message in Retina

PHP 8.2.x and PHP 8.3.x, 103 bytes

This program wasn't written in PHP 8.<?=$_=2+range("0","A")[1]?>.x, it was built for PHP 8.<?=5-$_?>.x!

Try on PHP Sandbox

How it works

According to PHP: Backward Incompatible Changes,

<?php
range('9', 'A');  // ["9", ":", ";", "<", "=", ">", "?", "@", "A"], as of PHP 8.3.0
range('9', 'A');  // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], prior to PHP 8.3.0
?>

The following code depends on version difference:

range("0", "A")

Jelly/Pyth, 104 bytes

_"!ylleJ rof tliub saw ti ,htyP ni nettirw t'nsaw margorp sihT".q."
“zỤƦSṾƬỤƁɗe⁻ȷ6qḣ¢ƓṆ[²İ¦¥ỴȧỊ:Ċ¹ḃ$7f»

Run it in Jelly or Pyth

JavaScript (V8) and Python 2, 114 bytes

p=["Python","Javascript"]
x=3/2*2
print("This program wasn't written in "+p[x-2]+", it was built for "+p[3-x]+"!")

This takes advantages of the difference in division between Python 2 and Javascript, where Python 2 uses integer division, and that Javascript uses floating point division. This also uses the fact that V8 Javascript has a print() function.

Try it online! (JS)

Try it online! (Python)

Lua/Python, 150 bytes

Code:

print(1^2==1 and "This program wasn't written in Lua, it was built for Python!" or "This program wasn't written in Python, it was built for Lua!")

Explanation

This program makes use of three things:

  1. Python and Lua both print output with the 'print()' function.
  2. Python interprets the '^' operator as bitwise-xor, while Lua interprets it as an exponent operator.
  3. This was the tricky part. Python and Lua have completely different syntaxes and keywords for conditionals, so I had to find a syntax that means the same thing in both languages. I was able to do this when I stumbled upon the fact that ' and or ' will return the '' if '' is True, and '' if it is False.

When I first started this challenge, I attempted to make use of the fact that Python zero-indexes lists, while Lua one-indexes them. However, this failed because Lua uses curly brackets instead of Python's straight brackets. At first I thought it might work since curly brackets denote sets in Python, but Python doesn't allow you to access a set element the same way you access a list element since Python sets are by definition 'unordered,' so I gave up that idea and looked for alternatives until I remembered that the '^' operator doesn't mean exponentiation in Python, and I devised a solution based on the fact that the '^' operator means exponentiation in Lua, but not Python.

Try it Online! (Python)

Try it Online! (Lua)

Vyxal V, 53 bytes

`λ« ƛ¾ wṠǒ't «ḭ in %, it λ¨ €₇ λ⟑ %!`‛₴ŀ:‛ V+"w1→iR∑%

Try it Online!

`...`                            # String with % in place of the language names
     ‛₴ŀ              # String 'Vyxal'
        :             # Duplicate
         ‛ V+         # Append ' V' to one copy
             "        # Pair with itself
              w       # Wrap in a list
               1→iR   # If flagless, this stores 1 to the variable iR.
                      # If the V flag, this stores 1 to the variable i, and swaps the two
                   ∑  # Unwrap
                    % # Format, replacing the %s

-11 thanks to Aaron Miller.

Vyxal, Vyxal r, 62 49 bytes

-13 bytes because I really overcomplicated this :/

‛₴ŀ`₴ŀ r`"`λ« ƛ¾ wṠǒ't «ḭ in %, it λ¨ €₇ λ⟑ %!`$%

Try it Online!

Explanation:

‛₴ŀ                # Push "Vyxal"
   `₴ŀ r`          # Push "Vyxal r"
         "         # Join top two values
          `...`    # Push target string with "%" where the names should go
               $   # Swap top two values (does nothing with "r" flag)
                %  # Insert "Vyxal" and "Vyxal r" in the string where the "%" are

Assembly (MIPS, SPIM)/Assembly (GCC, MIPS Linux O32), 319 313 309 305 270 256 255 241 233 bytes

.globl main
main:la $5,p+9
lh $3,-7($5)
li $6,54
jal w
sub $5,5
li $6,5
jal w
xor $3,5
w:move $2,$3
syscall
jr $ra
.data
p:.word 0xf0fa4,0x5350494d
.ascii"!This program wasn't written in "
.word 0x4d495053
.ascii", it was built for "

Try it online!

Since it reuses argc, it must be called with no arguments. This is implied given that "neither program should take any input from the user.".

Outputs This program wasn't written in SPIM, it was built for MIPS! on SPIM (on a little endian machine).

Outputs This program wasn't written in MIPS, it was built for SPIM! on a real MIPS64 machine from the GCC Compiler Farm (specifically gcc22).

Explanation

Two words: Endian memes.

MIPS is big endian, while SPIM is little endian. This is perfect for us.

The first magic number is a "hybrid" encoding of the sys_write syscall. We store the SPIM syscall number in the most significant 16 bits, and the Linux syscall number in the least significant 16 bits.

We then do a halfword load on the address + 2.

On big endian, this would load the least significant bytes, while on little endian, it would load the most significant bytes. That is why you never cast pointers in C if you want your code to be portable. 😏

This is actually what we want: we will load the Linux syscall on big endian, and the SPIM syscall on little endian.

This is also used to obtain the sys_exit syscall number.

On SPIM, the syscall for sys_write is 15, while the syscall for sys_exit is 10.
On Linux, the syscall for sys_write is 4004, while the syscall for sys_exit is 4001.

15 XOR 10 is 4004 XOR 4001 is 5, so sys_write XOR 5 is sys_exit, quick maffs! 🤓

Therefore, to magically convert both the SPIM and MIPS syscalls from sys_write to sys_exit, we can simply XOR by 5!

The second two magic numbers are "SPIM" and "MIPS" in big endian packed ASCII, respectively. These are inline with the strings.

"SPIM" being simply "MIPS" backwards means that it will be reversed on little endian. On MIPS, this will be "SPIM" and "MIPS", respectively, while on SPIM, it will be "MIPS" and "SPIM", respectively.

The reason we store the strings backwards is because it is shorter, and more importantly, both GAS and SPIM will insert alignment bytes for .words if they are not 4 byte aligned which mangle our output.

By coincidence, the second half of the string ends one byte after a word boundary, and the first half of the string is one byte off from being aligned, so we just merge them together to remove all padding (and allowing us to merge the last ! into the next .ascii block).

| = word boundary, @ = padding, $ = EOS, W = .word
|   |   |   |   |   |   |   |   | W |   |   |   |   |   | W |
@This program wasn't written in MIPS, it was built for @SPIM!$
| W |   |   |   |   |   |   |   |   | W |   |   |   |   |   |
SPIM!This program wasn't written in MIPS, it was built for $

Note that while it looks like I could save space by writing 0xf0fa4 in base 10, I can't, because for some reason, SPIM doesn't like comma separated numbers unless they are in hex.

Ungolfed version (not compatible with SPIM because SPIM doesn't allow arithmetic in .word):

        .data
hybrid_syscall:
        # sys_write syscall. SPIM is the high 16 bits, MIPS Linux
        # is the low 16 bits.
        # By doing a halfword read, we can automatically read the
        # right syscall number thanks to endianness.
        .word (15 << 16) | 4004     # -9(string_1)

string_2: # "SPIM!"
        # "SPIM" in big endian packed ASCII.
        # SPIM will store this backwards as "MIPS".
        .word ('S' << 24) | ('P' << 16) | ('I' <<  8) | 'M'
        # This "!" also aligns string_1 so the "MIPS" is aligned.
        .ascii "!"

string_1: # "This program wasn't written in MIPS, it was built for "
        .ascii "This program wasn't written in "
        # "MIPS" in big endian packed ASCII.
        # SPIM will store this backwards as "SPIM".
        .word ('M' << 24) | ('I' << 16) | ('P' <<  8) | 'S'
        .ascii ", it was built for "

        .text
        .globl main
main:
        # Pointer to string_1
        la      $a1, string_1
        # Load the Linux sys_write syscall on big endian and the
        # SPIM sys_write syscall on little endian.
        # *(uint16_t *)(hybrid_syscall + 2) == sys_write
        # Uses a relative offset from string_1.
        lh      $v1, -9+2($a1)
        # strlen(string_1)
        li      $a2, 54
        # do_syscall(sys_write, string_1, strlen(string_1))
        jal     do_syscall

        # Pointer to string_2
        # In the golfed version, we subtract five from the last
        # pointer, because a1 is always returned unmodified.
        la      $a1, string_2
        # strlen(string_2)
        li      $a2, 5
        # do_syscall(sys_write, string_2, strlen(string_2))
        jal     do_syscall

        # Do an XOR to magically convert sys_write to sys_exit.
        xor     $v1, 5
        # FALLTHROUGH: do_syscall(sys_exit)

        # Runs a syscall.
        # C equivalent: syscall(v1, ...)
        # v1: syscall number
        # varargs: passed to syscall as-is
do_syscall:
        # Move the syscall number into v0.
        move    $v0, $v1
        # As long as our program is called with no arguments
        # which is implied by the rules, we can reuse argc to pass
        # 1 as the first argument, which corresponds to stdout.
        # li      $a0, 1

        # write(STDOUT_FILENO, string, length)
        # exit(1)
        syscall
        # Return
        jr      $ra

ARM64/ARM32 Assembly, 195 194 193 bytes

.globl main
main:@a:r0 .req x0;r1 .req x1;r2 .req x2
adr r0,s
adr r2,16
ldr r1,[r2],8
ldr r2,[r2]
b printf
.quad 64,32,64
s:.asciz"This program wasn't written in ARM%d, it was built for 
ARM%d!"

Works only with Clang's assembler in GNU syntax (not Apple syntax)

Explanation:

Not the smallest thing in the world but pretty clever IMO

@a:r0 .req x0;r1 .req x1;r2 .req x2

ARM32 uses '@' for comments, and this line is ignored. In ARM64, this is interpreted as a label.

The .req lines are simply aliasing the ARM64 registers to the ARM32 names.

It is basically the same as this:

#define r0 x0
#define r1 x1
#define r2 x2

This is the magic, though:

adr r2,16

Load r2 with the address pc + 16. In ARM64, the PC register points to the current instruction, but in ARM32, the PC register points to the current instruction plus 8 bytes, thanks to some questionable design decisions.

A similar trick can be done with Thumb, as in Thumb mode, the PC register points to the current instruction plus 4 bytes, but that isn't as interesting.

Therefore, r2 will point to 64, 32 on ARM64, and 32, 64 on ARM32.

$ clang wrongasm.s -m64 && ./a.out
This program wasn't written in ARM64, it was built for ARM32!
$ clang wrongasm.s -m32 && ./a.out
This program wasn't written in ARM32, it was built for ARM64!

x86_64/i386 machine code (with libc call), 91 bytes

One last machine code one, this time with actual machine code (and golfed assembly for the lulz). xx xx xx xx represents an unlinked placeholder, to main+23 (printf_str) and printf, respectively.

bf xx xx xx xx 8d 77 38  8d 57 3f 56 52 57 e8 xx
xx xx xx 5f 5a 5e c3 54  68 69 73 20 70 72 6f 67
72 61 6d 20 77 61 73 6e  27 74 20 77 72 69 74 74
65 6e 20 69 6e 20 25 73  2c 20 69 74 20 77 61 73
20 62 75 69 6c 74 20 66  6f 72 20 25 73 21 00 78
38 36 5f 36 34 00 69 33  38 36 00

x86_64: Try it online!

i386: Try it online!

What? You didn't expect me to not golf the demo, did you? 😏

Explanation

It is pretty simple. It abuses the fact that x86_64 and i386 have completely different calling conventions.

x86_64 (on Unix) passes (most) arguments in registers, starting with rdi, rsi, and rdx. It ignores the stack unless you run out of registers. This is called the System V calling convention.

i386 (on Unix and usually on Windows) passes all arguments on the stack in right to left (i.e. backwards from C) order. It ignores the registers. This is called the cdecl calling convention.

So I set up the x86_64 message in the registers, and the i386 message on the stack (with the arguments rearranged), then call printf. It's that simple.

Ungolfed assembly (substitute registers starting with r with e for i386):

        .intel_syntax noprefix
        .globl main
main:
        # First, set up a System V call for x86_64 in the registers.
        # We assume the program is low enough in memory and that PIC is off.
        #     printf(printf_str, "x86_64", "i386");
        mov     edi, offset printf_str
        lea     esi, [rdi + 56] # x86_64_str
        lea     edx, [rdi + 64] # i386_str
        # And then we set up a cdecl call for i386, but swap the arguments.
        # Since the arguments are already in registers, we can just push them.
        #     printf(printf_str, "i386", "x86_64");
        push    rsi # x86_64_str
        push    rdx # i386_str
        push    rdi # printf_str
        # Call printf, using each architecture's calling convention
        call    printf
        # Clean up the stack and return. We can't add to rsp, as the offsets
        # would be different on i386.
        pop     rdi
        pop     rdx
        pop     rsi
        ret
printf_str:
        .asciz "This program wasn't written in %s, it was built for %s!"
x86_64_str:
        .asciz "x86_64"
i386_str:
        .asciz "i386"

Python 2 and Zsh, 117 bytes

q="This program wasn't written in %s, it was built for %s!"
r='\';printf $q zsh Python;r=';print q%("Python","zsh")#'

Try it online! (Python)

Try it online! (zsh)

This works because of a difference in string tokenisation - in zsh, '\' is a whole string consisting of a backslash; in Python it's only the start.

Dead question, but as a Christmas project I'm working through the entire back catalogue of questions.

Batch (.cmd or .bat), 92 bytes

If this counts...

@set[=.cmd.bat&call echo This program wasn't written for %~x0, it was built for %%[:%~x0=%%!

Whitespace and Malbolge, 1318 1055 bytes

Did I just outgolf Dennis? Yes I outgolfed Dennis. Although, it happened so that Kevin outgolfed me. Thanks for -263!

  		   			D'`rq
  			">7<Y
  		kW8Ux
   	  54-P>
   			=MLon
  			 %[k5F
   	  h}UeA
  				b?,__
  			 		)(r8Y
  		  	   Xtsl2
   	 	 Sonmf
   			,jLba
  		 f_%cE
 	  		[`Y}@
   		  ?[ZYR
   	  vVUTS
   	RQJIm
   		 	M/KDh
  			 HA)E>
 	  	 	bB$@?
   	 		>=6Z{
  				3810/
   				.R2r0
 	  		/.'&+
   		  $H('&
   	feB"!
 	  	 ~`_{z
  					  s9qvu
  			tsrk1
  		 	ohmlk
  				jc)J`
   	   &GF\a
   	 		ZY^]\
  			UyYXW
   		  9UNrR
   	QJOHM
   Fj-CH
  		   	AF?c=
  		  	   B;:9]
   		 =<|{9
   	2V0v4
 	  	 -QP0/
   		 o-&Jk
  			)"!&}
   		  C#c!x
 }|u;s
    	xwpun
   	 	 4UTpo
   				ng-kj
 	  			ihgfH
   		  %]\[`
  		     	Y^W{[
   		 Z<RvV
   	 		UT65Q
  				JnNG/
   				Ei,HG
 	  		 F?D=B
   	 	A@?8\
  				<54Xy
   	 	 x6/S3
  		210/o
   			-&Jk#
 	  	 (!~%$
   	   {Ab~w
 	  			|u;yx
   	 		qYutm
   	3kpon
   g-kji
  		 	  hgfH%
]\[`_
  ^WVzZ
   		 	   <Rv9O
	   	TMRQP
  ImGLE
 DhHGF
ED=%;
_?>=<;4z2V6/u-,+O/.'&J*j(!~}C#c!x}|u;\xqvotsl2poQPlkd*KJ`ed]\"ZY^W{UZYRWVOsSRKJOHGkKJIHA@dDCBA#">7[;{z870Tu3210).-,%$H"'&%$#"!~w=^]s9Zvo5Vlqpih.leM*u

Try it online! (Malbolge)

Try it online! (Whitespace)

Keg/><>, 246 123 103 bytes

 "This program wasn't written in ><> it was built for Keg!"r>o<ø“0⊂kB7≤1⑵“` in Keg, it` “034⊂06“` ><>!`

-23 bytes saved to using string compression methods

Try it online! (><>)

TIO will be added after Keg is updated.

Answer History

123 bytes

 "This program wasn't written in ><> it was built for Keg!"r>o<ø`This program wasn't written in Keg, it was built for ><>!`

Try it online! (Keg)

Try it online! (><>)

-123 bytes due to @JoKing pointing out that I clearly haven't used ><> for a while. ;)

246 bytes

 "This program wasn't written in ><> it was built for Keg!"rvø`This program wasn't written in Keg, it was built for ><>!`#
#                                                     vo;!?l<
#                                                     >     ^

Try it online! (Keg)

Try it online! (><>)

Apparently, Keg polyglots well with 2d languages. Probably because strings aren't delimited with "'s but backticks rather.

Go/Java 10+, 308 bytes

Takes advantage of the var keyword introduced in Java 10. Will not run on earlier Java versions.

package main;/*\u002a\u002fpublic class Main{public static void main(String[]args){/**/var g="\u0022+";func main(){//";
g="Go";var j="Java";if(g!="Go"){var t=j;j=g;g=t;}
/*\u002a\u002fSystem.err./**/print("This program wasn't written in "+g+", it was built for "+j+"!");g="\u0022+"}//";
var w="\u0022+"//";}}

Ungolfed and commented:

// Required at the beginning of all Go programs.
// Consequently, the Java file needs to be saved in a directory called "main".
package main;
// Java substitutes unicode escape sequences like \u002a before lexing the code.
// It sees "/**/public class...", starting a main class and function.
// Go sees it as a comment.
/*\u002a\u002fpublic class Main{public static void main(String[]args){/**/

// Use another escape sequence to end a string for Java but not for Go, then
// declare Go's main function. Close the Java string with a quote hidden in a
// comment. Java sees "var g = ""+"...//";" while Go sees var g = "\"+";func...
var g = "\u0022+";func main() { //";
    // Reuse the variable g to save space
    g = "Go";
    var j = "Java";
    // The meat of detecting the language we're using.
    // Go's == compares strings by comparing their characters;
    // Java's == tests whether the strings are the same object.
    if (g == "Go") {
        var t = j;
        j = g;
        g = t;
    }
    // In Java, calls System.err.print. In Go, calls builtin "print",
    // which writes to stderr.
    /*\u002a\u002fSystem.err./**/print("This program wasn't written in " + g + ", it was built for " + j + "!");
    // Boilerplate to close Go. We can't close Java first nor let them share a
    // closing brace because Go needs and Java forbids "var" outside functions.
    g = "\u0022+"}//";
// Boilerplate to close Java.
var w = "\u0022+"  //";}}

sed, sed -E, 105 bytes

s/^/This program wasn't written in sed, it was built for sed -E!/
s/(.*)(,.*)( -E)(\(\)\(\)\(\))?/\1\3\2/

Try sed -E Try sed

The second line rearranges the -E only when -E is provided. The extra (\(\)... mess is to keep sed from erroring out from invalid match groups otherwise.

Haskell and ink, 160 bytes

--{i}ink{c}Haskell!->END
data K=VAR
g
 VAR i="This program wasn't written in "
f
 VAR c=", it was built for "
main=mapM putStr[g VAR 0,"Haskell",f VAR 0,"ink!"]

Try it online! (Haskell, ink)

In ink, the lines that begin with VAR are global variable declarations. Those happen at the start of the program regardless of whether those lines are ever reached during execution. This means we can end the program at the first line and not have to worry about printing anything we surround those with to make them look like valid Haskell.

In Haskell, the first line is a comment. We then define a datatype with VAR as a constructor. This lets us create functions that take VAR as a parameter, which is what lets us sneak ink's variable declarations in.

There is also a pretty boring 140-byte solution that abuses comment syntax to just concatenate two entirely separate programs (Haskell, ink)

Bash/Zsh, 86 bytes

a=({Z,Ba,Z}sh)
echo This program wasn\'t written in ${a[1]}, it was built for ${a[2]}!

Try it online! (Bash) | Try it online! (Zsh)

Bash indexes from 0, Zsh indexes from 1.

Perl 6 / Perl 5, 106 bytes

my $a=5;my @a=6;print "This program wasn't written in Perl ",11-$a[0],", it was built for Perl ",$a[0],"!"

Pretty standard fare with sigil inflection.

Try it online!

Aheui/Python3

'''
밣밙반따따밥다맣밙밚밤따따밥다맣밙밚밤따따밙다맣밙밚밤따따밙반따밙다다맣받밙반따따박다맣밙밚밤따따밙반따박다다맣밙밚밤따따밙반따밥다다맣밙밚밤따따밙반따반밧나다다맣밙밚밤따따받다맣밙밚밤따따밙반따밥다다맣밞밙반따따밠다맣밙밚밤따따밞다맣받밙반따따박다맣밙밚밤따따밙반따밞다다맣밞밙반따따밠다맣밙밚밤따따밙반따밙다다맣밙밚밤따따밙반따다맣받밙반따따밞다맣밙밚밤따따밙반따밦다다맣받밙반따따박다맣밙밚밤따따밙반따밞다다맣밙밚밤따따밙반따밥다다맣밙밚밤따따밙다맣밙밚밤따따밙반따밦다다맣밙밚밤따따밙반따밦다다맣밙밚밤따따반밧나다맣밙밚밤따따밙반따다맣받밙반따따박다맣밙밚밤따따밙다맣밙밚밤따따밙반따다맣받밙반따따박다맣밙밙밚밙밚밥밤따따따따따따밙밙밚밤따따따다맣밙밙밚밙밚밥밤따따따따따따밙밙밚밙밣따따따따밙밚밤따따밥밙반따따밣다다다다맣밥밙반따따밥다맣받밙반따따박다맣밙밚밤따따밙다맣밙밚밤따따밙반따밦다다맣받밙반따따박다맣밙밚밤따따밙반따밞다다맣밞밙반따따밠다맣밙밚밤따따밙반따밙다다맣받밙반따따박다맣밞밙반따따밣다맣밙밚밤따따밙반따밠다다맣밙밚밤따따밙다맣밙밚밤따따밣다맣밙밚밤따따밙반따밦다다맣받밙반따따박다맣밙밚밤따따박다맣밙밚밤따따밙반따반밧나다다맣밙밚밤따따밙반따밥다다맣받밙반따따박다맣밣밙반따따맣밙밚밤따따박밙반따따반밧나다다맣밙밚밤따따밙반따밦다다맣밙밚밤따따밥다맣밙밚밤따따밙반따반밧나다다맣밙밚밤따따밙반따다맣받밙반따따받다맣희
'''
print("This program wan't written in Python, it was built for 아희!")

Aheui code generated by https://apteryx.moe/straheui/.

Aheui code is in comment of python, while aheui dismiss every non-Korean characters.

Brainfuck/PHP 812 chars

<?php/*[-]>[-]>++++[-<++++++++>]<>[-]>++++++[-<++++++++++>]<+++++>[-]>++++++++++[-<++++++++++>]<---<<<>>+++++++++++++++++++.>+++++++.+.++++++++++.<<.>>---.++.---.--------.+++++++++++.-----------------.++++++++++++.<<.>>++++++++++.----------------------.++++++++++++++++++.-----.<<+++++++.>>++++++.<<-------.>>+++.-----.---------.+++++++++++..---------------.+++++++++.<<.>>-----.+++++.<<.>------------------.>++++.-----------------.++++++++.+++++.--------.+++++++++++++++.------------------.++++++++.<<++++++++++++.------------.>>--.+++++++++++.<<.>>+++.----------------------.++++++++++++++++++.<<.>>-----------------.+++++++++++++++++++.------------.+++.++++++++.<<.>>--------------.+++++++++.+++.<<.>++++++++++++++.--------.++++++++.<+.*/echo "This program wasn't written in PHP, it was built for Brainfuck!";

This is just Brainfuck Code in a PHP Comment that is getting ignored, while Brainfuck will ignore the PHP.

JavaScript 1.8/JavaScript 1.7, 89 bytes

a=![].reduce;`This program wasn't written in JS 1.${8-a}, it was built for JS 1.${7+a}!`

Because Array.prototype.reduce is new in 1.8

EDIT: Golfed out 7 bytes by directly initializing a instead of using reverse()

EDIT: JavaScript can be written as JS, saving 8 bytes

EDIT: Thanks Hedi for pointing out that I can save 3 more bytes if I don't use the variable b any more

EDIT: Golfed out 6 bytes by computing 7+a and 8-a, where a=1 if reduce is defined (JS 1.8) and a=0 if it is not defined (JS 1.7)

EDIT: Hedi golfed out 6 more bytes suggesting the use of template string

EDIT: ETHproductions golfed out 2 bytes suggesting a=!![].reduce; instead of a=[].reduce?1:0;

EDIT: no1xsyzy golfed out one more byte suggesting to revers the boolean check

Haskell/Standard ML (MLton), 175 bytes

Explanation

Haskell's line comment marker, --, is a valid name for a Standard ML (SML) identifier. SML's function and value introduction keywords, fun and val, are valid Haskell identifiers. So we define -- in SML to be the identity function (which arbitrarily defines fun in Haskell to be id). We define i in SML to be the beginning of the output string, which makes val in Haskell a constant function evaluating to that string. Then we can hide our main Haskell program in an ML comment, and hide the ML comment delimiters from Haskell using --.

Haskell, 175 bytes

fun--id
 =id;
val i="This program wasn't written in ";--print(i^"Standard ML, it was built for Haskell!");(*
main=putStrLn$val 1++"Haskell, it was built for Standard ML!"-- *)

Try it online!

Standard ML (MLton), 175 bytes

fun--id
 =id;
val i="This program wasn't written in ";--print(i^"Standard ML, it was built for Haskell!");(*
main=putStrLn$val 1++"Haskell, it was built for Standard ML!"-- *)

Try it online!

Hugs 98 Haskell/GHC Haskell, 203 bytes

Edit: Please also see this version, which is more interesting, and now shorter as well!

This takes advantage of an accidental change in the strictness of foldl' in the base library that came with GHC 7.10. Said change was noted several years ago, but has not been reverted. The "version names" I've used are a bit bogus, but they mirror the ones on TIO. It would be trivial to use something different.

import Control.Exception
import Data.List
p#q=putStrLn$"This program wasn't written in Haskell"++p++", it was built for Haskell"++q++"!"
main=handle(\ErrorCall{}->""#"98")$foldl'(!)(error"")[1]
_!_="98"#""

Try it online (GHC)

Try it online (Hugs)

Haskell GHC/Hugs98, 199 bytes

I've already written a different program for these language variants, but I think this one is much more clever. And now, it's also shorter!

Thanks to @ASCII-only for suggesting putStr instead of putStrLn. Thanks to @ØrjanJohansen for suggesting id rather than a custom operator for a related answer, and then shedding a full 30 bytes by realizing the Num instance can be left empty.

instance Eq(a->b)where _==_=0<1
instance Show(a->b)
instance Num(a->b)
p#q=putStr$"This program wasn't written in Haskell"++p++", it was built for Haskell"++q++"!"
main|(0`id`)==1=""#"98"|0<1="98"#""

Try it online (GHC Haskell)

Try it online (Hugs98 Haskell)

Explanation

Hugs 98 used a "relaxed" interpretation of operator sections, where (x!) meant (!) x. In even vaguely recent times, GHC has only used that relaxed interpretation when a certain language extension is enabled. The rest of the time, (x!) means \y -> (!) x y. The latter (more strictly standards-compliant) interpretation can cause the type constraints on (x`id`) to be stronger. In particular, it requires id to be a function of (at least) two arguments.

Haskell has a mechanism for defaulting ambiguous types under certain narrow conditions. The defaulting mechanism is just sensitive enough to the imposed constraints that we can detect the difference in operator section interpretation.

Open questions

Python 3/Clojure, 121 112 bytes

Based off nihilazo's answer.

# is comment in Python, and strings appearing next to each other are concatenated together, as in C.

Clojure is a Lisp, so parentheses need to surround every function. Since Python's print needs parentheses, we add printf inside the parentheses since it's the closest to a no-op we can use. As a bonus, printf lets us choose format the arguments very flexibly.
#_ skips the next form (list () or literal, e.g. number 0). Note that this doubles as comment character in Python.
%s and %n$s are the the same as in C, resolving to the next argument and the nth argument respectively.

Python 3

#_0
print(#_0 printf"%s%4$s%3$s%s!"
"This program wasn't written in ""Clojure"
", it was built for ""Python""!")

Try it online!

Clojure

#_0
print(#_0 printf"%s%4$s%3$s%s!"
"This program wasn't written in ""Clojure"
", it was built for ""Python""!")

Try it online!

Common Lisp / C, 208 156 150 119 bytes

;main(){puts(
//(format't"~A~2*~A~2@*~AC!"
"This program wasn't written in ""C"", it was built for ""Common Lisp""!");}

Try it online for C

Try it online for Common Lisp

-52 bytes thanks to @ceilingcat!

-37 bytes thanks to @ASCII-only and his excellent mastering of CL format function

Racket/Standard ML, 166 bytes

;val p=print(*
#lang racket
(display(string-append;*);p
"This program wasn't written in ";p"SML"(*
"Racket"; *);p
", it was built for ";p"Racket!\n";(*
"SML!\n")); *)

Try it online!

This is a port of my Racket/Haskell solution to ML.

Python/Clojure, 166 Bytes

#_()(println"This program wasn't written in Clojure, it was built for Python!")(comment
print("This program wasn't written in Python, it was built for Clojure!")#_())

Clojure – Try it online!

Python 3 – Try It Online!

Has room for improvement, not even a clever answer but I wanted to try it anyway.

Relies on the fact that #_() is an (unintentional?) reader no-op in Clojure (#_ will skip the next form, () is an empty form) yet starts a comment in python as python uses # for commenting.

Java 7/Java 8: 230 bytes

class M{public static void main(String[]a){Class c=null;try{c=Class.forName("java.time.Period");}catch(Throwable t){}System.out.printf("This program wasn't written in Java %d, it was built for Java %d!",c==null?7:8,c==null?8:7);}}

Try it online

Explanation
The java.time package was added in Java 8, which means it doesn't exist in Java 7 (or older), which will cause Class.forName to throw a ClassNotFoundException. The variable c stays null, which is then checked for by the tenary statements.

Haskell/Racket, 177 bytes

Just some simple comment play. I go to a bit of trouble to share strings.

Haskell

;p=putStr{-
#lang racket
(display(string-append;-};main=do{p
"This program wasn't written in ";p"Haskell"{-
"Racket";-};p
", it was built for ";p"Racket!\n"{-
"Haskell!\n"));-}}

Try it online!

Racket

;p=putStr{-
#lang racket
(display(string-append;-};main=do{p
"This program wasn't written in ";p"Haskell"{-
"Racket";-};p
", it was built for ";p"Racket!\n"{-
"Haskell!\n"));-}}

Try it online!

Ruby/Crystal, 149 140 bytes

v = 1e10.class == Float ? ["Ruby", "Crystal"] : ["Crystal", "Ruby"]
puts "This program wasn't written in #{v[0]}, it was built for #{v[1]}!"

Crystal is a language similar to Ruby, but it is compiled. In Crystal, the type of the literal 1e10 is Float64, while in Ruby it is Float. Probably can be golfed some.

C89/C99, 171 152 136 114 111 107 105 bytes

Thanks at @Hurkyls, @Qwertiys, @jimmy23013 and @MD XF for your hints.

golfed version:

c;main(){c=-4.5//**/
-4.5;printf("This program wasn't written in C%d, it was built for C%d!",90-c,98+c);}

ungolfed version:

c;

main()
{
    c = -4.5//**/
    -4.5;
    printf("This program wasn't written in C%d, it was built for C%d!",90-c,98+c);
}

Little description:

C versions previous C99 just had the multiline comment like this:

/*foo*/

with C99 the single line comment was introduced. like this:

//foo

so if you compile a line like this:

c =-4.5//**/
-4.5;

the for the c99 compiler compiling-related code would be:

c = -4.5 -4.5;

while the for a c89 compiler relevant code would be:

(as the first / isn't part of a comment and therfor treat as operator)

c = -4.5 / -4.5;

C++ (gcc) / R, 163 bytes

#include<cstdio>
#define cat(x)x
#define sprintf(a,b,c)int main(){printf(a,c,b);}
cat(sprintf("This program wasn't written in %s, it was built for %s!","R","C++"))

C++ (gcc) : Try it online!

R : Try it online!

# is the comment character in R, so using preprocessor's magic of C++ we can switch between the two languages

Brainfuck/VBA (immediate), 568 bytes

?"This program wasn't written in VBA, it was built for Brainfuck!"'>--->->>>>-->>>>>>->>-->>->>>-->>-->>>>>>>>-->>>-->->>->>>>>>>-->-->>>-->>->>-->>>>>>-->>>>-->->->->-->+[-[>+++++++<-]<+++]>---->++>--->-->->+>->->-->--->->+++>-->+>>+++>->-->++>->+>>->-->->->--->-->+>-->-->+>->->+++>-->-->--->->--->-->+++>+>-->->+>>+++>->+>--->->-->-->->+>--->-->->+>++>->->+>+[-[>+++++++<-]<++++]>---->--->+++>--->>+>--->->+++>++>->+++>+>+>--->+++>>++>+>+>+>--->->--->+>+>>++>+>--->++>+>>->+++>--->++>+>++>-->->->+>--->+>+>--->+++>>+>--->++>--->>+>+>+>+++>->+>->>->++>+[-<++++]>[.>]

Try it online!

Pretty simple approach.

Yabasic / VBA, 130 bytes

n=-8*(Now>0):?"This program wasn't written in "+Mid$("YabasicVBA",n,8)+", it was built for "+Trim$(Mid$("VBA    Yabasic",n,8))+"!"

Explaination

n=-8*(Now>0)                            ''  Key operation: Differentiates Between VBA and Yabasic
                                        ''  Now is defined in VBA with the system time, but not in
                                        ''  Yabasic; Evaluates to 0 in Yabasic, and 8 in VBA
?"This program wasn't written in "      ''  Print beginning of sentance
  +Mid$("YabasicVBA",n,8);              ''  Print current language
  +", it was built for "                ''  Print middle
  +Trim$(Mid$("VBA    Yabasic",n,8))    ''  Print other language
  +"!"                                  ''  Print Exclaimation mark

Try it online! (Yabasic)

VBScript/JScript, 117 bytes

a="J"
b="VB"
rem=c=a;a=b;b=c
WScript.echo("This program wasn't written in "+a+"Script, it was built for "+b+"Script")

Python/QBasic, 160 142 bytes

Tested with Python 3 and QBasic 1.1. Won't work in Python 2 without adding from __future__ import print_function to line 4.

1# DEFSTR A-B
a = "QBasic"
b = "Python"
'';a,b=b,a;PRINT=print
PRINT ("This program wasn't written in " + a + ", it was built for " + b + "!")

If I'm allowed to turn off the autoformatter (which is an option in QB64, though not in the original QBasic), I can get it down to 114 bytes using Python 2:

1#DEFSTR A-B
a="QBasic"
b="Python"
'';a,b=b,a
print"This program wasn't written in "+a+", it was built for "+b+"!"

C (gcc) / Processing.org (Java mode) 174 bytes

void setup(){//\
System.out.
printf("This program wasn't written in %s it was built for %s !",//\
"Processing","C"//\
/*
"C","Processing"//\
*/
);}//\
/*
main(){setup();}//*/

Ruby/Python 3, 127 122 114 109 bytes

a=["Python","Ruby"];b=(0 and 1);print("This program wasn't written in "+a[b]+", it was built for "+a[~b]+"!")

Explanation: Ruby evaluates 0 to true whereas Python evaluates it to false. The b=(0 and 1) determines whether 0 is truthy, so it represents the array index of the language it's being called from. Python had to come first because it can act oddly when the statement after the and evaluates to false. Also, that link says that it only works in older Python versions but I tried it in Python 3 and it worked fine.

Thanks kirbyfan64sos for removing 5 13 bytes!

Edit: Turns out 0 and 1 instead of 0 and 1 or 0 will also determine whether 1 is truthy in both languages.

Python / CJam, 144 bytes.

Not gonna win this, but it's interesting.

"""This program wasn't written in CJam, it was built for Python!" """;print('This program wasn\'t written in Python, it was built for CJam!')#";

To Python:

"""This program wasn't written in CJam, it was built for Python!" """

A multi-line string with """ delimiters. This is evaluated and the result is discarded.

;

End a statement and begin a new one.

print('...')

Print the message.

#";

A single-line comment.

To CJam:

""

Push an empty string to the stack.

"..."

Push the message to the stack.

 ""

The leading space does nothing, and "" pushes the empty string to the stack.

";print('This program wasn\'t written in Python, it was built for CJam!')#"

Push another string literal.

;

Delete that string literal. Now the stack contains "" "message" "". The stack items are concatenated together and printed.

C and ecpp, 140 bytes

#ifdef ECPP
#replace "C" "ECPP"
#replace "ECPP" "C"
#endif
main(){puts("This program wasn't written in ""C"", it was built for ""ECPP""!");}

Try ecpp online!
Try C online!

The #ifdef and #endif avoid syntax errors in C. #replace "C" "ECPP" replaces the string "C" with the string "ECPP", and #replace "ECPP" "C" replaces the string "ECPP" with "C".

This takes advantage of C's automatic string concatenation capabilities.

Excel / Google Sheets, 128 126 Bytes

Anonymous worksheet function that takes no input and outputs to the calling cell.

="This program wasn't written in "&IfError(M("Google Sheets, it was built for Excel"),"Excel, it was built for Google Sheets")

Or

="This program wasn't written in "&Substitute(IfError(M("Google Sheets1Excel"),"Excel1Google Sheets"),1,", it was built for ")

Emoji/Emojicode, 170 bytes

👴💬This program wasn't written in Emoji, it was built for Emojicode!💬➡
🏁🍇😀🔤This program wasn't written in Emojicode, it was built for Emoji!🔤🍉

Try Emoji online!
Try Emojicode online!

AWK/C++ (gcc), 201 bytes

#include <cstdio>
/*#\/* /
BEGIN{
#*/int main(){const char *a[2];
a[0]="AWK";a[1]="C++";
/*#\/* / 
b=0
#*/int b=1;
printf("This program wasn't written in %s, it was built for %s!\n",a[b], a[(b+1)%2]);}

Try it online - AWK!

Try it online - C++(gcc)!

I suppose this is essentially and AWK/C, but I tested it with C++ and am using #include <cstdio> so that makes it C++ right? :)

BF/SPL, 5342 bytes

I'm pretty sure this is the first Shakespeare Programming Language polyglot on this site.

Probably not going to win any prizes. Works by sneaking BF code into act/scene/program titles. The SPL code uses exclamation points instead of periods except for a few cases. The programs aren't supposed to take input, so the commas in the character declarations are "commented out" by zeroing cells and putting square brackets around the commas. The same procedure applies when hiding the square brackets around the enter/exeunt statements.

[-][.
Ford,.
Page,.
Act I:]+++++++++[>+++++++++<-]>+++.
Scene I:>[.
[Enter Ford and Page]
Ford:
You is sum of bad bad bad bad bad bad day and sum of bad bad bad bad day and bad bad day!Speak thy mind!
Scene II:]<<++[>++++++++++<-]>.
Page:
You is sum of bad bad bad bad bad bad day and sum of bad bad bad bad bad day and bad bad bad day!Speak thy mind!
Scene III:+.
Page:
You is sum of thyself and day!Speak thy mind!
Scene IV:++++++++++.
Page:
You is sum of thyself and sum of bad bad bad day and bad day!Speak thy mind!
Scene V:>++++[>++++++++<-]>.
Ford:
You is fat fat fat fat fat cat!Speak thy mind!
Scene VI:[-<+>]<<---.
Page:
You is sum of thyself and sum of big pig and pig!Speak thy mind!
Scene VII:++.
Page:
You is sum of thyself and fat cat!Speak thy mind!
Scene VIII:---.
Page:
You is sum of thyself and sum of big pig and pig!Speak thy mind!
Scene IX:--------.
Page:
You is sum of thyself and big big big pig!Speak thy mind!
Scene X:+++++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and sum of fat cat and cat!Speak thy mind!
Scene XI:<++++[->----<]>-.
Page:
You is sum of thyself and sum of big big big big pig and pig!Speak thy mind!
Scene XII:++++++++++++.
Page:
You is sum of thyself and sum of fat fat fat fat cat and big big pig!Speak thy mind!
Scene XIII:>.
Ford:
Speak thy mind!
Scene XIV:<++++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and fat cat!Speak thy mind!
Scene XV:<++++[->-----<]>--.
Page:
You is sum of thyself and sum of big big big big big pig and sum of fat fat fat cat and fat cat!Speak thy mind!
Scene XVI:<++++[>++++<-]>++.
Page:
You is sum of thyself and sum of fat fat fat fat cat and fat cat!Speak thy mind!
Scene XVII:-----.
Page:
You is sum of thyself and sum of big big pig and pig!Speak thy mind!
Scene XVIII:>+++++++.
Ford:
You is sum of thyself and sum of fat fat fat cat and pig!Speak thy mind!
Scene XIX:<++++++.
Page:
You is sum of thyself and sum of fat fat cat and fat cat!Speak thy mind!
Scene XX:>-------.
Ford:
You is sum of thyself and sum of big big big pig and cat!Speak thy mind!
Scene XXI:<+++.
Page:
You is sum of thyself and sum of fat cat and cat!Speak thy mind!
Scene XXII:-----.
Page:
You is sum of thyself and sum of big big pig and pig!Speak thy mind!
Scene XXIII:---------.
Page:
You is sum of thyself and sum of big big big pig and pig!Speak thy mind!
Scene XXIV:+++++++++++.
Page:
You is sum of thyself and sum of cat and sum of fat cat and fat fat fat cat.Speak thy mind!Speak thy mind!
Scene XXV:<+++[>-----<-]>.
Page:
You is sum of thyself and sum of big big big big pig and cat!Speak thy mind!
Scene XXVI:+++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and cat!Speak thy mind!
Scene XXVII:>.
Ford:
Speak thy mind!
Scene XXVIII:<-----.
Page:
You is sum of thyself and sum of big big pig and pig!Speak thy mind!
Scene XXIX:+++++.
Page:
You is sum of thyself and sum of fat fat cat and cat!Speak thy mind!
Scene XXX:>.
Ford:
Speak thy mind!
Scene XXXI:[->++<]>++.
Page:
You is sum of thyself and sum of big big big big big pig and sum of fat fat cat and cat!Speak thy mind!You is sum of thyself and sum of big pig and pig!Speak thy mind!
Scene XXXII:++++.
Page:
You is sum of thyself and big red hog!Speak thy mind!
Scene XXXIII:<+++++[>-----<-]>-.
Page:
You is sum of thyself and big big big big big pig!Speak thy mind!
Scene XXXIV:[-<+>]<------------.
Ford:
Speak thy mind!
Scene XXXV:<-----.
Page:
You is sum of thyself and sum of fat fat fat fat fat fat cat and sum of big pig and pig!Speak thy mind!
Scene XXXVI:+++++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and sum of fat cat and cat!Speak thy mind!
Scene XXXVII:>.
Ford:
Speak thy mind!
Scene XXXVIII:<+++.
Page:
You is sum of thyself and sum of fat cat and cat!Speak thy mind!
Scene XXXIX:<++++[->-----<]>--.
Page:
You is sum of thyself and sum of big big big big big pig and sum of fat fat fat cat and fat cat!Speak thy mind!
Scene XL:<++++[>++++<-]>++.
Page:
You is sum of thyself and sum of fat fat fat fat cat and fat cat!Speak thy mind!
Scene XLI:>.
Ford:
Speak thy mind!
Scene XLII:<<++++[>----<-]>-.
Page:
You is sum of thyself and sum of big big big big pig and pig!Speak thy mind!
Scene XLIII:<+++++[>++++<-]>-.
Page:
You is sum of thyself and sum of fat fat fat fat cat and sum of fat cat and cat!Speak thy mind!
Scene XLIV:------------.
Page:
You is sum of thyself and sum of big big big big pig and fat fat cat!Speak thy mind!
Scene XLV:+++.
Page:
You is sum of thyself and sum of fat cat and cat!Speak thy mind!
Scene XLVI:++++++++.
Page:
You is sum of thyself and fat fat fat cat!Speak thy mind!
Scene XLVII:>.
Ford:
Speak thy mind!
Scene XLVIII:<--------------.
Page:
You is sum of thyself and sum of big big big big pig and fat cat!Speak thy mind!
Scene XLIX:+++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and cat!Speak thy mind!
Scene L:+++.
Page:
You is sum of thyself and sum of fat cat and cat!Speak thy mind!
Scene LI:>.
Ford:
Speak thy mind!
Scene LII:>+++++++[<+++++++>-]<++.
Page:
You is sum of thyself and sum of big big big big big pig and big big big big pig!Speak thy mind!
Scene LIII:---.
Page:
You is sum of thyself and fat fat cat!Speak thy mind!
Scene LIV:----.
Ford:
You is sum of thyself and cat!Speak thy mind!
Scene LV:>+++++++[<------>-]<-.
Ford:
You is cat!
Scene LVI:>[.
[Exeunt]

Test out BF at https://repl.it/E8Hh/23.

SPL code was tested at the compiler found here: https://github.com/drsam94/Spl/.

Python / Retina, 133 120 119 117 115 bytes

Now that I know more about Retina and regexes, I've golfed it a bit more. It also actually works now.

#?.*
print"This program wasn't written in Python, it was built for Retina!"
#?.*t"

#?(\w+)(,.* )(.+)!"
#$3$2$1!
#

Python just prints the statement. Retina replaces anything with the Python print statement, then removes the print and any quotes. Then, I swap Python and Retina and remove the #.

Try in Python | Try in Retina

JavaScript / Python3, 119 bytes

i=1//2
d=['print','console.log']
s=['python','js']
eval(d[i])('this program is not '+s[i]+', it was built for '+s[1-i])

Tested on Node.js v6.x and Python 3.5.1

The trick was to use Python's "floor division" operator which is the same as JavaScript's line comment //. This is how we swap 0 and 1 for i depending on the language.

This won't work on python2 because print was not a function until python3 and therefore cannot be evaluated using eval. It should work for almost any JavaScript VM.

Edit

Golfed 7 bytes by removing j variable and using s[1-i] instead of s[j].

PowerShell 2/PowerShell 3, 144 118 Bytes

$p="PowerShell ";$a,$b=try{$d=[ordered]@{};3,2}catch{2,3}"This program wasn't written in $p$a, it was built for $p$b!"

Saved a bunch of bytes thanks to @Matt

There are probably other ways of doing this, but this is a simple one, and relatively short. The [ordered] keyword was only introduced with PowerShell v3 and later, which means that PowerShell v2 doesn't support it. A simple try/catch to set the appropriate variables, and we're off and running. (Note that the $d= is necessary to suppress setting $a to the hashtable and $b to an array when run on PowerShell 3.)

Haskell / Literate Haskell (195 bytes)

I hope this isn't cheaty, but I fully intended it to be cheeky!

main = putStrLn "This program wasn't written in Haskell, it was built for Literate Haskell!"
{-

> main = putStrLn "This program wasn't written in Literate Haskell, it was built for Haskell!"

-}

brainfuck/C 749 bytes

//-[--->+<]>-.[---->+++++<]>-.+.++++++++++.+[---->+<]>+++.[-->+++++++<]>.++.---.--------.+++++++++++.+++[->+++<]>++.++++++++++++.[->+++++<]>-.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.-----.[++>---<]>++.[->+++<]>-.[---->+<]>+++.--[->++++<]>-.-----.---------.+++++++++++..+++[->+++<]>.+++++++++.-[->+++++<]>-.-[--->++<]>-.+++++.-[->+++++<]>-.[->+++<]>++.[--->+<]>----.+++[->+++<]>++.++++++++.+++++.--------.-[--->+<]>--.+[->+++<]>+.++++++++.-[++>---<]>+.-[--->++<]>-.+++++++++++.[---->+<]>+++.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.+[---->+<]>+++.[->+++<]>++.[--->+<]>-.------------.+++.++++++++.[---->+<]>+++.++[->+++<]>.+++++++++.+++.[-->+++++<]>+++.+[->++<]>+.-[-->+<]>.
main(){puts("This program wasn't written in C it was built for brainfuck!");}

Crystal / Ruby, 117 bytes

c="Crystal";r="Ruby";x='a'!="a";puts "This program wasn't written in "+(x ?c: r)+", it was built for "+(x ?r: c)+"!"

Crystal is heavily inspired by Ruby, so not much trickery is needed here except a way to detect which language is being used. This snippet abuses a key difference in both languages: Crystal has a character type (Char), while Ruby only has a String.

In Crystal, 'a' is a character literal, while "a" is a string literal. In Ruby, both are string literals. The code tests if 'a'=="a" (true in Ruby, false in Crystal) then uses that to decide whether to print Crystal or Ruby.

sed / Hexagony 251 Bytes

/$/cThis program wasn't written in sed, it was built for Hexagony!
#...>32;p;r;o;g;r;\+/;a;w;23+;m;a<.;.>s;n;+39;t;+32\s/;n;e;;t;i;r;w;<. |.>+32;i;n;+32;H;e\ ;/4+;y;n;o;g;a;x;< i>4;+32;i;t;+32;\;/u;b;23+;s;a;w<h>;i;l;t;+32;f\;/;s;23+;r;o;< T>e;d;+33;@

sed: Try it Online!
Hexagony: Try it Online!


In sed, it prints the correct string if it matches the empty string at the end (always). The second line is a comment. This does require a string on STDIN, but it can be empty (allowed based on this consensus).

Example:

echo '' | sed -f whatLanguage.sed

In Hexagony, the first / redirects to the bottom left, it follows the left side up to where the sed part starts, then just wraps left to right, down a line, right to left, down a line, and so on. The expanded hex looks like this:

         / $ / c T h i s p r 
        o g r a m w a s n ' t 
       w r i t t e n i n s e d 
      , i t w a s b u i l t f o 
     r H e x a g o n y ! # . . . 
    > 3 2 ; p ; r ; o ; g ; r ; \
   + / ; a ; w ; 2 3 + ; m ; a < .
  ; . > s ; n ; + 3 9 ; t ; + 3 2 \
 s / ; n ; e ; ; t ; i ; r ; w ; < . 
| . > + 3 2 ; i ; n ; + 3 2 ; H ; e \ 
 ; / 4 + ; y ; n ; o ; g ; a ; x ; < 
  i > 4 ; + 3 2 ; i ; t ; + 3 2 ; \
   ; / u ; b ; 2 3 + ; s ; a ; w <
    h > ; i ; l ; t ; + 3 2 ; f \
     ; / ; s ; 2 3 + ; r ; o ; < 
      T > e ; d ; @ . . . . . .
       . . . . . . . . . . . .
        . . . . . . . . . . .
         . . . . . . . . . .

Python 2/C, 179 bytes

#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/

Syntax-highlighted version:

Python:

#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/

C (poor highlighting, sorry)

#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/

Emotinomicon/Python 2, 168 bytes

#😭!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT😲⏪⏬⏩
print"This program wasn't written in Python 2, it was built for Emotinomicon!"

or with more languages:

Emotinomicon/Python 2/><>, 267 bytes

v=0
 #😭!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT😲⏪⏬⏩
for _ in[0]:print"This program wasn't written in Python 2, it was built for ><>!"
"""
"
>v
v>"!nocimonitomE rof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT"
>l?!;o
"""

but I'm bored so let's add another language:

Emotinomicon/Python 2/><>/Gol><>, 358 bytes

v=0
 #😭!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT😲⏪⏬⏩
for _ in[0]:print"This program wasn't written in Python 2, it was built for ><>!"
"""
`
"
?
>v
v>"!><>loG rof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT"
>l?!;o
"
>!v~~~~~"!nocimonitomE rof tliub saw ti ,><>loG ni nettirw t'nsaw margorp sihT"0q
  >l?!;o
"""

JavaScript ES6 / Python2, 98 bytes, REPL ONLY

js = 'python'
python = 'js'
s = 'this program is not ' + `js` + ', it was built for ' + `python`
s

Tested with Python 2.7.10 and Chrome 52.

The caveat here is actually printing the output....Python uses print s and JS uses console.log(js). So instead I assume you are using a REPL and that s alone will print to stdout.

JavaScript/Ruby, 170 bytes

Might be 2.0 only, doesn't appear to work in at least 2.1.5... Edit: Updates as per advice from @Jordan hopefully it works in a few more versions now!

a='1';c=console=console||eval('def c.log s;$><<s end;c');c.log("This program wasn't written in "+(d=['JavaScript','Ruby'])[b= ~(a=~/1/)]+', it was built for '+d[b+1]+'!')

Abuses the ~ operator in that Ruby will treat =~ as a regex match returning the position of the first match in the string (0), but JavaScript will treat it as = ~/1/ which is -1 (since /1/ is converted to NaN for numeric operations, which has 0 value).

QBasic / Javascript, 153 134 bytes

UPDATE: Saw that the text could be de-duplicated:

a$="This program wasn't written in "
b$=", it was built for "
PRINT(a$+"JS"+b$+"QB!")
'';function PRINT(){alert(a$+"QB"+b$+"JS!");}

First post! Anyway, my code is:

PRINT ("This program wasn't written in JS, it was built for QB!")
'';function PRINT(){alert("This program wasn't written in QB, it was built for JS!");}

In QBasic, it prints the first line and doesn't execute the second line because it's believed to be a comment (thank you '). In JS, it calls the function PRINT, which is defined on the second line.

C/Java, 277 bytes

//\u000apublic class Main{static String s="This program wasn't written in Java, it was built for C!";public static void
main(//\u000aString[] a
)
{printf("This program wasn't written in C, it was built for Java!");}
//\u000astatic void printf(String a){System.out.println(s);}}

Javascript ES6, ES5 131 127 bytes

I just thought I post this for fun

"This program wasn't written in "+((c=eval("try{let a=0}catch(e){1}"))?"ES5":"ES6")+", it was built for "+(c?"ES6":"ES5")+"!"

The main part of the code is this:

try{d.join``;0}catch(e){1}

If the version of javascript is ES5, this returns 1, because d.join`` throws an error.

Fuzzy Octo Guacamole and Jolf, 112 bytes

(non-competing, FOG is newer than the challenge)

a++++"This program wasn\'t written in ""Jolf"", it was built for ""Fuzzy Octo Guacamole""!"//__ssss.Z_sssts''.jX

Prints This program wasn't written in Fuzzy Octo Guacamole, it was built for Jolf! in FOG, and This program wasn't written in Jolf, it was built for Fuzzy Octo Guacamole! in Jolf.

This was fun.

FOG side is complicated, because there is no command to swap the top 2 items.

FOG Explanation:

a++++"This program wasn\'t written in ""Jolf"", it was built for ""Fuzzy Octo Guacamole""!"//__ssss.Z_sssts''.j_;

The a adds the 2 top items, adding 0 and 0 and pushing the result, 0. Does nothing.

The + increment, so at the end the stack has [5].

The strings just push those to the stack.

The // does nothing but push '/' to the stack twice, but in Jolf it is a comment.

The __ pops the 2 '/'s we pushed, just removing them.

The ssss moves the top 4 strings, the parts that need rearranging, to the other stack. They are now in reverse order also.

The . switches stacks.

Z reverses the stack.

_ pops the '!', so we get it out of the way. It is set to the temp var.

Then we move the 'Fuzzy Octo Guacamole', the 'was built for', and the 'Jolf' to the other stack in that order. That is the 3 s.

t pushes the temp var, which is still the '!' and then the next s puts it on the other stack.

We have all the strings, but how to print?

We first push '', the empty string.

Then we switch stacks with ..

Then we use j. This is join. It pushes the current stack as a string with the top of the inactive stack as a separator.

This is equivalent to the python ''.join(stack).

Then the X pops and prints, and we are done!

Side note: The poor 5 is left on the stack, all by himself. ;_;

Jolf Explanation:

Much simpler.

Jolf is prefix, so the a gets the alert function ready.

The + all concatenate the strings, so they just get stuck together.

So this just prints as-is, no need to rearrange. And the // is a comment, and hides the FOG side code.


Thanks to @CᴏɴᴏʀO'Bʀɪᴇɴ for making Jolf, a wonderful language to use.

Aʟsᴏ, ғʀᴇᴇ ᴘʟᴜɢ ғᴏʀ sᴍᴀʟʟ ᴄᴀᴘs!!!

Pyke/Foo, 71

"This program wasn't written in ""Foo"", it was built for ""Pyke"R3"!"s

Try it in Pyke!

Foo just prints everything in double quotes.

R3 rotates the top 3 items of the stack and s joins them together. It auto-prints the stack at the end

MATLAB / Octave, 118 116 Bytes

x=all(version-82);s={'Octave','MATLAB'};
fprintf('This code wasn''t written in %s, it was built for %s!',s{2-[x ~x]})

This works because version returns something like: 8.4.0.150421 (R2014b), in MATLAB, and 3.6.2 in Octave. version-82 will contain a zero if there is an R in the version name. all(version-82) gives true if there are only non-zero values, and false if one value is zero.

CoffeeScript+CJam

Uses CoffeeScript's ### and CJam's e#

e###
"This program wasn't written in CJam, it was built for CoffeeScript!"
e### ###
e### alert "This program wasn't written in CoffeeScript, it was built for CJam!"

How CJam sees it

e# comment
push "This program wasn't written in CJam, it was built for CoffeeScript!"
e# comment
e# comment

How Coffee sees it:

e
###
comment
###
###
comment
###
alert("This program wasn't written in CoffeeScript, it was built for CJam!")

Mathematica 9/Mathematica 10, 115 bytes

Print["This program wasn't written in",a=" Mathematica ",If[b=Now==Now,9,10],", it was built for",a,If[b,10,9],"!"]

A bit late to the party... In Mathematica 9, Now remains unevaluated, and therefore equals itself. In Mma 10, each evaluation has a slight time offset, causing the two Nows to be unequal.

Mouse-2002 / Factor, 192 bytes

These two languages also don't share much but this was fun.

IN: m
! '8!'"This program wasn"''!'"t written in Mouse, it was built for Factor"33!'"!"$
USING: io ;
: x ( -- ) "This program wasn't written in Factor, it was built for Mouse!" print ;
MAIN: x

How this looks to Mouse:

IN: m     ~  pointlessly assign 8 to N and push 12
!' 8 !'   ~  print the codepoint 12 (from m) and then a backspace
       "This program wasn"     ~ print this string
                         '' !' ~ push the codepoint for ', then print that 

"t written in Mouse, it was built for Factor" ~ print this string

33 !' "!" $  ~ push 33, then print that ASCII char, then print a newline, and end the program

How this looks to Factor:

! project folder name
IN: m
! comment!
! '8!'"This program wasn"''!'"t written in Mouse, it was built for Factor"33!'"!"$
! import statement
USING: io ;
! macro definition
: x ( -- ) "This program wasn't written in Factor, it was built for Mouse!" print ;
! program start
MAIN: x

This was actually quite a lot of work to get right.

Mouse-2002 / Python 2, 157 bytes

These two languages don't share much.

' ''"This program wasn"!'' "t written in Mouse, it was built for Python"33!'"!"#A;$A@$
print"This program wasn't written in Python, it was built for Mouse!"

How Mouse sees this:

' ''"This program wasn"!'' "t written in Mouse, it was built for Python"33!'"!"#A;$A@$


Broken down:

'               ~ push space charcode 
 ''             ~ push literal ' charcode

   "This program wasn"                              ~ print

!               ~ print TOS (a literal ' )
 ''             ~ push another literal ' 

   "t written in Mouse, it was built for Python"    ~ print

33!'            ~ push 33, then print that ASCII char (!)
    "!"         ~ print a newline
       #A;      ~ call a macro named A
          $A@   ~ define a bodiless macro named A
             $  ~ end the program; everything after will be pushed but not run

How Python sees this:

' ''"This program wasn"!'' "t written in Mouse, it was built for Python"33!'"!"#A;$A@$
print"This program wasn't written in Python, it was built for Mouse!"


Broken down:

# oh look, a bunch of pointless string literals and a comment!
' ''"This program wasn"!'' "t written in Mouse, it was built for Python"33!'"!"#A;$A@$
# oh look, a print statement!
print"This program wasn't written in Python, it was built for Mouse!"

Shells/Emacs Lisp (157 bytes)

:; echo "This program was not written for shells, it was built for Emacs!"; exit
(message "This program was not written in Emacs, it was built for shells!")

: is a nop in both languages. ; is a comment in Emacs Lisp and a delimiter in many shells. :; is used as a startup hack for Emacs Lisp scripts, if you need to pass more than one argument to Emacs itself by the command line.

JavaScript / JavaScript ES6, 110 bytes

"This program wasn't written in "+((b=[a="JavaScript",c=a+" ES6"].keys)?c:a)+", it was built for "+(b?a:c)+"!"

Checks for the existence of .keys. Most browsers these days are ES6 so I recommend installing a separate engine such as Rhino if you really want to test this.

Ruby 2.1.5/JavaScript, 189

i
=begin
=9;n=console.log;end='';y
=end
//=~'';def n(x);puts x;end
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")

This does some simple polyglot manipulation to make n a function that prints to stdout. That's the only polyglot trick. The real trick is that Ruby has a bug in the Regexp matcher wherein "k" and "s" do not match /[^\W]/i due to case-folding. It's in the official documentation, too.

Anyway, to Ruby, this looks like:

i       # a pointless variable declaration
=begin
  This is a block comment
=end
//=~''; # just a pointless regex evaluation

# declare a method `n` which puts to stdout
def n(x)
  puts x
end

# call n.  b will equal 1 since this erroneously fails to match.
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")

And to JavaScript, it looks like:

i=begin=9;  // pointless assignment of i and begin to 9
n=console.log; // set up `n` as a function to log to stdout

// more pointless assignments....
end='';
y=end

// comments
//=~'';def n(x);puts x;end

// call n.  b will be 0 because JS does not share Ruby's bug.
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")

BASH/JavaScript, 171 164 bytes

/* 2>&-;echo This program wasn\'t written in BASH, it was built for JavaScript\!;#*/console.log("This program wasn't written in JavaScript, it was built for BASH!")

First post to PPCG!

Python 2.7/><> - 160 bytes

#v"This program wasn't made for ><>, it was built for Python 2.7!"
#l
#0
#)
#?
#!
#;
#o
#!
print"This program wasn't made for Python 2.7, it was built for ><>!"

Pretty simple program. Python ignores the everything after a # cause it's a comment, while a # in ><> makes the pointer turn around.

Python/Lisp 158 chars

""""(princ "This program wasn't written in Lisp, it was built for Python!")""";print 'This program wasn\'t written in Python, it was built for Lisp!';""" " """

Perl/PHP, 99 bytes

<?$p=erl;">;$p=HP#"
;$o=$p^erl^HP;print"This program wasn't written in P$o, it was built for P$p!";

For PHP, I assume the default interpreter settings, as they are without any ini. If you are uncertain, you may disable your local ini with -n as in php -n script.php.

Python 2.7.9/Python 2.7.10, 127 bytes

We've had a couple posts that used minor versions, but none that have gone to the next level down...

import types
n=len(dir(types))
print"This program wasn't written in Python 2.7.%d, it was made for Python 2.7.%d!"%(n%33,-n%52)

Try it on Ideone (Python 2.7.10) and repl.it (technically Python 2.7.2, but should give the same result as 2.7.9).

Python 2.7.10, according to the changelog:

Added an __all__ to the types module.

This pushed len(dir(types)) from 42 to 43, giving a numerical difference we can exploit to generate the desired output.

Are solutions with more than two languages allowed? If so:

Python 3 / JavaScript / jq, 284 bytes

0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

Highlighted for Python:

0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

Highlighted for JavaScript:

0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

No idea how to start explaining the jq part; just know that the string interpolation syntax in jq works as a "string inside string" of sorts: between "\(" and ")", jq is in a string inside a string, while Python and JavaScript consider them individual strings.

Using jq -n -r, python3 and node.

jq / Python 3, 151

"\("; print('This program wasn\u0027t written in Python 3, it was built for jq!')#" | "This program wasn't written in jq, it was built for Python 3!")"

The problem gets a little bit complicated when one of the languages does not have a comment syntax.

Run with jq -n -r or with python3.

Scala/Groovy, 128 bytes

Adapting my Java/Groovy snippet for Scala instead lets us get rid of a lot of Java boilerplate:

def Scala=" Groovy"
def Groovy=" Scala"
print("This program wasn't written in$Scala, it was built for$Groovy!".replace('$',' '))

Java/Groovy, 190 186 184 181 bytes

class A{public static void main(String[]a){String Groovy=" Java",Java=" Groovy";System.out.print("This program wasn't written in$Java, it was built for$Groovy!".replace('$',' '));}}

Ungolfed:

class NotThatLanguage {
  public static void main(String[] args) {
    String Groovy=" Java", Java=" Groovy";
    System.out.print("This program wasn't written in$Java, it was built for$Groovy!".replace('$', ' '));
  }
}

Batch .BAT File / Batch .CMD File, 194 185 Bytes

@ECHO OFF
SET a=BAT
SET b=CMD
CALL :F&&GOTO :C||GOTO :O
:C
SET a=CMD
SET b=BAT
:O
ECHO This program wasn't written for %a% File, it was built for %b% File!
GOTO :EOF
:F
md;2>nul
SET v=1

Edit: Saved 9 bytes, and corrected a missing ! thanks to DLosc

Yeah, there's differences between BAT and CMD files. Reference. Essentially, CMD sets the ERRORLEVEL on a SET command, while BAT doesn't, meaning that here the ERRORLEVEL set by the malformed md command gets cleared by the SET v=1 in one version but not the other. This script is based on the example provided by "Ritchie" in that newsgroup thread.

Note that the shortened script above presumes ENABLEEXTENSIONS to be set ON (it is by default on every platform). The expanded script below explicitly sets it, to guarantee correct functionality. Without that, the SET command for CMD doesn't allow all extensions, and (on some systems, maybe) might not set the ERRORLEVEL appropriately.

Expanded and remarked

@ECHO OFF
setlocal ENABLEEXTENSIONS

REM Call the :FUNC subroutine and branch based on the resulting errorlevel
CALL :FUNC&&GOTO :CMD||GOTO :BAT

REM Just in case. If we reach this, though, hoo-boy ...
GOTO :EOF

:BAT
REM We're a BAT file, so set variables and goto output
SET a=BAT
SET b=CMD
GOTO :OUTPUT

:CMD
REM We're a CMD file, so set variables and goto output
SET a=CMD
SET b=BAT
GOTO :OUTPUT

:OUTPUT
REM Print out the result, then go to end of file
ECHO This program wasn't written for %a% File, it was built for %b% File!
GOTO :EOF

:FUNC
REM Simple subroutine to set the ERRORLEVEL appropriately
md;2>nul
REM Right now, ERRORLEVEL on both CMD and BAT is 1
SET v=1
REM Right now, ERRORLEVEL on CMD is 0, but BAT is still 1

C / Python, 238 chars

This doesn't print 100% exactly what's requested, but quite close.
A reboot of my valentine's day card.

#define def main(){0?
#define print printf(
#define return 0)));}
#define pass 0);

def main():
    print "This program wasn't written in ",
    pass
    print "Python",
    print ", it was built for ",
    print "C",
    return

main();

Perl/Tcl 171 bytes

#\
sub set{eval"\$$_[0]=\"$_[1]\""}sub puts{}
set a, "This program wasn't written in";
set b, "l, it was built for";
#\
print"$a Per$b Tcl!\n"||
puts "${a,} Tc${b,} Perl!"

No trailing semicolon or newline. This exploits Tcl comments being, well, odd!

/// and Retina, 95 + 3 = 98 bytes

/
//

This program wasn't written in \/\/\/, it was built for Retina!
/?./....(.*)(R.*)!
$2$1///!

+3 bytes for the -s flag in Retina.

Explanation for ///

The first instruction is

/
//

removes all newlines from the rest of the code, resulting in

This program wasn't written in \/\/\/, it was built for Retina!/?./....(.*)(R.*)!$2$1///!

Everything up to the ! is just a literal and printed to STDOUT. The next instruction is

/?./....(.*)(R.*)!$2$1/

But the search string ?. cannot be found, so nothing happens. Then the remaining code is //! which is an incomplete instruction so the program terminates, having printed the correct string.

Explanation for Retina

/
//

This tells Retina to replace / with //. But the input is empty, so this doesn't match anything.

<empty>
This program wasn't written in \/\/\/, it was built for Retina!

This replaces the input with the string in the second line.

/?./....(.*)(R.*)!
$2$1///!

This matches the string \/\/\/, it was built for Retina! and replaces it with Retina, it was built for ///! to give the correct result.

Commodore 64 Basic/QBasic, 169

In order to get the capitalization right, you'll need to switch your Commodore 64 to character set 2 by pressing <SHIFT> + <C=>.

1 c$ = "QBasic": d$ = "Commodore 64 Basic"
2 if(fre(0) < 0) then e$ = c$:c$ = d$:d$ = e$
3 print "This program wasn't written in "; c$; ", it was built for "; d$; "!"

In Microsoft dialects of Basic, the "fre()" function returns the available free space. Now, QBasic can run on surprisingly low-memory IBM compatibles, so you can't reliably tell QBasic and Commodore Basic apart just by the amount of free space. However, the Commodore Basic version returns a signed 16-bit integer where the QBasic version returns a 32-bit one -- and since the Commodore 64 has more than 32767 bytes free with just a small program, while QBasic, as a real-mode program, will never see more than 1048576 bytes, "fre(0)" will always return a negative number on a C64 and a positive number under QBasic.

Commodore Basic's 80-character-per-line limit and QBasic's autoformatter interact in annoying ways here. For example, I found a neat trick involving an if-then-else statement (invalid in Commodore Basic, but an "end" statement keeps the Commodore interpreter from encountering the invalid bits) -- except that the resulting line is 86 characters long after QBasic's autoformatter gets through adding whitespace. Likewise, line 1 can't be combined with line 2: the result would be 88 characters long after autoformatting.

JavaScript/JavaScript ES6, 132 130 bytes

var v=[];v[0]=v[1]=" JavaScript";v[[].fill?0:1]+=" ES6";alert("This program wasn't written in"+v[0]+", it was built for"+v[1]+"!")

JavaScript/Haskell, 158 bytes 147 bytes

General idea: sneak each one's comment syntax into the other.

In one line:

u="This program wasn't written in ";v=", it was built for ";j="JavaScript";h="Haskell";{-console.log(u+j+v+h+"!")}//-}main=putStrLn$u++h++v++j++"!"

What this looks like to Haskell:

-- some variable definitions
u = "This program wasn't written in "
v = ", it was built for "
j = "JavaScript"
h = "Haskell"

-- a comment
{-console.log(u+j+v+h+"!")}//-}

-- the main method that does the dirty deed
main = putStrLn $ u ++ h ++ v ++ j ++ "!"

What this looks like to JavaScript:

/* variables can be declared without `var` */
u = "This program wasn't written in ";
v = ", it was built for ";
j = "JavaScript";
h = "Haskell";

/* hey look, an anonymous block! */
{ 
  /* we negate the `undefined` that comes out of console.log */
  -console.log(u+j+v+h+"!")
} 
/* there are two automatic semicolon insertions here:
   one before `}` and one before EOF. */

/* a one-line comment. */
//-}main=putStrLn$u++h++v++j++"!"

Brainf***/Thue, 829 bytes

a::=~This program wasn't written in Thue, it was built for Brainf***!
::=
a++++++++[>+>++>+++>++++>+++++>++++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++>+++++++++++++>++++++++++++++>+++++++++++++++>++++++++++++++++<<<<<<<<<<<<<<<<-]>>>>>>>>>>>----.++++>>.+.->+++.---<<<<<<<<<<.>>>>>>>>>>.++.---.+<-.+>++.--<<+.->>---.+++<<<<<<<<<<.>>>>>>>>>>>-.+<<<+.->>+++.-----.++<<<<<<<<<-.+>>>>>>>>>>----.++++<<<<<<<<<<<.>>>>>>>>>>>-.+<++.--<+.->>----.++++----.++++<<---.+++>--.++<<<<<<<<<<.>>>>>>>>>+.->--.++<<<<<<<<<<.>>>>++.-->>>>>>++.--<<+.->+.->--.++<--.++<<<<<<<<++.--++.--++.-->----.++++<<.>>>>>>>>>+.->>----.++++<<<<<<<<<<<.>>>>>>>>>>>-.+<<<+.->>+++.---<<<<<<<<<<.>>>>>>>>++.-->>>---.+++<<+.->----.++++>----.++++<<<<<<<<<<<.>>>>>>>>>--.++>-.+++.--<<<<<<<<<<.>>>>>>>----.++++>>.>>---.+++<<---.+++<<<<<<<<<+.-<<<<.

Python/Boo, 102 bytes

v=1//2
n=("Python","Boo");print"This program wasn't written in "+n[v]+", it was built for "+n[1-v]+"!"

Explanation: Boo's syntax is strongly based on Python's, but it uses // as a C-style comment, whereas Python uses it for integer division.

MySQL (5) / Perl (5), 144 bytes

-- $_;print"This program wasn't written in Perl, it was built for MySQL!";
select"This program wasn't written in MySQL, it was built for Perl!";

h/t

Java/C, 418 Bytes

It might not have been a wise decision to use Java, nonetheless here's my solution:

//\u000a/*
#include <stdio.h>
#define public
#define static }
#define String int i,char*v
#define args
#define class
#define long g(){int
#define A struct{struct{int(*printf)();}out;}System={printf};f()
#define true 0
//*/
public class A{public static void main(String[]args){int c=true==(0==0)?1:0;System.out.printf("This program wasn't written in %s, it was built for %s!",c==0?"C":"Java",c==0?"Java":"C");}long f;}

Turns out Java and C are quite close. Except java is a lot more verbose and has a lot of keywords C doesn't need. And Java doesn't like the mixture of int's and booleans.

Annotated version

//\u000a/*                  /* \u000a gets replaced by a newline by javac
                               -> single line comment in C, multiline in java */
#include <stdio.h>          /* include needed, so I can use printf as function pointer */
#define public
#define static }
#define String int i,char*v /* make main declaration C compatible */
#define args
#define class
#define long g(){int        /* to remove closing bracket for `class {}` */
#define A struct { \        /* System.out.printf for C */
              struct { \
                  int (*printf)(); \
              } out; \
          } System = { printf }; \
          f()
#define true 0              /* Nothing is true, everything is permitted */
//*/                        /* single line comment in C, ends java multiline comment */
public class A {
    public static void main(String[] args) {
        int c = true == (0 == 0) ? 1 : 0; /* 1 for Java, 0 for C */
        System.out.printf("This program wasn't written in %s, it was built for %s!",
            c == 0 ? "C" : "Java",
            c == 0 ? "Java": "C");
    }
    long f; /* extra member, in java. gets redefined in C to get rid of the last } */
}

There might be some possibilites to cut off a few bytes here and there.

Haskell/Python 198 185 Bytes

Haskell

pass#b=b
pass##b=pass++b
p=print#putStrLn where print=p
main=p("This program wasn't written for "##(
 "Python"#"Haskell")##
 ", it was built for "##(
 "Haskell"#"Python")##
 "!")

Python

pass#b=b
pass##b=pass++b
p=print#putStrLn where print=p
main=p("This program wasn't written for "##(
 "Python"#"Haskell")##
 ", it was built for "##(
 "Haskell"#"Python")##
 "!")

Not actually sure if it works with all Pythons. Should work with python 3 at least.

If quotes in the output were valid, we could remove the third line and just use print in main (it'd print quotes around the string in haskell) - I'm assuming this is not valid here.

Explanation: The first 2 lines are no-ops in python (they just consist of pass), in Haskell they define 'select second' and 'concatenate' and concatenate operators respectively. The next line defines a 'variable' both in python and in haskell; In python it's pointing to print, in haskell it's defined as putStrLn (the where part shadows print, without it we would get type instantiation errors because of print there). The part after that is just abusing the fact that consecutive string literals in Python are concatenated like in C, in haskell we use the concatenation operator instead. We swap out "Python" and "Haskell" using our selection operators.

In python, the assignment to main is useless but valid. In Haskell, it's required because we need a main :: IO ().

Haskell / C - 225 219 bytes

Probably not optimized very well.

Haskell

int /* x = x -- */ printf(const char*,...); /*
main = putStrLn "This program wasn't written in C, it was built for Haskell!"
-- */ int main () { printf("This program wasn't written in Haskell, it was built for C!"); }

C

int /* x = x -- */ printf(const char*,...); /*
main = putStrLn "This program wasn't written in C, it was built for Haskell!"
-- */ int main () { printf("This program wasn't written in Haskell, it was built for C!"); }

TeX / BASH - 192 bytes

echo "This program wasn't written in bash, it was built for TeX!";: "\output{\setbox0\hbox{\box255}\setbox0\vbox{This program wasn't written in \TeX, it was built for bash!}\shipout\box0}\end"

Trick is basically in the : "...." which lets bash do nothing with what comes inside the " ". TeX on the other hand just print it's own stuff onto a white paper. I know I could save 1 byte by writing "TeX" instead of "\TeX", but I wont, this looks much nicer: enter image description here

Inspired by http://pts.szit.bme.hu

Bonus:

TeX / many shells - 244 bytes

S=$(ps | grep `echo $$`$5 | awk '{ print $4$6 }');echo "This program wasn't written in $S$6, it was built for TeX!";: "\output{\setbox0\hbox{\box255}\setbox0\vbox{This program wasn't written in \TeX, it was built for shells!}\shipout\box0}\end"

This can in addition be run with dash, sh, ksh, et. al and will produce:

sheß@donald:~$ bash sh.sh
This program wasn't written in bash, it was built for TeX!
sheß@donald:~$ dash sh.sh
This program wasn't written in dash, it was built for TeX!
sheß@donald:~$ sh sh.sh
This program wasn't written in sh, it was built for TeX!

Perl5 / JavaScript

y= 1, split = function(){return ''; " =; #"}
print ( "This program wasn't written for", split( //, " Perl, it was built for JavaScript!") );
y), "\bJavascript, it was built for Perl!");
x=split();

Perl 5 / Perl 6

perl -e '$x= ~ -2; printf "This program wasn\x27t written in perl\%d, it was built for perl\%d", 4+abs($x), 7-abs($x);'

Fishing/><> 233 217 bytes

v++C-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC+CCCCCCC-CCCCCCCCCCCCCCCCCCC+CCCCCC
\   "This program wasn't written in ""><>"  ", it was built for Fishing!"
>r!`ol?!;32.                         Fishing                     ><>!`N

Fishing is a language based on a fisherman walking around catching fish. To make a program in this language who first have to define a dock on which he walks around. The dock only provides control flow to a program. The dock in this program is:

v++C-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC+CCCCCCC-CCCCCCCCCCCCCCCCCCC+CCCCCC

Whenever the C command is found, the fisherman throws out his line to catch an instruction. The + and - instructions decrease and increase the length of his line respectively. v changes his throw direction to downwards. The fish that he catches in this program are:

`This program wasn't written in Fishing, it was built for ><>!`N

><> is a language based on a fish moving through the water. The v command starts the fish moving downwards, where it is then reflected to the right with the \ command. Everything between quotes is pushed onto the stack. After the string is pushed onto the stack, the fish wraps around to the other side where it is reflected downwards by \. It then prints out the contents of the stack with:

>r!`ol?!;32.

Perl 5 / Perl 6, 113 bytes

$X=5;$Y=6;if ("a".chars>0) {$X++;$Y--}print "This program wasn't written in Perl $X, it was built for Perl $Y!\n"

This proved to be harder than anticipated.

How it works? In perl 6 the "a".chars gives a result of 1.
But in Perl 5 the string "achars" is compared against a number, which results in false.

(** shakes finger at perl 6 for making it harder to golf **)

Ruby/Python, 105 chars

a=["Ruby","Python"];a.sort();print("This program wasn't written in "+a[0]+", it was built for "+a[1]+"!")

PHP/Perl, 98 96 bytes

$a="HP";$b="erl";
//;$a=$b;$b=HP;
print"This code wasn't written in P$a, it was built for P$b!";

Dunno if this is cheating or not, since as far as I can tell the only way to run PHP without an opening <? tag is something like php -r $(cat codefile.php). But assuming that's legal... // is a PHP comment, but in Perl it's a regex (which, in a statement by itself, doesn't do anything). The rest should be pretty self-explanatory.

Edit: Now using a bareword in the Perl-only part. I wanted to use those in the first place for both languages, but PHP displays a warning when you do that, contrary to "There should be no output to stderr."

VB6 / ES6 – 115 bytes

VB6

l="VB"
o="ES"
'';[l,o,MsgBox]=[o,l,alert]
MsgBox("This program wasn't written in "+l+"6, it was built for "+o+"6!")

ES6

l="VB"
o="ES"
'';[l,o,MsgBox]=[o,l,alert]
MsgBox("This program wasn't written in "+l+"6, it was built for "+o+"6!")

JavaScript/CoffeeScript, 125 124 bytes

console.log("This program wasn't written in",(a=['Coffee','Java'])[+(b=0=='0')]+"Script, it was built for",a[b^1]+"Script!")

In CoffeeScript, a==b is compiled down to a===b, which makes the intermediate condition false. I used a bit of magic to convert the boolean value to an integer.

Saved 1 byte thanks to @DomHastings!

125-byte version:

console.log("This program wasn't written in",(a=['Coffee','Java'])[(b=0=='0')+0]+"Script, it was built for",a[b^1]+"Script!")

Befunge/><>, 141 138 134 133 130 bytes

3 bytes saved thanks to @Cole.

To be exact, I'm using Befunge-98.

\"!><> rof tliub saw ti ,egnufeB"   >" rof nettirw t'nsaw margorp sih"'T>:#,_@'~~~~~~
>l?v"!egnufeB rof tliub saw ti ,><>"^
?!;>ol

Using the facts that:

Foo/CJam, 70 bytes

"This program wasn't written in ""Foo"", it was built for ""CJam"\@"!"

In Foo, as many have found out, it just prints everything in the double quotes, and ignores most other character or does something that doesn't affect the output in most cases. In short, \@ does nothing and the strings are all printed as-is.

In CJam, \ swaps the top two items, and @ moves the 3rd item to the top, which arrange the strings into the right order. And after the program ends, everything left in the stack is automatically printed.

Brainfuck/Bash 4.3, 849 848 843 bytes

#-[--->+<]>-.[---->+++++<]>-.+.++++++++++.+[---->+<]>+++.[-->+++++++<]>.++.---.--------.+++++++++++.+++[->+++<]>++.++++++++++++.[->+++++<]>-.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.-----.[++>---<]>++.[->+++<]>-.[---->+<]>+++.--[->++++<]>-.-----.---------.+++++++++++..+++[->+++<]>.+++++++++.-[->+++++<]>-.-[--->++<]>-.+++++.-[->+++++<]>-.+[->++<]>.---[----->+<]>-.+++[->+++<]>++.++++++++.+++++.--------.-[--->+<]>--.+[->+++<]>+.++++++++.+++[----->++<]>.------------.-[--->++<]>-.+++++++++++.[---->+<]>+++.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.+[---->+<]>+++.[->+++<]>++.[--->+<]>-.------------.+++.++++++++.[---->+<]>+++.++[->+++<]>.+++++++++.+++.[-->+++++<]>+++.+[->++<]>.[-->+++<]>--.--[--->+<]>--.-----------.--[--->+<]>--.++[-->+++<]>+.------.+++++.[--->++<]>
echo -e "This program wasn't written in Bash 4.3, it was built for Brainfuck!"

Brainfuck/Javascript 936 chars

/*[-]>[-]>++++[-<++++++++>]<>[-]>++++++[-<++++++++++>]<+++++>[-]>++++++++++[-<++++++++++>]<---<<<>>+++++++++++++++++++.>+++++++.+.++++++++++.<<.>>---.++.---.--------.+++++++++++.-----------------.++++++++++++.<<.>>++++++++++.----------------------.++++++++++++++++++.-----.<<+++++++.>>++++++.<<-------.>>+++.-----.---------.+++++++++++..---------------.+++++++++.<<.>>-----.+++++.<<.>------------------.>++++.-----------------.++++++++.+++++.--------.+++++++++++++++.------------------.++++++++.<<++++++++++++.------------.>>--.+++++++++++.<<.>>+++.----------------------.++++++++++++++++++.<<.>>-----------------.+++++++++++++++++++.------------.+++.++++++++.<<.>>--------------.+++++++++.+++.<<.>++++++++.>-----------------.+++++++++++++++++++++.---------------------.++++++++++++++++++.----------------.+++++++++++++++.---------.+++++++.++++.<<+*/console.log("This program wasn't written in Javascript, it was built for Brainfuck!");

This is just Brainfuck Code in a Comment Javascript will ignore, but Javacript Code that Brainfuck will ignore. So it is perfect. :D

Lua/C - 182 164 bytes

#if 0
print"This program wasn't written in Lua, it was built for C!"--[[
#endif
main(){printf("This program wasn't written in C, it was built for Lua!\n");}/*]]--*/

Takes advantage of the feature where Lua treats a hash mark on the first line as a comment to allow for Unix shebangs. Otherwise wraps the other language's comments in its own comments.

To shave bytes, I rely on implicit behavior that only emits warnings in GCC and Clang: implicit declaration of int for main and implicit definition of printf.

CJam/GolfScript, 81 78 bytes

"This program wasn't written in "o"GolfScript"", it was built for ""CJam"oo"!"

Original 81 byte version:

"This program wasn't written in "["CJam"", it was built for ""GolfScript"]-1a%"!"

Python 3/><>, 177 173 172 167 Bytes

Thanks to @mathmandan for shaving 5 bytes off!

Well this was an experience, and a trying one, too. Any golf suggestions are welcome, since this is pretty long. I tried my best to reuse text, but it was quite difficult.

Technically, it would be Python 3 that this program should output (and I could change that if I didn't meet the specs -- but in the example Python/C output Python was listed).

aa=" ni nettirw t'nsaw margorp sihT\"\""
v="><>!"                 #v   "><>"r~/
a=", it was built for "+v#\a
print(aa[-3::-1]+"Pytho" +"n"+a)
#  .4b;!?lor"!nohtyP r"~/

Try it on an online ><> interpreter and a Python 3 interpreter (the ><> interpreter requires you to input the code manually)

Returns

This program wasn't written in ><>, it was built for Python!

in ><> and

This program wasn't written in Python, it was built for ><>!

in Python.

Explanation (Python)

For the Python side of things, it's pretty simple. Here's the code that we care about (basically the code without comments, which are denoted by a # in Python). Note that in Python \ is an escape character when used in strings, so \" evaluates to " in the string.

aa=" ni nettirw t'nsaw margorp sihT\"\""
v="><>!"
a=", it was built for "+v
print(aa[-3::-1]+"Pytho" +"n"+a)

What we care most about here is the operations performed on the variable aa:

aa[-3::-1]: reverses the string and chops off the quotation marks (thanks to @mathmandan)

The print statement thus evaluates to

"This program wasn't written in " + "Pytho" + "n" + ", it was built for ><>!"

Explanation (><>)

Now we get to the more difficult part. Once again, here's the code with the unnecessary bits removed.

aa=" ni nettirw t'nsaw margorp sihT\"\
                          v   "><>"r~/
a=", it was built for "+v \a

   .4b;!?lor"!nohtyP r"~/

Line 1:

aa=" ni nettirw t'nsaw margorp sihT\"\

aa=         pushes 1 onto the stack (evaluates 10==10, basically)
" ni ... \" pushes the first part plus a \ onto the stack.
\           deflects the pointer downwards

The stack right now (if printed): \This program wasn't written in

Line 2:

Note that line 2 begins at the / because of the position of the pointer from line 1, and moves right to left.

v   "><>"r~/

/     deflects the pointer leftwards
~r    pops the / off the stack and then reverses it
"><>" pushes ><> onto the stack
v     deflects the pointer downwards

The stack right now: ><> ni nettirw t'nsaw margorp sihT

Line 3:

Like the previous line, this one begins at the \, which is where line 2 sends the pointer. Note that because the pointer wraps around the line when it reaches the first a I'll be writing my explanation in order of where the pointer goes (and thus what is executed)

a=", it was built for "+v \a

\aa=       deflect and push 1 onto the stack
", i ... " push the string onto the stack
+v         sum the last two values pushed and deflect

The stack right now(x is the character formed by the addition of "r" and a space. -- it is not the actual character, just a placeholder from me):

xof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT

Line 4:

The pointer simply continues downwards so this line warrants no further explanation.

Line 5:

Starting at / and going leftwards.

.4b;!?lor"!nohtyP r"~/

~"r Python!" pops x off and adds back r and a space
r            reverses the stack
o            pops and prints a character
l?!;         pushes the length of the stack and stops if it's 0
b4.          pushes 11 then 4 then moves to that location (where o is)

The stack right now (the output reversed):

!nohtyP rof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT

And that should be it for the explanation. Let me know if there is any inconsistency between the explanation/code or if I did anything wrong; I golfed down my code some more while I was in the middle of writing the explanation so I might have mixed bits of old and new code up.

Selectors Level 4/Selectors Level 3, 148 chars

:has(*){--a:4;--b:3}*{--a:3;--b:4;content:"This program wasn't written in Selectors Level "var(--a)", it was built for Selectors Level "var(--b)"!"}

It works like this:

I think it should work, but I don't have any implementation to test it.

Thankfully, the name of the spec is only "Selectors Level X" instead of "CSS3 Selectors and Foo for Bar Module Level X".

23/Malbolge, 5688 bytes

                    bCBA@?>=<;:987
                                                                                        6543210/.-,+*)
                                                                                          ('&%$#"!~}|{zy
                                                                                               xwvutsrqponmlk
                                                                                                  jihgfedcba`_^]
                                                                                     \[ZYXWVUTSRQPO
                                                                                               NMLKJIHGFEDCBA
                                                                                    @?>=<;:9y76543
                                                                210/(L,l*)(!E}
                   |B"!~}|{zyxwvu
                                                                                                     tsrqponmlkjiha
                                                                                                  fed]#a`_^]?zZY
                                                                                         XWVUTSRQ3ONMLK
                   JIHGFEDCBA:^>=
                                                                                                       <;:98705.R21q/
                                                                                               .-,+*#G'&%${"!
                                                                                            x>|{zyxwYutm3k
                                                                                                        ponmlkjihg`&^c
                                                                                     ba`_^]\[ZYXWVO
                   sSRQPONMLEi,HG
                                                                                                      FEDCBA@?>=6Z:9
                                                                                    y76543210/.-,+
                                                                                                          *)('&%$#"y?w|u
                   ;sxwvutm3qSonm
                                                                                                       fkjiha'edcba`_
                                                                                            ^]\[ZYXWVUTSRQ
                   PONM/EiIHGFEDC
                               BA@?>7[;:987w5
                                      432+O/o-,%I)('
                                     &}$#z@~}|{zsxw
                   vutsrqponmlkji
                                                                                                 ha'&dFba`_^]\U
                                                                                            yYXWVUTMRQPONM
                   LKDhH*F?DCBA@?
                                                                                                 8\<;:98765432r
                                                                                        0/.-&J*)('&f$#
                                                                                                       "!~}|{zyxwvuts
                                                                                                       rqj0nmOkjihaf_
                                                                                            %cE[!_^]\[=SwW
                                                                                                     VU7SLpPONMLEJI
                                                                                                          HAeEDC%A@?>=<;
                   :9876543210/.-
                                                                                                       ,+$H('&}${A!xw
                          ={]yxwvutsrk1o
                                                                                                 nmOejib(fedcE"
                                                                                                      `_^]?[ZYRvVUT6
                                                                                     RKo2HMLKJIHAe
                                                                                                           EDCBA@?>=<;:9
                    87w5432+O/.-,
                                                                                                 +*)('&%e#"y?w
                                                                                     |{zs9wvun4rqp
                                                                                                      onmlNjib(fedc
                                                                                           ba`_^]\[ZYXWV
                                                                                                   8TMqKPONMLKDh
                                                                                                      +GFEDCB;_?>=<
                                                                                                    ;:9y7654321*N
                    .-,+*)('&f|{A
                                                                                                       !~}|{]yxwvo5s
                                                                                             rqpinmlkjihg`
                                                                                            &dcbD`_^]\[Tx
                                                                        ;WVUTMRQJnN0F
                                                 KDhH*FEDC<A@?
     >=<5Y92765.R?

Note that the program requires a trailing linefeed. No line contains trailing whitespace, so copy/paste should work just fine.

Verification

To test the Malbolge code in this online interpreter, paste it in the Malbolge code area and click Load/Reset, then Execute.

To test the 23 code in this online interpreter, paste it in the Source area, press Enter to insert the trailing linefeed, type 23 in the Console area (to switch from the default 23.dezsy notation to auto-detection) and click Run Interpreter!.

PHP/Javascript(ES6), 191 bytes

This one is quite obvious for some people. And I think it is bigger than the existing PHP/JS answer.

$e=($j="\0"=='\0')?[a=>console.log(a.join(''))][0]:function($a){echo(join('',$a));};$L=['PHP','Javascript'];$e(["This program wasn't written in ",$L[+$j],', it was built for ',$L[+!$j],'!']);

You can try it on:

I believe there's a bit more to chop off.

Python 2/Python 3, 92

Uses the "standard" Python version check (integer vs. float division).

print("This program wasn't written in Python %d, it was built for Python %d!"%(3/2*2,4-3/2))

Ruby 1.8/Ruby 1.9, 87

puts"This program wasn't written in Ruby 1.#{?9%49}, it was built for Ruby 1.#{?8%47}!"

In Ruby 1.8, ?9 is the ASCII value of "9", which is 8 modulo 49. In Ruby 1.9, it's the string "9", and %49 is a formatting operation that does nothing since "9" doesn't have any format strings in it.

PHP/Javascript 178 chars

/*<?php echo "This program wasn't written in PHP, it was built for JavaScript!*"."/";exit;?>*/console.log("/*This program wasn't written in JavaScript, it was built for PHP!*/");

This is not perfect due to the Fact it is in this Format: /*{Message}*/.

It abuses the Comments from Javascript and the exit; function from PHP, which also causes the stupid Format.

Python/Pip, 103 bytes

print(#x)O
"This program wasn't written in "#xO"Pip"Y
"Python"#xO
", it was built for "  "Pip!")
#xy.'!

GitHub repository for Pip

The main difficulty with Python and Pip is that they use completely different syntax for output (print vs O/P), for string concatenation (+ vs .), and for assignment (= vs :). At least they have the same syntax for defining strings! This is how Python interprets the program, with comments moved for clarity:

print(                             #x)O
"This program wasn't written in "  #xO"Pip"Y
"Python"                           #xO
", it was built for "  "Pip!")     
                                   #xy.'!

Literal strings in Python that are separated only by whitespace are concatenated.

Now here's how the program looks to the Pip interpreter:

p r i n t                           No-ops (all lowercase letters are variables)
(#x)                                Another no-op (# is the unary length operator)
O"This program wasn't written in "  Output without newline
#x                                  No-op
O"Pip"                              Output
Y"Python"                           The yank operator Y assigns its operand to y
#x                                  No-op
O", it was built for "              "Pip!") is a comment since it comes after two spaces
#x                                  No-op
y.'!                                Concatenate ! to the end of y and print (implicit)

Javascript / C, 148 146 143 chars

//\
alert/*
main(){puts/**/("This program wasn't written in "//\
+"Javascript"+/*
"C"/**/", it was built for "//\
+"C!")/*
"Javascript!");}/**/

C: http://codepad.org/u8UimGLc http://codepad.org/Y80M5jpc http://codepad.org/m4DB2Ndd
Javascript: just copy code to browser console

Perl/Ruby, 129 bytes

0&&eval('def sort a,b;[b,a] end');printf"This program wasn't written in %s, it was built for %s!",(@a=sort"Perl","Ruby")[0],@a[1]

No regular expression abuse in this one, just making the most of the fact that 0 is truthy in Ruby to eval a definition for sort (which actually reverses) and printfing. Ruby didn't like using the list for the arguments, so I had to do each one individually.

PHP/MySQL, 147 bytes

-- $argc;die("This program wasn't written in PHP, it was built for MySQL!");
SELECT("This program wasn't written in MySQL, it was built for PHP!");

Perl/JavaScript ES6, 170 bytes

$a='Perl',$b='JavaScript';/1/&&($a=[$b,$b=$a].shift());$_="This program wasn't written in $a, it was built for $b!";/1/?console.log($_.replace(/\$./g,$r=>eval($r))):print

Again abusing regular expressions, but this time the fact that /1/ is truthy in JavaScript (because it's a RegExp object) and falsy in Perl (because $_ is empty) to switch the variables and run the correct print statement.

Note: This is ES6 JavaScript to work around Perl throwing a syntax error.

C/C++, 136

#include<stdio.h>
int main(){
char*a="++",z=sizeof'c'/2;
printf("This program wasn't written in C%s, it was built for C%s!\n",a+z,a+2-z);
}

Newlines added for formatting. Try it in C or C++.

SWI-Prolog 6/SWI-Prolog 7, 156 bytes

P='SWI-Prolog ',A=6,B=7,(is_list(""),N=A,M=B;N=B,M=A),atomic_list_concat(['This program wasn\'t written in ',P,N,', it was built for ',P,M,'!'],W),write(W).

Uses the fact that double-quotes "" are string codes (i.e. list of character codes) in SWI-Prolog versions older than 7, and are a proper String type in version 7. is_list("") will thus be false in version 7 and true in earlier versions.

Brainfuck/Foo, 769 bytes

-[--->+<]>-.[---->+++++<]>-.+.++++++++++.+[---->+<]>+++.[-->+++++++<]>.++.---.--------.+++++++++++.+++[->+++<]>++.++++++++++++.[->+++++<]>-.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.-----.[++>---<]>++.[->+++<]>-.[---->+<]>+++.--[->++++<]>-.-----.---------.+++++++++++..+++[->+++<]>.+++++++++.-[->+++++<]>-.-[--->++<]>-.+++++.-[->+++++<]>-.+[->++<]>.---[----->+<]>-.+++[->+++<]>++.++++++++.+++++.--------.-[--->+<]>--.+[->+++<]>+.++++++++.+++[----->++<]>.------------.-[--->++<]>-.+++++++++++.[---->+<]>+++.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.+[---->+<]>+++.[->+++<]>++.[--->+<]>-.------------.+++.++++++++.[---->+<]>+++.++[->+++<]>.+++++++++.+++.[-->+++++<]>+++.+++[->++<]>.+[--->+<]>++..[--->+<]>----."This program wasn't written in Foo, it was built for Brainfuck!"

An extremely intricate and complex answer... or not.