Що є основою математики для значень першого / другого / третього класів у мовах програмування?


19

Додано

Щойно знайшли два пов’язані питання

/math//q/1759680/1281

/programming//a/2582804/156458


У мовах програмування - з Прагматики мови програмування Майкла Скотта

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

Мітки - це значення третього класу в більшості мов програмування, але значення другого класу в Algol. Підпрограми відображають найбільшу кількість варіацій. Вони є першими класовими значеннями для всіх функціональних мов програмування та більшості мов скриптів. Вони також є значеннями першого класу в C # і, з деякими обмеженнями, в декількох інших імперативних мовах, включаючи Fortran, Modula-2 і -3, Ada 95, C і C ++. 11 Вони є значеннями другого класу в більшості інших імперативних мов і значення третього класу в Ada 83.

  1. Що є основою математики для значень першого / другого / третього класів у мовах програмування?

    Термінологія нагадує мені логіку першого / другого порядку, але вони пов'язані?

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

    • передано як параметр,
    • повернуто з підпрограми, або
    • присвоюється змінній.

    Чому конкретні випадки важливі, а інші випадки не згадуються?

Спасибі.


23
Класифікація значень на перший / другий клас так само безрезультатна, як класифікація мов на парадигми. Все, що ви закінчите, - це неясні узагальнення, які заплутують картину. Це не правильний підхід до розуміння мов програмування. Що важливо - це розуміння синтаксису, статики та динаміки мови, але це занадто багато, щоб увійти в коментар
gardenhead

3
Убік: PL / Я був би прикладом етикетки як першокласного. В PL / I ви можете оголосити змінні, введені для мітки, призначити їм місця коду та перейти до них. Ви також можете передавати їх як параметри і навіть створювати їх масиви.
Тераот

@Theraot: Можливо, я зустрічаюся сам, але чи я єдиний, хто коли-небудь мав справу з призначеними та обчисленими GOTOs у FORTRAN? І ні, я не написав @ $%! код, я застряг перепрофілювавши його.
jamesqf

@jamesqf Мені відомо про присвоєння міток у FORTRAN та COBOL, ні, я цього не використовував. Я не впевнений, як класифікувати там мітки. Однак, по тому, що я читаю (у мене є посібники) PL / я виходить за рамки цього, і я переконаний, що етикетки там першокласні.
Тераот

2
Також дивіться en.wikipedia.org/wiki/First-class_citizen
Jasmijn

Відповіді:


45

Немає такого, і це досить умовно.

Єдине корисне розрізнення між першим класом та всіма іншими. Кожен випадок, що знаходиться в дужці "інший", має свій окремий набір правил у кожному випадку, і згуртовування їх усіх разом просто не дуже корисно. "Перший клас" означає "Вам не потрібно шукати правила", а "інше" - це "Ви повинні вивчити правила".

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


10
+1, хоча у контексті такої книги, як « Прагматика мови програмування», яка порівнює велику кількість конструкцій на великій кількості мов та аналізує схожість та відмінності та наслідки в глибині, я вважаю, що такий вид скорочень може бути корисним. (Тільки не ходіть навколо, не очікуючи, що інші люди зрозуміють "секонд-хенд" та "третя рука" як такі, що означають конкретні речі.)
ruakh

(Ну, де під "секонд-хендом" і "третьою рукою" я, звичайно, маю на увазі "другий клас" і "третій клас" :-P)
ruakh

3
Якщо ви хочете торгувати функціями секонд-хенду, вам краще зробити це мовою, де функції є громадянами першого класу. ^^
5gon12eder

@ 5gon12eder: "Функції секонд-хенду" були б тими, кого ти дзвониш із сторонніх бібліотек, ні?
jamesqf

11

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

Значення першого класу - це дані, інші - код. (грубо кажучи: я впевнений, що є винятки. Але це дійсно гарне наближення, яке стосується мов реального світу.)

У деяких мовах ви можете розглядати код як дані. Функціональні мови відомі цим: деякі з них дозволяють вам змінювати код програми під час її запуску (основа генетичного програмування ).

Такі мови, як C і C ++, дозволяють приймати адресу функцій: хоча ви не можете їх змінити, ви можете передавати функції як параметри іншим функціям. C ++ також має синтаксичний цукор функторів . Ідея полягає в тому, щоб створити цілий об’єкт, який на поверхні, схоже, поводиться як функція і може передаватися навколо, як би це дані. Що інакше значення нижчого класу, можна трактувати як значення першого класу.

Математично я вважаю, що найкращий спосіб - це продумати AST програми . Зазвичай кожен маркер має певний тип, який може бути або не сумісний з іншими типами. Подумайте l-значення, r-значення та інші цілі безладні типи значень у C ++ . Потім додайте до ключових слів, символів, які є функціями тощо. Деякі з них можуть бути значеннями першого, другого чи третього класів залежно від мови.

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


