Что такое компьютерный язык программирования?

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

Какое полезное определение языка компьютерного программирования и каковы его основные и необходимые компоненты? Каковы ключевые особенности, которые различают языки (функциональные, императивные, декларативные, объектно-ориентированные, сценарии и т.д.)?

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

Связано с Tangential, что это касается компьютерных языков, которые позволяют другим языкам существовать? Например, возьмите язык сценариев, такой как Javascript, Perl или PHP. Я полагаю, что часть определения состоит в том, что на каком-то уровне есть интерпретатор, наиболее вероятно реализованный на C или С++. Можно ли написать интерпретатор для Javascript в Javascript? Это требование для полного языка? То же самое для Perl, PHP и т.д.?

Я был бы доволен списком понятий, которые можно искать или исследовать дальше.

Ответ 1

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

Какое полезное определение языка компьютерного программирования и каковы его основные и необходимые компоненты?

Я бы сказал, что определяющая характеристика языка программирования такова: вещи, написанные на этом языке, в конечном итоге должны быть преобразованы в что-то, что выполняется. Таким образом, псевдокод, хотя, возможно, имеет структуру и строгость языка программирования, на самом деле не является языком программирования. Аналогично, UML может выражать множество мощных идей абстрактным образом, как это может быть в языке программирования, но он не подходит, потому что люди обычно не пишут UML для выполнения.

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

Даже если слово "язык программирования" не было частью общего словаря группы, с которой я разговаривал, я думаю, что для других было бы очевидно, что нам нужен способ общения с компьютером. Так же, как никто не ожидает, что автомобиль прогонит себя (пока!) Без внешних инструкций в форме взаимодействия с рулевым колесом и педалями, никто не может ожидать, что аппаратное обеспечение будет функционировать, не сказав, что делать. Как отмечалось выше, язык программирования является каналом, через который мы можем сделать это общение.

Связано с Tangential, что это касается компьютерных языков, которые позволяют другим языкам существовать?

Все полезные языки программирования имеют свойство, называемое полнотой Тьюринга. Если один язык из набора Тьюринга может что-то сделать, то любой из них может; они считаются вычислительно эквивалентными.

Однако только потому, что они одинаково "мощные", это не значит, что они одинаково хороши для людей. Вот почему многие люди готовы пожертвовать беспрецедентным микроуправлением, которое вы получаете от написания ассемблерного кода, в обмен на выразительность и мощь, которые вы получаете с языками более высокого уровня, такими как Ruby, Python или С#.

Можно ли написать интерпретатор для Javascript в Javascript? Это требование для полного языка? То же самое для Perl, PHP и т.д.?

Так как на C есть написанный на Javascript интерпретатор, из него следует написать Javascript-интерпретатор в Javascript, так как оба являются Turing-complete. Однако, опять же, обратите внимание, что Тьюринг-полнота ничего не говорит о том, как трудно что-то делать на одном языке по сравнению с другим - только с самого начала. Ваш Javascript-интерпретатор внутри JavaScript может быть ужасно неэффективным, потреблять абсурдные объемы памяти, требовать огромной вычислительной мощности и быть ужасно уродливым взломом. Но Turing-полнота гарантирует, что это можно сделать!

Ответ 2

Хотя это прямо не отвечает на ваш вопрос, мне напомнили о том, что Павел Грэхем о развитии эволюции " Revenge of the Nerds языки программирования. Это, безусловно, интересное место для начала вашего расследования.

Ответ 3

Слегка длинный рывок вперед.

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

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

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

Например:

Сделай мне кофе.

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

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

Мы знаем все эти определения наизусть, но мы должны были изучить их в какой-то момент.

Таким же образом компьютер может "учиться" также "понимать" слова.

Coffee::make()->giveTo($me);

Это может быть вполне допустимое выражение на компьютерном языке. Если компьютер "знает", что означает Coffee, make() и giveTo(), и если $me определено. Он выражает ту же идею, что и английское предложение, только с другим, более строгим синтаксисом.

В другой среде вы должны сказать немного разные вещи, чтобы получить тот же результат. На японском языке, например, вы, вероятно, сказали бы что-то вроде:

コ ー ヒ ー を 作 っ て も ら っ て も 良 い で す か?
Kōhī o tsukuttemoratte mo ii desu ka?

Что грубо перевести на:

if ($Person->isAgreeable('Coffee::make()')) {
    return $Person->return(Coffee::make());
}

Такая же идея, тот же результат, но подразумевается $me, и если вы не проверяете isAgreeable, сначала вы можете получить ошибку времени выполнения. В компьютерных терминах, которые были бы несколько похожи на поведение Ruby, возвращали результат последнего выражения ( "грамматическая функция" ) и сначала проверяли доступную память (экологическая необходимость).

Если вы разговариваете с очень медленным человеком с небольшим лексиконом, вам, вероятно, придется объяснять вещи намного подробнее:

Идите на кухню.
Возьмите банк.
Заполните горшок водой.
...

Как и Ассемблер.: О)

Во всяком случае, суть в том, что язык программирования на самом деле является языком, подобным человеческому. Их синтаксис отличается и специализирован для проблемной области (логика/математика) и "слушателя" (компьютеров), но они просто способы переноса идей и концепций.

EDIT:
Еще один момент о "оптимизации для слушателя" заключается в том, что языки программирования пытаются устранить двусмысленность. Пример "сделай меня кофе" можно, технически, понимать как "превратить меня в кофе". Человек может сказать, что означает интуитивно, компьютер не может. Следовательно, в языках программирования все обычно имеет только одно и одно значение. Там, где это не так, вы можете столкнуться с проблемами, в качестве примера используется обычный оператор + "в Javascript.

1 + 1     -> 2
'1' + '1' -> '11'

Ответ 4

Не определение, но я думаю, что в языках программирования есть по существу две направления развития:

  • Те, кто работает над тем, что машина может сделать с чем-то более выразительным и менее привязанным к машине (Assembly, Fortran, C, С++, Java,...)

  • Те, кто сходит с математической или теоретической теории вычислительной техники, вычисляет что-то реализуемое на реальной машине (Lisp, Prolog, ML, Haskell,...)

Конечно, на самом деле картина не такая аккуратная, и обе нити влияют друг на друга, заимствуя лучшие идеи.

Ответ 6

Интересно.

Я бы сказал, что определяющей чертой языка программирования является способность принимать решения на основе ввода. Эффективно, if и goto. Все остальное - много и много синтаксического сахара. Это идея, которая породила Brainfuck, что на самом деле замечательно забавляет (пытается) использовать.

Есть места, где линия размывается; например, я сомневаюсь, что люди подумают, что XSLT действительно является языком программирования, но это Turing-complete. Я даже решил проблему Project Euler с ней. (Очень, очень медленно.)

Приходят в голову три основных свойства языков:

  • Как это работает? Скомпилирован ли он голым металлом (C), скомпилированным в основном голосом с некоторым просмотром времени выполнения (С++), запуском на виртуальной машине JIT (Java,.NET), интерпретируемой байт-кодом (Perl) или чисто интерпретируемой (uhh.. )? Это не сильно комментирует сам язык, но говорит о том, насколько переносимым может быть код, какую скорость я могу ожидать (и, следовательно, какие широкие классы задач будут работать хорошо), а иногда и насколько гибким является язык.
  • Какие парадигмы он поддерживает? Процедурный? Функциональная? Является ли стандартная библиотека построена с помощью классов или функций? Есть ли отражение? Есть ли, в идеале, поддержка для всего, что я хочу сделать?
  • Как я могу представить свои данные? Существуют ли массивы, и они фиксированные или нет? Насколько легко использовать строки? Существуют ли встроенные структуры или хеши? Что такое система типа? Есть объекты? Являются ли они основанными на классах или основанными на прототипе? Все ли объект или есть примитивы? Могу ли я наследовать от встроенных объектов?

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

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

Да, вы можете написать интерпретатор Javascript в Javascript или интерпретатор Python в Python (см. PyPy) или интерпретатор Python в Javascript. Такие языки называются самообслуживания. Взгляните на Perl 6; с самого начала это было целью его основной реализации.

В конечном счете все просто нужно перевести на машинный код, не обязательно C. Вы можете написать D или Fortran или Haskell или Lisp, если хотите. C просто старый стандарт. И если вы напишете компилятор для языка Foo, который в конечном итоге выплюнет машинный код любым способом, вы можете переписать этот компилятор в Foo и пропустить посредника. Конечно, если ваш язык чисто интерпретируется, это, вероятно, приведет к переполнению стека...

Ответ 7

Человеческое выражение, которое:

  • описывает математические функции
  • позволяет включать и выключать компьютер.

Ответ 8

Этот вопрос очень широк. Мое любимое определение заключается в том, что язык программирования является средством выражения вычислений

  • Точно
  • На высоком уровне
  • Мы можем рассуждать о них

Вычислением я имею в виду то, что означало Тьюринг и Церковь: машина Тьюринга и лямбда-исчисление имеют эквивалентную выразительную силу (что является теоремой), а гипотеза Церкви-Тьюринга (что является догадкой) говорит примерно о том, что нет более сильных понятие вычисления там. Другими словами, виды вычислений, которые могут быть выражены в любых языках программирования, в лучшем случае являются видами, которые могут быть выражены с помощью машин Тьюринга или программ лямбда-исчисления &mdash, а некоторые языки могут выражать только подмножество этих вычислений.

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

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

Выражение вычислений на высоком уровне - это то, что программирует langauges. Важной причиной того, что существует так много разных языков программирования, является то, что существует множество различных способов понимания проблем на высоком уровне. Часто, если у вас есть важный новый класс проблем для решения, вам может быть лучше всего создать новый язык программирования. Например, написание Ларри Уолл предполагает, что решение класса проблем под названием "системное администрирование" было мотивом для его создания Perl.

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

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

  • Изменение a[i] не может повлиять на значение a[i-1].

Мой ученик также применил принцип рассуждения, который недействителен в C:

  • Сумма целых чисел без знака будет не меньше, чем любое целое число в последовательности.

Это не верно в C, потому что сумма может переполняться. Одна из причин, по которой некоторые программисты предпочитают такие языки, как Standard ML - это то, что в SML этот принцип рассуждений всегда действителен. Из широко используемых языков, вероятно, у Haskell есть самые сильные принципы рассуждений. Ричард Берд разработал экваториальные рассуждения о программах с высоким искусством.


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

Ответ 9

Одна вещь, которую многие типы "ИТ" забывают, состоит в том, что существуют два типа языков компьютерного программирования:

  • Языки программирования программирования: C, Java, Perl, COBAL и т.д.

  • Языки аппаратного обеспечения: VHDL, Verilog, System Verilog и т.д.

Ответ 10

Как друг научил меня компьютерным языкам, язык - это мир. Мир общения с этой машиной. Это мир для реализации идей, алгоритмов, функциональности, описанных Алонзо и Аланом. Это технический эквивалент математических структур, которые создали вышеупомянутые ученые. Это язык с эпрессами, а также пределы. Однако, как сказал Людвиг Витгенштейн, "пределы моего языка означают пределы моего мира", всегда существуют ограничения и то, как он выбирает язык, который лучше подходит для его потребностей.

Это общий ответ... некоторые мысли на самом деле и меньше ответа.