TGViewer
Сіпласпластик Сіпласпластик @cpplastic · 739 subscribers
Post #349 397
Класно бути програмістом на C++: захотів покодити іншою мовою — скомпілив її 😂

От я сьогодні з цього почав, бо вирішив згадати мову io, але під arm64 на macOS її немає, бо там якийсь асемблерний код не компілюється. Автори кажуть, мовляв, треба окрему версію Homebrew поставити для цього, але то якогось занадто головняково, тож я просто скомпілював з сорців. Версія з master одразу падала з помилкою, тому довелося трохи пострибати по теґах.

Першу сьогоднішню задачу з Advent of Code я розвʼязав дуже швидко, а от другу вже повертів туди-сюди, бо, як це часто буває, налажав десь у корнер-кейсах. А там якраз був ОДИН такий 😅

Тепер про саму мову. Вона наче й не складна, але є там трохи дивні моменти, коли начебто схожі конструкції поводять себе трохи по-різному.

З класного: там все є виразом (expression), тобто у всього є результат, тому можна хоч цикл for записати у змінну. Ну, насправді це й не цикл, а просто функція в Object. Взагалі треба дуже уважно дивитися, що яка функція повертає, бо інколи це не те що ти очікуєш.

Ще з цікавого: вирішив я написати функцію з трохи тупою назвою mapPairs, яка виконує блок коду на кожній парі зі списку та повертає список результатів. Мабуть, можна було цікавіше щось вигадати, але пох.

Використовую її потім якось отак (тут report — це список):
increasing := true
decreasing := true

report mapPairs(l, r,
increasing = increasing and l < r
decreasing = decreasing and l > r

result := (increasing or decreasing) and (l - r) abs <= 3
"#{l}, #{r}: #{result}" interpolate println

result
)

Прикол тут наступний: якогось спеціального синтаксису для лямбд немає. mapPairs — це просто метод з трьома параметрами: l, r та блок коду. Причому l та r я до того ніде не створював, але в блоці коду їх використовую разом з іншими змінними з локального скоупа, звідки викликаю це. Як же це працює? А отак:
List mapPairs := method(
left := call argAt(0) name
right := call argAt(1) name
body := call argAt(2)

context := Object clone prependProto(call sender)

if(call sender hasLocalSlot("self"),
context setSlot("self", call sender self)
)

result := List clone

for (i, 0, self size - 2,
context setSlot(left, self at(i))
context setSlot(right, self at(i + 1))
result append(context doMessage(body))
)

result
)

У context клонується все з sender (так-так, в io методи — це надсилання повідомлень, як у SmallTalk), потім у ньому ж створюються l та r, а потім отой блок коду виконується вже в цьому контексті. Трошки винесло мені мозок короч.

Працює io десь разів у 10 повільніше за Haskell. Файл на 1000 рядків у мене оброблявся 200 з копійками мілісекунд. З іншого боку, оптимізаціями там і не пахне. Не казатиму вам, яка складність у мого алгоритму, бо там треш ))
  • 👍 8
  • 🔥 2
More from @cpplastic
  1. Oct 7, 2026Post #543
  2. Oct 2, 2026Щось не злетіло з self-driving cars у автовиробників, еге ж? А стільки галасу було. Ну зат…
  3. Sep 24, 2026Ух, яку ж класну доповідь подивився: «Scott Jenson: Are we really going to use the same De…
  4. Sep 23, 2026Post #540
  5. Sep 21, 2026«Порекламую» вам український сайт, який мені дуже подобається. Взяв слово в лапки, бо як і…
  6. Sep 18, 2026Ви ж знаєте, що я полюбляю Tailscale 💠 попри те, що недоліків у них теж вистачає? Але сам…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →