用您喜欢的语言编写另一种语言的程序


168

确定的Real Programmer可以用任何语言编写Fortran程序。

来自真正的程序员不要使用Pascal

您的任务是用您选择的编程语言编写程序,但只允许使用另一种语言。也就是说,丢弃所有一种语言的编码约定,并用另一种语言的编码约定替换它们。越多越好。使您的程序看起来像是用另一种语言编写的。

例如,讨厌Java的Python爱好者可以使用Java编写以下Python程序:

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

Pascal发烧友被迫使用C可以这样写:

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

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

您必须编写完整的程序。该程序不必做任何有用的事情。

祝好运。这是一次人气竞赛,因此获胜最多的代码将获胜!


1
@ m.buettner创建扩展名为的文件.litcoffee。这可能会有所帮助。
Ismael Miguel 2014年

答案很长(并且以前写的;并且不是独立的),但是:C中的Postscript 中的 Postscript扫描器
luser droog 2014年

51
我认为您(或大多数答案)不理解报价的要点。并不是说Real Programmer即使在Pascal或LISP中编写代码,也不会像Fortran那样写词:这是即使在Pascal或LISP中编写时,他也采用了Fortran的思维方式。例如“ 正如所有Real Programmers所知,唯一有用的数据结构是Array。 ”。最好的答案是Prolog中的过程代码,C中的功能代码,Pascal中的面向对象代码。
彼得·泰勒

1
我希望有人会用另一种 Lisp方言
来做

6
@itsjeyd Greenspun的第十个编程规则:“任何足够复杂的C或Fortran程序都包含临时的,非正式指定的,臭虫缠身的,缓慢执行CommonLisp的一半程序。”
约书亚·泰勒

Answers:


143

C ++中的C

#include <stdio.h>

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

60
我看到你在那儿做什么;)
el.pescado 2014年

27
嗯,这是一个把戏,看到C ++是“向后兼容”与C
敏捷Hammerthief

5
@AlexM。我认为,如果这是一个更长的(程序上的)示例,则显然会更有意义。该示例显然将从使用某些类中受益,并使用其他C习语,其中一些STL优点将更为合理(例如char*代替std::string)。
Martin Ender 2014年

47
在C,C ++,Objective-C Objective-C ++中有效!多么精彩的多语言答案。
nneonneo 2014年

7
@BenJackson Psh,真正的 C程序员使用char *argv[]
托马斯

123

GNU C中的x86汇编

不,我不只是使用asm关键字,因为建立的问题是针对真正的程序员的……在ARM上应该可以正常运行。

(只是为了证明这一点,我根本没有“编写”程序集-它是GCC Clang(503.0.38)为顶部的注释代码生成的输出,被盲目地转换为宏。)

这仅适用于32位模式。没关系,因为真正的程序员无论如何都按字长编码。

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

只要看看所有这些演员。Casts表示我比编译器更真正的程序员,对吗?


8
+1,那是...扭曲。;)我call特别喜欢您的处理方式。
Ilmari Karonen 2014年

2
哇。这是一项伟大的工作。
杰克·艾德利2014年

我有一个用于C64的汇编器,其工作方式类似于此。它为所有6510指令添加了BASIC关键字,我记得您已经将for pass=1:3...next它包裹起来。在BASIC解释器中执行该命令将其组装。
本杰克逊

5
这是纯诗。
Nicu Stiurca 2014年

1
这是个硬汉,编译器肯定感到惊讶。
互联网由catz制作,2014年

102

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

;什么想法可以消除?


18
说真的,你们。
凯尔·斯特兰德

2
为什么要定义the两次?
2014年

16
安全胜过遗憾;-)
urzeit 2014年

20
现在使其成为句。
Nicu Stiurca 2014年

1
你能吗#define . ;
mbomb007 '16

74

用JavaScript操脑

Javascript是一门难懂的语言!让我们使用Brainfuck,这是一种更易理解的语言:

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

我想我用javascript写了一个动脑筋的解释器。

上面的示例只是输出Hello World!而忽略了输入(无,符号)。
但这也适用于输入!例如,尝试,+>,+>,+>,+<<<.>.>.>.和类型golf的对话框。它将输出ASCII表中的下一个字符:hpmg

编辑:对不懂脑操的人的简短解释。
想象一个无限的整数数组,a到处都初始化为零,该数组的一个元素上有一个指针i,以及一个用户输入u
Brainfuck真的很容易学习,但是很难写:

  • + 递增到当前值: a[i]++
  • - 递减: a[i]--
  • > 使指针指向下一个元素: i++
  • < 以前的 : i--
  • []定义一个在当前值为零时中断的循环:while (a[i]) { ... }
  • . 打印当前元素: String.fromCharCode(a[i])
  • , 用用户输入设置当前元素: u.charCodeAt(...)

22
+1表示幽默,比JavaScript更可理解。
Agi Hammerthief 2014年

您确定replace语句内的Brainfuck字符不会影响程序吗?
Fraxtil

3
@fra该文件不是一个Brainfuck程序,它是一个JavaScript程序,其中包含一个Brainfuck程序,该程序在运行时会转换为javascript。
地下

3
好吧,--ii--?多年以来似乎是假的:jsperf.com/decrementgolf
Michael M.

4
这不仅是竞赛的创造性提交,而且还非常清楚地说明了Brainfuck语法。如果可以的话,+ 10!
SebastianH

74

我认为出色的Lennart Augustsson已经赢得了两次。

首先,下面是他从2009年开始将其BASIC实施为Haskell Monadic DSL的“周末黑客”的示例:

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

它通过重载数字类型来工作。行号实际上是接受参数的函数。该行的其余部分是该函数的参数。该函数返回抽象语法树的表示形式,供BASIC解释器继续使用。

我还建议您查看Augustsson参加2006年国际混淆C竞赛的参赛作品,在该竞赛中,他设法挤入了4k:

  • 字节码解释器,用C的子集(他称为混淆的C)编写。
  • 用字节码编写的混淆C->字节码编译器。

他们可以共享同一个文件,因为byetecode位于C注释中。

自从我追踪奥古斯特森的工作已经过去了几年,所以从那以后他可能还会提出其他出色的事情。


2
是奥古斯特森,不是奥古斯特森。
汉斯·隆德马克2014年

@HansLundmark谢谢。修复。
皮塔鲁

71

PHP和JavaScript

这是一个多语种:

您可以使用两种语言运行此代码:

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

这里的技巧是Javascript在以'和开头的字符串中使用转义序列"
另一方面,PHP仅在以"和开头的字符串中使用转义序列<<<

然后,我们声明函数printf,该函数与printPHP 类似,但是会输出格式化的字符串。

PHP 要求 var以开头$,而Java语言只是允许。


没人Array(…)在JS中使用它,并且显然array(…)在PHP中使用它。[…]会更好;)!
Blackhole 2014年

12
我不在乎人们是否Array()在JS中使用:我在乎我有一个TRUE多重语言。我用这段代码使JS犯罪最严重,但是我想要的是它可以运行并且在两者中执行完全相同的操作,但同时看起来像JS和PHP。
Ismael Miguel

而且顺便说一句,[...]在PHP <5.4.0中是无效的,这很糟糕。......如果我将其扔到PHP 4、5或Javascript中,我希望它可以工作,而不是到处都出现语法错误。
Ismael Miguel

2
如果您希望代码看起来像JS,则必须使用[…],这在PHP中看起来很标准,因此可以满足您的目标。顺便说一句,PHP <5.4?是时候更新了,伙计…
Blackhole 2014年

8
兼容性比“外观”更重要。并且Array是Array对象的构造函数的正确名称。基本上,使用[]与相同Array()。我看不出有什么不好的。但是我有一个简单的问题:可行吗?(顺便说一句,我必须在工作中使用php 5.3.28。)
Ismael Miguel

55

用JS操脑

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

12
我在这里看不到任何误解。甚至不是一个单个字符的><,.-
迈克尔M.

8
@Michael:谁说这不是一个造成无限循环的程序?
Konrad Borowski14年

19
这是JSF * ck吗?

8
地球上它是如何做到的是
nandhp 2014年

4
哦 终于有人做到了。我花了一些时间试图弄清楚如何仅使用字符+![]()来编写JS程序,但从未完全弄清楚。我有时间的时候需要分析一下……
Matti Virkkunen 2014年

54

这是2005年IOCCC获奖者之一,这是一个 C语言程序,除上述定义外,它看起来像一个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
最好的细节。
qwr 2014年

39

C语言中的C ++

好的,所以您是C ++程序员,但被迫使用C?没问题,您只需要编写C中缺少的一些补充标头即可。例如,这是C中有效的Hello World程序:

在补充头文件中iostream,编写:

#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

在文件中string,写入

#define string

在文件helloworld.c(您的实际C代码)中,编写

#include <iostream>
#include <string>

using namespace std;

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

和编译helloworld.c与C编译器,指示编译器还找<...>无论你存储的文件的头文件iostreamstring,例如,如果你正在用gcc编译,把文件iostreamstring在当前目录中,编译

gcc helloworld.c -o helloworld -I.

注意:volatilein标头iostream可用于即使在最大警告级别时也可以进行无警告的编译(从volatile变量读取被认为是有效的)。


3
这是一些代码拖曳,不是吗。
李斯特先生2014年

好吧,该程序完全按照它的样子执行,不是吗?
celtschk 2014年

8
这种方式比C ++中的C更加有趣和令人印象深刻。
凯尔·斯特兰德

如果您volatile在此处不使用哪种编译器会发出警告,以及什么样的警告?
R. Martinho Fernandes 2014年

1
@KyleStrand但是“ C in C ++”更符合问题中的引号。真正的程序员即使使用C ++编译器,也可以使用C进行编程。
李斯特先生2014年

36

CQL-咖啡因查询语言

(或“ SQL on Caffeine”)

这可能有点过于雄心勃勃。这是尝试在CoffeeScript中编写SQL(ish)声明性代码。这需要ECMAScript 6代理功能。您可以使用在节点中对其进行测试--harmony-proxies

让我们建立一个定义代理的模板。(摘自Benvie对这个问题的评论

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

现在定义一个代理对象和一些可疑的全局变量和函数:

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

嗯,这是很多设置!但是现在我们可以执行以下操作(控制台方式的输入/输出):

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

这不是一个实际的多语种,但这并不是重点。我知道它@用于SQL中的变量,但是我需要所有@s作为列和表名,因为我还没有找到代理全局对象的方法(如果真的不可能的话,我也不会感到惊讶-对于一个很好的理由)。

我还将括号括起来(尤其是在VALUES和之后IN)。不幸的是,我根本不知道是一种允许像这样的正常条件的方法year > 2000,因为它们会立即评估为布尔值。

仍然这看起来很像SQL,并且绝对比命令式/函数式/面向对象的声明式更具声明性,因此它应该可以很好地解决这个问题。我实际上在想,如果我稍微完善一下代码并支持更多功能,这可能是一个有用的CoffeeScript模块。

无论如何,这很有趣!:)

对于不太熟悉CoffeeScript的用户,SQL查询可编译为以下JavaScript:

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

设置很多,但是看起来不错。我不是CoffeeScript程序员,但看起来确实很棒。@SQL中的in用于会话变量。
Ismael Miguel 2014年

我决定现在将关键字设置为全局关键字。现在@,列和表名只有。
Martin Ender 2014年

现在看起来很像SQL!您在这一方面做得很好!
Ismael Miguel

1
我不太在乎咖啡,但这太棒了。
KRyan 2014年

2
@tac谢谢,但是不,我只是为了这个挑战而一起砍掉了它。有趣的巧合:以一种干净的方式重做并将它放在GitHub上是我潜在的/长期的编码项目列表,直到我今天早上将其删除为止。
Martin Ender

27

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

它也可以在VBScript中使用。


1
聪明。您甚至不需要大多数分号。
js1568 2014年

@ js1568谢谢!现在,我删除了不需要的分号。
牙刷

20

C ++中的F#

而不是想象力和讨厌的预处理器。我认为将C ++更改为完全不同的语言而不是使用一些别名使其看起来像Java或PHP会很有趣。我真的不希望这会招来很多赞誉,这只是一个有趣的词条。

#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

在这里尝试。

可悲的是,向STDOUT编写某些东西几乎可以完成所有工作,尽管我敢肯定,如果有人向它扔了足够多的巫术,他们可以做得更多。


2
为了使最后一行在F#中工作,必须为exit 00
Jwosty 2014年

20

Python和...没人会猜测(编辑:dc)

这是一些有效的python代码,但实际上该程序是用非常不同的语言编写的:

# 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

该代码以两种语言运行,没有错误。

这种结合是非常疯狂的。我很乐意等一两天再说另一种语言。请留下评论以供猜测。

编辑:语言是从dc基于堆栈的语言。你可以在这里看到著名的关键字,比如foriforin,但只有字母没关系!的,,因为它出现在第一时间是字母后它具有在直流没有意义被接通到一个寄存器s(同样为:)。


1
除非代码在两种语言中都做不到相同的事情,否则我认为像Befunge这样的语言可以解决问题。
Thomas Eding 2014年

好的,我编辑代码以放入实际选择的语言。
Thomas Baruchel 2014年

18

C ++允许您使用InteLib库编写类似Lisp的代码:

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

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


4
欢迎!当答案不是他们自己的工作时,我们要求用户将其帖子标记为Community Wiki。(并提供适当的归因,但您已经这样做了,所以谢谢!)
Jonathan Van Matre 2014年

原始与否,您获得我的投票了:)
2014年

15

空格中的C#

好的,首先尝试其中之一,让我们看看它如何进行。

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!

如果格式由于必须在每行的开头放置四个空格而变得很麻烦,这里还是使用。用于空格,而#用于制表符:

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和CSS

不是编程语言,但是……此文档是有效的HTML 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>
<!-- */ -->

这是可行的,因为出于历史原因,样式表中允许使用HTML注释。哦,每个有效的HTML文档也是一个有效的PHP程序,所以这也是PHP。:)



由于CSS可以认为是完整的,所以这可能是一个有效的答案。
亚当·戴维斯

2
HTML和CSS不是编程语言:)
2014年

9

Scala中的C

桥接层模拟了一个更加浪漫的时代,即字符串仍然是以null终止的字节数组。

// 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!"愚弄了你
暴民埃里克(Erik the Outgolfer)

8

sed和APL

我的老板要我写sed脚本,但是我宁愿整天写APL。不过,他对我的工作感到非常满意,因为这样的脚本可以在他的sed版本中完美运行:

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

您可以使用此永久链接在我的新网站上尝试。它是GNU APL的JavaScript版本。最终版本将在GNU APL 1.3版正式发布之后发布,但是如果您喜欢GNU APL,则可以完美地将其用于永久链接。


7

Haskell中的C

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

当然,由于cmainargcor 不执行任何操作argv,因此参数封送处理代码无效,并且由于cmain始终返回0,因此“ if”语句的“ else”分支无效。但是“ if”语句什么也没做。

所有的花括号和分号都是不必要的,大多数括号和某些do关键字也不需要。“ if”语句本可以写为if exitCode == 0 then exitWith ExitSuccess else exitWith (ExitFailure (fromIntegral exitCode))


7

Forth中的C ++

: #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";
}

不是最灵活的解决方案,但是如果完全按照所示方式编写,它就可以工作。


7

Java中的Haskell

(“香草” Java 7,而不是Java 8)(是的,我知道拳击会破坏性能;甚至尝试使用高阶函数也会变得冗长:D)

Java具有非常严格的语法,因此我没有更改语法,而是尝试使代码在语义上更类似于Haskell样式。

编辑-添加了部分功能应用程序。

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

(是的,这种疯狂所做的只是计算6!


6

AWK中的COBOL

本着报价的精神。纯净的AWK,可能由COBOL程序员编写。

任务是对文件上的记录进行计数。这个早期的开发版本将自己用于测试。从单元测试中发布后,正确的文件将被硬编码。

如果我能突出显示语法以在黑色上进行磷光绿,那将是很棒的...

即使是正确的列号,也就是每行开头有七个空格(以前从未在awk中这样做),并破坏了第72列的long print语句。

   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(或其他任何东西)

Racket灵活的模块和宏系统使它能够为特定领域和通用语言的全新语言实现模块支持。同时支持DatalogAlgol 60,因此以下都是有效的Racket程序:

#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

您还可以添加对其他语言的支持:例如,请参阅Danny Yoo对如何实现对Brainfuck的支持的描述,该描述允许使用Racket程序,例如:

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

而且由于在编译模块级别增加了支持,因此可以链接以不同语言编写的模块,也可以将一种语言的片段嵌入以另一种语言编写的模块中。


5

Java SML

从我开始学习Java并尝试以功能样式使用Java以来​​,我仍然有一些古老的代码。稍微清理一下:

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

Perl中的Java

可以算作违反规则,但我不在乎。显然,它打算看起来像Java程序。如果不明显,它将打印20个斐波那契数字。

需要安装Inline :: Java模块。

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和...没人能猜到(编辑:DC)

这是我的第二篇文章;这是一段有效的J代码,返回1:

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

我正在等待一两天,然后再告诉另一种语言运行相同的代码而没有错误。请留下评论以进行猜测。

编辑:另一种语言是来自非常古老的Unix计算器dc的基于堆栈的语言。


3
它在GolfScript,BF,HQ9 +,...中运行无误
Peter Taylor

好的,我不知道有那么多语言可以做到。我编辑代码以放入实际选择的语言。
Thomas Baruchel 2014年

@ברוכאל在这些语言中运行时没有错误,因为那些语言没有错误,或者没有适用于此代码的错误。例如。Brainfuck会忽略所有不在其中的字符,.,+-<>[]因此您的程序等效于Brainfuck,...[.]+这是一个有效但毫无意义的程序。AFAIK只能通过不匹配来废脑袋程序[]
immibis 2014年

@immibis。这是错误的。dc是一个旧的计算器,我可以保证更改代码中的一件事会引发错误。我花了很多时间在代码的某些部分上,以找出将字母正确排序的一些技巧。我的代码Postscript / dc非常极端:没有错误,但更改任何内容都会使其出错。dc与“那些语言”无关;dc比“那些语言”大20或30年;它通常安装在任何Linux发行版上。如果您没有听说过,请浏览一下。
Thomas Baruchel 2014年

1
@ברוכאל您误解了-我在说的是Brainfuck,HQ9 +,golfscript等-不是DC。
immibis 2014年

4

dc运行PostScript文件

dc可以正确运行以下代码:

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 Java

这是来自实际的实际项目。它利用了持久不变的数据结构,即使没有必要也使用递归。实际上,它更像Java中的Kore(项目实现的语言),但是样式基本上与ML相同。但是Kore的哲学是作者不应该格式化他的代码,因此也不格式化Java代码(它会被eclipse自动格式化)。

从列表中删除n个元素

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

在ML / Haskell中,您要进行模式匹配以提取头部和尾部,在这里您说list.cons().xlist.cons().tail

在列表中插入一个元素

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

从字面上定义 List是如何定义代数数据类型的。这是删除了eclipse生成的样板的版本:

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

是根据特里实现的地图数据结构:

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

这些类型开始占用与代码一样多的空间。例如,在put中,该方法具有302个类型的字符和343个代码的字符(不计算空格/换行符)。


2

Ruby中的BASIC

在很早以前就实现了。该源是在GitHub上。受到Scala中类似事物的启发

设定

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

基本代码

#!./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在C ++模板中

几个月前,我用C ++模板制作了这个FizzBu​​zz。它几乎是以下Haskell代码的实现,所有这些都在C ++模板中实现。实际上,即使整数算术也可以在类型级别上重新实现---注意,没有一个模板使用int参数!

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

和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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.