Яке значення "не складається"?


35

Я бачу, що багато текстів, особливо функціональних текстів програмування, стверджують, що певні поняття CS "не складаються" . Приклади: замки не складаються, монади не складаються.

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

Чи може хтось пояснити, що означає ця фраза під час використання в виразах, як у двох прикладах, наведених вище (тобто замках та монадах)?


Це за значенням ближче до функції композиції, ніж до об'єднання об'єктів.
Андрес Ф.

Приблизно і неофіційно, якщо у вас є дві окремі речі, які використовують замки, важко їх склеїти. (у випадку із замками важко обійтися без введення тупиків; у випадку з
монадами

Відповіді:


35

Коли люди кажуть, що "X не складає", те, що вони означають під "скласти", насправді означає "скласти разом", а що і як ви складаєте їх, може бути дуже різним, залежно від того, що саме "X".

Крім того, коли вони кажуть "не складається", вони можуть означати деякі дещо різні речі:

  1. Ви не можете скласти два X разом, період.
  2. Ви можете помістити два хрестики разом, але результат не може бути X (IOW: X НЕ замкнуто щодо композиції .)
  3. Можна скласти два X разом, але отриманий X може не працювати так, як ви очікували.

Прикладом №1 є парсери зі сканерами / лексерами. Ви можете почути фразу "сканери / лексеми не складають". Це насправді не так. Що вони означають, це "аналізатори, які використовують окремий етап лексингу, не складають".

Навіщо ви хочете складати парсери? Ну, уявіть, ви такий продавець IDE, як JetBrains, Eclipse Foundation, Microsoft або Embarcadero, і ви хочете створити IDE для веб-рамок. У типовій веб-розробці ми часто змішуємо мови. У вас є HTML-файли з <script>елементами, що містять ECMAScript і<style>елементи, що містять CSS. У вас є файли шаблонів, що містять HTML, деяку мову програмування та метасинтаксис мови мови шаблонів. Ви не хочете писати різні підсвічувачі синтаксису для "Python", "Python, вбудований у шаблон", "CSS", "CSS у HTML", "ECMASCript", "ECMAScript у HTML", "HTML", "HTML у межах шаблон "і так далі тощо. Ви хочете написати підсвічувач синтаксису для Python, один для HTML, один для мови шаблону, а потім скласти три в підсвічувач синтаксису для файлу шаблону.

Однак лексери розбивають весь файл на потік лексем, що має сенс лише для цієї однієї мови. Аналізатор іншої мови не може працювати з лексемами, якими передається лексера. Наприклад, парсери Python, як правило, написані таким чином, що лексери відслідковують відступ і вводять підроблені INDENTта DEDENTлексеми в потік токенів, таким чином дозволяючи парсеру бути без контексту, хоча синтаксис Python насправді не є. Однак лексер HTML повністю ігнорує пробіли, оскільки він не має значення в HTML.

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

Прикладом №2 є рядки з запитами SQL. Ви можете мати два рядки, у кожному з яких є синтаксично правильний SQL-запит, але якщо ви об'єднаєте два рядки, результат може бути не синтаксично правильним запитом SQL. Ось чому ми маємо запит алгебру , як ARel, які роблять складати.

Замки - приклад №3. Якщо у вас є дві програми з блокуваннями, і ви об'єднали їх в одну програму, у вас все ще є програма з блокуваннями, але навіть якщо дві оригінальні програми були повністю коректними, без тупиків і перегонів, отримана програма не обов'язково має це майно. Правильне використання блокування - це загальна властивість всієї програми та властивість, яка не зберігається під час створення програм. Це відрізняється від, наприклад, операції, що роблять складати. Програма, яка правильно використовує транзакції, може складатися з іншою такою програмою і дасть комбіновану програму, яка правильно використовує транзакції.


1
Іншими словами, "не складається" означає "не утворює напівгрупу" (або, трохи більш сильно, моноїд).
Джон Перді

Я не впевнений, що потрібна асоціативність, тому більше схожа на Magma (про яку я дізнався буквально 3 секунди тому :-D)
Jörg W Mittag

Однак, якщо ви запитаєте когось, що вони означають, коли вони говорять, що "блоки не складаються", я впевнений, що вони не відповідуть "Я маю на увазі, що набір правильних одночасних програм із блокуваннями та операція з композицією утворюють Magma" .
Йорг W Міттаг

Га, звичайно, ні. Просто альтернативне фразування. У мене є відчуття, що асоціативність потрібна для підтримки «плоского» почуття композиції, але немає жодного сильного аргументу, який би підтвердив це.
Джон Перді

20

Композиційність означає, що ви можете легко та надійно комбінувати програмні компоненти разом, щоб отримати більші компоненти та більш складні функціональні можливості.

Деякі речі, які допомагають зробити компоненти більш компонованими:

  1. Ідентифікація. Функція idempotent завжди створюватиме однакові вихідні або побічні ефекти, якщо їх викликають кілька разів з однаковими значеннями параметрів. Це покращує композитивність, оскільки результат виклику функції передбачуваний.

  2. Референтна прозорість. Референтно-прозорий вираз завжди оцінюватиме однаковий результат. Це покращує композиційність, дозволяючи замінювати однакові вирази один для одного, а також дозволяє обчислювати вирази незалежно один від одного (тобто на різних потоках) без використання замків.

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

  4. Чистота. Чисті функції не мають побічних ефектів. Вони мають лише вхід і вихід, що робить їх більш компонованими, оскільки ви можете помістити вихід однієї функції на вхід іншої функції, не турбуючись про те, змінилося чи не щось поза функцією.

Замки не складаються, тому що вони є зовнішнім елементом, на який потрібно покластися, поєднуючи дві операції разом, які поділяють певний стан, і з усіляких причин, пов'язаних зі складністю, пов'язаною з використанням замків.

Фраза "монади не складають" не має для мене особливого сенсу. Вся суть монади полягає в тому, щоб взяти якусь велику річ, наприклад введення з клавіатури або вихід з екрана, і перетворити її в більш чисту математичну форму, яка насправді є більш компонованою.


4
Я думаю, що stackoverflow.com/questions/7040844/… робить гарну роботу, пояснюючи, що "монади не складають", мабуть, означає, хоча я згоден, що монади набагато композиційніші, ніж замки.
Іксрек

Ваші бали за "референтну прозорість" та "чистоту" - це насправді дві вимоги до чистоти . Термін "референтна прозорість" слід уникати, оскільки він не є чітко визначеним .
BlueRaja - Danny Pflughoeft

1
Монада - це алгебраїчна структура з певними операціями. Те, що ви описали у своєму останньому абзаці, - це IOтип, який фіксує "ставні дії", такі як введення з клавіатури. Значення IOтипу справді складаються, але це цілий тип, IO який є монадою. Цей тип не складається з інших типів, які є монадами, як, скажімо, тип списку. Тобто, ми не можемо систематично проводити тип , IO . Listякий веде себе , як і IO і Listодночасно. Чи має це сенс? Я не впевнений, що я це добре пояснив.
Тихон Єлвіс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.