Menulis program dalam bahasa favorit Anda dalam bahasa lain [ditutup]


168

Programmer Nyata yang ditentukan dapat menulis program Fortran dalam bahasa apa pun.

dari Real Programmer Jangan Gunakan Pascal

Tugas Anda adalah menulis program dalam bahasa pemrograman pilihan Anda, tetapi Anda hanya diperbolehkan menggunakan bahasa lain. Artinya, buang semua konvensi pengkodean dari satu bahasa dan ganti dengan konvensi pengkodean dari bahasa lain. Lebih banyak lebih baik. Jadikan program Anda terlihat seperti ditulis dalam bahasa lain.

Misalnya, penggemar Python yang membenci Java dapat menulis program Python berikut di Jawa:

void my_function()                                                             {
    int i = 9                                                                  ;
    while(i>0)                                                                 {
        System.out.println("Hello!")                                           ;
        i = i - 1                                                              ;}}

Penggemar pascal yang dipaksa menggunakan C bisa menulis ini:

#define begin {
#define end }
#define then
#define writeln(str) puts(str)

if (i == 10) then
begin
    writeln("I hate C");
end

Anda harus menulis program yang lengkap. Program tidak perlu melakukan sesuatu yang bermanfaat.

Semoga berhasil. Ini adalah kontes popularitas sehingga kode dengan suara terbanyak menang!


1
@ m.buettner buat file Anda dengan ekstensi .litcoffee. Mungkin membantu.
Ismael Miguel

Sedikit panjang (dan sebelumnya ditulis, dan tidak mandiri) untuk jawaban, tetapi: scanner Postscript di Postscript di C .
luser droog

51
Saya tidak berpikir Anda (atau sebagian besar jawaban) mengerti maksud dari kutipan. Bukannya seorang Programmer Nyata menulis kode yang terlihat seperti Fortran meskipun dia menulis dalam Pascal atau LISP: dia menggunakan cara berpikir Fortran bahkan ketika menulis dalam Pascal atau LISP; mis. " Seperti yang diketahui semua Pemrogram Riil, satu-satunya struktur data yang berguna adalah Array. ". Jawaban yang bagus adalah kode prosedural dalam Prolog, kode fungsional dalam C, kode berorientasi objek dalam Pascal.
Peter Taylor

1
Saya berharap seseorang akan melakukan dialek Lisp, well, apa pun selain dialek Lisp lain ...
itsjeyd

6
Peraturan Pemrograman Kesepuluh Kesepuluh @itsjeyd Greenspun : "Program C atau Fortran yang cukup rumit mengandung ad-hoc, yang ditentukan secara tidak resmi, dipenuhi bug, implementasi lambat dari setengah CommonLisp."
Joshua Taylor

Jawaban:


142

C dalam C ++

#include <stdio.h>

int main(int argc, char** argv)
{
        printf("Hello world!\n");
        return 0;
}

60
Saya melihat apa yang Anda lakukan di sana;)
el.pescado

27
Nah, itu trik yang murah, mengingat C ++ 'kompatibel' dengan C.
Agi Hammerthief

5
@AlexM. Saya pikir itu akan lebih dalam semangat pertanyaan jika ini adalah contoh yang lebih panjang (prosedural) yang jelas akan mendapat manfaat dari menggunakan beberapa kelas dan yang menggunakan idiom C lain di mana beberapa kebaikan STL akan jauh lebih masuk akal (katakanlah char*bukannya std::string).
Martin Ender

47
Berlaku di C, C ++, Objective-C, dan Objective-C ++! Benar-benar jawaban polyglot yang luar biasa.
nneonneo

7
@ BenJackson Psh, programmer C yang sebenarnya gunakan char *argv[]!
Thomas

122

rakitan x86 dalam GNU C

Tidak, saya tidak hanya menggunakan asmkata kunci, karena pertanyaan yang dibuat ini adalah untuk programmer nyata ... ini akan berjalan dengan baik di ARM.

(Hanya untuk membuktikan intinya, saya tidak "menulis" perakitan sama sekali - ini adalah output yang dihasilkan oleh GCC Clang (503.0.38) untuk kode yang dikomentari di atas, diterjemahkan secara buta ke dalam makro.)

Ini hanya berfungsi dalam mode 32-bit. Itu tidak masalah karena kode programer sungguhan untuk ukuran kata.

#include <stdio.h>
#include <stdint.h>
/*
int fac(int x) {
    if (x < 1) return 1; else return x * fac(x - 1);
}

int fib(int x) {
    if (x < 2) return x; else return fib(x - 1) + fib(x - 2);
}

int main(void) {
    int a = fib(10), b = fac(10);
    printf("%d %d\n", a, b);
    return 0;
}
*/

typedef union REG {
    intptr_t i; int _i; void * v; union REG * r;
} REG;

#define LPAREN (
#define RPAREN )
#define MACRO(N) ); N##_MACRO LPAREN

#define push MACRO(PUSH)
#define pop  MACRO(POP)
#define mov  MACRO(MOV)
#define sub  MACRO(SUB)
#define add  MACRO(ADD)
#define imul MACRO(IMUL)
#define cmp  MACRO(CMP)
#define jge  MACRO(JGE)
#define jmp  MACRO(JMP)
#define call MACRO(CALL)
#define ret  MACRO(RET) _
#define label MACRO(LABEL)

#define NO_OP(X) 

#define PUSH_MACRO(VAL) *(esp -= 4) = (REG)(VAL)
#define POP_MACRO(DST) (DST) = (typeof(DST))(esp->i); esp += 4
#define MOV_MACRO(VAL, DST) (DST) = (typeof(DST))((REG)VAL).i;
#define SUB_MACRO(VAL, DST) CMP_MACRO(VAL, DST); \
    (DST) = (typeof(DST))(((REG)DST).i - ((REG)VAL).i)
#define ADD_MACRO(VAL, DST) DST = (typeof(DST))(((REG)DST).i + ((REG)VAL).i); \
    ZF = ((REG)DST).i == 0; OF = 0; SF = ((REG)DST).i < 0
#define IMUL_MACRO(VAL, DST) DST = (typeof(DST))(((REG)DST).i * ((REG)VAL).i); \
    ZF = ((REG)DST).i == 0; OF = 0; SF = ((REG)DST).i < 0
#define CMP_MACRO(L, R) CMP_MACRO_(((REG)L).i, ((REG)R).i)
#define CMP_MACRO_(L, R) (OF = 0, ZF = L == R, SF = (R - L) < 0)
#define JGE_MACRO(TGT) if (SF == OF) { goto TGT; } else {}
#define JMP_MACRO(TGT) goto TGT;
#define CALL_MACRO(PROC) CALL_MACRO_(PROC, __COUNTER__)
#define CALL_MACRO_(PROC, CTR) PUSH_MACRO(CTR - STARTIP); \
    goto PROC; case CTR - STARTIP:
#define RET_MACRO(_) eip = esp->i; esp += 4; if (eip) { continue; } else { goto *finalreturn; }
#define LABEL_MACRO(NAME) NAME

#define MY_ASM(X) do { const int STARTIP = __COUNTER__; \
    switch(eip) { case 0: MY_ASM_1 X } } while (1);
#define MY_ASM_1(X) MY_ASM_2(NO_OP LPAREN 0 X RPAREN;)
#define MY_ASM_2(X) X

#define CAT(L, R) _CAT(L, R)
#define _CAT(L, R) L##R

#define callASM(F) callASM_(F, CAT(_TMP_, __COUNTER__))
#define callASM_(F, LABEL) (({ PUSH_MACRO(0); stackbase = esp; finalreturn = &&LABEL; \
    goto F; LABEL:; }), (intptr_t)eax)


const int STACKSIZE = 4096;
REG callstack[STACKSIZE], * stackbase;
REG * eax, * ecx, * edx, * ebx, * esi, * edi, * esp, * ebp;
int SF, ZF, OF, eip; void * finalreturn;

int main(void) {
    eax = ecx = edx = ebx = esi = edi = esp = ebp = &callstack[STACKSIZE - 1];
    eip = 0;
    finalreturn = &&TOP; TOP:

    PUSH_MACRO(10);
    int a = callASM(_fac);
    PUSH_MACRO(10);
    int b = callASM(_fib);

    printf("%d %d\n", a, b);
    return 0;


    MY_ASM((
    label _fac:                                   // @fac
        push ebp
        mov esp, ebp
        sub 24, esp
        mov 8[ebp], eax
        mov eax, (-8)[ebp]
        cmp 1, (-8)[ebp]
        jge LBB0_2
        mov 1, (-4)[ebp]
        jmp LBB0_3
    label LBB0_2:
        mov (-8)[ebp], eax
        mov (-8)[ebp], ecx
        sub 1, ecx
        mov ecx, *esp
        mov eax, (-12)[ebp]         // 4-byte Spill
        call _fac
        mov (-12)[ebp], ecx         // 4-byte Reload
        imul eax, ecx
        mov ecx, (-4)[ebp]
    label LBB0_3:
        mov (-4)[ebp], eax
        add 24, esp
        pop ebp
        ret

    label _fib:                                   // @fib
        push ebp
        mov esp, ebp
        sub 24, esp
        mov 8[ebp], eax
        mov eax, (-8)[ebp]
        cmp 2, (-8)[ebp]
        jge LBB1_2
        mov (-8)[ebp], eax
        mov eax, (-4)[ebp]
        jmp LBB1_3
    label LBB1_2:
        mov (-8)[ebp], eax
        sub 1, eax
        mov eax, *esp
        call _fib
        mov (-8)[ebp], ecx
        sub 2, ecx
        mov ecx, *esp
        mov eax, (-12)[ebp]         // 4-byte Spill
        call _fib
        mov (-12)[ebp], ecx         // 4-byte Reload
        add eax, ecx
        mov ecx, (-4)[ebp]
    label LBB1_3:
        mov (-4)[ebp], eax
        add 24, esp
        pop ebp
        ret
    ))
}

Lihat saja semua gips itu. Pemain berarti aku realer programmer dari compiler, kan?


