Комментарии 47
А зачем вы мне это прислали? Думаете я не знаю? Команда Rust молодцы, что тут сказать.
Но я думал вы что-то своё покажете, а не чужую работу. Интересно было бы посмотреть на ваши личные компиляторные наработки.
Ну раз уж сами попросили :) Вот платформа lsFusion. Свой язык, открытая платформа. У нас свойства и действия объявляются отдельно от классов, есть множественное наследование и диспетчеризация по классам всех параметров. Более того, вообще нет обычной записи через точку.
Но в целом, зачем вообще привязывать функцию к одному «главному» объекту ? В Вашем же примере расстояние считается между двумя точками. Чем первая принципиально заслужила владеть этой операцией больше второй ?
Например, остаток товара на складе на lsFusion можно описать так:
CLASS Sku 'Товар';
CLASS Stock 'Склад';
balance 'Остаток' = DATA NUMERIC[14,3] (Sku, Stock);У свойства два параметра. Зачем выбирать, в какой класс его запихнуть — в товар или в склад ?
А вообще, чтобы сослаться на Rust, обязательно сначала свой компилятор написать ? Вы бы лучше объяснили, чем Ваш подход отличается. Наличие своего компилятора у собеседника на это никак не влияет.
Выдумывать отдельные языки для прикладных задач, следом искать похвалы на форумах и конечно агрессивно защищать свою бурду - анимешник на лицо. "Подписаться не забудь, я там распальцовку для ссылки на объект показываю"
Ссылка по делу, и идея куда старше Rust: непрозрачный FILE* в C играл роль объекта с методами ещё в семидесятых, а fopen/fread/fclose – его интерфейс. Rust честно развёл данные и поведение: структуры хранят поля, методы живут отдельно. Позднее связывание включается осознанно, через объекты трейтов, и цена видна сразу – рядом с данными едет таблица вызовов.
и раскрываю все тайны IT‑индустрии!
Это видимо была первая: мы научились считать квадрат расстояния в программе! Огромный прогресс однако!
Миллениалы эдак С изобретут
Что-то пытаюсь понять но суть ускользает. Я правильно понимаю, что объявлена точка (point) и вызван ее метод? Т.е. у точки есть поведение и состояние? Т.е. point по сути является экземпляром класса Point несмотря на отсутствие слова "class"? В общем суть изобретения не ясна.
Насколько проще стало без классов
...
Отсутствие классов в компиляторе заставляет его автора оставить какой-то способ связать данные с функциями.
Выглядит так, что Вы сами создали себе ограничение и придумали велосипед для его обхода, вернувшись в исходную точку.
Можно объявить ещё один тип
Coordinatesс теми же полямиxиyи передать его вlengthSquared. Другое имя само по себе не делает данные несовместимыми.
В ООП их просто наследовали бы от единого суперкласса.
К нашему
lengthSquared(p: Point)можно добавить второй вариант — для квадрата расстояния до другой точки:
Исходная функция с одним параметром это частный случай расстояния до нуля координат. Зачем тут перегрузка, когда можно обойтись default value.
Я удалил классы, но оставил объекты с методами
Это неправда, у вас именно что классы, только вместо ключевого слова class используется type, а синтаксис объявления метода сделан как частный случай объявления функции. Грубо говоря, нельзя сделать функцию, принимающую type как первый аргумент, и не создать при этом метод. Чего в этом хорошего, я хз. Выглядит как чисто синтаксическое упражнение.
Вы не правы, это не классы, а протоколы
И в чём отличие? Ну кроме как расстояние по Левенштейну в 8?
Отличия фундаментальные, странно что вы их не понимаете.
Протоколы - это конструкт статического анализа, который появляется и исчезает на уровне текста программы. Это у меня в языке есть.
Классы - материализация в памяти, которая протекает на низкие уровни и тащит за собой конструкты в духе таблиц виртуальных методов или заголовков синхронизации. Этого у меня в языке нет.
Я тоже не понимаю, ни VT ни синк примитивы не обязаны быть в классах, по факту класс это тот же конструкт статического анализа.
Как не назови хоть type хоть class по сути одно и то же, разметка памяти.
А внешние методы ровно то же, что и методы класса, просто функция первый аргумент которой ссылка на объект типа.
Хотите методы без классов - идите в Раст. Там это всё очень хорошо математически продуманно.
Поздравляю, вы открыли утиную типизацию
Работа сама по себе классная — разобрать метод до “функция + receiver + резолв по имени типа” и собрать это в рабочий компилятор не так просто, respect. Но по применимости не уверен: без traits/interfaces (как в Rust или Go) структурная проверка работает “в одну сторону” — метод не увидит literal без явной аннотации, и полиморфизма тут не появляется. По сути это function(receiver, ...) с доп. слоем резолва через точку, без выгод, ради которых обычно и отказываются от классов. Как учебный проект — топ, но какую реальную задачу это решает лучше, чем прямой вызов функции?
Пример решения реальной задачи https://habr.com/ru/articles/1010530/
Тоже занимался подобной идеей, но столкнулся со множеством проблем, когда ЯП начинает обрастать "мясом".
Например, как сделать так, чтобы два объекта имели разные методы, что-то типа myCube.volume() и mySphere.volume()? Получается, что нужно будет разрешать перегрузку функций по типу аргумента, но тогда что делать, если перегрузки конфликтуют друг с другом, что если несколько одинаковых функций импортируются из других модулей, и...
В общем, на синтетических примерах идея кажется простой до гениальности, а в реальном рабочем ЯП превращается в глубокую кроличью нору костылей.
Что-то вроде классов типов в Haskell?
Ага, так и хотелось сказать что это type class на минималках.
Я тоже пробовал свой язык дизайнить и кажется, что если есть типы-суммы с тегами и тайпклассы, то как будто можно построить адекватный язык без наследования. Отличия конечно будут, но мне понравилось что получилось, и штуки типа vtable и прочего если очень надо - можно эмулировать.
Я больше скажу. Всё это кажется смешно и просто, пока сам с нуля не напишешь
Хотелось, чтобы эти вещи работали без обязательной упаковки в класс.
зачем? как будто классы как раз придуманы, чтобы хранить рядом данные и методы работы с ними - для более простой организации кода.
Мне структурная типизация из TS тоже видится более элегантной, чем то, что мы имеем в шарпе с явным наследованием
Картинка с троллейбусом из буханки
Уберём аннотацию у переменной и вызовем lengthSquared(point) напрямую. Получим те же 25. Мы нигде не объявляли, что литерал что‑то реализует. Его поля уже подходят под тип параметра функции.
не совсем удачный пример поскольку достаточно хороший вывод типов мог бы сделать то же самое и при номинальной системе типов, я полагаю 🤔
вообще-то классы придумали чтобы работали нормальные математические операции, например:
distance = point1 - point2;
point3 = point1 + point2;
Но это видимо слишком страшная тайна чтобы про нее вспоминать.
Нет. Классы придумали не для этого. Классы в программировании это изначально, в момент придумывания, вообще про обмен сообщениями между машинами состояний. Ближе всего к “изначальному ООП” - Эрланг.
Нет, для "нормальных математических операций" достаточно было сделать возможность объявлять функции с именами "+","-", ... и принимать структуры в качестве аргументов. Нет никакой причины, по которой операция умножения вектора на скаляр должна быть членом класса вектора.

Я удалил классы, но оставил объекты с методами