Чому ми використовуємо стійкі структури даних у функціональному програмуванні?


22

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


є досить добре розширене обговорення цього питання в abelson & sussman, структурі та інтерпретації комп'ютерних програм
vzn

Відповіді:


19

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

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

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

Математика ніколи не працювала зі змінними об'єктами даних. Отже, не існує жодних прийомів міркувань, які б ми могли позичити у них. Існує безліч наших власних методик, розроблених в галузі інформатики, особливо Флойд-Хоаре Логіка . Однак, це освоїти складніше, ніж стандартні математичні методи, більшість учнів не справляється з ними, і тому вони рідко навчаються.

Для швидкого огляду того, як дві парадигми відрізняються, ви можете ознайомитись з першими поданнями моїх конспектів лекцій щодо Принципів мов програмування .


Це має для мене багато сенсу. Дякуємо, що поділилися вашими PPT. Чи поділяєте ви також відеозаписи?
gpuguy

@gpuguy. Я не так багато використовую powerpoint. Дошка - мій улюблений засіб. Але роздатковий матеріал повинен бути досить читабельним сам по собі.
Uday Reddy,

+1 Математика ніколи не працювала зі змінними об'єктами даних. Також посилання на ваші конспекти лекцій.
Гай Кодер

15

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

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

Чому легше використовувати стійкі структури даних? Тому що люди справді погано відслідковують псевдоніми та інші види несподіваних взаємодій між різними частинами програми. Вони автоматично думають, що дві речі називаються xі y, то немає нічого commmon. На жаль, потрібні зусилля, щоб зрозуміти, що "ранкова зірка" і "вечірня зірка" - це дійсно те саме. Так само дуже легко забути, що структура даних може змінюватися через те, що з нею працюють інші потоки або тому, що ми назвали метод, який трапляється змінювати структуру даних і т. Д. Багато з цих проблем просто відсутні в роботі стійкі структури даних.

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


коли він має стільки переваг, то чому б не використовувати стійку структуру даних і в імперативних мовах?
gpuguy

4
Можливо, незабаром ви запитаєте "Навіщо використовувати імперативні мови?"
Андрій Бауер

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

1
@gpuguy. Стійкі структури даних можуть бути і повинні використовуватися і в імперативних мовах, коли вони застосовуються і підходять. Щоб мати можливість їх використовувати, мова повинна підтримувати управління пам’яттю на основі збору сміття. У багатьох сучасних мовах є такі: Java, C #, Scala, Python, Ruby, Javascript тощо
Uday Reddy,

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

2

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

Це надзвичайно корисно в області формальних методів.
Наприклад:

  • Офіційні докази перевірки програми спрощуються за допомогою розширеної статистичної перевірки;
  • Ряд властивостей реляційної алгебри корисний для вирішення SAT, використовуючи такі інструменти, як Сплав;
  • Galois Connections дозволяють розрахунково підходити до специфікації програмного забезпечення, як видно з цього блогу , з посиланням на документ , від Shin-Cheng Mu та José Nuno Oliveira.
  • З'єднання Галуа (та функціональне програмування) можна використовувати в дизайні за контрактом, оскільки вони є більш загальним поняттям, ніж Лоріка Хоара.

Приклад

{p}П{q}[П]ϕpϕq[П]

  • [П]П
  • ϕpϕq)pq

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


2

Я хочу на низькому рівні зрозуміти, що буде, якщо структура даних не буде стійкою?

Давайте розглянемо генератор псевдовипадкових чисел з величезним простором стану (на кшталт " Мерсенн твістер " зі станом 2450 байт) як структуру даних. Ми насправді не хочемо використовувати будь-яке випадкове число більше одного разу, тому, мабуть, є мало причин реалізувати це як незмінну стійку структуру даних. Тепер давайте запитаємо, що може піти не так у наступному коді:

mt_gen = CreateMersenneTwisterPRNGen(seed)
integral = MonteCarloIntegral_Bulk(mt_gen) + MonteCarloIntegral_Boundary(mt_gen)

Більшість мов програмування не вказують порядок, в якому MonteCarloIntegral_Bulkі MonteCarloIntegral_Boundaryбуде оцінюватися. Якщо обидва беруть посилання на змінний mt_gen як аргумент, результат цього обчислення може залежати від платформи. Що ще гірше, можуть бути платформи, де результат взагалі не відтворюється між різними пробіжками.

