Programm in deiner Lieblingssprache in einer anderen Sprache schreiben [geschlossen]


168

Der entschlossene Real Programmer kann Fortran-Programme in jeder Sprache schreiben.

von echten Programmierern verwenden Pascal nicht

Ihre Aufgabe ist es, ein Programm in der Programmiersprache Ihrer Wahl zu schreiben, Sie dürfen jedoch nur eine andere Sprache verwenden. Das heißt, wirf alle Kodierungskonventionen aus einer Sprache weg und ersetze sie durch Kodierungskonventionen aus einer anderen Sprache. Je mehr desto besser. Stellen Sie Ihr Programm so ein, als ob es in einer anderen Sprache geschrieben wäre.

Zum Beispiel könnte ein Python-Fan, der Java hasst, folgendes Python-Programm in Java schreiben:

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

Pascal-Enthusiast, der gezwungen ist, C zu verwenden, könnte Folgendes schreiben:

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

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

Du musst ein komplettes Programm schreiben. Das Programm muss nichts Nützliches tun.

Viel Glück. Dies ist ein Beliebtheitswettbewerb, bei dem der Code mit den meisten Stimmen gewinnt!


1
@m.buettner erstelle deine datei mit der Endung .litcoffee. Es könnte helfen.
Ismael Miguel

Ein wenig lang (und zuvor geschrieben, und nicht in sich geschlossene) für eine Antwort, aber: Postscript - Scanner in Postscript in C .
Luser Droog

51
Ich glaube nicht, dass Sie (oder die Mehrheit der Antworten) den Sinn des Zitats verstehen. Es ist nicht so, dass ein echter Programmierer Code schreibt, der lexikalisch wie Fortran aussieht, obwohl er in Pascal oder LISP schreibt. Es ist so, dass er eine Fortran-Denkweise anwendet, auch wenn er in Pascal oder LISP schreibt. zB " Wie alle echten Programmierer wissen, ist die einzige nützliche Datenstruktur das Array. " Gute Antworten wären der prozedurale Code in Prolog, der funktionale Code in C und der objektorientierte Code in Pascal.
Peter Taylor

1
Ich hoffe, jemand wird einen Lisp-Dialekt
sprechen, na

6
@itsjeyd Greenspuns zehnte Programmierregel : "Jedes ausreichend komplizierte C- oder Fortran-Programm enthält eine ad-hoc, informell spezifizierte, fehlerbehaftete, langsame Implementierung der Hälfte von CommonLisp."
Joshua Taylor

Antworten:


142

C in C ++

#include <stdio.h>

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

60
Ich sehe, was du dort getan hast;)
el.pescado

27
Nun, das ist ein billiger Trick, da C ++ 'abwärtskompatibel' mit C.
Agi Hammerthief,

5
@AlexM. Ich denke, es wäre sinnvoller, wenn dies ein längeres (prozedurales) Beispiel wäre, das eindeutig von der Verwendung einiger Klassen profitieren würde und das andere C-Idiome verwendet, bei denen eine gewisse STL-Güte viel sinnvoller wäre (sagen wir char*statt std::string).
Martin Ender

47
Gültig in C, C ++, Objective-C und Objective-C ++! Was für eine wunderbar vielsprachige Antwort.
Nneonneo

7
@BenJackson Psh, echte C-Programmierer verwenden char *argv[]!
Thomas

122

x86-Assembly in GNU C

Nein, ich habe nicht nur das asmSchlüsselwort verwendet, da die festgestellte Frage für echte Programmierer ist ... dies sollte auf ARM einwandfrei funktionieren.

(Nur um den Punkt zu beweisen, habe ich die Assembly überhaupt nicht "geschrieben" - es ist die Ausgabe, die von GCC Clang (503.0.38) für den kommentierten Code oben erzeugt wurde und blind in Makros übersetzt wurde.)

Dies funktioniert nur im 32-Bit-Modus. Das ist in Ordnung, da echte Programmierer sowieso auf die Wortgröße codieren.

#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
    ))
}

Schau dir nur all diese Darsteller an. Casts bedeuten, dass ich ein echter Programmierer bin als der Compiler, oder?


8
+1, das ist ... verdreht. ;) Mir gefällt besonders, wie du damit umgegangen bist call.
Ilmari Karonen

