Странная языковая особенность

Из эмпирического тестирования кажется, что max() и min() в списке вернут первое в списке, которое соответствует max() / min() в случае связи:

>>> test = [(1, "a"), (1, "b"), (2, "c"), (2, "d")]
>>> max(test, key=lambda x: x[0])
(2, 'c')
>>> test = [(1, "a"), (1, "b"), (2, "d"), (2, "c")]
>>> max(test, key=lambda x: x[0])
(2, 'd')
>>> min(test, key=lambda x: x[0])
(1, 'a')
>>> test = [(1, "b"), (1, "a"), (2, "d"), (2, "c")]
>>> min(test, key=lambda x: x[0])
(1, 'b')

И Отличное слежение Джереми подтверждает, что это действительно так.

975
задан 22 revs, 8 users 38% 26 September 2011 в 15:40
поделиться

285 ответов

Не совсем языковая особенность, но недостаток реализации: некоторые ранние компиляторы Фортрана реализовывали константы, используя постоянный пул. Все параметры были переданы по ссылке. Если вы вызвали функцию, например

f(1)

Компилятор передает адрес константы 1 в пуле констант в функцию. Если вы присвоили значение параметру в функции, вы бы изменили значение (в данном случае значение 1) глобально в программе. Вызвало царапины на голове.

160
ответ дан Richard Pennington 26 September 2011 в 15:40
поделиться

Oracle имеет несколько проблем с SQL WTF.

  1. Oracle рассматривает пустые строки как нулевые.

  2. Обработка нулевых значений в сравнении "<>".

    create table wtf (key number primary key, animal varchar2(10));    
    insert into wtf values (1,'dog');
    insert into wtf values (2,'');
    insert into wtf values (3,'cat');    
    select * from wtf where animal <> 'cat';
    

Единственная возвращаемая строка - это строка (1, «собака»).

73
ответ дан 4 revs, 4 users 60% 26 September 2011 в 15:40
поделиться

В JavaScript void не является ключевым словом, не является объявлением типа, не является именем переменной и не является ни функцией, ни объектом. void - это префиксный оператор, аналогичный -, --, ++ и !. Вы можете добавить его к любому выражению, и это выражение будет иметь неопределенное значение.

Он часто используется в букмарклетах и ​​встроенных обработчиках событий, как в этом довольно частом примере:

<a href="javascript:void(0)">do nothing</a>

То, как он используется в этом примере, делает его похожим на вызов функции, когда на самом деле это просто слишком умный способ получить примитивное значение undefined. Большинство людей не совсем понимают истинную природу void в JavaScript, и это может привести к множеству неприятных ошибок и странных неожиданных событий.

К сожалению, я думаю, что оператор void является единственным действительно гарантированным способом получить значение undefined в JavaScript, поскольку undefined, как указано в другом ответе, является именем переменной, которое можно переназначить, и {}.a может быть испорченным Object.prototype.a = 'foo'

Обновление: Я подумал о другом способе генерации undefined:

(function(){}())

Да, немного многословно, и это еще менее ясно, что возвращение «неопределенного» является его целью.

70
ответ дан 8 revs, 3 users 71% 26 September 2011 в 15:40
поделиться

JavaScript является объектно-ориентированным, верно? Таким образом, методы работы на литеральных строках и числах должны работать. Как "hello".toUpperCase() и 3.toString(). Оказывается, что вторая ошибка синтаксиса, почему? Поскольку синтаксический анализатор ожидает, что число, сопровождаемое точкой, является литералом с плавающей запятой. Это не WTF, WTF в том, что вам нужно только добавить еще одну точку, чтобы она работала:

3..toString()

Причина в том, что литерал 3. интерпретируется как 3.0, а 3.0.toString() отлично работает.

132
ответ дан 2 revs, 2 users 80% 26 September 2011 в 15:40
поделиться

В PHP имена функций не чувствительны к регистру. Это может привести вас к мысли, что все идентификаторы в php не чувствительны к регистру. Угадай еще раз. Переменные чувствительны к регистру. WTF.

function add($a, $b)
{
    return $a + $b;
}

$foo = add(1, 2);
$Foo = Add(3, 4);

