Что является основой математики для значений первого / второго / третьего класса в языках программирования?

19

добавленной

Просто нашел два связанных вопроса

/math//q/1759680/1281

/programming//a/2582804/156458


В языках программирования, из прагматики языка программирования Майкла Скотта

В общем случае считается, что значение в языке программирования имеет статус первого класса, если его можно передать в качестве параметра, вернуть из подпрограммы или присвоить переменной. Простые типы, такие как целые числа и символы, являются значениями первого класса в большинстве языков программирования. Напротив, значение «второго класса» может быть передано в качестве параметра, но не возвращено из подпрограммы или присвоено переменной, а значение «третьего класса» даже не может быть передано в качестве параметра.

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

  1. Что является основой математики для значений первого / второго / третьего класса в языках программирования?

    Терминология напоминает мне логику первого / второго порядка, но связаны ли они?

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

    • передается в качестве параметра,
    • вернулся из подпрограммы, или
    • назначен в переменную.

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

Благодарю.

Тим
источник
23
Классификация значений в первый / второй класс так же бесплодна, как и классификация языков по парадигмам. Все, что вы в итоге получите, - это смутные обобщения, которые запутывают картину. Это не правильный подход к пониманию языков программирования. Важно понимать синтаксис, статику и динамику языка, но это слишком много, чтобы
упоминать их
3
Кроме того: PL / I был бы примером этикеток первого класса. В PL / I вы можете объявить переменные, напечатанные для метки, назначить им места кода и перейти к ним. Вы также можете передавать их как параметры и даже создавать их массивы.
Theraot
@Theraot: Возможно, я встречаюсь с собой, но я единственный, кто когда-либо имел дело с назначенными и вычисляемыми GOTO на Фортране? И нет, я не писал @ $%! код, я застрял переделывать его.
jamesqf
@jamesqf Мне известно о назначении меток в FORTRAN и COBOL, нет, я этим не пользовался. Я не уверен, как классифицировать этикетки там. Тем не менее, за то, что я прочитал (у меня есть руководства), PL / I выходит за рамки этого, и я убежден, что этикетки там первоклассные.
Theraot
2
Также см en.wikipedia.org/wiki/First-class_citizen
Jasmijn

Ответы:

45

Их нет, и это довольно произвольно.

Единственное полезное различие между первым классом и всеми остальными. Каждый случай, который находится в «другой» скобке, имеет свой собственный набор правил в каждом случае, и объединение их всех вместе просто не очень полезно. «Первый класс» означает «Вам не нужно искать правила», по сути, а «другой» - «Вы должны изучить правила».

Например, в C ++ отдельные функции являются значениями первого класса, если они не сохраняют состояния. Наборов перегрузки нет, но лямбды есть. В C # функции, как правило, являются первоклассными значениями, но при работе с выводом типов возникают некоторые неловкие ситуации, которые не позволяют использовать их во всех случаях.

DeadMG
источник
10
+1, хотя в контексте такой книги, как « Прагматика языка программирования», в которой сравнивается большое количество конструкций на большом количестве языков, а также подробно анализируются сходства, различия и последствия, я думаю, что этот вид сокращения может быть полезен. (Только не думайте, что другие люди поймут, что слова «подержанные» и «третьи руки» означают конкретные вещи.)
ruakh,
(Ну, где под «подержанными» и «третьими руками» я, конечно, подразумеваю «второй класс» и «третий класс». :-P)
ruakh
3
Если вы хотите торговать с использованием подержанных функций, вам лучше сделать это на языке, где функции являются гражданами первого класса. ^^
5gon12eder
@ 5gon12eder: «функции из вторых рук» - это те, которые вы вызываете из сторонних библиотек, не так ли?
jamesqf
11

Я согласен с DeadMG, важное различие между первоклассным и «всем остальным». Однако есть более знакомый способ классификации различий.

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

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

Такие языки, как C и C ++, позволяют вам получать адреса функций: хотя вы не можете их изменять, вы можете передавать функции в качестве параметров другим функциям. C ++ также имеет синтаксический сахар функторов . Идея состоит в том, чтобы создать целый объект, который, на первый взгляд, ведет себя как функция и может передаваться как данные. То, что в противном случае является значением более низкого класса, может рассматриваться как значение первого класса.

