Использование C для реализации других языков каким-либо образом ограничивало их дизайн?

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

9 ответов

Решение

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

Тем не менее, в некоторых случаях существуют ограничения. Пример: в компиляторе haskell GHC есть perl-скрипт, называемый Evil Mangler, для изменения кода сборки, выводимого GCC, для реализации некоторых важных оптимизаций. По этой причине они частично перешли на внутренне сгенерированную сборку и LLVM. Тем не менее, это не ограничивает языковой дизайн - только выбор доступных оптимизаций компилятором.

Я склонен не соглашаться.

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

Однако сложнее утверждать, что сам язык Си не имел никакого влияния на дизайн более поздних языков. Возьмите например использование фигурных скобок { } чтобы сгруппировать операторы в блоки, понятие, что пробел и отступ в основном не важны, имена нативного типа (int, charи т. д.) и другие ключевые слова, или способ определения переменных (т. е. сначала объявление типа, затем имя переменной, необязательная инициализация). Многие из сегодняшних популярных и распространенных языков (C++, Java, C#, и я уверен, что их даже больше) разделяют эти концепции с C. (Вероятно, они не были совершенно новыми с C, но AFAIK C придумал это конкретное сочетание синтаксиса языка.)

Нет, короче. В действительности, посмотрите на языки, написанные на C. Например, Lua примерно так же далека от C, как вы можете получить, не становясь Perl. Имеет первоклассные функции, полностью автоматизированное управление памятью и т. Д.

Это необычно для новых языков, которые будут затронуты языком их реализации, если только этот язык не содержит серьезных ограничений. Хотя я определенно не одобряю C, это не ограниченный язык, просто очень подверженный ошибкам и медленный для программирования по сравнению с более современными языками. Ох, кроме как в ЭЛТ. Например, Lua не содержит функциональных возможностей каталога, потому что он не является частью CRT, поэтому они не могут реализовать его в стандарте C. Это один из способов, которым C ограничен. Но с точки зрения языковых возможностей, это не ограничено.

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

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

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

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

В то время как реализация языка в C, вероятно, повлияла на другие языки, скорее всего, это такие вещи, как экранирование в строках, что, вероятно, не ограничивает.

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

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

Многие разработчики выбирают C по нескольким причинам. Во-первых, C - очень распространенный язык. Проекты с открытым исходным кодом, в частности, заключаются в том, что найти опытного разработчика на языке C относительно легче, чем найти эквивалентного разработчика на некоторых других языках. Во-вторых, С обычно поддается микрооптимизации. При написании синтаксического анализатора для языка сценариев его эффективность оказывает большое влияние на общую производительность сценариев, написанных на этом языке. Для компилируемых языков более эффективный компилятор может сократить время компиляции. Многие компиляторы C очень хороши в создании чрезвычайно оптимизированного кода (что также является одной из причин того, почему многие встроенные системы запрограммированы на C), а критичный к производительности код может быть написан в виде встроенной сборки. Кроме того, C стандартизирован и обычно является статической целью. Код можно записать в стандарт ANSI/C89, и не нужно беспокоиться о его несовместимости с будущей версией C. Изменения, внесенные в стандарт C99, добавляют функциональность, но не нарушают существующий код. Наконец, C очень портативен. Если по крайней мере один компилятор существует для данной платформы, это, скорее всего, компилятор Си. Использование очень переносимого языка, такого как C, позволяет максимально увеличить количество платформ, которые могут использовать новый язык.

Единственное ограничение, которое приходит на ум, - это расширяемость и хостинг компиляторов. Рассмотрим случай C#. Компилятор написан на C/C++ и является полностью нативным кодом. Это делает его очень трудным для использования с приложением C#.

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

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

Вывоз мусора. Языковые реализации поверх Java или.NET используют GC виртуальной машины. Те, кто на вершине C, как правило, используют подсчет ссылок.

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

Если бы кто-то написал DSL в groovy (/ схема /lisp/haskell/lua/javascript/ и некоторые другие, в которых я не уверен), функции могут стать членами первого класса. Создание функций для членов первого класса и учет анонимных функций позволяет писать краткий и более понятный для человека код (как продемонстрировано в LINQ).

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

Реализация компилятора / интерпретатора в C не имеет каких-либо серьезных ограничений. С другой стороны, реализация компилятора языка X to C делает. Например, согласно статье в Википедии о C--, при компиляции языка более высокого уровня для C вы не можете выполнять точную сборку мусора, эффективную обработку исключений или оптимизацию хвостовой рекурсии. Это та проблема, которую C-- должен был решить.

Другие вопросы по тегам