2
Beeindruckend. Das ist eine großartige Arbeit.
Jack Aidley

Ich hatte einen Assembler für den C64, der in etwa so funktionierte. Es wurden BASIC-Schlüsselwörter für alle 6510-Anweisungen hinzugefügt, und ich erinnere mich, dass Sie es umschlossen for pass=1:3...nexthaben. Die Ausführung im BASIC-Interpreter hat es zusammengestellt.
Ben Jackson

5
Das ist reine Poesie.
Nicu Stiurca

1
Das ist ein harter Mann, der Compiler ist begeistert.
Internet ist von Catz

102

Englisch in 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

Irgendwelche Ideen, um das zu beseitigen ;?


18
Im Ernst, Leute.
Kyle Strand

2
warum thezweimal definieren ?
Joshua Taylor

16
besser sicher als leid ;-)
urzeit

20
Jetzt mach es zu einem Haiku.
Nicu Stiurca

1
Können Sie#define . ;
mbomb007

74

Brainfuck in JavaScript

Javascript ist eine schwierige Sprache! Lass uns Brainfuck benutzen, eine verständlichere Sprache: 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)')
)

Ich glaube, ich habe einen Brainfuck-Interpreter in Javascript geschrieben.

Das obige Beispiel gibt Hello World!die Eingabe einfach aus und ignoriert sie (kein ,Symbol).
Das funktioniert aber auch mit Eingängen! Zum Beispiel versuchen , ,+>,+>,+>,+<<<.>.>.>.und geben Sie golfden Dialog in. Die nächsten Zeichen in der ASCII-Tabelle werden ausgegeben:hpmg

EDIT : Kurze Erklärung für Leute, die Brainfuck nicht kennen.
Stellen Sie sich ein unendliches Array von Ganzzahlen vor a, die überall auf Null initialisiert sind, einen Zeiger auf ein Element dieses Arrays iund eine Benutzereingabe u.
Brainfuck ist sehr leicht zu lernen, aber schwer zu schreiben:

  • + Inkremente zum aktuellen Wert: a[i]++
  • - dekrementiert es: a[i]--
  • > Lässt den Zeiger auf das nächste Element zeigen: i++
  • < der Vorherige : i--
  • [und ]definieren Sie eine Schleife, die abbricht, wenn der aktuelle Wert Null ist:while (a[i]) { ... }
  • . Aktuelles Element drucken: String.fromCharCode(a[i])
  • , Setzt das aktuelle Element mit Benutzereingabe: u.charCodeAt(...)

22
+1 für den Humor, dass Brainfuck verständlicher ist als JavaScript.
Agi Hammerthief

Sind Sie sicher, dass die Brainfuck-Zeichen in den replaceAnweisungen das Programm nicht beeinflussen?
Fraxtil

3
@fra Diese Datei ist kein Brainfuck-Programm, sondern ein Javascript-Programm, das ein Brainfuck-Programm enthält, das zur Laufzeit in Javascript konvertiert wird.
U-

3
Na, --ischneller als i--? Scheint seit Jahren falsch: jsperf.com/decrementgolf .
Michael M.

4
Dies ist nicht nur ein sehr kreativer Beitrag zum Wettbewerb, sondern erklärt auch die Syntax von Brainfuck sehr deutlich. +10 wenn ich könnte!
SebastianH

74

Ich denke, der brillante Lennart Augustsson hat dies bereits zweimal gewonnen.

Hier ist zunächst ein Beispiel für seine Implementierung von BASIC als Haskell Monadic DSL am Wochenende ab 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

Es funktioniert durch Überladen des Nummerntyps. Die Zeilennummern sind wirklich Funktionen, die Argumente akzeptieren. Der Rest der Zeile ist Argumente für die Funktion. Die Funktion gibt eine Darstellung des abstrakten Syntaxbaums zurück, an der der BASIC-Interpreter arbeiten kann.

Ich empfehle dir auch, dir Augustssons Teilnahme am 2006 International Obfuscated C Contest anzuschauen, bei dem er es geschafft hat, sich in 4 km zu quetschen:

  • Ein Bytecode-Interpreter, der in eine Teilmenge von C geschrieben ist (die er als Verschleiertes C bezeichnet).
  • Ein in Bytecode geschriebener Compiler für verschleierte C -> Bytecodes.

