У Cargo Shuffle ми познайомилися зі стеком даних у Factor і зі словами-перестановками, які його перевпорядковують. Ця вправа розвиває цю тему: ми будемо визначати слова, які обчислюють на основі своїх вхідних даних, а не просто переміщують їх.
! починає коментар у рядку: Factor ігнорує все від ! до кінця рядка. У наведених нижче прикладах ! використовується і для позначення того, що робить код, і для показу того, що він виведе.
У Factor функцію називають словом. Виклик слова знімає кілька значень із верхівки стека й натомість кладе туди інші значення.
. знімає верхнє значення й друкує його; слова цілочисельної арифметики
+, -, * знімають два числа й кладуть результат:
2 3 + . ! prints 5
8 3 - . ! prints 5 (8 - 3, not 3 - 8)
2 3 * . ! prints 6
Споріднене слово .s друкує весь стек даних, нічого не споживаючи. Це зручно в listener (інтерактивному рядку Factor, де ми набираємо код і бачимо результати), щоб побачити, що залишає по собі фрагмент коду. Ось чому пізніші приклади іноді закінчуються на .s, а не на .: вони залишають на стеку більше ніж одне значення, і .s показує їх усі.
Слова арифметики живуть у словнику math, тож файл, який їх використовує, потребує math у своєму рядку USING:.
Для кожного слова в документації вказано стековий ефект вигляду
( inputs -- outputs ). Це контракт слова: воно знімає вхідні дані з верхівки стека й залишає на їхньому місці вихідні дані. Назви всередині потрібні лише для того, щоб допомогти нам його читати. Factor їх не використовує, він відстежує лише порядок, у якому значення розташовані на стеку.
! + is specified as ( x y -- sum )
! . is specified as ( x -- )
Правий вхід розташований на верхівці стека. Тож у 8 3 - на верхівці стоїть 3, стековий ефект має вигляд ( x y -- difference ), а результат дорівнює 8 - 3.
Завершальний ? у вихідних даних позначає «булеве значення» (англ. Boolean), але у вправі з лазаньєю використовуються лише числа.
Нижче зустрінеться одне слово-перестановка з Cargo Shuffle: swap
( x y -- y x ), яке міняє місцями два верхні значення, коли вони стоять у неправильному порядку для наступного слова.
: починає визначення слова, далі йде стековий ефект, потім тіло, а ; його завершує.
: square ( x -- x^2 ) dup * ;
4 square . ! => 16
Компілятор Factor перевіряє, що тіло справді відповідає оголошеному стековому ефекту: слово, яке заявляє ( x -- y ), але залишає на стеку нуль або два значення, не скомпілюється.
CONSTANT: визначає імʼя для фіксованого значення. Константа сама є словом: виклик константи кладе значення на стек:
CONSTANT: pi 3
pi pi * . ! => 9
CONSTANT: належить до базового синтаксису і не потребує рядка USING:. Розміщуймо константи на початку файлу, перед будь-яким словом, яке їх використовує.
Тіло слова може викликати будь-яке слово, яке вже перебуває в області видимості, зокрема ті, які ми визначили раніше в тому самому файлі:
: double ( x -- 2x ) 2 * ;
: quadruple ( x -- 4x ) double double ;
5 quadruple . ! => 20
Саме так останнє завдання у вправі повторно використовує попереднє.
І слова, і константи використовують lowercase-kebab-case: маленькі літери, зʼєднані дефісами (наприклад, expected-bake-time, preparation-time).
У цій вправі ми напишемо трохи коду, щоб допомогти приготувати чудову лазанью з нашої улюбленої кулінарної книги.
На нас чекають чотири завдання, усі повʼязані з часом, витраченим на приготування лазаньї.
Визначте константу expected-bake-time, яка повертає, скільки хвилин лазаньї потрібно запікатися в духовці.
Згідно з кулінарною книгою, лазанья має бути в духовці загалом 40 хвилин.
expected-bake-time .
! => 40
Визначте слово preparation-time. Воно бере зі стека кількість шарів, які ми додали до лазаньї, і залишає, скільки хвилин ми витратили на приготування, якщо припустити, що на підготовку кожного шару потрібно 2 хвилини.
4 preparation-time .
! => 8
Визначте слово remaining-time. Воно бере кількість хвилин, які лазанья вже провела в духовці, і залишає, скільки хвилин їй ще треба там залишатися.
25 remaining-time .
! => 15
Визначте слово total-working-time. Воно бере зі стека два аргументи (спочатку кількість шарів у лазаньї, потім кількість хвилин, які лазанья вже провела в духовці) і залишає загальний час, витрачений на приготування на цей момент: час підготовки плюс час, уже проведений у духовці.
3 20 total-working-time .
! => 26
Зареєструйтеся на Exercism, щоб вивчати й опановувати Factor, а також 47 концепцій163 вправи та справжнє наставництво від людей, і все це безкоштовно.