Для чого потрібне ключове слово rec у F #?


28

У F # необхідно використовувати recключове слово. У Haskell немає необхідності чітко вказувати, чи є дана функція рекурсивною чи ні.

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

Відповіді:


16

Існує властива різниця в семантиці Haskell і F #. У Haskell виклик функції не виконує жодного реального обчислення, але виділяє об'єкт купи, відомий як 'thunk'. Це абсолютно добре, щоб грудка мала посилання на себе чи інший грудок. Однак у F # виклик функції - це фактичний виклик, роблячи вирази let x = 1 : 2 : x in xнедійсними - так, як це потрібно xпобудувати до того, як 1 : 2 : xбуде побудовано. Однак це все-таки більш-менш розумне визначення для нескінченного списку, певний спосіб його визначення повинен існувати. Тут криються коріння для rec. Якщо ви хочете більше, шукайте та читайте оперативні семантики для SML та Haskell - це інакше.


2
AFAIK, Haskell цілеспрямовано не має оперативної семантики.
dan_waterworth

@dan_waterworth неможливо скласти без визначеної оперативної семантики.
пермеакра

8
Мова Haskell не визначає оперативної семантики, а натомість забезпечує денотаційну семантику. Коли ви створюєте компілятор, оперативна семантика неявно визначена, але це не означає, що вона є частиною мовного стандарту Haskell.
dan_waterworth

6
@dan_waterworth На практиці існує лише одна реалізація та стандарт мови Haskell: ghc, а також є лише один стандарт F #: реалізація цього Microsoft. Тож теоретично ви можете мати рацію, але практика - зовсім інший звір.
пермеакра

19

На це запитання дано відповідь на SO , і воно містить деякі сильні історичні передумови, чому використовується "rec".

Ось важлива цитата для нащадків:

У французькій сім'ї мов CAML (включаючи OCaml) функції за замовчуванням не є рекурсивними. Цей вибір дозволяє легко замінити визначення функцій (та змінних), використовуючи let у цих мовах, тому що ви можете посилатися на попереднє визначення всередині нового пункту визначення. F # успадкував цей синтаксис від OCaml.


12

Рекурсивна letвизначає значно складнішу семантику, ніж звичайна. Тому, для простоти та чистого дизайну мови, є вагомий привід мати і те, і інше, як роздільне let, let*і letrecв схемі.

Простий let x = y in zеквівалент ((fun x -> z) y). Рекурсивний випуск набагато складніше і може включати використання комбінатора з фіксованою точкою.

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