Можна створити ефективну структуру даних, що змінюється, для mt_gen таким чином, що будь-яке переплетення виконання MonteCarloIntegral_Bulkі MonteCarloIntegral_Boundaryдасть "правильний" результат, але інше переплетення взагалі призведе до іншого "правильного" результату. Ця невідтворюваність робить відповідну функцію "нечистою", а також призводить до деяких інших проблем.

Невідтворюваності можна уникнути, застосувавши фіксований порядок послідовного виконання. Але в цьому випадку код може бути впорядкований таким чином, що в будь-який момент часу доступна лише одна посилання на mt_gen. У введеній функціональній мові програмування для забезпечення цього обмеження можна використовувати типи унікальності, тим самим забезпечуючи безпечні оновлення, що змінюються, також у контексті чистої функціональної мови програмування. Все це може звучати приємно і безглуздо, але, принаймні, теоретично моделювання Монте-Карло незручно паралельне, і наше "рішення" просто знищило цю власність. Це не просто теоретична проблема, а цілком реальна практична проблема. Однак ми маємо змінити (функціонал, який пропонує) наш генератор псевдовипадкових чисел та послідовність випадкових чисел, які він виробляє, і жодна мова програмування не може зробити це автоматично для нас. (Звичайно, ми можемо використовувати іншу бібліотеку псевдовипадкових чисел, яка вже пропонує необхідну функціональність.)

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


Андрій Бауер порушив питання про підрахунок змінних змінних структур. Цікаво, що різні імперативні мови, такі як Fortran і C, мають різні припущення щодо дозволеного псевдонімування аргументів функції, і більшість програмістів зовсім не знають, що в їхній мові взагалі є модель псевдоніму.

Семантика незмінності та значення може бути дещо завищеною. Що ще важливіше, це те, що система типу та логічний каркас (як, наприклад, абстрактна модель машини, модель псевдоніму, паралельна модель чи модель управління пам'яттю) вашої мови програмування надають достатню підтримку для роботи "безпечно" з "ефективними" даними споруди. Введення "переміщення семантики" в C ++ 11 може виглядати як гігантський крок назад з точки зору чистоти та "безпеки" з теоретичної точки зору, але на практиці це навпаки. Система типів та логічна основа мови були розширені, щоб усунути величезні частини небезпеки, пов'язані з новою семантикою. (І навіть якщо залишаються шорсткі краї, це не означає, що це не вдалося поліпшити "кращим"


Удей Редді порушив питання про те, що математика ніколи не працювала з об'єктами даних, що змінюються, і що типові системи для функціональних програм добре розроблені для незмінних об'єктів даних. Це нагадало мені пояснення Жана-Іва Жирара, що математика не використовується для роботи зі змінними об'єктами, коли він намагається мотивувати лінійну логіку.

Можна запитати, як розширити тип системи та логічні рамки функціональних мов програмування, щоб дозволити «безпечно працювати» з «ефективними» змінними непостійними структурами даних. Одна з проблем тут може полягати в тому, що класична логіка та булеві алгебри можуть бути не найкращою логічною основою для роботи зі змінними структурами даних. Можливо, лінійна логіка та комутативні моноїди можуть бути краще підходять для цього завдання? Можливо, я повинен прочитати, що Філіп Вадлер повинен сказати про лінійну логіку як систему типів для функціональних мов програмування? Але навіть якщо лінійна логіка не зможе вирішити цю проблему, це не означає, що типову систему та логічні рамки функціональної мови програмування не можна було б розширити, щоб забезпечити "безпечний" та "ефективний"


@DW Ви, мабуть, праві, що ця відповідь не є окремою відповіддю. Наразі він поширюється лише на певні моменти, підняті у відповідях Удай Редді та Андрія Бауера. Я думаю, що можу змінити його на самості та безпосередньо відповісти на "Я хочу зрозуміти на низькому рівні, що буде, якщо структура даних не буде стійкою?" частина питання. Я б розглядав генератор псевдовипадкових чисел з величезним простором стану (на кшталт "Мерсенн твістер" зі станом 2450 байт) як структуру даних і пояснював речі, які можуть піти не так.
Томас Клімпель

@DW Я не відчуваю, що будь-яка відповідь на це питання дійсно відповідає на питання. Зокрема, немає нічого особливого в тому, що насправді є стійкими структурами даних (крім того, що вони непорушні) та як вони реалізуються.
Гільденстерн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.