Хотя мой вопрос может быть совершенно неуместным, но я почувствовал закономерность между большинством языков программирования и их официальными реализациями.
Интерпретируемые (байтово-интерпретируемые?) Языки, такие как Python, Lua и т. Д., Обычно имеют чрезвычайно мягкий и простой синтаксис и, как правило, не содержат типов или не требуют от разработчика явного написания типов переменных в исходном коде;
Скомпилированные языки, такие как C, C ++, Pascal и т. Д., Обычно имеют строгий синтаксис, обычно имеют типы и в основном требуют больше времени на разработку кода
Языки, официальные реализации которых являются JIT-компилированными, такие как Java / C #, обычно являются уникальным компромиссом между двумя вышеупомянутыми с некоторыми из лучших возможностей обоих.
Некоторые из более современных скомпилированных языков программирования, такие как D и Vala (и реализация Java GNU GJC), возможно, являются исключением из этого правила и напоминают синтаксис и функции языков JIT-Compiled, таких как Java и C #.
Мой первый вопрос: действительно ли это актуально? Или это просто совпадение, что большинство интерпретируемых языков имеют простой синтаксис, JIT-компилированные имеют умеренный синтаксис и функции и т. Д.
Во-вторых, если это не совпадение, то почему так? Как, например, некоторые функции могут быть реализованы только на языке программирования, если вы, скажем, JIT-компилируете его?
источник
Ответы:
Между семантикой и синтаксисом нет никакой связи. Homoiconic скомпилированные языки, такие как Scheme, имеют довольно минималистичный синтаксис. Низкоуровневые скомпилированные мета-языки, такие как Forth, еще проще. Некоторые очень строго типизированные скомпилированные языки построены на тривиальном синтаксисе (например, ML, Haskell). OTOH, синтаксис Python очень тяжелый, с точки зрения ряда правил синтаксиса.
И да, типизация не имеет ничего общего с синтаксисом, она на стороне семантики языка, если только это не что-то извращенное, как в C ++, где вы даже не можете анализировать, не имея всей доступной информации о типизации.
Общая тенденция заключается в том, что языки, которые развивались слишком долго и не содержали никаких конструктивных мер защиты от синтаксических отклонений, рано или поздно превратились в синтаксические мерзости.
источник
type checking
» чрезвычайно контрпродуктивен и не должен использоваться, он очень вводит в заблуждение, он не отражает природу систем типов.В основном это совпадение.
Языки программирования со временем эволюционировали, а технология компиляторов и интерпретаторов улучшилась. Эффективность базовой обработки (т. Е. Время компиляции, накладные расходы на интерпретацию, время выполнения и т. Д.) Также не так важна, поскольку мощные вычислительные платформы выросли.
Синтаксис языка действительно оказывает влияние - например, Паскаль был очень тщательно спроектирован, чтобы он мог использовать однопроходный компилятор - то есть один проход по исходному тексту, и у вас есть исполняемый машинный код. Ада, с другой стороны, не обратила на это никакого внимания, а компиляторы Ады, как известно, трудны для написания - большинству требуется более одного прохода. (Один очень хороший компилятор Ada, который я использовал много лет назад, был 8-проходным компилятором. Как вы можете себе представить, он был очень медленным.)
Если вы посмотрите на старые языки, такие как Fortran (скомпилированный) и BASIC (интерпретированный или скомпилированный), у них / был очень строгий синтаксис и семантические правила. [В случае с Бейсиком, то есть не со старым Бейсиком Билла, вам нужно вернуться к этому оригиналу.]
С другой стороны, при взгляде на другие более старые вещи, такие как APL (куча веселья), это была своего рода динамическая типизация. Это также обычно интерпретировалось, но также могло быть скомпилировано.
Сложный синтаксис сложен - если это означает, что у вас есть вещи, которые являются необязательными или могут быть выведены, то это означает, что язык обладает достаточным богатством, чтобы его можно было отбраковать. Опять же, у BASIC было это много лет назад, когда утверждение «LET» стало необязательным!
Многие из идей, которые вы сейчас видите (например, типизирование или динамическая типизация), на самом деле очень старые - впервые появились в 1970-х или в начале 1980-х годов. То, как они используются, и языки, на которых эти идеи используются, изменилось и выросло. Но по сути, многое из того, что нового, на самом деле - это старые вещи, одетые в новую одежду.
Вот несколько примеров из головы:
Я мог бы продолжить.
Обновление: потому что я не был достаточно ясен.
Набор текста может широко варьироваться.
Фиксированная статическая типизация во время компиляции распространена (например, C, Ada, C ++, Fortan и т. Д.). Это где вы объявляете вещь типа, и так всегда.
Также возможно иметь динамическую типизацию, когда вещь выбирает тип, который ей назначен. Например, PHP и некоторые ранние версии BASIC, а также APL, где вы назначали бы целое число переменной, и с тех пор это был целочисленный тип. Если позже вы присвоили ей строку, то это был тип строки. И так далее.
И затем есть свободная типизация, например PHP, где вы можете делать действительно странные вещи, такие как присвоение числового целого числа (в кавычках, то есть строки) переменной, а затем добавление к ней числа. (например, «5» + 5 приведет к 10). Это земля странного, но иногда очень и очень полезного.
ОДНАКО это функции, разработанные на языке. Реализация просто делает это возможным.
источник
Я думаю, что все наоборот: реализация зависит от синтаксиса. Например, если ваш синтаксис допускает рефлексию, то реализация должна предоставить среду выполнения, которая это поддерживает.
источник
Я в целом согласен с fast_now в том, что ваши наблюдения в основном являются результатом истории. Тем не менее, основные рассуждения сводятся к чему-то вроде этого:
(На самом деле это не цитата, а моя собственная формулировка.) Когда я пишу
comfortable
здесь, я имею в виду то, что вы назвалиbest features of both
. Точнее, я не хочу говорить за или против статической / динамической типизации или строгого / мягкого синтаксиса. Вместо этого важно видеть, что основное внимание уделяется разработчикам и повышению их уровня комфорта при работе с языком.Вот несколько причин, которые не были упомянуты в предыдущих ответах, которые могут дать вам некоторые идеи о том, почему вы наблюдаете эти вещи (и все они основаны на истории разработки языка программирования):
У нас есть сотни языков программирования в эти дни. Когда появляется новый, как он может найти широкую аудиторию? Это главная причина, почему новые языки всегда пытаются повысить уровень комфорта разработчиков. Если язык может сделать то же самое, что и старый, но может сделать это намного проще / проще / элегантнее / и т.д. Вы можете рассмотреть возможность переключения.
Кривая обучения идет рука об руку с этим. В прошлом у нас было мало языков, и мы потратили время на изучение одного из них. Даже если это означало потратить много времени. Комфорт снова повышается, если вы придумали язык, который разработчики могут выучить очень быстро. Сложность любого вида (например, сложный сложный синтаксис) отрицательно сказывается на этом и, следовательно, уменьшается в новых языках.
Технологические достижения (прямая историческая причина здесь) несут ответственность за то, что сборщики компиляторов теперь могут уделять больше внимания удобству разработчика. В первые дни мы были рады возможности создать компилятор вообще. Однако это часто подразумевало жесткие ограничения. По мере развития технологических ноу-хау мы смогли снова снять эти ограничения.
В общем, языки программирования и компиляторы получили развитие, похожее на разработку типичных приложений для конечных пользователей:
источник
(Not a quote really, just my own formulation.)
Ну, вы отформатировали его как код, а не как цитату, так что я не думаю, что кто-то думал, что это цитата :)Данный язык программирования может или не может предоставлять или ограничивать достаточную семантическую информацию для компилятора, чтобы определить, как преобразовать его в исполняемый код без добавления решений времени выполнения («какой тип это переменная?» И т. Д.). Некоторые языки явно предназначены для это ограничение обязательно, или его легко определить.
По мере того, как компиляторы становятся умнее, они могут догадываться или профилировать достаточно информации, чтобы генерировать исполняемый код для наиболее вероятного пути (путей), даже для языков, которые не были специально разработаны таким образом, чтобы выставлять или ограничивать эти решения.
Однако языки, в которых код (evalString ()) может быть создан или введен во время выполнения (и другие вещи, которые компилятор не может вывести или угадать), могут требовать, чтобы интерпретатор или JIT-компилятор были доступны во время выполнения, даже при попытках предварительно скомпилируйте их.
В прошлом язык программирования и его реализация могли развиваться так, чтобы соответствовать некоторым аппаратным ограничениям, таким как, может ли интерпретатор соответствовать 4k или 16k, или компилятор мог завершить работу менее чем за минуту процессорного времени. Поскольку машины становятся быстрее, стало возможным (пере) компилировать некоторые ранее интерпретированные программы так быстро, как программист может нажать клавишу возврата или интерпретировать ранее скомпилированный исходный код программы быстрее, чем чуть более старое оборудование может запускать оптимизированные скомпилированные исполняемые файлы.
источник