echo "foo is $foo"; // outputs foo is 3
echo "Foo is $Foo"; // outputs Foo is 7
97
ответ дан 3 revs, 3 users 70% 26 September 2011 в 15:40
поделиться

Моя самая большая ненавистная особенность - любой синтаксис файла конфигурации, который включает условную логику. Подобные вещи распространены в мире Java (муравей, мавен и т. Д. Вы знаете, кто вы есть!).

Вы просто заканчиваете программирование на языке c ** p с ограниченной отладкой и ограниченной поддержкой редактора.

Если вам нужна логика в вашей конфигурации, «Pythonic» подход кодирования конфигурации на реальном языке будет намного лучше.

126
ответ дан 2 revs, 2 users 73% 26 September 2011 в 15:40
поделиться

Я немного боролся по этому поводу:

1;

В Perl модули должны возвращать что-то истинное .

138
ответ дан miku 26 September 2011 в 15:40
поделиться

x = x + 1

Это было очень трудно переварить, когда я был новичком, и теперь функциональные языки его не используют, , что еще сложнее!

Если вы не видите, как это странно: Рассматривайте знак равенства как утверждение утверждения вместо действия присваивания , как вы использовали делать в базовой алгебре, то это эквивалентно высказыванию "ноль равен единице".

20
ответ дан 3 revs, 2 users 72% 26 September 2011 в 15:40
поделиться

Информировать 7 . Пример правильной программы:

    Chomsky is a room. 
    A thought is a kind of thing. 
    Color is a kind of value. 
    The colors are red, green and blue. 
    A thought has a color. It is usually Green. 
    A thought can be colorful or colorless. It is usually colorless. 
    An idea is a thought in Chomsky with description "Colorless green ideas sleep furiously." 
    A manner is a kind of thing. 
    Furiously is a manner. 
    Sleeping relates one thought to one manner. 
    The verb to sleep (he sleeps, they sleep, he slept, it is slept, he is sleeping) implies the sleeping relation. 
    Colorless green ideas sleep furiously. 

Другие глупости, подобные этой Симулятор машины Тьюринга можно найти.

8
ответ дан 2 revs, 2 users 95% 26 September 2011 в 15:40
поделиться

В SQL

NULL не равно NULL

Так что вы не можете сделать:

WHERE myValue == NULL

Это всегда будет возвращать false.

NULL != NULL
8
ответ дан Stephane Grenier 26 September 2011 в 15:40
поделиться

По моему мнению, это не должно быть разрешено в C ++:

class A {
public:
  virtual string foo(){return "A::foo";}
};

class B : public A {
public:
  virtual string foo(){return "B::foo";}
};

int main () {
  B* b = new B();
  // In my opinion the following should not be allowed
  cout << b->A::foo() << endl;  // Will print "A::foo"
}

Это может показаться правильным, но это означает, что вы не можете переопределить метод, не позволяя пользователям подкласса вызывать оригинальный метод вместо новый.

Просто подумайте о подклассе коллекции, где вы хотите увеличить количество элементов при добавлении элемента в саму коллекцию.

Логичным решением было бы переопределить метод add (), чтобы увеличить счетчик перед добавлением элемента, но пользователь новой коллекции может добавить элемент к нему, используя старый метод, так что вы обходите приращение и получаете элементы. -счетчик не согласен с фактическим количеством элементов коллекции.

Это невозможно в Java.

9
ответ дан 5 revs, 3 users 94% 26 September 2011 в 15:40
поделиться

PL / SQL позволяет объявлять переменные и имена функций как ключевые слова. Следующее является компилируемым PL / SQL:

create or replace 
  function function 
  return number  as
  return number;
begin 
  function.return := 4;
  return   return;
end function;
/

Это создало функцию с именем function. Позже:

SQL> select function from dual;

  FUNCTION
----------
         4
6
ответ дан 2 revs 26 September 2011 в 15:40
поделиться

В MUMPS вы можете получить GOTO со смещением. Если у вас есть (мои MUMPS ржавые ...)

some_label if x=1 do_something
           else  do_something_else

Тогда код

           goto some_label+1

перейдет к выражению ELSE ...

8
ответ дан user245605 26 September 2011 в 15:40
поделиться