Sie können dieselbe Datei gemeinsam nutzen, da der Byetecode in C-Kommentaren platziert wird.

Es ist ein paar Jahre her, dass ich Augustssons Arbeit verfolgt habe, also gibt es vielleicht noch andere großartige Dinge, die er sich seitdem ausgedacht hat ...


2
Es ist Augustsson, nicht Augustssen.
Hans Lundmark

@ HansLundmark Danke. Behoben.
Pitarou

71

PHP und Javascript

Dies ist eine Mehrsprachigkeit:

Sie können diesen Code in beiden Sprachen ausführen:

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]));

Der Trick dabei ist, dass Javascript Escape-Sequenzen in Strings verwendet, die mit 'und beginnen ".
Andererseits verwendet PHP Escapesequenzen nur in Strings, die mit "und beginnen <<<.

Dann deklarieren wir die Funktion printf, die printeiner formatierten Zeichenkette in PHP ähnelt, diese aber ausgibt.

PHP setzt voraus , dass vars mit beginnen $, während Javascript dies einfach erlaubt.


Niemand verwendet Array(…)JS und es ist eindeutig array(…)in PHP. […]wäre weit besser;)!
Blackhole

12
Es ist mir egal, ob Leute Array()in JS verwenden oder nicht: Es ist mir wichtig, dass ich einen WAHREN Polyglott habe. Ich mache mit diesem Code eines der schlimmsten JS-Verbrechen, aber alles, was ich will, ist, dass er ausgeführt wird und in beiden genau dasselbe tut, aber wie JS und PHP zur gleichen Zeit aussieht.
Ismael Miguel

Und übrigens [...]ist in PHP <5.4.0 ungültig, was schlecht ist ....... Wenn ich das in PHP 4, 5 oder Javascript wirf, erwarte ich, dass es funktioniert, anstatt überall Syntaxfehler zu verursachen.
Ismael Miguel

2
Wenn Sie möchten, dass Ihr Code wie JS aussieht, müssen Sie den Code verwenden […], der in PHP als Standard erscheint und daher für Ihr Ziel in Ordnung ist. Und übrigens PHP <5.4? Zeit für ein Update, Mann ...
Blackhole

8
Kompatibilität ist wichtiger als "Aussehen". Und Arrayist der RECHTE Name des Konstruktors des Array-Objekts. Grundsätzlich ist using []dasselbe wie Array(). Ich sehe nichts schlechtes daran. Aber ich habe eine einfache Frage: Funktioniert? (btw, ich habe auf PHP 5.3.28 bei der Arbeit zu verwenden.)
Ismael Miguel

55

Brainfuck in JS

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

12
Ich sehe hier keinen Brainfuck. Nicht einmal ein einziger Char in><,.-
Michael M.

8
@Michael: Wer hat gesagt, dass es kein Programm ist, das eine Endlosschleife macht?
Konrad Borowski

19
ist das JSF * ck?

8
Wie um alles in der Welt macht es das ?
Nandhp

4
Oo. Jemand hat das endlich getan. Ich habe einige Zeit damit verbracht, herauszufinden, wie man ein JS-Programm nur mit den Zeichen +! [] () Schreibt, konnte es aber nie ganz herausfinden. Ich muss das analysieren, wenn ich Zeit habe ...
Matti Virkkunen

54

Dies ist einer der Gewinner des IOCCC 2005 , ein C-Programm, das, abgesehen von dieser Reihe von Definitionen, wie ein Java-Programm aussieht:

