Что такое конструкция программирования первого класса?

При попытке сделать что-то достаточно продвинутое в С# (вроде какого-то взлома) возникает понятие "первого класса".

Например, метод представляет собой конструкцию программирования первого класса, потому что вы можете делать с ней xyz (xyz - это не то, что делает этот метод, но то, что дает вам общий метод, я не могу вспомнить, что такое xyz) но в .NET 1.1 делегаты не могли быть переданы в методы, потому что они не были конструкциями программирования первого класса (я читал что-то в этих строках).

Что такое конструкция программирования первого класса?

Спасибо

Ответ 1

Я подозреваю, что вы не найдете формального определения Очевидно, что Jörg W Mittag нашел один:)

Учитывая это формальное определение, остальная часть моего ответа - это просто мое понимание этого в то время. Разумеется, все, кто использует термин "первоклассная конструкция", означает, что одно и то же - это другой вопрос.

Способ определить, является ли что-то "конструкцией первого класса" или нет, это спросить себя что-то вроде этого:

Поддерживается ли функция и тщательно интегрированы с остальной частью языка, или есть много ненужные ограничения, которые дают создается впечатление, что это просто "болтаться", возможно, один конкретный вариант использования без учета других областей, где конструкция может быть действительно полезной если бы это было более полно "частью язык"?

Как вы можете видеть, это определенная серая область:)

Делегаты на С# - хороший пример. В С# 1 вы могли передавать делегаты в методы, и было много способов, с помощью которых они были хорошо интегрированы в язык (такие вещи, как доступные преобразования, обработка событий, + = и - = перевод делегата .Combine/Remove). Я бы сказал, что они были конструкциями первого класса. Однако это не противоречит тому факту, что делегаты чрезвычайно сильно выиграли от С# 2 и 3, с анонимными методами, неявными преобразованиями групп методов, лямбда-выражениями и ковариацией. Они, вероятно, больше представляют собой конструкцию первого класса... и хотя я бы сказал, что они были "первоклассниками" на С# 1, я мог понять, почему кто-то может не согласиться.

Аналогичный случай может быть сделан для IEnumerable. В С# 1.0 он поддерживался foreach, но цикл foreach не удалял IEnumerator в конце. Эта часть была исправлена ​​в С# 1.2, но для использования IEnumerable s была только поддержка языка, не создавая их. С# 2.0 предоставили блоки итератора, которые делают тривиальным реализацию IEnumerable (и его общий эквивалент). Означает ли это, что понятие последовательной последовательности не является конструкцией "первого класса" в С# 1.0? Дискуссионный, в основном...

Ответ 2

Понятие "первоклассный гражданин" или "первоклассный элемент" в языке программирования было введено британским ученым-компьютерщиком Кристофером Стрейчи в 1960-х годах в контексте первоклассного функции. Наиболее известная формулировка этого принципа, вероятно, содержится в Структуре и интерпретации компьютерных программ (незадолго до Exercise 1.40) Джеральда Джея Суссмана и Гарри Абельсона:

  • Они могут быть названы переменными.
  • Они могут быть переданы в качестве аргументов процедур.
  • Они могут быть возвращены в результате процедур.
  • Они могут быть включены в структуры данных.

По сути, это означает, что вы можете делать с этим элементом языка программирования все, что вы можете делать со всеми другими элементами в языке программирования.

Ответ 3

Что такое конструкция программирования первого класса?

Что-то является конструкцией первого класса, если язык поддерживает его способом, аналогичным другим типам объектов.

Например, в С++ функции не считаются первоклассными конструкциями: вы можете создавать другие объекты во время выполнения, но вы не можете создавать новые функции. Напротив, в С# 3 и более поздних функциях, вероятно, будут считаться первоклассные конструкции с введением lambdas/анонимных функций.

Как и во многих других вещах, это, естественно, субъективное определение. Википедия хорошее резюме для более конкретных примеров, а также C2.

Ответ 5

Мое понимание конструкции программирования первого класса заключается в том, что это означает, что вы можете делать то, что бы это ни было, наилучшим образом, без необходимости делать две или три других вещи, или объединить две или три другие концепции.

Таким образом, Java не имеет первоклассной поддержки закрытия. Мы можем несколько подделать его, построив класс (используя другое понятие), который поддерживает почти все материалы, которые вы используете для закрытия, а затем создаете экземпляры этого класса (другое понятие) или анонимно расширяете этот класс (еще одно понятие).

То же самое с "функциями". В Java у вас не может быть функций, но у вас могут быть статические методы, которые аналогичны, но все еще отличаются.

Один (а не я) мог также утверждать, что поддержка дженериков Java не является первым классом, потому что это библиотека взлома и на самом деле не "на" языке. Это означает, что некоторые из вещей, которые вы можете сделать в С# с дженериками, которые вы не можете сделать в Java.

Ответ 6

Что такое конструкция программирования первого класса?

Простой ответ: это то, что поддерживает все стандартные операции, которые предоставляет язык. На объектно-ориентированном языке конструкции первого класса, как и следовало ожидать, являются объектами. Оказывается, на таких языках часто, по соображениям эффективности или наследия, граждане второго сорта, обычно примитивные типы данных, которые не являются надлежащими объектами и для которых вы не можете делать определенные вещи.

Например, в Java Point является полноценным объектом. Вы можете объявить

List<Point> plist;

а затем поместите в него точки. Int не является полноценным объектом. Есть определенные вещи, которые вы не можете сделать с помощью подкласса из него, например, или вызывать методы на нем, кроме определенных предопределенных операторов. Также вы не можете сохранить его в

List<int> intlist;

У Java есть проблема для этой проблемы в том, что существует тип "boxed", Integer, который является полноценным объектом. Например, вы можете объявить List<Integer>. Однако использование Integer гораздо менее эффективно, чем при использовании "int". Java обеспечивает автоматический бокс и распаковку (то есть преобразование) типа Integer в int и обратно в контекстах, где тот или иной требуется, чтобы помочь программисту объединить лучшее из обоих миров.

Имея два типа: Integer и int - для целочисленного числа, это сбивает с толку и что-то вроде взлома. Ранняя версия Java, как мне сказали, не имела примитивов, и все ее типы были полнофункциональными объектами. Это оказалось слишком медленным для его предполагаемого использования (ранняя Java, конечно же, была медленной!), Поэтому были добавлены некоторые примитивы, которые не поддерживали правильную объектную семантику.

в .NET 1.1 делегаты не могли быть переданы в методы, потому что они не были конструкциями программирования первого класса (я читал что-то в этих строках).

Я ничего не знаю о .NET, но кажется, что у вас есть идея. Вы правы - если делегаты не могут быть переданы в методы, подобные любому другому стандартным объектам, они не являются конструкциями программирования первого класса.