8
+1, itu ... bengkok. ;) Saya sangat suka bagaimana Anda menangani call, khususnya.
Ilmari Karonen

2
Wow. Itu pekerjaan yang bagus.
Jack Aidley

Saya punya assembler untuk C64 yang bekerja seperti ini. Ia menambahkan kata kunci BASIC untuk semua instruksi 6510 dan saya ingat Anda membungkusnya for pass=1:3...next. Melaksanakannya di penerjemah BASIC mengumpulkannya.
Ben Jackson

5
Ini adalah puisi murni.
Nicu Stiurca

1
Ini pria yang tangguh, kompilernya pasti kagum.
Internet dibuat dari catz

102

Bahasa Inggris di C

#include <stdio.h>
#define This
#define program     int main() {
#define aims
#define to
#define output      printf(
#define some
#define example
#define text(a)     #a
#define the
#define screen      "\n");
#define it          
#define also
#define will
#define calculate   ;int a = 
#define result
#define of
#define and
#define print       ; printf("%d\n", a);
#define seriously   return 0; }

This program aims to output some example text (Hello) to the screen;
it also will calculate the result of 3 + 4 and print the result; seriously

Ada ide untuk menghilangkan ;?


18
Serius, kalian.
Kyle Strand

2
mengapa mendefinisikan thedua kali?
Joshua Taylor

16
lebih baik aman daripada menyesal ;-)
urzeit

20
Sekarang buatlah itu menjadi haiku.
Nicu Stiurca

1
Bisakah Anda#define . ;
mbomb007

74

Brainfuck dalam JavaScript

Javascript adalah bahasa yang sulit! Mari kita gunakan Brainfuck, bahasa yang lebih dimengerti: o)

eval(

//write your easy code below

"++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."

//end of easy code

.replace(/\]/g,'}')
.replace(/\[/g,'while(a[i]){')
.replace(/\+/g,'a[i]++;')
.replace(/-/g,'a[i]--;')
.replace(/>/g,'i++;')
.replace(/</g,'i--;')
.replace(/\./g,'o+=String.fromCharCode(a[i]);')
.replace(/,/g,'a[i]=u.charCodeAt(j++);')
.replace(/^/,'var a=new Array(1000).join(\'0\').split(\'\'),i=500,o=\'\',u=prompt(\'Enter input if needed\'),j=0;')
.replace(/$/,'alert(o)')
)

Saya kira saya menulis penerjemah brainfuck dalam javascript.

Contoh di atas hanya ouputs Hello World!dan mengabaikan input (tanpa ,simbol).
Tapi itu bekerja dengan input juga! Misalnya, coba ,+>,+>,+>,+<<<.>.>.>.dan ketik golfdialog. Ini akan menampilkan karakter berikutnya dalam tabel ASCII:hpmg

EDIT : Penjelasan singkat untuk orang yang tidak tahu brainfuck.
Bayangkan sebuah array integer tak terhingga yang adiinisialisasi ke nol di mana-mana, sebuah pointer pada satu elemen array ini i, dan input pengguna u.
Brainfuck sangat mudah dipelajari tetapi sulit untuk menulis:

  • + kenaikan ke nilai saat ini: a[i]++
  • - menurunkannya: a[i]--
  • > membuat untuk menunjuk poin elemen berikutnya: i++
  • < sebelumnya : i--
  • [dan ]tentukan loop yang terputus ketika nilai saat ini nol:while (a[i]) { ... }
  • . cetak elemen saat ini: String.fromCharCode(a[i])
  • , setel elemen saat ini dengan input pengguna: u.charCodeAt(...)

22
Beri +1 untuk humor dalam menyatakan bahwa brainfuck lebih dapat dipahami daripada JavaScript.
Agi Hammerthief

Apakah Anda yakin bahwa karakter Brainfuck di dalam replacepernyataan tidak memengaruhi program?
Fraxtil

3
@fra File ini bukan program brainfuck, ini adalah program javascript yang berisi program brainfuck yang dikonversi ke javascript saat runtime.
undergroundmonorail

3
Nah, --ilebih cepat dari itu i--? Tampaknya salah sejak bertahun-tahun: jsperf.com/decrementgolf .
Michael M.

4
Ini bukan hanya pengajuan yang sangat kreatif untuk kontes, tetapi juga menjelaskan sintaks brainfuck dengan sangat jelas. +10 jika aku bisa!
SebastianH

74

Saya pikir Lennart Augustsson yang brilian telah memenangkan ini dua kali.

Pertama, inilah contoh implementasi "hack akhir pekan" nya BASIC sebagai Haskell Monadic DSL, dari 2009:

import BASIC

main = runBASIC' $ do

    10 LET I =: 1
    20 LET S =: 0
    30 LET S =: S + 1/I
    40 LET I =: I + 1
    50 IF I <> 100000000 THEN 30
    60 PRINT "Almost infinity is"
    70 PRINT S
    80 END

Ini bekerja dengan membebani jenis nomor. Nomor baris benar-benar fungsi yang menerima argumen. Sisa dari baris adalah argumen ke fungsi. Fungsi mengembalikan representasi Pohon Sintaks Abstrak untuk penerjemah BASIC untuk dikerjakan.

Saya juga merekomendasikan Anda untuk memeriksa entri Augustsson ke Kontes C International Obfuscated 2006, di mana ia berhasil masuk ke dalam 4k:

  • Juru bahasa bytecode, ditulis dalam himpunan bagian C (yang ia sebut C Jelas).
  • Sebuah Redup C -> bytecode compiler, yang ditulis dalam bytecode.

Mereka dapat berbagi file yang sama karena byetecode ditempatkan di dalam komentar C.

Sudah beberapa tahun sejak saya mengikuti karya Augustsson, jadi mungkin ada hal-hal brilian lain yang muncul sejak saat itu ....


2
Ini Augustsson, bukan Augustssen.
Hans Lundmark

@HansLundmark Terima kasih. Memperbaikinya.
Pitarou

71

PHP dan Javascript

Ini adalah polyglot:

Anda dapat menjalankan kode ini dalam kedua bahasa:

if("\0"=='\0')
{
    function printf(){
        $b=Array();
        $a=$b['slice']['call'](arguments);
        $a=$a['join']('');
        console.log($a);
        return $a.length;
    };

    function strtoupper($s){return $s['toUpperCase']();}

    function count($a){return $a['length'];}
}

printf('this is cool!');

$c=Array('a','b','c','d');

for($i=0,$l=count($c);$i<$l;++$i)printf("\n",strtoupper($c[$i]));

Kuncinya di sini adalah bahwa Javascript menggunakan urutan melarikan diri dalam string dimulai dengan 'dan ".
Di sisi lain, PHP hanya menggunakan urutan pelarian dalam string yang dimulai dengan "dan <<<.

Kemudian, kita mendeklarasikan fungsi printf, yang mirip dengan printtetapi menghasilkan string yang diformat dalam PHP.

PHP mengharuskan vars mulai dengan $, sementara Javascript memungkinkan.


Tidak ada yang menggunakan Array(…)JS, dan itu jelas array(…)dalam PHP. […]akan jauh lebih baik;)!
Blackhole

12
Saya tidak peduli apakah orang menggunakan Array()JS atau tidak: Saya peduli bahwa saya memiliki polyglot yang BENAR . Saya membuat salah satu kejahatan JS terburuk dengan kode ini, tetapi yang saya inginkan adalah ia menjalankan dan melakukan hal yang sama persis di keduanya, tetapi terlihat seperti JS dan PHP pada saat yang sama.
Ismael Miguel

Dan btw, [...]tidak valid dalam PHP <5.4.0, yang buruk ....... Jika saya melempar ini ke dalam PHP 4, 5 atau Javascript, saya berharap ini berfungsi, alih-alih memberikan kesalahan sintaksis di mana-mana.
Ismael Miguel

2
Jika Anda ingin kode Anda terlihat seperti JS, Anda harus menggunakan […], yang tampaknya cukup standar di PHP, dan karenanya OK untuk tujuan Anda. Omong-omong, PHP <5,4? Saatnya memperbarui, kawan ...
Blackhole

8
Kompatibilitas lebih penting daripada "penampilan". Dan Arrayadalah nama yang BENAR dari konstruktor objek Array. Pada dasarnya, menggunakan []sama dengan Array(). Saya tidak melihat hal buruk dengan itu. Tapi saya punya satu pertanyaan sederhana: Bekerja? (btw, saya harus menggunakan php 5.3.28 di tempat kerja.)
Ismael Miguel

55

Brainfuck di JS

