Бесполезная диссертация, ищущая определение

В настоящее время, независимо от того, являетесь ли вы программистом или нет, вы наверняка слышали о программировании. Возможно, вы даже задавались вопросом: что такое язык программирования?

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

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

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

Язык программирования — это любой набор правил, который преобразует строки или графические элементы программы […] в различные виды вывода машинного кода.

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

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

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

Другими словами, способ давать инструкции компьютеру. Что мне не нравится в этом определении, так это использование слова «используются». Мы исправим это позже.

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

Но, подождите, я слышал о концепции алгоритма…

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

Мммм. Наиболее склонные к лингвистике читатели возразят, что последняя формулировка не обязательно эквивалентна нашему общему определению. Чтобы понять причину, давайте рассмотрим, что такое алгоритм:

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

и вернемся ненадолго к нашему общему определению: мы сразу понимаем, что высказывание «сделай мне чашку кофе» можно считать программой согласно ему (представьте, что ваш компьютер умеет варить кофе). Дьявол здесь прячется в слове «конкретный»: если сказать просто «кофе» недостаточно для обозначения конкретного предмета, наше предложение даже не программа, иначе оно есть!

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

Дело в том, что алгоритм должен быть однозначным в отношении атомарных действий, необходимых для его выполнения: если бы приготовление кофе было известной стандартной процедурой для каждого компьютера, наш запрос также идентифицировал бы алгоритм. Реальность такова, что если вам посчастливилось иметь компьютер, который готовит кофе, то макроскопическое действие было реализовано в нем с помощью некоего алгоритма, состоящего из более простых действий, таких как «переместить руку в определенном направлении», «взять чашку». и так далее. И эти небольшие действия в дальнейшем реализуются с помощью еще более простых действий, таких как «активировать 2-й двигатель на 0,1 с» и т. д., которые можно понять из схем на оборудовании.

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

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

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

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

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

И последнее соображение: согласно этому самому последнему определению почти все может быть (потенциально) языком программирования. Нам просто нужно построить подходящую среду, которая переводит наши вещи на машинный язык, чтобы в конце у нас была недвусмысленная инструкция для процессора. Это меня не беспокоит. В конце концов, существует огромное множество языков программирования, и многие из них изобретаются каждый год (https://en.wikipedia.org/wiki/List_of_programming_languages), чтобы продемонстрировать, что почти все может быть языком программирования.

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

«Формальный язык» — это просто способ обозначить язык, слова и грамматика которого четко (математически) определены. Языки программирования должны быть формальными языками, которым приписывается (недвусмысленное) семантическое/значение.

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

А теперь, когда я как следует все запутал, оставлю вам пример:

Первые две строки — это инструкции C (C — известный язык программирования), а квадратный блок показывает фрагмент того, как эти строки переводятся на машинный язык. Эти числа, записанные в шестнадцатеричной форме, являются наиболее близким представлением того, что может понять 64-разрядный процессор Intel, что все еще может быть полезно людям.

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