/*
 * 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
Ausführlichkeit vom Feinsten.
Qwr

39

C ++ in C

OK, Sie sind ein C ++ - Programmierer, müssen aber C verwenden? Kein Problem, Sie müssen nur einige zusätzliche Header schreiben, die in C fehlen. Beispiel: Hier ist ein gültiges Hello World-Programm in C:

iostreamSchreiben Sie in die zusätzliche Header-Datei :

#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

In Datei stringschreiben

#define string

helloworld.cSchreiben Sie in die Datei (Ihren aktuellen C-Code)

#include <iostream>
#include <string>

using namespace std;

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

Und beim Kompilieren helloworld.cmit einem C - Compiler anweisen , den Compiler auch zu suchen , <...>Dateien Header , wo Sie die Dateien gespeichert iostreamund string, zum Beispiel, wenn Sie mit gcc kompilieren und die Dateien setzen iostreamund stringim aktuellen Verzeichnis, kompiliert mit

gcc helloworld.c -o helloworld -I.

Hinweis: Der volatilein-Header iostreamdient dazu, ein warnfreies Kompilieren auch bei maximaler Warnstufe zu ermöglichen (ein Lesevorgang aus einer flüchtigen Variablen wird als wirksam angesehen).


3
Das ist ein bisschen Code-Trolling, nicht wahr?
Mr Lister

Nun, das Programm macht genau das, was es zu tun scheint, nicht wahr?
Celtschk

8
So viel lustiger und beeindruckender als C in C ++.
Kyle Strand

Welche Art von Compiler warnt, wenn Sie ihn hier nicht verwenden volatile, und welche Art von Warnung?
R. Martinho Fernandes

1
@KyleStrand Aber das "C in C ++" stimmt mehr mit dem Zitat in der Frage überein. Echte Programmierer programmieren in C, auch wenn sie einen C ++ - Compiler haben.
Mr Lister

36

CQL - Caffeinated Query Language

(oder "SQL on Caffeine")

Das war vielleicht etwas zu ehrgeizig. Hier ist ein Versuch, deklarativen SQL-Code (ish) in CoffeeScript zu schreiben . Dies erfordert die ECMAScript 6-Proxy-Funktion . Sie können es im Knoten mit testen --harmony-proxies.

Lassen Sie uns eine Vorlage zum Definieren von Proxys einrichten. (Entnommen aus Benvies Kommentar zu diesem Thema )

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
)();

Definieren Sie nun ein Proxy-Objekt und einige verdächtige globale Variablen und Funktionen:

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

Nun, das war ziemlich viel Setup! Aber jetzt können wir Folgendes tun (Eingabe / Ausgabe in einem Konsolenstil):

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

Es ist kein Polyglot, aber darum geht es nicht wirklich. Ich weiß, dass dies @für Variablen in SQL verwendet wird, aber ich benötige alle @s für Spalten- und Tabellennamen, da ich keinen Weg gefunden habe, das globale Objekt als Proxy zu verwenden (und es würde mich nicht wundern, wenn es wirklich nicht möglich ist - und für ein guter Grund).

Ich habe auch einige Klammern in Klammern gesetzt (insbesondere nach VALUESund IN). Leider konnte ich überhaupt nicht herausfinden, wie man normale Bedingungen zulässt year > 2000, weil sie sofort zu einem Booleschen Wert ausgewertet würden.

Trotzdem ähnelt dies stark SQL und ist definitiv eher deklarativ als imperativ / funktional / objektorientiert, sodass es sich für die Frage eignen sollte. Eigentlich denke ich, wenn ich den Code ein wenig überarbeitet und ein paar weitere Funktionen unterstützt habe, könnte dies ein nützliches CoffeeScript-Modul sein.

Wie auch immer, das hat Spaß gemacht! :)

Für diejenigen, die nicht mit CoffeeScript vertraut sind, werden die SQL-Abfragen mit folgendem JavaScript kompiliert:

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)));
});

Das ist ziemlich viel Setup, sieht aber gut aus. Ich bin kein CoffeeScript-Programmierer, aber es sieht großartig aus. Das @in SQL wird für Sitzungsvariablen verwendet.
Ismael Miguel

Ich habe beschlossen, die Keywords jetzt global zu gestalten. Jetzt gibt es nur noch @s für Spalten- und Tabellennamen.
Martin Ender

Jetzt sieht es sehr nach SQL aus! Du hast eine schöne Arbeit mit diesem gemacht!
Ismael Miguel

1
Kaffee ist mir egal, aber das ist großartig.
KRyan

2
@tac danke, aber nein, ich habe es gerade für diese Herausforderung zusammen gehackt. Witziger Zufall: Das auf eine saubere Art und Weise zu wiederholen und auf GitHub zu stellen, stand auf meiner Liste potenzieller / langfristiger Codierungsprojekte, bis ich es erst heute Morgen entfernte.
Martin Ender

27

Visual Basic 6 (in 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()

Es funktioniert auch in VBScript.


1
Klug. Sie brauchen nicht einmal die meisten Semikolons.
js1568

@ js1568 Danke! Ich habe jetzt die Semikolons entfernt, die nicht benötigt werden.
Zahnbürste

20

F # in C ++

Eher einfallsloser und widerlicher Missbrauch des Präprozessors. Ich dachte, es würde Spaß machen, C ++ so zu ändern, dass es wie eine völlig unterschiedliche Sprache aussieht, anstatt ein paar Aliase zu verwenden, damit es wie Java oder PHP aussieht. Ich erwarte nicht wirklich, dass dies eine Menge positiver Stimmen einbringt, es ist nur zum Spaß.

#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

Probieren Sie es hier aus .

Leider reicht es nicht aus, etwas an STDOUT zu schreiben, obwohl ich mir sicher bin, dass jemand, der genug Hexerei draufwirft, es dazu bringen könnte, mehr zu tun.


2
Damit die letzte Zeile in F # funktioniert, muss sie entweder exit 0oder nur sein 0.
Jwosty

20

Python und ... niemand wird es erraten (edit: dc)

Hier ist ein gültiger Python-Code, aber tatsächlich ist das Programm in einer ganz anderen Sprache geschrieben:

# 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

Der Code wird in beiden Sprachen ohne Fehler ausgeführt.

Die Kombination ist sehr verrückt; Ich würde gerne ein oder zwei Tage warten, bevor ich erkläre, welche Sprache die andere ist. Bitte hinterlassen Sie Kommentare zum Erraten.

edit: Die Sprache war die Stack-basierte Sprache von DC. Sie können hier bekannte Schlüsselwörter wie sehen for, if, or, in, sondern nur die Buchstaben von Bedeutung! Das ,, was in dc keine Bedeutung hat, wird in ein Register umgewandelt, weil es das erste Mal nach dem Buchstaben erscheint s(dasselbe gilt für :).


1
Wenn der Code in beiden Sprachen nicht dasselbe tut, könnte eine Sprache wie Befunge den Trick machen.
Thomas Eding

OK, ich bearbeite den Code, um die Sprache zu bestimmen, die ich gewählt habe.
Thomas Baruchel

18

Mit C ++ können Sie mit der InteLib-Bibliothek lisp-ähnlichen Code schreiben:

(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();

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


4
Herzlich willkommen! Wir bitten Benutzer, ihre Beiträge als Community-Wiki zu kennzeichnen, wenn die Antwort nicht ihre eigene Arbeit ist. (Und ordentlich zuschreiben, aber das hast du schon getan, also danke!)
Jonathan Van Matre

Original oder nicht, hast du meine Stimme :)
itsjeyd

15

C # in Whitespace

Okay, probieren Sie zuerst eine davon aus, und lassen Sie uns sehen, wie es geht.

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!

Und für den Fall, dass die Formatierung durch das Platzieren von vier Leerzeichen vor jeder Zeile verpatzt wurde, ist dies wieder der Fall. für Leerzeichen und # für 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 und CSS

Keine Programmiersprachen, aber… dieses Dokument ist gültiges HTML und CSS:

<!-- 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>
<!-- */ -->

Dies funktioniert, da HTML-Kommentare aus historischen Gründen in Stylesheets zulässig sind. Ach ja, und jedes gültige HTML-Dokument ist auch ein gültiges PHP-Programm, das ist also auch PHP . :)



Da CSS als vollständig angesehen werden kann , kann dies eine gültige Antwort sein.
Adam Davis

2
HTML und CSS sind keine Programmiersprachen :)
Jet

9

C in der Scala

Die Überbrückungsschicht emuliert eine romantischere Ära, in der Strings noch nullterminierte Bytearrays waren.

// 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!"täuschte dich
Erik der Outgolfer

8

sed und APL

Mein Chef möchte, dass ich sed-Skripte schreibe, aber ich schreibe lieber den ganzen Tag über APL. Trotzdem ist er mit meiner Arbeit sehr zufrieden, da solche Skripte mit seiner Version von sed perfekt laufen:

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

Sie können es auf meiner neuen Website mit diesem Permalink versuchen . Es ist eine zu Javascript kompilierte Version von GNU APL. Die endgültige Veröffentlichung erfolgt später mit der offiziellen Veröffentlichung von GNU APL, Version 1.3, aber Sie können sie perfekt für Ihre Permalinks verwenden, wenn Sie GNU APL mögen.


7

C in 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)));
    };
}

