Typed lua + OOP
Не секрет, что язык программирования lua в десятки раз быстрее python. Это обосновывает, почему microsoft использует lua в vscode, а также почему этот язык используется в neovim.
Teal - это очень хорошая попытка сделать lua типизированным. Идея языка - применять типизацию во время компиляции кода, превращая его в обычный lua (похоже на typescript). Да, в runtime типизация может нарушиться (если есть ввод данных), но при правильной архитектуре можно этого избежать.
Есть игровые движки, где используется lua (и следовательно teal): LÖVE (игра Balatro), Solar2D (игра Coromon). Поэтому типизированный lua становится интересен.
В языке есть структура данных record - это как struct в других языках, но без методов. Через танцы с метатаблицами можно прикрутить методы к этим record.
Но я оформил pull request, который создает в этом языке struct - это продолжение record, но с методами и одиночным наследованием: https://github.com/teal-language/tl/pull/1161
struct - это намеренно примитивная реализация OOP. Пользователь регистрирует поля и методы:
local struct Person name: string end
Экземпляр создается через зарезервированный метод new, куда передаются аргументы для полей:
local a = Person.new {name = “Andrey”}
Наследование только одиночное:
local struct Employee:Person is_lead: boolean = false end
Если требуется вычислить поле посредством других имеющихся полей, то это делается через init без параметров:
function Employee:init() self.payroll_x2: boolean = self.is_lead == true end
init выполняется автоматически от родительского класса к текущему. Методы и поля экземпляра мапятся в метатаблицу текущего экземпляра (в том числе и родительские), это покрывает 95% случаев, но при этом не требует накладных расходов на диспетчеризацию в runtime. При желании, всегда можно сделать метод на текущем экземпляре, который явно позовет другой метод родительского экземпляра или обратится к полю родителя (а это покрывает оставшиеся 5%, но пользователь платит за это намеренно).
Почему бы не передавать параметры в init? А я отвечу: зачем? Ведь если требуется предварительная калькуляция с данными, которые не относятся к структуре, то напишите функцию-хэлпер, а далее передайте в экземпляр struct только то, что относится к структуре (и ничего лишнего).
Также можно создать статические поля:
local Employee:Person static q_of_employees: number = 0 end end
Статические поля также не имеют диспетчеризации и мапятся напрямую к текущему типу struct. При желании опять же можно вручную сделать диспетчеризацию к родительскому статическому полю, если потребуется.
И статические методы:
function Employee.print_q_of_employees() print(Employee.q_of_employees) end
Если PR не примут, то буду развивать свой форк, но мне не хочется постоянно поддерживать обновления teal, поэтому PR предпочтителен.
· вчера
В lua же уже есть OOP через __index. Или teal его как-то ломает?
Если так сильно нужен OOP, то реально проще поступить как c++ и самому доделать язык с блэкджеком и keyword'ами, разве нет?
Я не то чтобы хейчу ООП и топлю за функциональщину, просто у teal в документации "минимализм и типы", а тут прикручивание OOP, которое и не про типы и не очень про минимализм.
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
коммент удалён