Чи можна виразити * будь-яке * програмне завдання без стану?


13

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

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

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


1
Відповідний StackOverflow відповідь: stackoverflow.com/questions/3722084 / ...
jfriend00

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

6
Якщо ви хочете обговорити стан; чітко потрібно стан, якщо тільки для самої програми. Це здається, що ти думаєш про стан, що змінюється проти непорушного стану, - можливо, ти хочеш вказати, що ти маєш на увазі у питанні.
Біллі ONeal

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

Відповіді:


17

Коротка відповідь: так. За даними Вікіпедії, еквівалентність обчислення лямбда машинам Тьюрінга як універсальної моделі обчислення показала в 1937 році Алан Тьюрінг. Обчислювальна модель машини Тьюрінга - це те, що ти зазвичай маєш на увазі, коли говориш про імперативне або державне програмування, а обчислення лямбда - це математична формалізація "чистого функціонального програмування".

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


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

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

@emilio Заявлення про те, що існує проблема, що базується на еквівалентному стані (як ви описуєте), не є доказом того, що не існує версії такого рішення, що не має статусу.
Біллі ONeal

2
@EmilioGaravaglia ви переглядаєте стан перекладача лямбда-числення. Якщо міркувати в лямбдальному обчисленні, не потрібно міркувати про стан. Також аспект "Змінності" відрізняється.
wirrbel

1
@EmilioGaravglia: Держава в імперативному програмуванні - це конфігурація пам’яті за один раз, тут простір параметрів задається всіма можливими значеннями пам’яті, а стан - одна конфігурація за часом (смуга машини тюрінга). Під час написання програми в обчисленні лямбда не існує прямої сутності, наприклад поля пам'яті. Виконання програми - це застосування лямбда-перетворень. Проміжні кроки можуть нагадувати "стан", але вони є лише рівнозначними виразами одного і того ж значення. Нічого не змінюється під час оцінювання, вирази просто переписуються та обробляються у «простішу» форму.
wirrbel

14

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

Незалежно від того, чи маєте ви щось запам’ятати, або це залежить від того, що ви зробили, у вас є держава.

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

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

коли ви fna(fnb(x))надаєте стан fnb, що, в свою чергу, створить стан для fna. Це пов’язано з тим, що xіснує до того, як fnb викликається (так, це відбувається з власного "минулого").

Це не питання "існування держави" чи "держави не існує". Це матер "я дбаю" або "я не хочу".


0

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

Суто функціональні програми - це лише функції. Таким чином, для практичних застосувань суто функціональна програма вводить пару (old_state * present_stimulus) і виводить пару (new_state * present_response). Для очікування чергового стимулу та розповсюдження держави потрібен зовнішній, стаціонарний "лупер".

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

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


0

Ви можете уникати явного стану, що змінюється, доки вам не доведеться взаємодіяти із зовнішнім світом.

У JavaScript для того, щоб програма фактично мала ефект, ніж переймання процесорних циклів, ви повинні змінити об'єкт Dom або Window, і ці API є статними. Але я припускаю, що ви можете створити обгортку, яка передала об'єкти Dom і Window як параметри до коду JavaScript, а потім отримала новий Dom / Window як вихід. Це дозволить ізолювати код JavaScript від стану змін.

Звичайно, ви все ще покладаєтесь на стан, оскільки вікно браузера та DOM за своєю суттю. Будь-яка інтерактивна програма за своєю суттю є державною, але ви все одно можете структурувати свій код таким чином, щоб мінімізувати явний стан.

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


0

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

Ви, ймовірно, могли б це зробити, але ви використали б імена функцій як сховище. Закінчується вигуком gobblyday на зразок:

if (sm.atBegining()) sm.start() else if (sm.done()) sm.stop() ) else sm.progress()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.