在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?

请每个回答只回答一个特征。


当前回答

在Java中(这是一个导致赋值的if语句)

result = (Boolean condition) ? (if Boolean is true) : (if Boolean is false);

or

data Nat = Z|S Nat deriving Show
nattoInt Z = 0
nattoInt (S a) = 1 + nattoInt a

buildNat 0 = Z
buildNat a  =  S (buildNat (a - 1))

在Haskell…我仍然不太明白这是如何定义自然数的(我完全理解理论:-p)

其他回答

在Python中,函数参数的“编译时”(或声明时)计算可能令人困惑:

def append(v, l = []):
    l.append(v)
    return l


print append(1)
print append(2)

>>> [1]
>>> [1,2]

其意图可能是:

def append(v, l = None):
    if l is None:
        l = []
    l.append(v)
    return l

print append(1)
print append(2)

>>> [1]
>>> [2]

这种行为对于缓存之类的事情很有用,但它可能是危险的。

附加特性:具有可变内容的元组:

a = (1,2,[3])
a[2][:] = [4] # OK
a[2] = [2] # crashes

大约在1977年,我在Lisp中添加了“format”函数,那时“printf”甚至还不存在(我是从与Unix相同的源:Multics复制的)。它一开始很无辜,但后来被一个接一个的特征填满了。当Guy Steele引入迭代和相关特性时,事情就失控了,这些特性被Common Lisp X3J13 ANSI标准所接受。下面的示例可以在Common Lisp The Language, 2nd Edition第22.3.3节中的表22-8中找到:

(defun print-xapping (xapping stream depth)
  (declare (ignore depth))
  (format stream
      "~:[{~;[~]~:{~S~:[->~S~;~*~]~:^ ~}~:[~; ~]~ ~{~S->~^ ~}~:[~; ~]~[~*~;->~S~;->~*~]~:[}~;]~]"
      (xectorp xapping)
      (do ((vp (xectorp xapping))
           (sp (finite-part-is-xetp xapping))
           (d (xapping-domain xapping) (cdr d))
           (r (xapping-range xapping) (cdr r))
           (z '() (cons (list (if vp (car r) (car d)) (or vp sp) (car r)) z)))
          ((null d) (reverse z)))
      (and (xapping-domain xapping)
           (or (xapping-exceptions xapping)
           (xapping-infinite xapping)))
      (xapping-exceptions xapping)
      (and (xapping-exceptions xapping)
           (xapping-infinite xapping))
      (ecase (xapping-infinite xapping)
        ((nil) 0)
        (:constant 1)
        (:universal 2))
      (xapping-default xapping)
      (xectorp xapping)))

在JavaScript中:

var something = 12;

function nicelyCraftedFunction()
{
  something = 13;
  // ... some other code
  // ... and in Galaxy far, far away this:
  if( false ) // so the block never executes:
  { 
    var something; 
  }
}
nicelyCraftedFunction(); // call of the function

通常你会期望某个变量的值是13。 但在JavaScript中不是这样——变量有函数作用域,所以后面的声明会影响上游的一切。

在使用C/ c++ /Java表示法的语言(如JS)中,你会期望变量具有块范围,而不是像这样…

因此,编译器甚至可以从最终生成的字节码中删除的死代码块仍然会对正常执行的其余代码产生副作用。

因此,在调用函数之后,某些东西仍然是12 -不变的。

Perl:

可以编写一个完全由标点符号组成的程序。

这是怎么回事?!

INTERCAL可能是最奇怪的语言特征的最佳汇编。我个人最喜欢的是COMEFROM语句,它(几乎)与GOTO相反。

COMEFROM is roughly the opposite of GOTO in that it can take the execution state from any arbitrary point in code to a COMEFROM statement. The point in code where the state transfer happens is usually given as a parameter to COMEFROM. Whether the transfer happens before or after the instruction at the specified transfer point depends on the language used. Depending on the language used, multiple COMEFROMs referencing the same departure point may be invalid, be non-deterministic, be executed in some sort of defined priority, or even induce parallel or otherwise concurrent execution as seen in Threaded Intercal. A simple example of a "COMEFROM x" statement is a label x (which does not need to be physically located anywhere near its corresponding COMEFROM) that acts as a "trap door". When code execution reaches the label, control gets passed to the statement following the COMEFROM. The effect of this is primarily to make debugging (and understanding the control flow of the program) extremely difficult, since there is no indication near the label that control will mysteriously jump to another point of the program.