С математической точки зрения, я думаю, что лучший способ - думать об АСТ программы . Как правило, каждый токен имеет определенный тип, который может или не может быть совместим с другими типами. Подумайте о l-значении, r-значении и прочей неразберихе типов значений в C ++ . Затем добавьте ключевые слова, символы, которые являются функциями, и т. Д. Некоторые из них могут быть значениями первого, второго или третьего класса в зависимости от языка.

Я не уверен, что знание «класса» стоимости - это все, что важно, за исключением, может быть, в академической среде. В реальном мире важно знать, как вы можете передавать код, обрабатывая его как данные: функторы, лямбды / замыкания, указатели на функции и т. Д.


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

Денотационная семантика предоставляет математические основы для описания того, как значения и переменные работают в языке программирования. Это было так хорошо объяснено в моей компьютерной науке, что я получил высшую оценку на экзамене Denotational Semantics, потом забыл большую часть этого и никогда не нуждался в его использовании в течение 20 лет в качестве программиста.

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

Если вы прочтете спецификацию для большинства языков программирования, вы заметите диссидентскую нехватку денотационной семантики, однако в большинстве хорошо спроектированных языков в команде был кто-то, кто является экспертом в разработке языков программирования, поэтому хорошо понимает денотационную семантику.

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

Обратите внимание, что Майкл Л. Скотт является ведущим исследователем в области компьютерных наук, поэтому он поймет и будет очень счастлив использовать формальную математику, но, как и лучшие исследователи, он умеет объяснить применение исследования остальным из нас.

Ян
источник
Благодарю. Какие книги были использованы в вашем классе? Какие книги вы рекомендуете сейчас? Я самообучающийся
Тим
@ Тим, я учился более 20 лет назад! Я ожидаю, что книга Майкла Скотта - одна из лучших и будет охватывать больше, чем вам нужно, если вы не собираетесь проводить исследования уровня доктора философии.
Ян
3

Нет, слово «первый» в «первом классе» и в «первом порядке» означает разные вещи.

Но да, понятия «первый класс» и «первый порядок» взаимосвязаны. Они оба касаются классификации того, какие понятия, которые язык может описать, могут также абстрагироваться.

Концепция является первоклассной, если обычные механизмы абстракции языка могут абстрагироваться от этой концепции.

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

Понятие первого порядка, если его нельзя использовать для абстрагирования над собой.

Например, снова в Java, мы можем использовать методы, чтобы абстрагироваться от определенных вещей. Но мы не можем использовать методы для абстрагирования над методами, потому что имя метода не может быть передано как параметр метода. Это отличается в JavaScript, где вы можете использовать скобочную нотацию для доступа к свойству объекта по его имени в виде строки, и вы можете абстрагироваться над строками.

Концепция является вторым порядком, если ее можно использовать для абстрагирования от использования самого первого порядка, но не от использования второго порядка.

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

Концепция является третьим порядком, если ее можно использовать для абстрагирования от использования первого и второго порядка, но не от использования второго порядка.

И так далее.

Наконец, понятие более высокого порядка, если его можно использовать для абстрагирования от произвольного использования самого себя.

Описание: Если функция абстракции является первоклассной, она также имеет более высокий порядок. И если функция абстракции первого порядка, она не может быть первоклассной.

Toxaris
источник
1
Вы можете сделать List<List>на Java, хотя. Может быть, вы можете уточнить, что вы имеете в виду с этой частью?
Полигном
1
Хорошая точка зрения. Я имею в виду: class Foo<A> { A<Int> ... }. То есть я имею в виду использовать параметр универсального типа в качестве универсального класса. Затем 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функция, которая возвращает значение, которое представляет тип его аргумента.

Отрицание «первоклассного значения» в стандартной терминологии не является «первоклассным значением». Термин «ценность второго класса» обычно не используется, а «ценность третьего класса» еще меньше. Не ожидайте увидеть их за пределами этой книги. Абсолютно нет оснований для определения «второго» как «можно передать как параметр» и «третьего» как «нельзя передать как параметр», нет шкалы вещей, которая могла бы быть пронумерована по значению. Очень немногие языки имеют разницу между значениями, которые могут быть переданы в качестве параметра функциям, и значениями, которые могут быть назначены переменным, поэтому нецелесообразно определять имя для этой концепции.

Жиль "ТАК - перестань быть злым"
источник