Дмитpий Hecтepук

Блог о программировании — C#, F#, C++, архитектура, и многое другое

Плохие и хорошие идеи в языках программирования

12 комментариев

Что-то мне подсказывает, что сейчас не имеет смысл делать новые языки программирования для того, чтобы подстраивать их под новые парадигмы. Вот есть например такая штука как многопоточность, и казалось бы – нам нужны новые языки чтобы использовать эти 80 ядер.

На самом деле нет. Как 5 лет назад было нормой 2-4 ядра, так и сейчас. И да, я знаю что есть процы подороже и посерьезнее, только вот косяк: подавляющее большинство людей нынче пользуют скорее макбуки нежели десктопные РС, а на них сколько ядер? 12? 16? Древнее индейское поселение фигвам.

Поэтому в этом посте немного троллинга “современных” языков. При этом я не жалуюсь, у меня все работает. Просто мысли в слух.

Дорогая, мы продолбали операторы

Даже не операторы. Вы на раскладку клавиатуры смотрели? Что это за !@#$%^&*()_+ мля? Я вообще не понимаю почему у нас на главном органе компьютера такой вагон легаси. Ладно, я вас не прошу с QWERTY следать, но хоть мусор-то можно было убрать?

Я сотственно вот о чем:

  • Единственный вменяемый оператор в ЯП это +. Всё. Кроме плюса все остальное – бред.

  • Минуса на клавиатуре нет вообще. Есть тире - и я тут не пытаюсь быть педантом или типографилом, я просто говорю что использовать тире как минус это вообще неправильно.

  • Деление и умножение тоже продолбано. С какого перепугу “звездочка” это умножение? Умножение это ×. Насчет деления конечно можно поспорить, может / без полноценного фронт-енда a la Mathematica — это приемлимо, но я не уверен.

  • Оператор = никаким образом не означает присваивание. Коротко, Delphi, Mathematica и прочие – правы, нужно разделять присвоение и определение, если вы уж решили использовать = для записи значения в переменную. Я конечно склонен думать что x := 2 это первичное определение переменной (даже auto/var не нужен) а для записи значения подойдет x <- 3 или 3 -> x (это кстати подход в F#, VHDL).

  • Использование = для сравнения — абсолютно нормальная практика (т.е. if (x = 3)) если бы не одно но — числа с плавующей точкой так сравнивать нельзя т.к. нужно указывать погрешность. Я бы, может, и не отказался вместо abs(x-y) < tol писать что-то вроде x =1e-10= y хоть это и выносит порядочно мозг.

  • Вот эта галочка ^ это либо оператор возведения в степень (ну или **), либо ничего. XOR из нее сделали безумцы.

  • Скобки продолбали все и полностью. Вы понимаете, что в математике разные скобки ([], {}, ()) все имеют право на жизнь и используются чтобы не запутаться в сложных выражениях? Так тогда зачем квадратные скобки узурпировали для массовов а фигурные — для scope? А представьте ЯП где можно использовать любые для выражений, плюс компилятор проверяет согласованность.

  • Вообще в математике оператор × можно опускать, и я склонен думать что выражение 3x в том же С++ или C#, при желании, нельзя мизинтерпритировать как ничто кроме 3×x. Также сюда можно приплести units of measure, чтобы можно было писать 52m вместо 52 mm. (И да, я понимаю что непонятно xy это переменная или x*y, но можно же из контекста выводить? Или опасно?)

  • F# узурпировал prime mark ' как символ, но я бы его взял как транспозицию, как делает MATLAB.

  • А еще я бы разрешил произвольные названия переменных, только не как в F# (ВОТ ТАК) а что-то вроде:

    struct Values { #1, #2:i32 }
    Values v; print(v.2)
    

    Кстати, писать v.2 можно в Rust, тоже неплохая возможность.

Косяки с именами типов в C++ и не только

С++ ставит рекорд по полному факапу системы типов. Что такое unsigned long long? Никто не знает, поэтому мы и используем <cstdint>, но можно лучше (спасибо Rust):

  • Целочисленные типы = знаковость (i/u) + размер (сколько вешать в битах), например i32, u64 итд.

  • Для чисел с плавающей в луже точкой просто делаем f32/f64 (спасибо за вынос мозга, F#). Эй SG14, где там 16-bit float?

  • Если вам вдруг нужны пакованые SIMD типы, их можно добавить как p128/256/512. Но это экзотика. Придется вводить векторные операторы (.+, .*, и так далее) как это сделал MATLAB.

  • Использование этих коротеньких типов как постфиксы (var z = 3.0f32) — гениально, спасибо Rust.

  • Целочисленные переменные isize/usize с размером, равным слову проца — это очень умно, опять же спасибо, Rust. И что еще более гениально, так это то, что в Rust индекс массива — unsigned. А в С++ вполне можно написать x[-1] т.к. это всего лишь смещение указателя.

Поддержка векторно-матричных операций

Если все так пекутся о многопоточности и векторизации, почему нигде кроме MATLAB никто не напрягся впаять вектора/матрицы в язык? Более того, я бы предложил:

  • Улучшенную инициализацию, то есть

    X = [1 2; 3 4]; // instead of {{1,2},{3,4}
    X = [ 1 2
          3 4 ]; // also works, kind of
    

  • Вменяемые скалярные и векторные произведения, как сделал MATLAB — X*Y и X.*Y как векторное и Адамарово произведение соответственно.

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

  • Статические и динамические размеры. Очевидно но все же, хочется хороший API. То, что сейчас в С++ это адъ.

И ещё…

Ладно C# запилил observer pattern как event (немного неуклюже, конечно), но было бы неплохо получить binding operator =:= который жестко связывает два значения. А там и до резолва сложных выражений недалеко. Вообщем в современном мире это актуально.

Да, и неплохо было бы оставить операторы < и > в покое и не использовать их для шаблонов. Хотите шаблоны? Используйте « и » и мне плевать что этих символов нет на клавиатуре, т.к. клавиатуры ущербны по определению. И нет, я не предлагаю адъ вроде APL, я скорее предлагаю просто делать уже языкам графические front-end’ы как Mathematica.

Но об этом в следующем посте. ■

Реклама

Written by Dmitri

4 июля 2016 в 20:40

Опубликовано в Programming

Tagged with

комментариев 12

Subscribe to comments with RSS.

  1. http://tonsky.livejournal.com/302046.html

    Этот шрифт наводит красоту в коде

    vyacheslavbelikov

    4 июля 2016 at 22:57

    • Для начала нужно признать, что этот шрифт, как и \LaTeX, юзабелен только на high-DPI мониторах. На high-DPI конечно ситуация лучше, т.к. например можно использовать Arial Narrow, который очень хорош для экономии горизонтального пространства (особенно на ноутбуках).

      Все равно, вопрос не в шрифте а в используемых и неиспользуемых символах. Мы по идее должны использовать намного больше символов, а используем только те, что есть на клавиатуре. И это печально.

      Dmitri

      4 июля 2016 at 23:09

  2. Так можно далеко зайти. Я бы хотел трехмерный редактор кода. Или многомерный. Почему мы ограничены плоским экраном?

    dmitry.p

    6 июля 2016 at 10:54

    • Потому что многомерные экраны пока не делают. А вот front-end’ы уже делают. High DPI наконец то есть у многих пользователей, половина ноутбуков на рынке формально high-DPI, это решает проблему с использование «неудобных» шрифтов.

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

      Dmitri

      6 июля 2016 at 10:57

      • Но хочется highdpi на десктопном монике, для меня больная тема ((

        Podgorodnichenko Denis

        13 июля 2016 at 11:53

        • Боль в том, что хочется шесть 22-дюймовых мониторов с 4К, а их нет. Есть либо 22″ full HD (спасибо, уже есть), либо 4K от 24″. Мне 24″ слишком велики, 21.5″ в самый раз. Вообще, в идеале, я бы взял 22″ с разрешением QHD (1440p), но индустрия клала на меня и мои желания, так что имеем что имеем. Есть правда подозрение, что можно построить нечто из ноутбучных панелей — например Lenovo P70 это 4K на 17″, можно попытаться узнать что за матрица и закупиться.

          Dmitri

          13 июля 2016 at 12:42

  3. Про unsigned для индексов это кстати интересная тема,

    Вот смотри, сделали индекс только uint.

    uint index = 4;

    Дальше, я хочу взять текущий индекс и сместиться от него на минус одну позицию.

    int offset = 1;
    index = index — offset;

    А компилятор такой:
    error CS0266: Cannot implicitly convert type ‘long’ to ‘uint’. An explicit conversion exists (are you missing a cast?)

    Или вот еще: есть два индекса, я хочу получить смещение одного относительно другого, логично вычесть, но если мы попытаемся сделать так:

    uint firstIndex = 4;
    uint secondIndex = 6;

    int offset = firstIndex — secondIndex;

    то опять облом

    Но ведь это логично что индекс беззнаковый, а смещение знаковое, нет так ли?

    ИМХО, надо или жить с теми костылями что мы имеем, либо вводить отдельные типы для index/offset
    которые
    1) index — index будут давать offset
    2) index + index нелегален, ибо нет смысла
    3) index + offset = index

    ну итд

    этуже концепцию хорошо демонстрирует DateTime/TimeSpan

    PS. а как там в расте это решили?

    Podgorodnichenko Denis

    13 июля 2016 at 12:15

    • В Расте те же правила что и в С++, то есть unsigned — signed нельзя, а uint — uint который идет в отрицательные числа вообще упадет с overflow. Как мне видится, если действительно нужны вот такие смещения, нужно просто делать все вычисления в signed а потом для доступа к элементу массива просто кастовать в unsigned. Автоматической конверсии конечно же нет.

      Dmitri

      13 июля 2016 at 12:29

  4. когда речь заходит про скобочки и шаблоны я всегда вспоминаю лямбды из плюсов с аргументами шаблонами

    >Ладно C# запилил observer pattern как event (немного неуклюже, конечно), но было бы неплохо получить binding operator =:= который жестко связывает два значения. А там и до резолва сложных выражений недалеко. Вообщем в современном мире это актуально.

    хочется как в knockout чтоли?

    Podgorodnichenko Denis

    13 июля 2016 at 12:50

  5. По моим ощущениям, основной упор в посте сделан на пряморукой записи математических выражений. Трудно со всеми пунктами согласиться. Как говорится, язык — это инструмент. И многим математические возможности в языке/экосистеме вокруг языка не особо-то пригождаются. Я вот занят геймдевом, где казалось бы, должно быть полно математики, но мне некуда впихнуть математическое выражение сложнее, чем “отклампить арккосинус от данного числа”.

    Тем не менее, с основными выводами целиком и полностью согласен, а именно:
    1. Пора наводить порядок с типографикой. Времена изменились уже не раз, а «так исторически сложилось» сильно как никогда.
    2. Подход к программированию как к написанию текста (пусть и с подсказками, анализом и рефакторингами, причем и они не везде есть *косо смотрит на моднявые Goland и подобные*) — это legacy такое же дремучее, как и раскладка клавиатуры. Как минимум, лучше сразу с AST работать (как в Jetbrain MPS).

    Maxim Kamalov

    16 августа 2016 at 15:55

    • Кстати, я не упомянул шрифты с лигатурами. Но зато недавно купил Pragmata Pro. А еще в VS оказывается не работают все лигатуры в которых тире (-).

      Dmitri

      16 августа 2016 at 22:42


Оставить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: