• Странности Generic типов Java

      Я множество раз слышал о том, что дизайн Generic типов в Java является неудачным. По большей части претензии сводятся к отсутствию поддержки примитивных типов (которую планируют добавить) и к стиранию типов, а конкретнее — невозможности получить фактический тип параметра в рантайме. Лично я не считаю стирание типов проблемой, как и дизайн Generic-ов плохим. Но есть моменты, которые меня порядком раздражают, но при этом не так часто упоминаются.


      1


      Например, мы знаем, что метод Class#getAnnotation параметризован и имеет следующую сигнатуру: public <A extends Annotation> A getAnnotation(Class<A> annotationClass). Значит, можно писать вот такой код:


      Deprecated d = Object.class.getAnnotation(Deprecated.class);

      Тут я решаю вынести Object.class в отдельную переменную и код перестаёт компилироваться:


      Class clazz = Object.class;
      // incompatible types:
      // java.lang.annotation.Annotation cannot be converted to java.lang.Deprecated
      Deprecated d = clazz.getAnnotation(Deprecated.class);

      Где я ошибся?

      Читать дальше →
    • Встречайте Kotlin 1.1: JavaScript, корутины и многое другое

      • Перевод

      Мы рады представить вам Kotlin 1.1, новую версию языка программирования Kotlin.


      Kotlin 1.1

      Наша цель — сделать выразительный статически типизированный язык, на котором можно эффективно писать все компоненты современного приложения. Сегодняшний релиз делает два важных шага в этом направлении.


      Читать дальше →
    • Пишем MVP приложение на Kotlin под Android



        Разработка приложений на Kotlin под Android набирает популярность среди разработчиков, однако статей в русскоязычном сегменте Интернета довольно мало. Я решил немного подправить ситуацию, и написать туториал по разработке приложения на Kotlin. Мы напишем полноценное приложение с использованием всех трендовых библиотек (кроме RxJava) в мире Android-разработки. В конце у нас должно получиться расширяемое и легко тестируемое приложение (сами тесты мы писать не будем).
        Читать дальше →
      • Kotlin 1.0. Задай вопрос команде

          На этой неделе случилось важное для нас событие — вышла первая версия языка программирования Kotlin! Так как почти вся разработка Kotlin велась в Питерском офисе компании JetBrains, многие хабровчане уже знают, что такое Kotlin и пробовали его на практике, поэтому этот пост больше для комментариев: задавайте любые вопросы и команда Kotlin ответит. Мы онлайн!

          image

          Читать дальше →
        • Полвека «универсальным машинным языкам» (1966—2016): прошлое, настоящее, будущее

            КДПВ

            Прошлое


            Повествование можно начать с 1962 г., когда в Кембриджском университете началась работа над CPL («Cambridge Programming Language») — «усовершенствованным вариантом» ALGOL-60. К работе над языком подключился аспирант Мартин Ричардс; главной сложностью в реализации нового ЯП ему показалась необходимость ручного портирования компилятора для разных компьютерных платформ. В частности, когда кембриджский EDSAC-2 заменили на Atlas-2, разработчики CPL потратили много времени на портирование своего компилятора для новой платформы.

            Диссертация Мартина была посвящена «само-компилирующемуся» CPL: разработанный Мартином компилятор был написан на сильно упрощённом варианте CPL, компилятор которого несложно было написать на тогдашнем макроассемблере. Перенос CPL на новую платформу теперь можно было выполнить в два шага:
            1. Вручную пишем компилятор «упрощённого CPL»;
            2. Компилируем им компилятор «полного CPL».

            На этом Мартин не остановился, и разработал BCPL — систему для разработки переносимых компиляторов. Компилятор BCPL генерировал псевдокод, названный Мартином «OCODE».
            OCODE выглядел примерно так:
            OCODE «расшифровка» («procode»)
            94 5 L1 83 73 69 86 69
            95 4
            42 0
            42 0 40 2 14
            83
            42 0 42 1 40 2 14 83
            42 2
            40 3 42 1 15
            92
            85 L5
            90 L6
            42 1 40 4 40 2 14 83
            40 4 42 1 14 80 4 
            90 5 40 4 40 5 88 L6
            91 4
            42 2 40 3 42 1 15 92
            85 L7
            90 L8 40 4 40 2 14
            8 87 L9
            40 4 42 2 11 92
            85 L11
            90 L10
            42 0 40 6 40 2 14 83
            40 4 40 6 14 80 6
            90 L11
            40 6 40 3 22 86 L10
            91 6 90 L9
            40 4 42 1 14 80 4
            90 L7 40 4 40 5 88 L8
            91 4 97 103 0
            
            ENTRY 5 L1  'S' 'I' 'E' 'V' 'E'
            SAVE 4
            LN 0
            LN 0 LP 2 PLUS
            STIND
            LN 0 LN 1 LP 2 PLUS STIND
            LN 2
            LP 3 LN 1 MINUS
            STORE
            JUMP L5
            LAB L6
            LN 1 LP 4 LP 2 PLUS STIND
            LP 4 LN 1 PLUS SP 4
            LAB L5 LP 4 LP 5 ENDFOR L6
            STACK 4
            LN 2 LP 3 LN 1 MINUS STORE
            JUMP L7
            LAB L8 LP 4 LP 2 PLUS
            RV JF L9
            LP 4 LN 2 MULT STORE
            JUMP L11
            LAB L10
            LN 0 LP 6 LP 2 PLUS STIND
            LP 4 LP 6 PLUS SP 6
            LAB L11
            LP 6 LP 3 LS JT L10
            STACK 6 LAB L9
            LP 4 LN 1 PLUS SP 4
            LAB L7 LP 4 LP 5 ENDFOR L8
            STACK 4 RTRN ENDPROC 0
            
            ; заголовок процедуры
            ; стековый кадр (два параметра и две локальные переменные)
            ; поместить на стек число 0
            ; поместить ещё один 0, прибавить к нему 2-ой элемент стека
            ; записать в массив на вершине стека значение под ним
            ; всё то же самое для 1-ого элемента массива
            ; поместить на стек число 2
            ; вычесть единицу из значения 3-его элемента стека
            ; записать результат в локальную переменную
            ; перейти к метке L5
            ; объявление метки L6
            ; взять 4-ый элемент стека, записать в массив по этому индексу 1
            ; прибавить к 4-ому элементу стека 1, записать результат обратно
            ; L5: перейти к метке L6, если 4-ый элемент стека <= 5-ому
            ; объявление, что на стеке сейчас четыре элемента
            ; вычесть единицу из значения 3-его элемента стека
            ; перейти к метке L7
            ; L8: сложить 4-ый и 2-ой элементы стека
            ; прочитать значение по этому адресу; если это 0, перейти к L9
            ; умножить 4-ый элемент на два
            ; перейти к метке L11
            ; объявление метки L10
            ; взять 6-ой элемент стека, записать в массив по этому индексу 0
            ; прибавить к 6-ому элементу стека 4-ый, записать рез-т обратно
            ; объявление метки L11
            ; перейти к метке L10, если 7-ой элемент стека меньше 4-ого
            ; на стеке сейчас шесть элементов; объявление метки L9
            ; прибавить к 4-ому элементу стека 1, записать результат обратно
            ; L10: перейти к L8, если 4-ый элемент стека <= 5-ому
            ; на стеке четыре элемента; окончание процедуры
            (Для экономии места, последовательности команд записаны в одну строчку. Мартин в своём руководстве по BCPL поступает точно так же.)

            Исходный код на BCPL:
            LET sieve(workvec, vecsize) BE
            {
              workvec!0 := 0
              workvec!1 := 0
              FOR i = 2 TO vecsize-1 DO workvec!i := 1
              FOR i = 2 TO vecsize-1 DO
                IF workvec!i DO
                { LET j = 2 * i
                  WHILE j < vecsize DO
                  { workvec!j := 0
                    j := j + i
                  }
                }
            }
            
            В более новых версиях OCODE добавилась поддержка чисел с плавающей точкой (соответственно, набор поддерживаемых опкодов почти удвоился), а также удалили опкод ENDFOR — вместо него генерируется пара LE JT.

            Среди «универсальных машинных языков» OCODE уникален тем, что метки в нём определяются специальными инструкциями — т.е. для интерпретации программы её нужно сначала всю загрузить в память, и найти в ней метки.
            — а отдельная программа, кодогенератор, превращала файл с таким псевдокодом в исполнимую программу для конечного процессора. OCODE сохранялся в виде текстового файла из десятичных чисел, разделённых пробелами и переводами строк: в то время, когда OCODE разрабатывался, привязка формата файла к конкретному размеру байта ограничивала бы переносимость такого файла.

            Компилятор BCPL(1) поставлялся в виде OCODE, и чтобы перенести его на новую платформу, нужно было:
            1. Вручную написать интерпретатор псевдокода(2) (на любом языке, хоть на Бейсике);
            2. Адаптировать кодогенератор,(3) написанный на BCPL, для своей платформы;
            3. Запустить под интерпретатором (2) компилятор BCPL (1), скормить ему кодогенератор (3), и получить на выходе исполнимый файл кодогенератора(4);
              • Интерпретатор (2) нам с этого момента больше не нужен.
            4. Прогнать через кодогенератор (4) псевдокод компилятора (1), и получить на выходе исполнимый файл компилятора.


            Такой подход означал, что для переноса компилятора на новую платформу требуется лишь самый минимум низкоуровневого программирования; и действительно, реализация BCPL была завершена к 1967 г. — раньше, чем была завершена реализация CPL, начатая на несколько лет раньше!

            Достоинства BCPL применительно к системному программированию вдохновили Кена Томпсона на создание языка Би, а тот — коллегу Кена, Денниса Ритчи, на создание Си. Именно из BCPL пошла традиция обозначать {фигурными скобками} блоки программы, и именно на BCPL была написана первая программа «Hello, World!».
            GET "libhdr"
            
            LET start() = VALOF
            { writef("Hello*n")
              RESULTIS 0
            }
            
            Более важная нам причина, по которой BCPL вошёл в историю: OCODE — первая универсальная «архитектура набора команд» (ISA), т.е. «виртуальная машина», не привязанная ни к какой конкретной аппаратной платформе с её особенностями. BCPL, таким образом — первый язык программирования, соответствующий парадигме «Write once, run anywhere» (WORA): программу на BCPL можно распространять в скомпилированном виде, и её можно будет запустить на любой платформе, для которой существует OCODE-кодогенератор.
            Читать дальше →
          • Про Бурали-Форти, Пуанкаре и то самое определение единицы

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

              image

              Наверняка также вы задавались вопросом: что, чёрт подери, здесь написано? Формула из этой цитаты интересна тем, что у человека, имеющего высшее математическое образование, этот вопрос возникает столь же неумолимо, как и у любознательного семиклассника. У нелюбознательных семиклассников несколько иной круг интересов, выходящий за рамки данной статьи; однако даже они не откажут себе в удовольствии похихикать над «этими чокнутыми ботаниками», или как оно там формулируется на современном молодёжном сленге.

              В нижеследующем тексте я раскрою перед вами тайну этого загадочного сочетания символов. Пожалуйте под кат, однако помните поучительную историю о любопытной Варваре, которой на базаре рассказали про парадокс Банаха-Тарского, отчего она сошла с ума, разрезала себе нос на конечное количество частей и склеила из них рогатую сферу Александера.
              N.B. Я предупреждал.
            • Про модель, логику, ООП, разработку и остальное

                Часто ли вы задумываетесь – почему что-то сделано так или иначе? Почему у вас микросервисы или монолит, двухзвенка или трехзвенка? Зачем вам многослойная архитектура и сколько у вас вообще слоев? Что такое бизнес-логика, логика приложения, презентационная логика и почему все так разделено? Посмотрите на свое приложение – как оно вообще спроектировано? Что в нем и где находится, почему это сделано именно так?
                Потому что так написано в книжках или так говорят авторитетные личности? Какие ВАШИ проблемы решает тот или иной подход/паттерн?
                Даже то, что на первый взгляд кажется очевидным, порой бывает очень сложно объяснить. А иногда, в попытке объяснения, приходит понимание того, что очевидные мысли были и вовсе ошибочны.
                Давайте попробуем взять какой-нибудь пример и изучить на нем эти вопросы со всех сторон.
                Читать дальше →
              • Критерий выгодности подстановки и динамическая профилировка

                  image

                  Продолжаю тему межпроцедурных оптимизаций, введение в которую можно найти в предыдущем посте. Сегодня хочется немного порассуждать о подстановке функции (inlining) и о том, как подстановка влияет на производительность приложения.
                  Читать дальше →
                  • +28
                  • 7,2k
                  • 2
                • О великих велосипедах, или почему иногда нужно писать с нуля

                    Not invented here — источник инноваций и причина успеха?


                    Я не могу дать тебе рецепт успеха, но рецепт провала могу дать точно: каждый день и каждую минуту делай все так, как делают окружающие.
                    Неизвестный автор.


                    Очень часто в компаниях выступают против синдрома «not invented here». Я, как менеджер проектов, прекрасно понимаю соображения такого толка. Велосипеды — это лишние затраты, удлинение сроков разработки, сложность и дороговизна поддержки продукта в будущем, зависимость от разработчиков велосипеда и все такое прочее.

                    Но как программист, понимаю однозначно — без велосипедов не будет инноваций. А без инноваций не будет прорывных технологических решений, новых проектов. Будут только одинаковые, похожие друг на друга, собранные из одного набора кубиков проекты и приложения, никак не могущие конкурировать между собой (разве что кто кого засудит и «отожмет» рынок).

                    Не случайно поэтому Гугл выделяет 20% на свободное творчество, и это рождает такие великолепные переосмысления старых вещей, как почтовый клиент Gmail.

                    Но обо все по порядку. В этой статье я хочу коротко рассказать о трех «велосипедах», которые произвели революцию в своей области.
                    Читать дальше →
                  • Table bloat? Не, не слышал…



                      Думаю многим известна особенность PostgreSQL, которая приводит к эффекту раздувания таблиц, или table bloat. Известно что она проявляет себя в случаях интенсивного обновления данных, как при частых UPDATE так и при INSERT/DELETE операциях. В результате такого раздувания снижается производительность. Рассмотрим почему это происходит и как с этим можно бороться.
                      что?