Мне нравится отсутствие приоритета операторов в Smalltalk

2 * 3 + 4 * 5 = 6 + 4 * 5 = 10 * 5 = 50

вместо

2 * 3 + 4 * 5 = 6 + 4 * 5 = 6 + 20 = 26

Это связано с объектной природой smalltalk и тем фактом, что сообщения передаются слева направо. Если сообщение * отправляется на номер 2 с номером 3 в качестве параметра, то ответ на это сообщение равен 6. Довольно круто, вы даже можете обезьянить его, если почувствуете зло.

8
ответ дан dvincelli 26 September 2011 в 15:40
поделиться

В Java, если значение x равно NaN, то x == x возвращает false, а x != x возвращает true.

6
ответ дан Oak 26 September 2011 в 15:40
поделиться

Следующий код C # генерирует исключение NullReferenceException, а не print 1:

    static void SomeMethod(string format, params object[] args)
    {
        Console.WriteLine(args.Length);
    }

    static void Main(string[] args)
    {
        SomeMethod("blabla", null, "Ok here"); // print 2
        SomeMethod("blabla", null); // exception
    }
7
ответ дан Dudu 26 September 2011 в 15:40
поделиться

В PHP вы можете ссылаться на переменные, используя сигил и строковый литерал или переменную, содержащую имя переменной, например:

${'foo'} = 'test';
echo $foo;

Это выведет «test». Странная вещь в этом поведении состоит в том, что вы также можете использовать не-строки в качестве имен переменных, например:

${array()} = 'test';
echo ${array()};
${NULL} = 'test';
echo ${NULL};

Теперь у нас есть переменные с именем array () и даже NULL! Все содержат строку «тест».

6
ответ дан codysoyland 26 September 2011 в 15:40
поделиться

Литералы даты / времени VBScript (почему это все еще так редко?):

mydate = #1/2/2010 5:23 PM#

If mydate > #1/1/2010 17:00# Then ' ...

Редактирование: Литералы даты являются относительными (технически литералы , тогда?):

mydate = #Jan 3# ' Jan 3 of the current year

VB.NET, поскольку он компилируется, не поддерживает литералы относительной даты. Поддерживаются только литералы даты или времени, но предполагаемое время или дата считаются равными нулю.

Редактировать [2]: Конечно, есть несколько причудливых угловых случаев, которые связаны с относительными датами ...

mydate = #Feb 29# ' executed on 2010-01-05, yields 2/1/2029
16
ответ дан 5 revs, 2 users 79% 26 September 2011 в 15:40
поделиться

В Java вы можете ожидать, что

byte b = 0;
b++;

будет равен

byte b = 0;
b = b + 1;

Но это не так. Фактически вы получаете ошибку компилятора , так как результат сложения имеет тип int и поэтому не может быть назначен байтовой переменной b. При использовании составного оператора ++ Компилятор автоматически вставляет приведение здесь . Так

b++;

становится

b = (byte) b + 1;
17
ответ дан 2 revs, 2 users 68% 26 September 2011 в 15:40
поделиться

Это, возможно, уже упоминалось, но -

PHP обрабатывает восьмеричные значения:

$a = 07; // 7 (as it should be)
$b = 08; // 0 (would be an error in any sensible language)
$c = 018; // 1 (again, should have been an error)
$d = 0A; // error (as it should be)

См. Здесь: http://bugs.php.net/ bug.php? id = 29676

Также обратите внимание на комментарии к ошибке - Дерик называет это функцией (как показано в кавычках «исправление»), а не ошибкой, и он утверждает, что это «замедлится» PHP драматично во всех случаях, когда числа используются внутри скриптов "- но тогда, почему PHP вызывает ошибку для 0A?

Я думаю, можно написать целую книгу о странности PHP ...

17
ответ дан Tim Čas 26 September 2011 в 15:40
поделиться

В Perl вы можете сделать:

my $test = "Hello World";
substr($test, 0, 5) = "Goodbye";

print $test;

Это возможно на других языках?

18
ответ дан 2 revs, 2 users 89% 26 September 2011 в 15:40
поделиться

В JavaScript, впервые увидев !!a (как способ преобразования в логическое значение).