[][(![]+[])[+[[+[]]]]+([][[]]+[])[+[[!+[]+!+[]+!+[]+!+[]+!+[]]]]+(![]+[])[+[[
!+[]+!+[]]]]+(!![]+[])[+[[+[]]]]+(!![]+[])[+[[!+[]+!+[]+!+[]]]]+(!![]+[])[+[[
+!+[]]]]][([][(![]+[])[+[[+[]]]]+([][[]]+[])[+[[!+[]+!+[]+!+[]+!+[]+!+[]]]]+(
![]+[])[+[[!+[]+!+[]]]]+(!![]+[])[+[[+[]]]]+(!![]+[])[+[[!+[]+!+[]+!+[]]]]+(!
![]+[])[+[[+!+[]]]]]+[])[+[[!+[]+!+[]+!+[]]]]+([][(![]+[])[+[[+[]]]]+([][[]]+
[])[+[[!+[]+!+[]+!+[]+!+[]+!+[]]]]+(![]+[])[+[[!+[]+!+[]]]]+(!![]+[])[+[[+[]]
]]+(!![]+[])[+[[!+[]+!+[]+!+[]]]]+(!![]+[])[+[[+!+[]]]]]+[])[+[[!+[]+!+[]+!+[
]+!+[]+!+[]+!+[]]]]+([][[]]+[])[+[[+!+[]]]]+(![]+[])[+[[!+[]+!+[]+!+[]]]]+(!!
[]+[])[+[[+[]]]]+(!![]+[])[+[[+!+[]]]]+([][[]]+[])[+[[+[]]]]+([][(![]+[])[+[[
+[]]]]+([][[]]+[])[+[[!+[]+!+[]+!+[]+!+[]+!+[]]]]+(![]+[])[+[[!+[]+!+[]]]]+(!
![]+[])[+[[+[]]]]+(!![]+[])[+[[!+[]+!+[]+!+[]]]]+(!![]+[])[+[[+!+[]]]]]+[])[+
[[!+[]+!+[]+!+[]]]]+(!![]+[])[+[[+[]]]]+([][(![]+[])[+[[+[]]]]+([][[]]+[])[+[
[!+[]+!+[]+!+[]+!+[]+!+[]]]]+(![]+[])[+[[!+[]+!+[]]]]+(!![]+[])[+[[+[]]]]+(!!
[]+[])[+[[!+[]+!+[]+!+[]]]]+(!![]+[])[+[[+!+[]]]]]+[])[+[[!+[]+!+[]+!+[]+!+[]
+!+[]+!+[]]]]+(!![]+[])[+[[+!+[]]]]]((![]+[])[+[[+!+[]]]]+(![]+[])[+[[!+[]+!+
[]]]]+(!![]+[])[+[[!+[]+!+[]+!+[]]]]+(!![]+[])[+[[+!+[]]]]+(!![]+[])[+[[+[]]]
]+([][(![]+[])[+[[+[]]]]+([][[]]+[])[+[[!+[]+!+[]+!+[]+!+[]+!+[]]]]+(![]+[])[
+[[!+[]+!+[]]]]+(!![]+[])[+[[+[]]]]+(!![]+[])[+[[!+[]+!+[]+!+[]]]]+(!![]+[])[
+[[+!+[]]]]]+[])[+[[+!+[]]]+[[!+[]+!+[]+!+[]+!+[]+!+[]]]]+[+!+[]]+([][(![]+[]
)[+[[+[]]]]+([][[]]+[])[+[[!+[]+!+[]+!+[]+!+[]+!+[]]]]+(![]+[])[+[[!+[]+!+[]]
]]+(!![]+[])[+[[+[]]]]+(!![]+[])[+[[!+[]+!+[]+!+[]]]]+(!![]+[])[+[[+!+[]]]]]+
[])[+[[+!+[]]]+[[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]]])()

12
Saya tidak melihat brainfuck di sini. Bahkan satu karakter pun di><,.-
Michael M.

8
@ Michael: Siapa bilang itu bukan program yang membuat infinite loop?
Konrad Borowski

19
apakah JSF * ck ini?

8
Bagaimana di bumi gunanya itu ?
nandhp

4
Oo. Seseorang akhirnya melakukan ini. Saya menghabiskan beberapa waktu mencoba mencari cara untuk menulis program JS hanya menggunakan karakter +! [] () Tetapi tidak pernah bisa mengetahuinya. Saya perlu menganalisis ini ketika saya punya waktu ...
Matti Virkkunen

54

Ini adalah salah satu dari pemenang IOCCC 2005 , sebuah program C yang, kecuali oleh sekelompok definisi itu, terlihat seperti program java:

/*
 * Sun's Java is often touted as being "portable", even though my code won't
 * suddenly become uber-portable if it's in Java. Truth is, Java's one of
 * the most ugly, slow, and straitjacketed languages ever. It's popular
 * mainly because people hear the word "portable" and go "ewww".
 *
 * This program, then, is dedicated to bringing about the death of Java. We
 * good coders have been oppressed for too long by the lame language
 * decisions of pointy-haired bosses and academics who should know better. 
 * It's time we stand up against this junk, and bring back the fun in
 * programming! Viva La Revolution!
 */

#define aSet c
#define BufferedReader(x)1
#define byte Y[I][_^1]?do(:):_&1?do(.):do(`):8;++y;}
#define class int N=0,_,O=328,l=192,y=4,Y[80][64]={0},I;struct
#define do(c)a(#c "\b")
#define err c,c
#define getAllStrings(x));q()
#define if(x)b(#x)
#define IOException
#define line c
#define main(a)b(char*x){write(1,"\033[",2),null}main()
#define new
#define null a(x);}a(char*x){write(1,x,strlen(x));try;try;try;try;
#define out c,c
#define println(x)c
#define private int d(int
#define public short c;}c;typedef int BufferedReader;char*F="JF>:>FB;;BII";
#define return {return
#define static f(x){N=(N+x)%6,y--?f(0),f(1),f(4),f(1):++Y[(I=O+N[F]-66)
#define String
#define System c
#define this if(D):1,O=I,I/=16,l<_/32?if(B):l>_/32?if(A):2,l=_,_/=16,byte
#define throws
#define toArray(x)c
#define try for(;--c.c;)
#define void /16][(_=l+N[6+F]-66)/16]?O/=16,l/=32,O<I/16?if(C):O>I/16?this
#define while(k)if(2J),if(7;21H),f(0),f(4),f(4),if(H),/*

import java.io.*;
import java.util.*;

/**
 * A lame Java program.
 * @author  J. Random Worker
 */
class LameJavaApp
{

    /** The infamous Long-Winded Signature From Hell. */
    public static void main(String[] args)
        throws IOException
    {
        /* Don't get me started on this. */
        BufferedReader reader =
            new BufferedReader(new FileReader(args[0]));

        /* What, this long incantation just to print a string? */
        System.err.println("Hello world!");

        /* At least this is sane. */
        String line;
        while ((line = reader.readLine()) != null)
            System.out.println(line.length());
    }

    /**
     * Method with a needlessly long name.
     * @param   aSet        a set (!)
     */
    private String[] getAllStrings(Set<String> aSet)
    {
        /*
         * This dance is needed even in J2SE 5, which has type
         * templates. It was worse before that.
         */
        return aSet.toArray(new String[0]);
    }

}

3
Verbositas pada yang terbaik.
qwr

39

C ++ dalam C

OK, jadi Anda adalah seorang programmer C ++, tetapi dipaksa untuk menggunakan C? Tidak masalah, Anda hanya perlu menulis beberapa header tambahan yang hilang dalam C. Misalnya, inilah program Hello World yang valid di C:

Dalam file header tambahan iostream, tulis:

#include <stdio.h>

#define using volatile int
#define namespace message
#define std = 0
#define message(x) printf("%s\n",x)
#define cout 0
#define endl 0

Dalam file string, tulis

#define string

Dalam file helloworld.c(kode C Anda yang sebenarnya), tulis

#include <iostream>
#include <string>

using namespace std;

int main()
{
  string message("Hello world");
  cout << message << endl;
  return 0;
}

Dan ketika kompilasi helloworld.cdengan kompiler C, instruksikan kompiler untuk juga mencari <...>file header di mana pun Anda menyimpan file iostreamdan string, misalnya, jika Anda mengkompilasi dengan gcc dan meletakkan file iostreamdan stringdalam direktori saat ini, kompilasi dengan

gcc helloworld.c -o helloworld -I.

Catatan: volatileHeader in iostreamada untuk memungkinkan kompilasi bebas peringatan bahkan pada tingkat peringatan maksimum (pembacaan dari variabel yang tidak stabil dianggap memiliki efek).


3
Ini sedikit kode trolling, bukan?
Tn. Lister

Ya, programnya melakukan apa yang seharusnya dilakukan, bukan?
celtschk

8
Jauh lebih lucu dan lebih mengesankan dari C dalam C ++.
Kyle Strand

Kompiler seperti apa yang memperingatkan jika Anda tidak menggunakannya di volatilesini, dan peringatan seperti apa?
R. Martinho Fernandes

1
@KyleStrand Tapi "C dalam C ++" satu lebih selaras dengan kutipan dalam pertanyaan. Programer program nyata dalam C, bahkan jika mereka memiliki kompiler C ++.
Tn. Lister

36

CQL - Bahasa Query berkafein

(atau "SQL on Caffeine")

Ini mungkin agak terlalu ambisius. Berikut adalah upaya untuk menulis kode deklaratif SQL (ish) dalam CoffeeScript . Ini membutuhkan fitur Proxy ECMAScript 6 . Anda dapat mengujinya dalam simpul dengan --harmony-proxies.

Mari kita membuat template untuk mendefinisikan proxy. (Diambil dari komentar Benvie tentang masalah ini )

forward = (->
  _slice  = Array.prototype.slice
  _bind   = Function.prototype.bind
  _apply  = Function.prototype.apply
  _hasOwn = Object.prototype.hasOwnProperty

  Forwarder = (target) ->
    @target = target
    this

  Forwarder.prototype =
    getOwnPropertyNames: -> Object.getOwnPropertyNames(@target)
    keys: -> Object.keys(@target)
    enumerate: ->
      i = 0
      keys = []
      for value of @target
        keys[i++] = value
      keys
    getPropertyDescriptor: (key) ->
      o = @target;
      while o
        desc = Object.getOwnPropertyDescriptor o, key
        if desc
          desc.configurable = true;
          return desc;

        o = Object.getPrototypeOf o
    getOwnPropertyDescriptor: (key) ->
      desc = Object.getOwnPropertyDescriptor @target, key
      if desc
        desc.configurable = true
      desc
    defineProperty: (key, desc) -> Object.defineProperty @target, key, desc
    get: (receiver, key) -> @target[key]
    set: (receiver, key, value) ->
      @target[key] = value;
      true
    has: (key) -> key of @target
    hasOwn: (key) -> _hasOwn.call @target, key
    delete: (key) ->
      delete @target[key]
      true
    apply: (receiver, args) -> _apply.call @target, receiver, args
    construct: (args) -> new (_bind.apply @target, [null].concat args);

  forward = (target, overrides) ->
    handler = new Forwarder target;
    for k of Object overrides
      handler[k] = overrides[k]

    if typeof target is 'function'
      return Proxy.createFunction handler,
                                  -> handler.apply this, _slice.call arguments,
                                  -> handler.construct _slice.call arguments
    else
      return Proxy.create handler, Object.getPrototypeOf Object target

  forward
)();

Sekarang tentukan objek proxy dan beberapa variabel dan fungsi global yang mencurigakan:

sql = forward {
  tables: {}

  finalize: ->
    if typeof @activeRows isnt 'function'
      @result = []
      for row in @activeRows
        @result.push (val for val, i in row when @activeTable.columns[i] in @activeColumns)
    delete @activeRows
    delete @activeColumns
    delete @activeTable

  run: (q) ->
    q.call(this)
    @finalize()
    result = @result
    delete @result
    if typeof result isnt 'function' then console.log result
    return result
}, {
  get: (o,name) ->
    if name of @target
      return @target[name];
    (args...) -> {
      name
      args
    }
}

int = Number
varchar = (l) -> String

TABLE = (x) -> x
INTO = (x) -> x
CREATE = (tableData) ->
  name = tableData.name
  table =
    columns: []
  column = tableData.args[0]
  table[column.name] = []
  table.columns.push(column.name)
  while column = column.args[1]
    table[column.name] = []
    table.columns.push(column.name)

  sql.tables[name] = table

  sql.result = "Created table '#{name}'"

INSERT = (table) -> sql.activeTable = sql.tables[table().name]
VALUES = (rows...) ->
  for row in rows
    for val, i in row
      column = sql.activeTable.columns[i]
      sql.activeTable[column].push val

  sql.result = "Inserted #{rows.length} rows"

FROM = (table) ->
  sql.activeTable = sql.tables[table().name]
SELECT = (columns...) ->
  sql.activeColumns = []
  for col in columns
    if typeof col is 'function'
      col = col()

    sql.activeColumns.push col.name

  sql.activeRows = []
  for val in sql.activeTable[sql.activeTable.columns[0]]
    sql.activeRows.push []

  for col in sql.activeTable.columns
    for val, i in sql.activeTable[col]
      sql.activeRows[i].push val

IN = (list) -> { op: 'in', list }
WHERE = (column) ->
  i = sql.activeTable.columns.indexOf(column.name)
  if column.args[0].op is 'in'
    list = column.args[0].list
    sql.activeRows = (row for row in sql.activeRows when row[i] in list)
  else
    console.log 'Not supported!'

ASC = 'asc'
DESC = 'desc'
BY = (x) -> x
ORDER = (column) ->
  i = sql.activeTable.columns.indexOf(column.name)
  order = if column.args[0] is sql.ASC then 1 else -1
  sql.activeRows.sort (a,b) ->
    if a[i] < b[i]
      return -order
    else if a[i] > b[i]
      return order
    else
      return 0

Yah itu setup yang cukup banyak! Tapi sekarang kita bisa melakukan hal berikut (input / output dalam gaya konsol):

> sql.run ->
    CREATE TABLE @books(
      @title varchar(255),
      @author varchar(255),
      @year int
    );

Create Table 'books'

> sql.run ->
    INSERT INTO @books
    VALUES ['The C++ Programming Language', 'Bjarne Stroustrup', 1985],
           ['Effective C++', 'Scott Meyers', 1992],
           ['Exceptional C++', 'Herb Sutter', 2000],
           ['Effective STL', 'Scott Meyers', 2001];

Inserted 4 rows

> sql.run ->
    SELECT @title, @year FROM @books
    WHERE @author IN ['Bjarne Stroustrup', 'Scott Meyers']
    ORDER BY @year DESC;

[ [ 'Effective STL', 2001 ],
  [ 'Effective C++', 1992 ],
  [ 'The C++ Programming Language', 1985 ] ]

Ini bukan polyglot yang sebenarnya, tapi bukan itu intinya. Saya tahu itu @digunakan untuk variabel dalam SQL, tapi saya perlu semua @s untuk nama kolom dan tabel karena saya belum menemukan cara untuk proxy objek global (dan saya tidak akan terkejut jika itu benar-benar tidak mungkin - dan untuk alasan yang bagus).

Saya juga mengubah beberapa tanda kurung menjadi tanda kurung (khususnya setelah VALUESdan IN). Sayangnya, apa yang saya tidak tahu sama sekali adalah cara untuk memungkinkan kondisi normal seperti year > 2000, karena mereka akan mengevaluasi ke boolean segera.

Masih ini sangat mirip SQL dan jelas lebih deklaratif daripada imperatif / fungsional / berorientasi objek sehingga harus memenuhi syarat baik untuk pertanyaan. Saya sebenarnya berpikir jika saya sedikit memoles kode dan mendukung beberapa fitur, ini bisa menjadi modul CoffeeScript yang berguna.

Bagaimanapun, ini menyenangkan! :)

Bagi mereka yang tidak terlalu mengenal CoffeeScript, query SQL mengkompilasi ke JavaScript berikut:

sql.run(function() {
  return CREATE(
    TABLE(
      this.books(
        this.title(varchar(255), 
        this.author(varchar(255), 
        this.year(int)))
      )
    )
  );
});

sql.run(function() {
  INSERT(INTO(this.books));
  return VALUES([...], ['Effective C++', 'Scott Meyers', 1992], [...], [...]);
});

sql.run(function() {
  SELECT(this.title, this.year(FROM(this.books)));
  WHERE(this.author(IN(['Bjarne Stroustrup', 'Scott Meyers'])));
  return ORDER(BY(this.year(thisESC)));
});

Pengaturannya cukup banyak, tetapi memang terlihat bagus. Saya bukan seorang programmer CoffeeScript, tetapi memang terlihat hebat. The @di SQL digunakan untuk variabel sesi.
Ismael Miguel

Saya memutuskan untuk membuat kata kunci global sekarang. Sekarang hanya ada @s untuk nama kolom dan tabel.
Martin Ender

Sekarang sangat mirip dengan SQL! Anda melakukan pekerjaan yang bagus dengan yang ini!
Ismael Miguel

1
Saya tidak terlalu peduli untuk kopi, tapi ini luar biasa.
KRyan

2
@tac terima kasih, tapi tidak, saya hanya meretasnya bersama untuk tantangan ini. Kebetulan lucu: mengulang ini dengan cara yang bersih dan menaruhnya di GitHub ada dalam daftar proyek koding potensial / jangka panjang sampai saya menghapusnya pagi ini.
Martin Ender

27

Visual Basic 6 (dalam JavaScript)

'; Main sub-routine \
'; function Main() { ' \
Sub Main() '
    ' Do not throw any errors... \
    On Error Resume Next '; MsgBox = alert

    ' Show a message box... \
    MsgBox(1 / 0) '

    ' Show errors again... \
    On Error GoTo 0 '

    ' Show another message box... '
    MsgBox("Hello")
    ' ' } ' \
End Sub '

Main()

Ini juga berfungsi di VBScript.


1
Pintar. Anda bahkan tidak membutuhkan sebagian besar titik koma.
js1568

@ js1568 Terima kasih! Saya sekarang telah menghapus titik koma yang tidak diperlukan.
Sikat gigi

20

F # dalam C ++

Penyalahgunaan preprocessor yang tidak imajinatif dan tidak menyenangkan. Saya pikir itu akan menyenangkan untuk mengubah C ++ agar terlihat seperti bahasa yang sama sekali berbeda daripada menggunakan beberapa alias untuk membuatnya terlihat seperti Java atau PHP. Saya tidak benar-benar berharap ini untuk mengumpulkan satu ton upvotes, ini hanya untuk bersenang-senang.

#define let int
#define args ( int __, char* args[] ) { int ___ 
#define println printf(
#define exit "\n" ); return 0; }
#include <stdio.h>

let main args =
    println "F# is better than C++"
    exit

Coba di sini .

Sedihnya menulis sesuatu kepada STDOUT adalah semua yang bisa dilakukan, walaupun saya yakin jika seseorang melemparkan cukup sihir, mereka dapat membuatnya melakukan lebih banyak.


2
Agar baris terakhir berfungsi di F #, harus berupa exit 0atau adil 0.
Jwosty

20

Python dan ... tidak ada yang akan menebak (edit: dc)

Berikut adalah beberapa kode python yang valid, tetapi sebenarnya program ini ditulis dalam bahasa yang sangat berbeda:

# Initialize systems 1 and 2
# frame 1, divergency speed and divergency latency
f1ds, f1dl, z1 = [2,2,0]
# frame 2, divergency speed and divergency latency
f2ds, f2dl, z2 = [4,4,1]

# Set the most relevant value of ax (detected by low-energy collision)
ax = 42.424242

# Initialize list of successive energy states
s = [17.98167, 21.1621, 34.1217218, 57.917182]

# Most common value for nz parameter
# TODO: check if value from the article of A. Einstein is better
nz = 10

if z2>nz or ax in s:
  ax += 6
  f1ds = 8
  f2ds = 16
  z1 = 4
  z2 = 9

f1dl += z1
f2dl += z2

# main loop, iterate over all energy states
# Warning: hit Ctrl-C if nuclear explosion occurs and adjust either z or nz
for k in s:
  z = nz + k
  f1dl = f1ds + f2dl * z - z1 + 3.14
  f2dl = f2ds + f1dl * z - z2 + 10
  if k > 10 or z-2 in s:
    nz += 0xac  # hexadecimal coefficient found in famous article by E. Fermi

Kode berjalan dalam kedua bahasa tanpa kesalahan.

Kombinasi ini sangat gila; Saya akan senang menunggu satu atau dua hari sebelum mengatakan mana bahasa lain; silakan tinggalkan komentar untuk menebak.

sunting: Bahasa tersebut adalah bahasa berbasis stack dari dc. Anda mungkin lihat di sini kata kunci terkenal seperti for, if, or, in, tetapi hanya surat-surat penting! Yang ,tidak memiliki arti dalam dc berubah menjadi register karena pertama kali muncul adalah setelah huruf s(sama untuk :).


1
Kecuali kode melakukan hal yang sama di kedua bahasa, saya kira bahasa seperti Befunge dapat melakukan trik.
Thomas Eding

OK, saya mengedit kode untuk menempatkan bahasa yang sebenarnya saya pilih.
Thomas Baruchel

18

C ++ memungkinkan Anda untuk menulis kode mirip-lisp, dengan perpustakaan InteLib:

