пятница, 28 марта 2014 г.

Велосипед изобрели

Судя по всему, для компиляции выражений в блоках лямбд используется самописный компилятор, в котором забыли про некоторые новые возможности языка Java. Например, свеженький баг показывает проблему с обработкой исключений, когда для одного try используются одновременно catch и multi-catch.

А вчерашний баг в лямбдах показывает, что проблема в реализации autoboxing/unboxing. Давайте напишем две лямбды на стандартных интерфесах из пакета java.util.function:
    ((IntConsumer) value -> {
        while (value > 0) {
            System.out.println(value--);
        }
    }).accept(10);

    ((Consumer<Integer>) value -> {
        while (value > 0) {
            System.out.println(value--);
        }
    }).accept(10);
В первом случае будет напечатаны числа от 10 до 1, как и ожидается, а во втором - от 9 до 0.

9 комментариев:

  1. Тоже Жира, как я погляжу? :)
    Да, больше Жира!

    ОтветитьУдалить
  2. Баг, судя по всему, довольно хитрый. Оптимизатор чудит?

    ОтветитьУдалить
    Ответы
    1. Не оптимизатор, программист ;)

      Удалить
    2. В конечном итоге виноват, конечно, конкретный программист. Бага-то где? в оптимизаторе?

      Удалить
    3. Как мне кажется, ошибка в компиляторе. Похоже, что вместо использования уже готовых наработок, кто-то решил сам реализовать компиляцию кода внутри лямбд. Но я могу ошибаться...

      Удалить
    4. Сама запись не выглядит как-то особенно. Мне кажется, в какой-то статье про лямбды в Java похожий пример рассматривался. То есть, поведение должно быть ожидаемое. А тут всё выглядит как бага в оптимизаторе с боксингом/разбоксингом... :)
      Впрочем, я могу ошибаться, мои знания Java тянут на двойку с плюсом :)))

      Удалить
    5. Если один и тот же код работает странно в лямбдах и нормально в остальных случаях, то где-то есть есть ветка isInsideLambda, в написана (даже не скопирована) собственная реализация. А уж компилятора (я предполагаю) или оптимизатора - важно только тому, кто будет чинить.

      Удалить