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

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


当前回答

在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

其他回答

引用尼尔·弗雷泽的话(看那一页的末尾)

try {
    return true;
} finally {
    return false;
}

(在Java中,但在JavaScript和Python中行为显然是相同的)。其结果留给读者作为练习。

编辑:只要我们谈到这个问题,也要考虑到这一点:

try {
    throw new AssertionError();
} finally {
    return false;
}

在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 -不变的。

在J中,foreign(!:)是各种函数组合在一起。左边的参数是一个类别,右边的参数通常(但不总是)是不同的增量值。的东西。例如:

    2!:55 NB. Close console
    9!:10 NB. Set print precision
    6!:0  NB. Actual time
    6!:2  NB. Execution time
    4!:3  NB. Loaded scripts

当然,聪明的做法是把它们包装起来,但有些你只需要记住。顺便说一句,所有这些都是,想想看,三位一体的,有两个参数在右边,一个在左边。除非你给他们一个最终有效的论据,否则以上任何一条都不会起作用。

JavaScript真值表:

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

资料来源:Doug Crockford

Forth可以随时改变数字的基数:

HEX 10 DECIMAL 16 - .
0 Ok

它也不需要是预定义的:

36 BASE ! 1Z DECIMAL .
71 Ok