Da er cmainmit argcoder nichts tut argv, hat der Code für das Marshalling von Argumenten natürlich keine Wirkung, und da er cmainimmer 0 zurückgibt, ist der Zweig "else" der Anweisung "if" tot. Aber die "if" -Anweisung macht sowieso nichts.

Alle geschweiften Klammern und Semikolons sind nicht erforderlich, ebenso wie die meisten Klammern und einige doSchlüsselwörter. Die "if" -Anweisung hätte geschrieben werden können als if exitCode == 0 then exitWith ExitSuccess else exitWith (ExitFailure (fromIntegral exitCode)).


7

C ++ in 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";
}

Nicht die flexibelste Lösung, funktioniert aber, wenn genau wie abgebildet geschrieben.


7

Haskell in Java

("Vanille" Java 7, nicht Java 8) (Ja, ich weiß, dass das Boxen die Leistung beeinträchtigt, und selbst der Versuch, Funktionen höherer Ordnung zu verwenden, wird wahnsinnig wortreich: D)

Java hat eine sehr starre Syntax, daher habe ich versucht, den Code semantisch an den Haskell-Stil anzupassen, anstatt die Syntax zu ändern.

Bearbeiten - Teilfunktionsanwendung hinzugefügt.

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());
    }
}

(Ja, alles was dieser Wahnsinn macht ist rechnen 6!)


6

COBOL in AWK

Im Geiste des Zitats. Reines, unverfälschtes AWK, wie es von einem COBOL-Programmierer geschrieben wurde.

Die Aufgabe besteht darin, die Datensätze in einer Datei zu zählen. Diese frühe Entwicklungsversion zählt sich zum Testen. Die richtige Datei wird später bei Veröffentlichung von Unit Testing fest codiert ...

Wenn ich die Syntax-Hervorhebung dazu bringen könnte, phosphoreszierendes Grün auf Schwarz zu setzen, wäre das großartig ...

Sogar die Spaltennummern in dieser Zeile wurden korrigiert, das sind sieben Leerzeichen am Anfang jeder Zeile (noch nie zuvor in awk gemacht) und die langen print-Anweisungen in Spalte 72 werden gebrochen.

   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 (oder irgendetwas anderes) in Racket

Das flexible Modul- und Makrosystem von Racket ermöglicht die Implementierung der Modulunterstützung für völlig neue Sprachen, sowohl für domänenspezifische als auch für allgemeine Zwecke. Sowohl Datalog als auch Algol 60 werden standardmäßig unterstützt. Die folgenden Programme sind also beide gültig:

#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

Sie können auch Unterstützung für andere Sprachen hinzufügen: Siehe z. B. die Beschreibung von Danny Yoo zur Implementierung der Unterstützung für Brainfuck, die Racket-Programme wie die folgenden ermöglicht:

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

Und da die Unterstützung auf der Ebene der kompilierten Module hinzugefügt wird, ist es möglich, Module, die in verschiedenen Sprachen geschrieben wurden, zu verknüpfen oder einen Ausschnitt einer Sprache in ein Modul einzubetten, das in einer anderen Sprache geschrieben wurde.


5

SML in Java

Ich habe immer noch alten Code, als ich anfing, Java zu lernen und versuchte, ihn in einem funktionalen Stil zu verwenden. Leicht gereinigt:

