Коли функцію вважають громадянином першого класу на мові / платформі програмування?


61

Я неодноразово бачив заяви на зразок: "Будь ласка, зробіть цю функцію громадянином першого класу на такій мові / платформі". Наприклад, мова йде про перерахунки в C # /. Net. Отже, коли функція вважається "громадянином першого класу" мовою / платформою програмування?

Відповіді:


40

Визначення

Об'єкт є першокласним, коли він:

  • може зберігатися у змінних та структурах даних
  • може бути переданий як параметр підпрограмі
  • може бути повернуто в результаті підпрограми
  • може бути побудований під час виконання
  • має внутрішню ідентичність (незалежно від будь-якого імені)

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

http://en.wikipedia.org/wiki/First_class_object


1
Отже, що змушує об’єкти другого класу в .net / C #?
Гульшан

7
@Gulshan - ви можете аргументувати відсутність внутрішньої ідентичності - перерахунки C # - це в основному синтаксичний цукор (тобто "задане ім'я") для цілого значення. Порівняйте з Java, де енюми - це об'єкти самі по собі.
mikera

@mikera, в .NET перерахунки самі по собі є значеннями. Java просто не має жодних значень, лише об’єкти, це єдина різниця.
SK-логіка

@mikera: Хоча це не дозволяє перелікам Java мати деякі приємні властивості, такі як можливість представляти бітові поля з ними. Хоча їх реалізація, ймовірно, першокласна, у більшості їх API все ще є безліч цілих (або рядкових) констант, і багато застосувань їх не можна легко замінити перерахунками.
Джой

Я не думаю, що перерахунки можуть бути побудовані під час виконання. Я думав, що вони завжди були константами.
travis

33

Поняття «першокласний громадянин» або «елемент першого класу» мовою програмування було введено британським вченим-комп’ютером Крістофером Страчі в 60-х роках у контексті функцій першого класу. Найвідоміше формулювання цього принципу, ймовірно, у структурі та інтерпретації комп’ютерних програм Джеральда Джея Суссмана та Гаррі Абелсона:

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

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

Вся справа в "рівних правах": ви можете зробити все вищезазначене, скажімо, цілими числами, то чому б будь-яка інша річ відрізнялася?

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

Наприклад, оператори Java та методи Java мають подібний вид. Ви можете визначити нові методи, ви можете (дещо) вільно вибирати назви власних методів, ви можете переосмислити методи, ви можете перевантажувати методи. Джеймс Гослінг може все це зробити і з операторами, але ви і я не можете. Я маю в виду, всупереч поширеній думці, Java робить перевантаження оператора підтримки: наприклад, +оператор перевантажений byte, short, int, long, float, doubleі String, і IIRC в Java 7 також BigIntegerі BigDecimal(і , можливо, пара я забув), це просто , що вамне мають на це ніякого впливу. Це явно робить операторів другим класом згідно з цим другим визначенням. Зауважте, що методи все ще не є першокласними об'єктами згідно першого визначення. (Це робить операторів третім класом?)


6

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


Що робить клас громадянином першого класу в c ++?
Bjarke Freund-Hansen

2
@bjarkef: Схоже, на це вже відповіли відповідність опису, запропонованому в попередніх реченнях.
doppelgreener

@Jonathan: Так, вибачте, я неправильно прочитав "сконструювати їх під час виконання". Так, ви можете побудувати екземпляр класу під час виконання (об’єкт), але не сам клас. Саме це мене бентежило.
Bjarke Freund-Hansen

1
Проходження по параметру все ще недостатньо. У C / C ++ я все одно вважаю функції громадянами другого класу. Вони можуть передаватися як параметри, повертатися як результати, розміщені всередині інших об'єктів. Але ними не можна маніпулювати без допомоги інших конструкцій (наприклад, std :: bind потрібно прив’язувати параметри до функції).
Мартін Йорк

@Martin Я ніколи не говорив, що функціонують громадяни першого класу в C / C ++.
Pemdas

1

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

Приклад:

В C / C ++ я не вважаю функції громадянами першого класу (можуть інші).
Це тому, що існують способи маніпулювання функціями, які підтримуються безпосередньо мовою, але вимагають використання інших мовних функцій. Прив’язування параметрів до функції не підтримується безпосередньо, і ви повинні створити функтор для реалізації цієї функції.


1
Хіба це не зробить зв'язані функції (або "закриття") не першокласними, тоді як самі функції є? Яким чином підтримка 0x для закриття враховує ваш аналіз?
Фред Нурк

@Fred Nurk: Все залежить від мови. У деяких мовах закриття є першокласними системами. В інших ні. Я ще недостатньо знайомий із C ++ 0x, щоб зробити явний коментар.
Мартін Йорк

Скажімо, мова - або C, або C ++ (але не 0x), як у вашій відповіді. Невже ваше визначення поняття "першокласний" зробить пов'язані функції (або "закриття") не першокласними, тоді як самі функції є?
Фред Нурк

@Fred Nurk: Якщо ви обмежите єдине, що ви можете зробити з функцією - це зробити їх закриттям, то обов'язково. Але для мене це як би сказати, якщо платформа підтримує додавання цілих чисел лише імпортом бібліотеки. Тоді цілі числа є громадянами першого класу, але додавання цілих чисел не розглядається. На мій погляд, закриття - це операція, яку можна виконувати над функцією, яка ефективно повертає нову функцію (але це залежить від того, як ви її визначаєте). Але закриття та прив'язка - це лише дві операції, скільки інших ми виключаємо з обговорення (я не впевнений, що це було питання).
Мартін Йорк

@Martin: Я не повинен чітко пояснювати себе. З огляду на те, що "функція є громадянином першого класу, якщо вона реалізована виключно мовою", то функції як в C, так і в C ++ реалізуються виключно мовою, і тому вони будуть першокласними. Зв'язані функції (які також можна назвати "закриттями") - це те, про що ви говорите із параметрами прив'язки тощо, але це інша особливість.
Фред Нурк

-1

Щоб додати приклад до вже наданих відповідей:

У WCF / C # вам в даний час потрібно позначити об’єкт класу атрибутом договору про надання послуги, щоб він працював як послуга. Немає такого поняття, як:

public **service** MyService (in relation public **class** MyClass). 

Клас - це громадянин першого класу в c #, де служби немає.

Сподіваюся, це допомагає

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