Io Language: Синтаксис

Io Language: Синтаксис

У продовження серії статей про Io, хотілося б окремо зупинитися на синтаксисі мови.

У двох словах синтаксис Io можна описати так: простий, але дивний. Багатьох здивує такий підхід, але, поспішаю запевнити, як і в Lisp, синтаксис незручний тільки при погляді з боку. З естетичної точки зору можна окремо виділити той факт, що багато прогами на Io зовні здаються надміру розрідженими, на екрані залишається багато «зайвого», незаповненого корисним кодом місця, це відчуття мене не покидає досить давно, я поки не придумав, як повністю позбутися цього вивиху мозку, я просто придумав для себе деякі правила оформлення коду, при дотриманні яких ефект значно зморщується:

  • Довжина рядка не повинна перевищувати 80 символів (Привіт, text mode!)
  • Між клонуванням об'єкта та описом тіла нового має бути порожній рядок
  • Методи та властивості групуються
  • Без зайвої необхідності дужки на новий рядок не переносяться

Ну що, поїхали. Винос мозку № 2.

Синтаксис Io

В Io не існує поняття «ключове слово», будь-який текст на Io - вираз складається з імен об'єктів і повідомлень. Таким чином у нас немає ніяких «function, def, defun, define» та іншого синтаксичного сміття.

Об'єкт в Io є базовим контейнером, що складається зі слотів, слот - одиниця зберігання об'єктом чого-небудь. Ну натурально так - слот. Ось звідси і будемо танцювати.

В Io існує три різних за значенням операції «присвоювання»:

  • = (Оновити слот, компілюється в повідомлення updceSlot, якщо слот кудись подівся або ніколи не існував згенерується виняток)
  • := (Встановити слот, компілюється в setSlot, створює новий слот, присвоює значення)
  • ::= (Створює слот, компілюється в 1916 Slot, створює слот, створює мережу, встановлює значення)

Так що не лякайтеся,:= це зовсім не спадщина паскаля, не до ночі будь пом'януть.

(Тут я, до речі, ще трошки відійду вбік і відповім на каммент до попереднього посту: так, в Io можна перевантажувати присвоювання, в Io можна перевантажувати взагалі все)

Тепер кілька слів про повідомлення.

Повідомлення передаються об'єктам і записуються через пробіл, постфіксним чином, а оскільки в Io об'єкт взагалі все, дуже хвацько прокатують такі гламурні прийоми програмування як ланцюжки (chains). Наприклад можна наковбасити ось таку загогуліну:

Lenin speak split reverse foreach(println)

Загальні правила передачі повідомлень прості як три копійки: Object message. Все.

Обробник на кожне повідомлення лежить у своєму власному слоті, якщо так можна виразитися, ім'я слота це зразок який спрацьовує при передачі певного повідомлення об'єкту утримувачу слота. Створювати слоти так само просто, як і передавати повідомлення.

SomeObject someSlot := "" Пройдемте в нумера? "

Тут ми створюємо слот someSlot об'єкта someObject, що містить в собі строкове значення.

(У цьому місці я вперше за час написання статті відчув себе в ролі Капітана Очевидність, хехе)

Таким чином можна створювати властивості об'єктів.

Методи об'єктів створюються так:

SomeObject someMethod := method(SomeObject someSlot print)

Причому важливо зауважити, що method це не ключове слово, а стандартний метод об'єкта Object (А значить його теж можна, ага...)

Метод method (мій мозок...) повертає анонімну функцію, яку можна використовувати хоч прямо так, хоч присвоїти їй ім'я і отримати метод класу.

Крім методу method (ааа!! 1) існує метод block, різниця між ними тільки в тому, що block лексично обмежений рамками об'єкта з якого викликається. (Про систему повідомлень я напишу окремий пост, вона тут нетривіальна і мегакрута).

А ось тепер починаються дивні штуки.

Робимо особливу магію

Основна форма методів method і block така:

method(arg1, arg2, ... ,argN, do message)

Тобто визначення функції складання двох чисел буде виглядати так:

add := method(a, b, a + b)

Як видно, жодного примусового повернення результату тут не спостерігається. Повертається результат обчислення do message, як в lisp'e, erlang'e і взагалі майже у всіх мовах з потужною підтримкою функціональної парадигми. Хоча, справедливості заради, потрібно зауважити, що return в Io є і працює як звичайний, нормальний return.

Для зручності записи зазвичай do-частина переносять на наступний рядок, ось типу так:

add := method(a, b,
  a + b
)

Тобто можна сприймати круглі дужки як операторні, що б зайвий раз не травмувати психіку, хоча це не так.

Умовні конструкції

Форма така:

if(condition, true-expression, else-expression)

Також Io успадкував від папи-Smalltalk'a методи ifTrue, ifFalse, etc.

Ви можете записувати if у більш звичній формі:

if(condition) then(exp) else(exp)

Але зазвичай не потрібно (:

Оператори

Оператори в Io стандартніше нікуди, ніякої тобі префіксної нотації польського калькулятора, все до нудоти звичайно:

1 + 2
1 +(2)
1 +(2 * 4)
etc...

Рядки

У Io рядки найбільше схожі на рядки (Капітан очевидність, на допомогу!):

s := "" Ленін був грибом .\nІ радіохвилею ".

Довгі рядки і рядки з неекранованими символами можна впихнути в потрійні лапки:

s := «» «» «» Справа в тому, що перебуваючи в одному з головних храмів мексиканських, я довго розглядав фрески
і виявив, що більшість фресок присвячені якійсь події історії Мексики,
і яка до болю нагадала мені нашу Жовтневу революцію.
Ті ж самі виснажені люди, озброєні примітивними знаряддями праці,
які скидають якісь уряди -
це все дуже схоже, розумієте? «» «»

Екраном служить звичний більшості «бекслеш» «\». Недруковані символи успадковані з Сі '\n ,\t,'....

Коментарі

Io підтримує три форми коментарів:

C style:

/ *
Ніколи не компілюй це!
BadObject terribleMethod := method( someAwfulLogic )
*/

C++ style inline:

// OMFG!

И Unix style inline:

# Old
# School

Останні в основному використовуються для виготовлення «шебангів» (# !/usr/bin/io).

Ось, власне, весь синтаксис Io, мало яка мова може похвалитися тим, що його опис синтаксису влазить в одну статтю.

Далі за планом стаття про об'єктну модель Io.

Stay turned (-;

(З мого блогу)