(L|DEFUN, ISOMORPHIC, (L|TREE1, TREE2),
   (L|COND, 
     (L|(L|ATOM, TREE1), (L|ATOM, TREE2)),
     (L|(L|ATOM, TREE2), NIL),
     (L|T, (L|AND,
       (L|ISOMORPHIC, (L|CAR, TREE1), 
                      (L|CAR, TREE2)),
       (L|ISOMORPHIC, (L|CDR, TREE1), 
                      (L|CDR, TREE2))
 )))).Evaluate();

lih. http://www.informatimago.com/articles/life-saver.html


4
Selamat datang! Kami meminta pengguna untuk menandai posting mereka sebagai Wiki Komunitas ketika jawabannya bukan karya mereka sendiri. (Dan berikan atribusi yang tepat, tetapi Anda sudah melakukannya, jadi terima kasih!)
Jonathan Van Matre

Asli atau tidak, Anda mendapat suara saya :)
itsjeyd

15

C # di Whitespace

Oke, pertama coba di salah satu dari ini, jadi mari kita lihat bagaimana kelanjutannya.

using System; //very important  

namespace ConsoleApplication1  //namespace: name whatever you want      
{ 
 //start    
 class  Program  //class name:  also anything    
    {
    //main function 
    static void Main(string[] args) {
        for(int i=0;i<10;i++)   writeOutput(i); 
    } //end main    
    static void writeOutput(int i) { Console.WriteLine(i); }    //display output    


    } //class ends here         

}  //close namespace:   also very important     





//yay!

Dan jika pemformatan menjadi kacau karena harus meletakkan empat spasi di depan setiap baris, ini dia lagi. untuk ruang dan # untuk tab:

using.System;.//very.important#

namespace.ConsoleApplication1..//namespace:#name.whatever.you.want##
{.
.//start#
.class#Program..//class.name:#also.anything#.
#{
....//main.function#
#static.void.Main(string[].args).{
....#for(int.i=0;i<10;i++)#writeOutput(i);#
#}.//end.main#
#static.void.writeOutput(int#i).{.Console.WriteLine(i);.}#//display.output#

.
.#}.//class.ends.here.##

}..//close.namespace:#also.very.important#.#
.




//yay!

12

HTML dan CSS

Bukan bahasa pemrograman, tapi ... dokumen ini adalah HTML dan CSS yang valid :

<!-- p{color:red} /* -->
<!Doctype html>
<title>This is HTML and CSS</title>
<p>Hi!</p>
<!-- */ -->
<!-- p{color:red} /* -->
<!Doctype html>
<title>This is HTML and CSS</title>
<p>Hi!</p>
<!-- */ -->

Ini berfungsi, karena komentar HTML diizinkan dalam stylesheet karena alasan historis. Oh, dan setiap dokumen HTML yang valid juga merupakan program PHP yang valid, jadi ini juga PHP . :)


2
Itu cukup lucu dan semua tapi ini bukan tantangan polyglot .
Martin Ender

Karena CSS dapat dianggap turing lengkap , ini mungkin jawaban yang valid.
Adam Davis

2
HTML dan CSS bukan bahasa pemrograman :)
Jet

9

C dalam Scala

Layer bridging mengemulasi era yang lebih romantis ketika string masih null array yang diakhiri byte.

// Scala is a dynamic language
import scala.language.{ dynamics, postfixOps }

val self = this

val argc = args.length
val argv = args.map(_.getBytes)

type char = Array[Byte]
object char extends Dynamic {
  // This program uses expanded memory
  val buffers = new scala.collection.mutable.LinkedHashMap[String, char]

  // Malloc char buffer
  def applyDynamic(name: String)(length: Int) =
    buffers(name) = new Array(length)

  def **(argv: Array[Array[Byte]]) = argv
}

object & extends Dynamic {
  // dereference char pointer
  def selectDynamic(name: String) = char.buffers(name)
}

def printf(format: String, buffers: char*) =
  println(
    (format /: buffers){ case (msg, buffer) =>
      // Read string until \0 terminator
      val value = new String(buffer.takeWhile(0 !=))
      // Replace next %s token
      msg.replaceFirst("%s", value)
    }
  )

def scanf(format: String, buffers: char*) =
  buffers foreach { buffer =>
    val line = Console.readLine()
    // Write string to char* buffer
    line.getBytes(0, line.length, buffer, 0)
    // Remember to always null terminate your strings!
    buffer(line.length) = 0
  }

val PATH_MAX = 4096

implicit class Argumenter(args: Pair[_, _]) {
  def apply[T](f: => T) = f
}

object int {
  // Passthrough
  def main[T](f: => T) = f
  def argc = self.argc
}

// terminates the string after the first character
// investigate switching to "xor eax, eax" instead of having a hardcoded 0
// might save 3 bytes and valuable CPU time with this trick
val initialize = (_: char)(1) = 0

def exit(value: Int) = sys.exit(value)
// ---HOMEWORK-ASSIGNMENT-START---

int main(int argc, char **argv) {
  if (argc != 0) {
    printf("This program does not take parameters!");
    exit(1);
  }

  // I've copy pasted this code from somewhere
  // Code reuse is essential if we want to be DRY
  char first(PATH_MAX + 1);
  char last(PATH_MAX + 1);

  printf("Enter your first and last name:\n");
  scanf("%s%s", &first, &last);

  // Still learning references, do I need these here?
  // I've performed benchmarks on printf and I think it's faster this way
  printf("Your full name is %s %s", &first, &last);

  initialize(&first);
  printf("Your signature is %s. %s", &first, &last);

  exit(0);
}

"This program does not take parameters!"
bodoh

8

sed dan APL

Bos saya ingin saya menulis skrip sed, tapi saya lebih suka menulis APL sepanjang hari. Namun demikian, ia sangat senang dengan pekerjaan saya karena skrip tersebut berjalan dengan versi sednya:

i ← g ← 42
a ← d ← 10
s/s←2⊤42/s←2⊤43/g
s/s[01]*1/s⊣1/g
g

Anda dapat mencobanya di situs web baru saya dengan tautan permanen ini . Ini adalah versi javascript yang dikompilasi untuk GNU APL. Rilis final nanti dengan rilis resmi GNU APL, v. 1.3 tetapi Anda dapat menggunakannya dengan sempurna untuk permalink Anda jika Anda menikmati GNU APL.


7

C dalam Haskell

import Foreign.C.String
import Foreign.C.Types
import Foreign.Marshal.Array
import Foreign.Ptr
import System.Environment
import System.Exit

-- The meat of the program

cmain :: (CInt, Ptr (Ptr CChar)) -> IO CInt
cmain(argc, argv) = do {
    putStr("hello, world\n");
    return 0;
}

-- Of course, the above function doesn't do anything unless we write a wrapper
-- around it.  This could have been done more simply, using higher-level library
-- functions, but where's the fun in that?

main :: IO ()
main = do {
    args <- getArgs;
    argPtrs <- sequence [do {
        argPtr <- mallocArray0(length(arg)) :: IO (Ptr CChar);
        pokeArray0(0)(argPtr)(map(castCharToCChar)(arg));
        return argPtr;
    } | arg <- args ];
    argv <- mallocArray(length(argPtrs)) :: IO (Ptr (Ptr CChar));
    pokeArray(argv)(argPtrs);

    exitCode <- cmain(fromIntegral(length(args)),argv);

    if (exitCode == 0) then do {
        exitWith(ExitSuccess);
    } else do {
        exitWith(ExitFailure(fromIntegral(exitCode)));
    };
}

Tentu saja, karena cmaintidak melakukan apa pun dengan argcatau argv, kode marshaling argumen tidak berpengaruh, dan karena cmainselalu mengembalikan 0, cabang "lain" dari pernyataan "jika" sudah mati. Tetapi pernyataan "jika" tidak melakukan apa-apa.

Semua kurung kurawal dan titik koma tidak perlu, seperti juga sebagian besar kurung dan beberapa dokata kunci. Pernyataan "jika" bisa ditulis sebagai if exitCode == 0 then exitWith ExitSuccess else exitWith (ExitFailure (fromIntegral exitCode)).


7

C ++ dalam Forth

: #include ; : <iostream> ; : { ; : } ; : int ; : using ;
: namespace ; : std; ; : main() ; : cout ; : << ;
: "Hello,  ; : world!\n"; S" Hello, world!" type ; : return ; : 0; ;

#include <iostream>
using namespace std;

int main() {
    cout << "Hello, world!\n";
}

Bukan solusi yang paling fleksibel, tetapi berfungsi jika ditulis persis seperti yang ditunjukkan.


7

Haskell di Jawa

("vanilla" Java 7, bukan Java 8) (Ya, saya tahu bahwa kinerja reruntuhan tinju; dan bahkan mencoba menggunakan fungsi orde tinggi menjadi gila verbose: D)

Java memiliki sintaks yang sangat kaku, jadi alih-alih mengubah sintaks, saya mencoba membuat kode yang secara semantik lebih mirip dengan gaya Haskell.

Edit - menambahkan aplikasi fungsi parsial.

import java.util.Iterator;

interface Function1<A, B> {
    A call(B arg);
}

interface Function2<A, B, C> {
    A call(B arg1, C arg2);
}

class Reduce<A> implements Function2<A, Function2<A, A, A>, Iterable<A>> {

    @Override
    public A call(Function2<A, A, A> arg1, Iterable<A> arg2) {
        final Iterator<A> i = arg2.iterator();
        A r = i.next();
        while (i.hasNext())
            r = arg1.call(r, i.next());
        return r;
    }
}

class Range implements Iterable<Integer> {

    private final int min;
    private final int max;

    public Range(int min, int max) {
        this.min = min;
        this.max = max;
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int i = min;

            @Override
            public boolean hasNext() {
                return i <= max;
            }

            @Override
            public Integer next() {
                return i++;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }
}

public class Main {

    public static <A, B, C> Function1<A, C> applyPartial(final Function2<A, B, C> f, final B arg2) {
        return new Function1<A, C>() {
            @Override
            public A call(C arg) {
                return f.call(arg2, arg);
            }
        };
    }

    public static void main(String[] args) {

        final Function1<Integer, Iterable<Integer>> product = applyPartial(new Reduce<Integer>(), new Function2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer arg1, Integer arg2) {
                return arg1 * arg2;
            }
        });

        final Function1<Integer, Integer> fact = new Function1<Integer, Integer>() {

            @Override
            public Integer call(Integer arg) {
                return product.call(new Range(1, arg));
            }
        };

        final Integer x = fact.call(6);

        System.out.println(x.toString());
    }
}

(Ya, semua yang dilakukan kegilaan ini adalah komputasi 6!)


6

COBOL dalam AWK

Dalam semangat kutipan. AWK murni, tidak tercemar, karena dapat ditulis oleh programmer COBOL.

Tugasnya adalah untuk menghitung catatan pada file. Versi pengembangan awal ini menghitung sendiri untuk pengujian. File yang benar akan dikodekan kemudian ketika dirilis dari Unit Testing ...

Jika saya bisa mendapatkan sintaks untuk melakukan fosfor-hijau pada hitam, itu akan bagus ...

Bahkan mendapatkan nomor kolom yang benar pada yang satu ini, itu tujuh kosong pada awal setiap baris (tidak pernah melakukan itu di awk sebelumnya) dan melanggar pernyataan cetak panjang pada kolom 72.

   BEGIN { 
       PERFORM_000_INITIALISATION() 
       PERFORM_100_OPEN_FILES() 
       PERFORM_200_PROCESS_FILE() 
       PERFORM_300_CLOSE_FILES() 
       PERFORM_400_SHOW_THE_COUNTS() 
       exit 
   } 
   function PERFORM_000_INITIALISATION() { 
       INPUT_FILE_NAME = "COBOL.AWK" 
       RECORD_COUNT = 0 
   } 
   function PERFORM_100_OPEN_FILES() { 
   } 
   function PERFORM_200_PROCESS_FILE() { 
       PERFORM_210_PRIMING_READ() 
       PERFORM_220_PROCESS_INPUT_UNTIL_END() 
   } 
   function PERFORM_300_CLOSE_FILES() { 
   } 
   function PERFORM_400_SHOW_THE_COUNTS() { 
       print "COBOL.AWK: NUMBER OF RECORDS READ IS " RECORD_COUNT        
   } 
   function PERFORM_210_PRIMING_READ() { 
       PERFORM_900_READ_THE_FILE() 
       if ( FILE_STATUS < 0 ) { 
           print "COBOL.AWK ERR0001: INVALID FILE, HALTING, FILE N" \
                 "AME IS: " INPUT_FILE_NAME 
           exit 
           } 
       if ( FILE_STATUS == 0 ) { 
           print "COBOL.AWK ERR0002: NO RECORDS ON INPUT, HALTING," \
                 "FILE NAME IS: " INPUT_FILE_NAME 
           exit 
           } 
   } 
   function PERFORM_220_PROCESS_INPUT_UNTIL_END() {
       while ( FILE_STATUS != 0 ) { 
           INPUT_RECORD = $0 
           RECORD_COUNT = RECORD_COUNT + 1 
           PERFORM_900_READ_THE_FILE() 
           } 
   } 
   function PERFORM_900_READ_THE_FILE() { 
       FILE_STATUS = getline < INPUT_FILE_NAME 
   }        

6

Brainfuck (atau apa pun) di Racket

Modul fleksibel dan sistem makro Racket memungkinkannya untuk mengimplementasikan dukungan modul untuk bahasa yang sama sekali baru, baik untuk domain tertentu maupun untuk tujuan umum. Ada dukungan di luar kotak untuk Datalog dan Algol 60 , jadi berikut ini adalah program Racket yang valid:

#lang datalog
edge(a, b). edge(b, c). edge(c, d). edge(d, a).
path(X, Y) :- edge(X, Y).
path(X, Y) :- edge(X, Z), path(Z, Y).
path(X, Y)?

#lang algol60
begin
  integer procedure SIGMA(x, i, n);
    value n;
    integer x, i, n;
  begin
    integer sum;
    sum := 0;
    for i := 1 step 1 until n do
      sum := sum + x;
    SIGMA := sum;
  end;
  integer q;
  printnln(SIGMA(q*2-1, q, 7));
end

Anda juga dapat menambahkan dukungan untuk bahasa lain: mis. Lihat deskripsi Danny Yoo tentang cara menerapkan dukungan untuk Brainfuck, yang memungkinkan program Racket seperti:

#lang planet dyoo/bf
++++++[>++++++++++++<-]>.
>++++++++++[>++++++++++<-]>+.
+++++++..+++.>++++[>+++++++++++<-]>.
<+++[>----<-]>.<<<<<+++[>+++++<-]>.
>>.+++.------.--------.>>+.

Dan karena dukungan ditambahkan pada level modul yang dikompilasi, dimungkinkan untuk menautkan modul yang ditulis dalam bahasa yang berbeda atau menyematkan cuplikan dari satu bahasa di dalam modul yang ditulis dalam bahasa lain.


5

SML di Jawa

Saya masih memiliki beberapa kode kuno dari mulai ketika saya mulai belajar Java dan mencoba menggunakannya dalam gaya fungsional. Dibersihkan sedikit:

/**
 * Genericised ML-style list.
 */
public class FunctionalList<T> 
{
    private final T head;
    private final FunctionalList<T> tail;

    public FunctionalList(T x, FunctionalList<T> xs) {
        this.head = x;
        this.tail = xs;
    }

    public static <T> FunctionalList<T> cons(T x, FunctionalList<T> xs) {
        return new FunctionalList<T>(x, xs);
    }

    public static <T> T hd(FunctionalList<T> l) {
        return l.head;
    }

    public static <T> FunctionalList<T> tl(FunctionalList<T> l) {
        return l.tail;
    }

    public static int length(FunctionalList<?> l) {
        return len(l, 0);
    }

    private static int len(FunctionalList<?> l, int n) {
        return l == null ? n : len(tl(l), n + 1);
    }

    public static <T> FunctionalList<T> rev(FunctionalList<T> l) {
        return rev(l, null);
    }

    private static <T> FunctionalList<T> rev(FunctionalList<T> a, FunctionalList<T> b) {
        return a == null ? b : rev(tl(a), cons(hd(a), b));
    }

    public static <T> FunctionalList<T> append(FunctionalList<T> a, FunctionalList<T> b) {
        return a == null ? b : cons(hd(a), append(tl(a), b));
    }
}

5

Java dalam Perl

Mungkin dianggap melanggar peraturan, tapi saya tidak peduli. Jelas, ini dimaksudkan agar terlihat seperti program Java. Ini mencetak 20 angka Fibonacci, kalau-kalau tidak jelas.

Membutuhkan modul Inline :: Java untuk diinstal.

use Inline Java => <<'JAVA';
/**
 * @author  Konrad Borowski <x.fix@o2.pl>
 * @version 0.1.0
 */
class Fibonacci
{
    /**
     * Responsible for storing the number before last generated number.
     */
    private long beforeLastNumber = 0;

    /**
     * Responsible for storing the last generated number.
     */
    private long lastNumber = 1;

    /**
     * Receives the next Fibonacci number.
     * 
     * @return long integer that is the next Fibonacci number
      */
    public long next()
    {
        long temponaryLastNumber = lastNumber;
        lastNumber = beforeLastNumber + lastNumber;
        beforeLastNumber = temponaryLastNumber;
        return temponaryLastNumber;
    }

    /**
     * Outputs the Fibonacci number to standard output.
     */
    public void printFibonacci()
    {
        System.out.println(next());
    }

    /**
     * Outputs the Fibonacci number to standard output given number of
     * times.
     * 
     * @param times number of times to print fibonacci number
     */
    public void printFibonacciTimes(int times)
    {
        int i;
        for (i = 0; i < times; i++) {
            printFibonacci();
        }
    }

    /**
     * Constructor for Fibonacci object. Does nothing.
     */
    public Fibonacci()
    {
        // Do nothing.
    }
}
JAVA

###
 # The executable class that shows 20 Fibonacci numbers.
 ##
package OutputFibonacci
{
    ###
     # Shows 20 Fibonacci numbers. This method is public,
     # static, and returns void.
     ##
    sub main()
    {
        # In Perl, -> is object method separator, not a dot. This is stupid.
        new Fibonacci()->printFibonacciTimes(20);
    }
}

# Perl doesn't automatically call main method.
OutputFibonacci::main();

4

J dan ... tidak ada yang akan menebak (edit: dc)

Ini adalah entri kedua saya; di sini adalah sepotong kode J yang valid, yang mengembalikan 1:

10 o. 1 r. 2 i. 4 [ ( 0:`1: @. (2&|)) ] 8 #: *:@+: 42

Saya menunggu satu atau dua hari sebelum memberitahu yang merupakan bahasa lain menjalankan bagian kode yang sama tanpa kesalahan. Tinggalkan komentar untuk mencoba menebak.

sunting: Bahasa lainnya adalah bahasa berbasis tumpukan dari kalkulator Unix yang sangat kuno.


3
Ini berjalan tanpa kesalahan di GolfScript, BF, HQ9 +, ...
Peter Taylor

OK, saya tidak sadar bahwa banyak bahasa bisa melakukannya. Saya mengedit kode untuk menempatkan bahasa yang sebenarnya saya pilih.
Thomas Baruchel

@ ברוכאל ini berjalan tanpa kesalahan dalam bahasa-bahasa tersebut karena bahasa-bahasa tersebut tidak memiliki kesalahan, atau tidak memiliki kesalahan yang berlaku untuk kode ini. Misalnya. Brainfuck mengabaikan semua karakter yang tidak ada di dalam .,+-<>[]sehingga program Anda setara dengan ...[.]+di Brainfuck yang merupakan program yang valid tetapi tidak berguna. AFAIK program brainfuck hanya dapat tidak valid dengan memiliki ketidakcocokan [].
immibis

@immibis. Ini salah. dc adalah kalkulator lama dan saya dapat memastikan bahwa mengubah satu hal dalam kode saya akan menimbulkan kesalahan. Saya menghabiskan banyak waktu pada beberapa bagian kode untuk mencari cara rumit untuk meletakkan huruf-huruf dalam urutan yang benar. Sepotong kode saya Postscript / dc cukup ekstrim: tidak ada kesalahan tetapi mengubah apa pun akan membuatnya salah. dc tidak ada hubungannya dengan "bahasa-bahasa itu"; dc sekitar 20 atau 30 tahun lebih tua dari "bahasa-bahasa itu"; itu umumnya diinstal pada distribusi Linux apa pun. Silakan, telusuri sedikit jika Anda belum pernah mendengarnya.
Thomas Baruchel

1
@ ברוכאל Anda salah paham - Saya sedang berbicara tentang brainfuck, HQ9 +, golfscript, dll - bukan dc.
immibis

4

dc menjalankan file PostScript

dc dapat menjalankan bagian kode berikut tanpa kesalahan:

10 10 10 10 10 42 32 10 10
stop % first send a stop
0 0 srand rand
le pop pop 3.14 sin
lt 2 3 lt and pop
le 2 10 le xor
pop pop pop 1 0 0
<< /sox 2 >> [ exch begin sox end ] aload
3.14 floor

3

ML / (Ketat) Haskell di Jawa

Ini dari proyek nyata yang sebenarnya. Itu menggunakan struktur data abadi yang tetap dan menggunakan rekursi bahkan ketika tidak diperlukan. Sebenarnya, ini lebih mirip Kore (bahasa yang diimplementasikan proyek) di Jawa, tetapi gayanya pada dasarnya sama dengan ML. Tetapi filosofi Kore adalah bahwa penulis tidak boleh memformat kodenya, jadi tidak ada kode Java yang diformat juga (itu autoformatted oleh gerhana).

drop n elemen dari daftar :

  public static <T> List<T> drop(List<T> l, Integer n) {
    return n == 0 ? l : drop(l.cons().tail, n - 1);
  }

Di ML / Haskell, di mana Anda akan mencocokkan pola untuk mengekstrak kepala dan ekor, di sini Anda katakan list.cons().xdan list.cons().tail.

masukkan elemen dalam daftar :

  public static <T> List<T> insert(List<T> l, Integer i, T x) {
    if (i == 0)
      return cons(x, l);
    return cons(l.cons().x, insert(l.cons().tail, i - 1, x));
  }

Daftar didefinisikan secara harfiah bagaimana tipe data aljabar akan didefinisikan. Ini adalah versi dengan boilerplate yang dihasilkan eclipse dihapus:

public final class List<T> {

  public static final class Nil<T> {
  }

  public static final class Cons<T> {
    public final T x;
    public final List<T> tail;

    public Cons(T x, List<T> tail) {
      if (x == null)
        throw new RuntimeException("null head");
      if (tail == null)
        throw new RuntimeException("null tail");
      this.x = x;
      this.tail = tail;
    }
  }

  private final Nil<T> nil;
  private final Cons<T> cons;

  private List(Nil<T> nil, Cons<T> cons) {
    this.nil = nil;
    this.cons = cons;
  }

  public boolean isEmpty() {
    return nil != null;
  }

  public Nil<T> nil() {
    if (nil == null)
      throw new RuntimeException("not nil");
    return nil;
  }

  public Cons<T> cons() {
    if (cons == null)
      throw new RuntimeException("not cons");
    return cons;
  }

  public static <T> List<T> cons(Cons<T> cons) {
    if (cons == null)
      throw new RuntimeException("constructor received null");
    return new List<T>(null, cons);
  }

  public static <T> List<T> nil(Nil<T> nil) {
    if (nil == null)
      throw new RuntimeException("constructor received null");
    return new List<T>(nil, null);
  }
}

Berikut adalah struktur data peta yang diimplementasikan dalam hal trie :

public final class Map<K, V> {
  private final Tree<Character, Optional<Pair<K, V>>> tree;
  // keys are sorted in reverse order so entrySet can use cons instead of append
  private final Comparer<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> comparer =
      new PairLeftComparer<Character, Tree<Character, Optional<Pair<K, V>>>>(
          new ReverseComparer<Character>(new CharacterComparer()));

  private Map(Tree<Character, Optional<Pair<K, V>>> tree) {
    this.tree = tree;
  }

  public static <K, V> Map<K, V> empty() {
    return new Map<K, V>(new Tree<Character, Optional<Pair<K, V>>>(
        OptionalUtils.<Pair<K, V>> nothing(),
        ListUtils
            .<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> nil()));
  }

  public Optional<V> get(K k) {
    Tree<Character, Optional<Pair<K, V>>> t = tree;
    for (char c : k.toString().toCharArray()) {
      Tree<Character, Optional<Pair<K, V>>> t2 = getEdge(t, c);
      if (t2 == null)
        return nothing();
      t = t2;
    }
    if (t.v.isNothing())
      return nothing();
    return some(t.v.some().x.y);
  }

  public Map<K, V> put(K k, V v) {
    return new Map<K, V>(put(tree, k.toString(), v, k));
  }

  private Tree<Character, Optional<Pair<K, V>>> put(
      Tree<Character, Optional<Pair<K, V>>> t, String s, V v, K k) {
    if (s.equals(""))
      return new Tree<Character, Optional<Pair<K, V>>>(some(Pair.pair(k, v)),
          t.edges);
    char c = s.charAt(0);
    Tree<Character, Optional<Pair<K, V>>> t2 = getEdge(t, c);
    if (t2 == null)
      return new Tree<Character, Optional<Pair<K, V>>>(
          t.v,
          sort(
              cons(
                  pair(
                      c,
                      put(new Tree<Character, Optional<Pair<K, V>>>(
                          OptionalUtils.<Pair<K, V>> nothing(),
                          ListUtils
                              .<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> nil()),
                          s.substring(1), v, k)), t.edges), comparer));
    return new Tree<Character, Optional<Pair<K, V>>>(t.v, sort(
        replace(pair(c, put(t2, s.substring(1), v, k)), t.edges), comparer));
  }

  private List<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> replace(
      Pair<Character, Tree<Character, Optional<Pair<K, V>>>> edge,
      List<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> edges) {
    if (edges.cons().x.x.equals(edge.x))
      return cons(edge, edges.cons().tail);
    return cons(edges.cons().x, replace(edge, edges.cons().tail));
  }

  // I consider this O(1). There are a constant of 2^16 values of
  // char. Either way it's unusual to have a large amount of
  // edges since only ASCII chars are typically used.
  private Tree<Character, Optional<Pair<K, V>>> getEdge(
      Tree<Character, Optional<Pair<K, V>>> t, char c) {
    for (Pair<Character, Tree<Character, Optional<Pair<K, V>>>> p : iter(t.edges))
      if (p.x.equals(c))
        return p.y;
    return null;
  }

  public Map<K, V> delete(K k) {
    return new Map<K, V>(delete(tree, k.toString()).x);
  }

  private Pair<Tree<Character, Optional<Pair<K, V>>>, Boolean> delete(
      Tree<Character, Optional<Pair<K, V>>> t, String k) {
    if (k.equals(""))
      return pair(
          new Tree<Character, Optional<Pair<K, V>>>(
              OptionalUtils.<Pair<K, V>> nothing(), t.edges), t.edges.isEmpty());
    char c = k.charAt(0);
    Tree<Character, Optional<Pair<K, V>>> t2 = getEdge(t, c);
    if (t2 == null)
      return pair(t, false);
    Pair<Tree<Character, Optional<Pair<K, V>>>, Boolean> p =
        delete(t2, k.substring(1));
    List<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> edges = nil();
    for (Pair<Character, Tree<Character, Optional<Pair<K, V>>>> e : iter(t.edges))
      if (!e.x.equals(c))
        edges = cons(e, edges);
    if (!p.y)
      return pair(
          new Tree<Character, Optional<Pair<K, V>>>(t.v, cons(pair(c, p.x),
              edges)), false);
    boolean oneEdge = t.edges.cons().tail.isEmpty();
    return pair(new Tree<Character, Optional<Pair<K, V>>>(t.v, edges), oneEdge
        && t.v.isNothing());

  }

  public static class Entry<K, V> {
    public Entry(K k, V v) {
      this.k = k;
      this.v = v;
    }

    public final K k;
    public final V v;

  }

  public List<Entry<K, V>> entrySet() {
    return entrySet(ListUtils.<Entry<K, V>> nil(), tree);
  }

  private List<Entry<K, V>> entrySet(List<Entry<K, V>> l,
      Tree<Character, Optional<Pair<K, V>>> t) {
    if (!t.v.isNothing()) {
      Pair<K, V> p = t.v.some().x;
      l = cons(new Entry<K, V>(p.x, p.y), l);
    }
    for (Pair<Character, Tree<Character, Optional<Pair<K, V>>>> e : iter(t.edges))
      l = entrySet(l, e.y);
    return l;
  }
}

Jenis mulai mengambil ruang sebanyak kode. Sebagai contoh, di put , metode ini memiliki 302 karakter jenis dan 343 karakter kode (tidak termasuk spasi / baris baru).


2

BASIC dalam Ruby

Diterapkan ini sejak lama. The sumber di GitHub . Terinspirasi oleh hal serupa di Scala

Mempersiapkan

#!/usr/bin/env ruby

if caller.empty? && ARGV.length > 0
  $file = ARGV[0]
else
  $file = caller.last.split(':').first
end

require 'pp'

class String
  def %(other)
    self + other.to_s
  end
end

class RBaysick
  @@variables = {}
  @@code = []
  @@line = 0

  def initialize(contents)
    $DONT_RUN = true # To avoid endless loops.

    contents.gsub!(/( |\()'([^\W]+)/, '\1:\2 ')

    contents.gsub!(/(^| |\()(:[^\W]+)/, '\1GET(\2)')

    contents.gsub!(/ IF (.*) THEN (.*)/, ' IF { \1 }.THEN { GOTO \2 }')
    contents.gsub!(/LET *\(([^ ]+) *:= *(.*)\)/, 'LET(\1) { \2 }')
    contents.gsub!(/(LET|INPUT)(\(| )GET\(/, '\1\2(')
    contents.gsub!(/ \(/, '(')

    contents.gsub!(/^(\d+) (.*)$/, 'line(\1) { \2 }')

#    contents.gsub!(/(\)|\}|[A-Z]) ([A-Z]+)/, '\1.\2')

    contents.gsub!(/ END /, ' __END ')
    contents.gsub!(/^RUN/, '__RUN')

    puts contents if $DEBUG
    eval contents
  end

  def __RUN
    while @@line > -1
      puts "#{@@line}: #{@@code[@@line].inspect}" if $DEBUG
      unless @@code[@@line].nil?
        @@increment = true
        @@code[@@line].call
        next unless @@increment
      end
      @@line += 1
    end
  end

  class If < Struct.new(:value)
    def THEN
      yield if value
    end
  end

  def method_missing(name, *args)
    puts "Missing: #{name.to_s}(#{args.map(&:inspect).join(', ')})" if $DEBUG
  end

  def variables
    @@variables
  end

  def line(line, &block)
    @@code[line] = block
  end

  def add(line, cmd, *args)
    puts "DEBUG2: #{cmd.to_s}(#{args.map(&:inspect).join(', ')})" if $DEBUG
    @@code[line] = send(cmd, *args)
  end

  def IF
    ::RBaysick::If.new(yield)
  end

  def PRINT(str)
    puts "PRINT(#{str.inspect})" if $DEBUG
    puts str
    true
  end

  def LET(name, &block)
    puts "LET(#{name.inspect}, #{block.inspect})" if $DEBUG
    @@variables[name] = block.call
  end

  def GET(name)
    puts "GET(#{name.inspect}) #=> #{@@variables[name].inspect}" if $DEBUG
    @@variables[name]
  end

  def INPUT(name)
    puts "INPUT(#{name.inspect})" if $DEBUG
    LET(name) { $stdin.gets.chomp.to_i }
  end

  def ABS(val)
    puts "ABS(#{val.inspect}) #=> #{val.abs.inspect}" if $DEBUG
    val.abs
  end

  def GOTO(line)
    @@increment = false
    @@line = line
  end

  def __END
    exit
  end
end

RBaysick.new(open($file).read) unless $DONT_RUN || ($0 != __FILE__)

Kode dasar

#!./rbaysick.rb

10 PRINT "Welcome to Baysick Lunar Lander v0.0.1"
20 LET ('dist := 100)
30 LET ('v := 1)
40 LET ('fuel := 1000)
50 LET ('mass := 1000)

60 PRINT "You are a in control of a lunar lander."
70 PRINT "You are drifting towards the surface of the moon."
80 PRINT "Each turn you must decide how much fuel to burn."
90 PRINT "To accelerate enter a positive number, to decelerate a negative"

100 PRINT "Distance " % 'dist % "km, " % "Velocity " % 'v % "km/s, " % "Fuel " % 'fuel
110 INPUT 'burn
120 IF ABS('burn) <= 'fuel THEN 150
130 PRINT "You don't have that much fuel"
140 GOTO 100
150 LET ('v := 'v + 'burn * 10 / ('fuel + 'mass))
160 LET ('fuel := 'fuel - ABS('burn))
170 LET ('dist := 'dist - 'v)
180 IF 'dist > 0 THEN 100
190 PRINT "You have hit the surface"
200 IF 'v < 3 THEN 240
210 PRINT "Hit surface too fast (" % 'v % ")km/s"
220 PRINT "You Crashed!"
230 GOTO 250
240 PRINT "Well done"

250 END

RUN

2

Haskell di templat C ++

Saya membuat FizzBuzz ini dalam template C ++ beberapa bulan yang lalu di sebuah lark. Ini hampir merupakan implementasi dari kode Haskell berikut, semua dalam template C ++. Bahkan, bahkan aritmatika integer diimplementasikan kembali pada tingkat tipe --- perhatikan bahwa tidak ada templat yang menggunakan parameter int!

Kode Haskell:

import Control.Monad

m `divides` n = (n `mod` m == 0)

toFizzBuzz n
    | 15 `divides` n = "FizzBuzz"
    |  5 `divides` n = "Buzz"
    |  3 `divides` n = "Fizz"
    |      otherwise = show n

main = mapM_ putStrLn $ take 100 $ map toFizzBuzz [1..]

dan versi pemrograman templat C ++:

//  
//  Lazy compile-time fizzbuzz computed by C++ templates,
//  without conditionals or the use of machine arithmetic.
//
//         -- Matt Noonan (mnoonan@grammatech.com)

#include <iostream>

using namespace std;

//
//  The natural numbers: Nat = Zero | Succ Nat
//

template <typename n>
struct Succ
{
  typedef Succ eval;
  static const unsigned int toInt = 1 + n::toInt;
  static void print(ostream & o) { o << toInt; }
};

struct Zero
{
  typedef Zero eval;
  static const unsigned int toInt = 0;
  static void print(ostream & o) { o << toInt; }
};

//
//  Arithmetic operators
//    Plus Zero n = n
//    Plus Succ(n) m = Plus n Succ(m)
//    Times Zero n = Zero
//    Times Succ(n) m = Plus m (Times n m)
//

template <typename a, typename b>
struct Plus
{
  typedef typename Plus<typename a::eval,
                        typename b::eval>::eval eval;
};

template <typename M>
struct Plus <Zero, M>
{ typedef typename M::eval eval; };

template <typename N, typename M>
struct Plus <Succ<N>, M>
{ typedef typename Plus<N, Succ<M> >::eval eval; };

template <typename a, typename b>
struct Times
{
  typedef typename Times<typename a::eval,
                         typename b::eval>::eval eval;
};

template <typename M>
struct Times <Zero, M>
{ typedef Zero::eval eval; };

template <typename N, typename M>
struct Times <Succ<N>, M>
{ typedef typename Plus<M,
                        typename Times<N,M>::eval
                        >::eval eval; };

//
//  Lists
//

struct Nil
{
  typedef Nil eval;
  static void print(ostream & o) { }
};

template <typename x, typename xs>
struct Cons
{
  typedef Cons eval;
  static void print(ostream & o) {
    x::eval::print(o); o << endl; xs::eval::print(o);
  }
};

//
//  Take the first n elements of a list
//

template <typename, typename> struct Take;

template <typename _> struct Take<Zero,_>
{ typedef Nil eval; };

template <typename n, typename x, typename xs>
struct Take<Succ<n>, Cons<x,xs> >
{
  typedef Cons<x, Take<n, xs> > eval;
};

template <typename a, typename b>
struct Take
{
  typedef typename Take<typename a::eval,
                        typename b::eval>::eval eval;
};

//
//  Iterate f x0 makes the infinite list
//  x0, f(x0), f(f(x0)), ...
//

template <template<typename> class f, typename x0> struct Iterate
{
  typedef Cons<x0, Iterate<f, f<x0> > > eval;
};

//
//  Map a function over a list
//

template <template<typename> class a, typename b> struct Map
{ typedef typename Map<a,
                       typename b::eval>::eval eval;
};

template <template<typename> class f>
struct Map<f, Nil>
{ typedef Nil eval; };

template <template<typename> class f, typename x, typename xs>
struct Map<f, Cons<x,xs> >
{
  typedef Cons<f<x>, Map<f,xs> > eval;
};

//
//  Some useful things for making fizzes and buzzes
//

struct Fizz
{ static void print(ostream & o) { o << "Fizz"; } };

struct Buzz
{ static void print(ostream & o) { o << "Buzz"; } };

struct FizzBuzz
{ static void print(ostream & o) { o << "FizzBuzz"; } };

//
//  Some useful numbers
//

typedef Succ<Zero> One;
typedef Succ<One> Two;
typedef Succ<Two> Three;
typedef Plus<Two, Three> Five;
typedef Times<Two, Five> Ten;
typedef Times<Three, Five> Fifteen;
typedef Times<Ten, Ten> OneHundred;

//
//  Booleans
//

struct True {};
struct False {};

//
//  If/then/else
//

template <typename p, typename t, typename f>
struct If
{
  typedef typename If<typename p::eval, t, f>::eval eval;
  static void print(ostream & o) { eval::print(o); }
};

template <typename t, typename _>
struct If<True, t, _>
{
  typedef t eval;
};

template <typename _, typename f>
struct If<False, _, f>
{ typedef f eval; };

//
//  Testing if x divides y
//

template <typename a, typename b, typename c>
struct _Divides
{
  typedef typename _Divides<typename a::eval,
                            typename b::eval,
                            typename c::eval>::eval eval;
};

template <typename _, typename __>
struct _Divides<_, __, Zero> { typedef False eval; };

template <typename a>
struct _Divides<a, Zero, Zero> { typedef True eval; };

template <typename a, typename b>
struct _Divides<a, Zero, b>
{
  typedef typename _Divides<a, a, b>::eval eval;
};

template <typename _, typename n, typename m>
struct _Divides<_, Succ<n>, Succ<m> >
{
  typedef typename _Divides<_, n, m>::eval eval;
};

template <typename a, typename b>
struct Divides
{
  typedef typename _Divides<a, a, b>::eval eval;
};

//
//  "Otherwise" sugar
//

template <typename a>
struct Otherwise
{
  typedef typename a::eval eval;
  static void print(ostream & o) { a::eval::print(o); }
};

//
//  Convert a number to fizzes, buzzes as appropriate
//

template <typename n>
struct toFizzBuzz
{
  typedef typename
    If< Divides<Fifteen, n>, FizzBuzz,
    If< Divides<   Five, n>,     Buzz,
    If< Divides<  Three, n>,     Fizz,
    Otherwise<                   n
    > > > >::eval eval;
};

int main(void)
{
  // Make all of the natural numbers
  typedef Iterate<Succ, One> Naturals;

  // Apply fizzbuzz rules to every natural number
  typedef Map<toFizzBuzz, Naturals> FizzBuzzedNaturals;

  // Print out the first hundred fizzbuzzed numbers
  Take<OneHundred, FizzBuzzedNaturals>::eval::print(cout);

  return 0;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.