Чи є дублікат синтаксису для визначення названих функцій невірним дизайнерським рішенням?


9

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

У мене виникла проблема дизайну, оскільки моя мова не розрізняє функції, визначені за допомогою defсинтаксису (методи класу), і анонімні функції, призначені значенням (створеним за допомогою =>) - це усуває відмінності як в реалізації, так і в поведінці .

Результат полягає в тому, що наступні два визначення означають те саме:

def square(x: Int) = x*x

val square = (x: Int) => x*x

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

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

Я вважаю за краще це рішення, тому що воно дозволяє робити короткі та інтуїтивні визначення методів та названих функцій (через def), а також короткі визначення анонімних функцій (за допомогою =>).

Edit: Scala робить відмінність між ними - анонімної функцією не є таким же , як методи , визначених з defв Scala. Однак відмінності порівняно тонкі - дивіться пости, які я пов’язував раніше.


However, assigning existing functionsначебто пропущено кінець речення
Ізката

1
Чи можете ви визначити рекурсивні функції, використовуючи valпозначення?
Джорджіо

2
Я переконався, що це можливо і в Scala. У SML це не так, і ви повинні використовувати funдля визначення рекурсивної функції.
Джорджіо

3
Друга форма насправді не є особливою синтаксичною структурою, до речі def. Це лише побічний ефект того факту, що анонімна функція, скажімо, (x : Int) => x + 1є об'єктом, а об'єкти можна присвоювати значенням val f = .... Мовним дизайнерам довелося б піти з шляху, щоб заборонити синтаксис. Це не зовсім те саме, що явно докладати зусиль для підтримки двох різних синтаксисів, які роблять (приблизно) те саме.
KChaloux

3
Основна перевага мовою зробити щось більше, ніж один спосіб - це прекрасний спосіб розпочати непродуктивні релігійні дебати, які відволікають від реальних проблем (
думаючи

Відповіді:


3

Я думаю, що наявність двох конструкцій, які означають одне й те саме, але виглядають по-різному, повинна бути зведена до мови мінімум. Будь-яке дублювання збільшує, наскільки складно читати (і, таким чином, писати / змінювати код на) вашій мові. Усунення всіх дублювань неминуче мовою, яка може створювати довільні конструкції (наприклад, еквівалентність ітерації проти рекурсії).

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

Насправді, ви можете застосовувати цей принцип не тільки до названих функцій, але до будь-якої функції. Чому є якась різниця у визначенні названих функцій та анонімних функцій? У Лімі , функції завжди визначаються наступним чином: fn[<arguments>: <statements>]. Якщо ви хочете, щоб бути « під назвою» ви можете привласнити його змінної: var x = fn[<arguments: <statements>], і якщо ви хочете , щоб передати його в інший функції анонімно: function[fn[<arguments: <statements>]]. Якщо ви хочете, щоб вона була піднята, зробіть її постійною const var x = fn[<arguments: <statements>]. Єдина форма дає зрозуміти, що вони означають те саме.


Це досить цікаво, що constвикликає підйом, але це має ідеальний сенс. У JS function myFuncвикликає підйом, але var myFunc =це не так, що, можливо, трохи інтуїтивно зрозуміло, оскільки вони поводяться майже однаково інакше.
mpen

1
@mpen Так, насправді javascript по суті робить те саме. function fnName()...форма робить насправді створити константу, яка є те , що робить вантажопідйомним дійсну річ , щоб зробити з ним. Javascript робить речі досить заплутаними, коли ви використовуєте форму, var fn = function anotherFnName()...оскільки це робить ім'я anotherFnName не піднімаючим, навіть тому, що його явно постійним.
BT

2

Те, що ви опублікували, є дійсним шкалою та працює чудово.

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


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

2

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

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

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

Деталі

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