2
Приклад значення без коду, що не є першокласним: Lua має спеціальну ..."змінну", що використовується для позначення параметрів функції vararg. Ви можете використовувати його в багатьох виразах, як якщо б це був список цінностей (наприклад, print(...)або local args = {...}), але є деякі речі, з якими ви не можете зробити, наприклад, посилайтесь на нього у закритті ( function(...) return function() return ... end end).
Полковник тридцять два

8

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

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

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

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

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


Спасибі. Які книги використовували у вашому класі? Які книги ви зараз рекомендуєте? Я самоучок
Тім,

@Tim, я робив свій клас понад 20 років тому! Я очікую, що книга Мішель Скотт є однією з найкращих і охопить більше, ніж вам потрібно, якщо ви не збираєтеся робити дослідження рівня PHd.
Ян

3

Ні, слово "перше" в "першокласному" і в "першому порядку" означає різні речі.

Але так, поняття "першокласний" і "перший порядок" пов'язані між собою. Вони обидва стосуються класифікації того, які поняття, якими може описуватись мова, також можуть бути абстрактними.

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

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

Поняття є першим порядком, якщо його не можна використовувати для абстрагування над собою.

Наприклад, знову ж таки на Java ми можемо використовувати методи для абстрагування певних речей. Але ми не можемо використовувати методи для абстрагування над методами, оскільки ім'я методу не може бути передано як параметр методу. Це відрізняється від JavaScript, де ви можете використовувати позначення дужок для доступу до властивості об'єкта за його назвою у вигляді рядка, а ви можете абстрагуватися над рядками.

Концепція є другого порядку, якщо її можна використовувати для абстрагування над використанням першого порядку, але не над використанням другого порядку.

Наприклад, у Java ви можете використовувати Generics для абстрагування над типами (як у class Foo<T> { public List<T> content; }). Однак ви не можете використовувати дженерики для абстрагування над Generics (як в class Bar<T> { public T<Int> content; }). У Scala це різне.

Концепція - це третій порядок, якщо її можна використовувати для абстрагування над власним використанням першого порядку та другого порядку, але не над використанням другого порядку.

І так далі.

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

Резюме: Якщо функція абстракції є першокласною, вона також є вищого порядку. І якщо функція абстракції є першим порядком, вона не може бути першокласною.


1
Однак ви можете робити List<List>на Java. Може, ви зможете уточнити, що ви маєте на увазі під цією частиною?
Полігном

1
Гарна думка. Я маю в виду: class Foo<A> { A<Int> ... }. Тобто я маю на увазі використовувати параметр generic типу як загальний клас. Тоді Foo<List>б створити екземпляр A<Int>в List<Int>. У Java це неможливо. Спробую це відредагувати у відповідь пізніше.
Токсаріс

Дійсно, це неможливо.
Полігном

Я тепер замінив оманливий List<List>приклад. Дякуємо, що вказали на проблему, @Polygnome.
Токсаріс

@Toxaris Я думаю, що це просто ідіосинкратична термінологія, яку ти сам склав. "Концепція" - це не першого або другого порядку, це логічний кількісний показник.
Майлз Рут

2

Що є основою математики для значень першого / другого / третього класів у мовах програмування?

Жодного, що мені відомо.

Термінологія нагадує мені логіку першого / другого порядку, але вони пов'язані?

Не зовсім.

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

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

Чому конкретні випадки важливі, а інші випадки не згадуються?

Вам доведеться попросити автора у остаточної відповіді.

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


2

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

Наприклад, майже в кожній мові програмування машинні цілі числа обмеженого розміру (наприклад, 8-бітні цілі числа, або 32-бітні цілі числа, або 64-бітні цілі числа тощо) є значеннями першого класу. Ви можете зберігати їх у змінних, передавати їх і повертати їх до функцій і т. Д. У більшості мов, але не на мовах низького рівня, таких як збірка та C, рядки - це значення першокласного - але в C вони не є, ви тільки отримати покажчики на рядки. У C рядки та масиви не є першокласними значеннями: наприклад, ви не можете передавати масив функції, ви не можете призначити масив змінної масиву тощо. В C функції не є першокласними значеннями або: Ви не можете зберігати функцію у змінній, а лише вказівник на функцію. Навпаки, рядки та функції - це першокласні значення у більшості мов програмування високого рівня: ви можете зберігати їх у рядку тощо.

Прикладом концепції, яка не є першокласною для багатьох мов програмування, розроблених для компіляції, є типи. У такій мові, як C або Java, типи живуть під час компіляції, ви не можете ними маніпулювати за допомогою мовних конструкцій. (У Java також є система динамічного типу, заснована на класах; класи - це значення першого класу через відображення.) На відміну від мови, як Python, є typeфункція, яка повертає значення, що представляє тип його аргументу.

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

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