18
ответ дан Andrey Shchekin 26 September 2011 в 15:40
поделиться

В Хаскеле:

let 2 + 2 = 5 in 2 + 2

дает 5.

15
ответ дан user954298 26 September 2011 в 15:40
поделиться

Самую большую коллекцию (сегодня 1313) достойных и странных языков программирования, которую я знаю, вы найдете здесь: http://99-bottles-of-beer.net/ будьте готовы увидеть действительно странное вещи ;-) Каждый должен сделать свой выбор

10
ответ дан stacker 26 September 2011 в 15:40
поделиться

В более ранней версии Visual Basic функции без оператора «Return» просто «Return None», без какого-либо предупреждения (или ошибки) компилятора.

Это привело к самым сумасшедшим сеансам отладки, когда мне приходилось сталкиваться с этим языком на ежедневной основе.

11
ответ дан Adrian Kosmaczewski 26 September 2011 в 15:40
поделиться

В C или C ++ круглые скобки являются необязательными для аргумента sizeof ... при условии, что аргумент не является типом:

void foo() {
  int int_inst;

  // usual style - brackets ...
  size_t a = sizeof(int);
  size_t b = sizeof(int_inst);
  size_t c = sizeof(99);

  // but ...
  size_t d = sizeof int_inst; // this is ok
  // size_t e = sizeof int; // this is NOT ok
  size_t f = sizeof 99; // this is also ok
}

Я никогда не понимал, почему это так!

12
ответ дан 2 revs, 2 users 69% 26 September 2011 в 15:40
поделиться

Легкий выбор, Эрланг полон их. Например, 3 формы пунктуации,

a_function(SomeVariable) ->
  statements_end_with_commas(),
  case PatternMatching of
    0 -> now_we_end_with_semicolon;
    true -> except_the_last_one
  end.

%%  Function definitions end with periods!
12
ответ дан pablo.meier 26 September 2011 в 15:40
поделиться

Идентификаторы скобок в VBScript

VBScript имеет так называемые идентификаторы скобок , которые являются идентификаторами, определенными в квадратных скобках, например:

[Foo]

Они ' на самом деле это очень удобно, так как они позволяют вам именовать переменные и подпрограммы после зарезервированных слов, вызывать методы сторонних объектов, чьи имена являются зарезервированными словами, а также использовать практически любые символы Юникода (включая пробелы и специальные символы) в идентификаторах. Но это также означает, что вы можете повеселиться с ними:

[2*2] = 5

[Здравствуй, мир!] = [Hello, world!]

[] = "Looks like my name is an empty string, isn't that cool?"

For[For[i=0]=[0]To[To[To[0]
  [Next[To]([For[i=0])=[For[i=0]
Next

С другой стороны, идентификаторы скобок могут быть ошибкой, если вы забудете кавычки в утверждении, подобном этому:

If MyString = "[Something]" Then

, потому что If MyString = [Something] Then - совершенно законный синтаксис. (И именно поэтому IDE с подсветкой синтаксиса является обязательным!)


Больше информации об идентификаторах скобок в блоге Эрика Липперта :

12
ответ дан 3 revs, 2 users 90% 26 September 2011 в 15:40
поделиться

Perl полон странных, но аккуратных особенностей.

если можно использовать до или после такого утверждения как:

print "Hello World" if $a > 1;    
if ($a > 1) { print "Hello World"; }

То же самое верно и для foreach:

print "Hello $_!\n" foreach qw(world Dolly nurse);
15
ответ дан 3 revs, 3 users 75% 26 September 2011 в 15:40
поделиться

LOLCODE!

Весь язык. Хотя это не совсем вещь WTF, я никогда не сталкивался с языком, который звучит у меня в голове скрипучим мультяшным голосом. Также я никогда не смотрел на код раньше и хочу воскликнуть «aaaawwww cuuute!»

Эта программа отображает цифры 1–10 и завершается

HAI
CAN HAS STDIO?
IM IN YR LOOP UPPIN YR VAR TIL BOTHSAEM VAR AN 10
    VISIBLE SUM OF VAR AN 1
IM OUTTA YR LOOP
KTHXBYE
14
ответ дан Fahd 26 September 2011 в 15:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: