Что такое язык программирования? - PullRequest
8 голосов
/ 25 августа 2009

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

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

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

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

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

Ответы [ 10 ]

27 голосов
/ 25 августа 2009

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

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

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

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

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

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

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

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

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

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

5 голосов
/ 25 августа 2009

Хотя это не дает прямого ответа на ваш вопрос, мне напоминает эссе Пола Грэма Месть ботаников об эволюции языков программирования. Это, безусловно, интересное место для начала вашего расследования.

4 голосов
/ 25 августа 2009

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

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

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

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

4 голосов
/ 25 августа 2009

Немного длинная разглагольствования впереди.

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

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

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

Например:

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

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

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

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

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

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, вы можете получить ошибку во время выполнения. В компьютерных терминах это было бы несколько аналогично предполагаемому поведению Руби - возвращать результат последнего выражения («грамматическая особенность») и сначала проверять доступную память (необходимость среды).

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

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

Так же, как Ассемблер. : О)

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

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

1 + 1     -> 2
'1' + '1' -> '11'
3 голосов
/ 25 августа 2009

См. «Программирование, рассматриваемое как деятельность человека». EWD 117. http://www.cs.utexas.edu/~EWD/transcriptions/EWD01xx/EWD117.html

См. Также http://www.csee.umbc.edu/331/current/notes/01/01introduction.pdf

2 голосов
/ 17 января 2010

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

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

2 голосов
/ 25 августа 2009

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

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

  2. Языки аппаратного программирования: VHDL, Verilog, System Verilog и т. Д.

2 голосов
/ 25 августа 2009

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

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

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

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

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

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

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

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

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

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

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

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


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

2 голосов
/ 25 августа 2009

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

  • описывает математические функции
  • заставляет компьютер включать и выключать
2 голосов
/ 25 августа 2009

Интересно.

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

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

На ум приходят три основных свойства языков:

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

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

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

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

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

...