/**
 * 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 in Perl

Kann als Regelverstoß gelten, ist mir aber egal. Offensichtlich soll es wie ein Java-Programm aussehen. Es werden 20 Fibonacci-Zahlen ausgegeben, falls dies nicht offensichtlich ist.

Erfordert die Installation des Inline :: Java- Moduls.

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 und ... niemand wird es erraten (edit: dc)

Dies ist mein zweiter Eintrag; Hier ist ein Teil des gültigen J-Codes, der 1 zurückgibt:

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

Ich warte einen oder zwei Tage, bevor ich erkläre, in welcher anderen Sprache derselbe Code fehlerfrei ausgeführt wird. Hinterlassen Sie einfach Kommentare zum Erraten.

edit: Die andere Sprache ist die Stack-basierte Sprache aus dem sehr alten Unix-Rechner dc.


3
Es läuft ohne Fehler in GolfScript, BF, HQ9 +, ...
Peter Taylor

OK, mir war nicht bewusst, dass so viele Sprachen das können. Ich bearbeite den Code, um die Sprache zu bestimmen, die ich gewählt habe.
Thomas Baruchel

@ ברוכאל wird in diesen Sprachen fehlerfrei ausgeführt, da diese Sprachen keine Fehler aufweisen oder keine Fehler aufweisen, die auf diesen Code zutreffen. Z.B. Brainfuck ignoriert alle Zeichen, die nicht in .,+-<>[]Ihrem Programm enthalten sind, sodass Ihr Programm dem ...[.]+in Brainfuck entspricht, einem gültigen, aber sinnlosen Programm. Ein AFAIK-Brainfuck-Programm kann nur ungültig werden, wenn es nicht übereinstimmt [].
immibis

@immibis. Das ist falsch. dc ist ein alter Rechner und ich kann versichern, dass das Ändern einer Sache in meinen Codes einen Fehler auslösen würde. Ich habe viel Zeit mit einigen Teilen des Codes verbracht, um herauszufinden, wie man die Buchstaben in die richtige Reihenfolge bringt. Mein Stück Code Postscript / dc ist ziemlich extrem: Kein Fehler, aber das Ändern von irgendetwas macht ihn fehlerhaft. dc hat nichts mit "diesen Sprachen" zu tun; dc ist ungefähr 20 oder 30 Jahre älter als "diese Sprachen"; Es wird im Allgemeinen auf jeder Linux-Distribution installiert. Bitte stöbern Sie ein wenig, wenn Sie noch nichts davon gehört haben.
Thomas Baruchel

1
@ ברו youאל Sie missverstanden - Ich sprach über Brainfuck, HQ9 +, Golfscript, etc. - nicht DC.
immibis

4

DC läuft eine PostScript-Datei

dc kann den folgenden Code fehlerfrei ausführen:

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 / (Strict) Haskell in Java

Dies ist aus einem tatsächlichen realen Projekt. Es nutzt persistente unveränderliche Datenstrukturen und verwendet eine Rekursion, auch wenn dies nicht erforderlich ist. Eigentlich ist es eher wie Kore (die Sprache, die das Projekt implementiert) in Java, aber der Stil ist im Grunde der gleiche wie in ML. Die Philosophie von Kore ist jedoch, dass der Autor seinen Code nicht formatieren sollte. Daher wird auch kein Java-Code formatiert (er wird von Eclipse automatisch formatiert).

lösche n Elemente aus einer Liste :

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

In ML / Haskell, wo Sie das Muster abgleichen würden, um Kopf und Schwanz zu extrahieren, sagen Sie list.cons().xund list.cons().tail.

Ein Element in eine Liste einfügen :

  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));
  }

Liste ist wörtlich definiert, wie der algebraische Datentyp definiert werden würde. Hier ist eine Version, bei der die von Eclipse generierte Kesselplatte entfernt wurde:

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);
  }
}

Hier ist eine Kartendatenstruktur, die in Form eines Versuchs implementiert ist :

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;
  }
}

Die Typen fangen an, so viel Platz wie der Code einzunehmen. In put hat die Methode beispielsweise 302 Zeichen und 343 Zeichen Code (ohne Leerzeichen / Zeilenumbrüche).


2

BASIC in Ruby

Implementiert dies vor langer Zeit. Die Quelle ist auf GitHub . Inspiriert von einer ähnlichen Sache in Scala

Konfiguration

#!/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__)

BASIC-Code

#!./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 in C ++ - Vorlagen

Ich habe diesen FizzBuzz in C ++ - Vorlagen vor ein paar Monaten auf einer Lerche gemacht. Es ist so ziemlich eine Implementierung des folgenden Haskell-Codes, alles in C ++ - Vorlagen. Tatsächlich wird sogar die Ganzzahlarithmetik auf der Typebene neu implementiert - beachten Sie, dass keine der Vorlagen int-Parameter verwendet!

Der Haskell-Code:

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

und die Metaprogrammierungsversion des C ++ - Templates:

//  
//  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;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.