Каждый язык написан на C?

181

Иногда при программировании на разных языках (C / C ++, C #) мне приходит в голову эта мысль:

  • Все ли языки написаны на языке программирования C?
  • Является ли язык C матерью / отцом всех языков?
  • Все ли концепции ( ООП и т. Д.) Реализованы на C?

Я в правильном направлении?

FaizanRabbani
источник
58
@XLAnt: многие (возможно, даже большинство) компиляторов C написаны на C.
Йорг Миттаг
32
@Neil: C ++ ничего не компилирует. C ++ - это язык. Языки не компилируются, компиляторы делают.
Йорг Миттаг
12
@XLAnt: я так не думаю. Но первый компилятор Oberon, например, был написан на Oberon, а затем переведен вручную (я полагаю, что это форма компиляции) на Fortran. Затем этот компилятор был скомпилирован с помощью компилятора Fortran, полученный компилятор Oberon использовался для компиляции компилятора Oberon, и с этого момента предыдущая версия компилятора использовалась для компиляции следующей.
Йорг Миттаг
18
@Neil На самом деле это не так педантично. Это точно: язык - это спецификация. Он может быть реализован как компилятор, как интерпретатор, гибрид и т. Д. Вы можете написать компилятор для языка, но компилятор не является языком. Я предполагаю, что проблема становится запутанной, потому что есть языки, для которых нигде не написано никаких спецификаций, кроме его эталонной реализации. Но даже в этих случаях я бы сказал, что язык (т. Е. Идеал, который автор имел в виду) отличается от реализации / компилятора / интерпретатора / и т. Д.
Андрес Ф.
21
Downvoters: это довольно разумный вопрос с четким ответом. То, что ответ «нет», не является основанием для отрицательного ответа. Вместо этого рассмотрите возможность ответить и объяснить.
Андрес Ф.

Ответы:

208

Нет.

Диалекты OCaml, Haskell, Lisp, такие как Scheme, и некоторые другие языки часто используются при разработке языков для хобби.

Многие языки реализованы в C, потому что это вездесущий язык, а инструменты написания компиляторов, такие как генераторы лексера-парсера (такие как yacc и bison), понятны и почти так же вездесущи.

Но сам C изначально не мог быть разработан в C, когда он был впервые создан. На самом деле он был изначально разработан с использованием языка B. Более ранние языки (например, Fortran) обычно загружались с использованием родного языка ассемблера или даже машинного кода задолго до появления C.

Вне зависимости от этого языковые парадигмы, такие как ООП, обычно не зависят от языка. Например, функциональная парадигма была разработана (Алонзо Черчем) как основа математики задолго до появления какого-либо языка программирования. Парадигмы процедурного и структурного программирования возникли из математических работ таких теоретиков, как Джон фон Нейман. Объектная ориентация была разработана несколькими различными и не связанными усилиями, некоторые из лямбда-исчисления (функциональная парадигма) и некоторые из систем динамического программирования, таких как SmallTalk в Xerox PARC Алана Кея.

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

greyfade
источник
40
Хотя это правда, что первые компиляторы C, очевидно, не могли быть написаны на C, сейчас это возможно.
Рейраб
17
@reirab Возможный и правда. GCC написан на C и обычно компилируется с использованием GCC .
Darkhogg
9
Конечно, теперь GCC переписывается на C ++, но это не так важно, как тот факт, что первый компилятор C не мог быть написан на C.
greyfade
10
@greyfade gcc давно не был С. Он не «переписывается сейчас», а «написан на C ++ более двух лет» (хотя он и старше, чем тогда, когда произошло слияние, которое переместило его в C ++).
13
@greyfade - это не «C, но с возможностями C ++», как определение C ++?
KutuluMike
91

Все ли языки написаны на языке Си?

Язык - это набор абстрактных математических правил и ограничений («если я напишу это , это произойдет»). На самом деле это ни в чем не написано.

Он указывается, как правило, в виде смеси формализованного подмножества английского языка, математической записи и, возможно, некоторого специализированного языка спецификаций. Синтаксис часто указывается в варианте EBNF или ABNF .

Например, вот спецификация forвыражения из спецификации языка Ruby ISO:

§11.5.2.3.4 forВыражение

Синтаксис

  • for-expression for for-variable [здесь нет терминатора строки] in выражение do-clause end
  • для переменной левая сторона | множественная левая сторона

Семантика

For -выражение оценивается следующим образом:

  1. Оцените выражение . Если оценка выражения прекращается путем обкатки выражения , следующего выражения , или Redo-выражения , поведение не определено. В противном случае, пусть Oбудет результирующим значением.
  2. Позвольте Eбыть вызовом первичного метода формы первичное выражение [здесь нет разделителя строк] .each do | block-параметр-list- | block block-body end , где значение первичного выражения равно O, block-parameter-list является for-for переменная , block-body является составным оператором предложения do .

    Оценивать E; Однако, если блок , чей блок-тело является соединение-утверждение о сделае п из для-выражения называется в ходе этой оценки, шагов , описанных в §11.3.3 , за исключением стадии с) и стадией е) , 4), принять для оценки этого вызова.

  3. Значение for-expression является результирующим значением вызова.

Вот пример, отличный от правил соответствия типов Scala:

Полиморфный тип [a 1 >: L 1 <: U 1 ,…, a n >: L n <: U n ] T соответствует полиморфному типу [a1>: L ′ 1 <: U ′ 1 ,…, a n >: L ′ n <: U ′ n ] T ′ если, предполагая, что L ′ 1 <: a 1 <: U ′ 1 ,…, L ′ n <: a n <: U′n один имеет T <: T ′ И L i <: L ′ i и U ′ i<: U i для i ∈ {1,…, n} .


Является ли язык C матерью / отцом всех языков?

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

  • Планкалкюль (1943)
  • Speedcoding (1953)
  • Фортран (1954)
  • IPL (1956)
  • Лисп (1958)
  • Алголь (1958)
  • КОБОЛ (1959)
  • JOVIAL (1960)
  • APL (1962)
  • СИМУЛА ​​(1962)
  • СНОБОЛ (1962)
  • CPL (1963)
  • Бейсик (1964)
  • PL / I (1964)
  • РПГ (1964)
  • BCPL (1966)
  • ISWIM (1966)
  • MUMPS (1967)
  • Форт (1968)
  • ЛОГОТИП (1968)
  • РЕФАЛ (1968)
  • B (1969)
  • БЛИСС (1970)
  • Паскаль (1971)
  • KRL (1971)
  • Smalltalk (1972)

Все это существовало до того, как С был изобретен. И многие другие не имеют влияния С в них, даже после того, как он существует. Языки семейства PASCAL (ALGOL-58, ALGOL-60, ALGOL-X, ALGOL-W, PASCAL, Modula-2, Oberon, Oberon-2, Active Oberon, Component Pascal) представляют собой совершенно отдельную линию. Все семейство Lisp (LISP, Franz Lisp, InterLisp, MacLisp, Scheme, Flavors, LOOPS, CommonLoops, Dylan, CommonLisp, Arc, Clojure, Racket и т. Д.) Также не связано. Функциональные языки (ISWIM, KRL, Miranda, ML, SML, CAML, OCaml, F #, Haskell, Gofer, Clean) и все семейство с зависимой типизацией (Agda, Coq, GURU, Idris) находятся как можно дальше от Си. То же самое относится к семейству Smalltalk (Smalltalk, Self, Newspeak, Us, Korz), семейству логического программирования (PLANNER, Prolog, Mercury), SQL и многим другим.

Каждая концепция (ООП и т. Д.) Реализована на языке Си?

Первыми языками с концепциями ОО были Simula (1960) и Smalltalk (1972), но объектно-ориентированные системы были созданы еще в 1953 году (не называя их так). Опять же, это задолго до того, как существовал C, поэтому OO не может иметь никакого отношения к C.

Йорг Миттаг
источник
2
@leftaroundabout: Это отличный пост, один из моих любимых за долгие годы.
Йорг Миттаг
1
@FrancisDavey: Спасибо. Я начал составлять список по памяти, а затем добавил даты, которые я не помню, просматривая их в Википедии. После этого я нашел временную шкалу языков в Википедии и выбрал еще несколько языков. Поскольку статья о BCPL цитирует 1966 г., а временная шкала - 1967 г., я не заметил, что уже добавил BCPL. Я удалю дубликат.
Йорг Миттаг
1
В вашем списке "htroF" не написано в обратном направлении?
Чукс
2
«Путешествие во время физически невозможно» - Это очень спорные претензии. Не умаляет значение этого ответа, конечно.
Конрад Рудольф
50

Большая часть ядра многих важных языков написана на C, но ситуация меняется:

  • эталонная реализация Python ( CPython ) написана на C (но есть и другие реализации, написанные на других языках, например, Jython / Java, PyPy / Python, IronPython / C # ...)
  • PHP Zend Engine написан на C
  • Самый первый компилятор Java, разработанный Sun Microsystems, был написан на C, но теперь библиотеки классов всегда пишутся на Java (поскольку они предназначены для запуска с использованием самой Java VM). Некоторые библиотеки, использующие JNI (собственный интерфейс Java), могут быть частично написаны на множестве других языков, так как они предназначены для использования вне Виртуальной машины Java.

    Виртуальная машина Sun / Oracle написана на C ++. ВМ BEA / Weblogic / Oracle написана на C. Но есть JVM, написанные на Java, Lisp, SmallTalk (IBM) ...

  • Perl реализован как базовый интерпретатор, написанный на C, вместе с большой коллекцией модулей, написанных на Perl и C (но Pugs , компилятор и интерпретатор для языка программирования Perl 6, написан на Haskell)
  • официальный интерпретатор Ruby, часто называемый Ruby Interpreter или MRI Matz, написан на C и использует собственную виртуальную машину, специфичную для Ruby (но есть JRuby, реализация Java, которая работает на виртуальной машине Java; Rubinius, C ++ виртуальная машина с байт-кодом, которая использует LLVM для компиляции в машинный код во время выполнения ...)
  • около 50% R написано на С
  • и, конечно, C написан (был) на C ! (но первый компилятор C, предназначенный для PDP-11, представлял собой смесь B и ассемблера).

Есть много причин, почему C часто выбирали: производительность, портативность, опыт.

Последнее, вероятно, является наиболее важным: Python был запущен в 1991 году, PHP - в 1994/1995 годах, Perl - в 1988 году, Ruby - в 1995 году. В те годы только что была выпущена Java, а C ++ еще не был стандартизирован.


Несколько связано:

Manlio
источник
5
С точки зрения реализации компиляторов / интерпретаторов, C был / является ориентиром. Кроме того, это прямо или косвенно повлияло на многие более поздние языки (по крайней мере, синтаксически).
Манлио
2
довольно скоро вы сможете сказать, что C # был написан на C #! (вид)
DLeh
1
Большая часть Mono (которая включает в себя компилятор C # и многие / большую часть библиотеки базовых классов .NET) написана на C #.
Чарли Килиан
3
Ответ на вопрос "является ли C матерью / отцом всех языков?" это «нет», поэтому я не думаю, что было бы полезно предоставить множество примеров, написанных на C. Контрпримеры могли бы помочь, но ваш выбор по-прежнему происходит от C. Например, даже если Java, Python и т. д. теперь они хостинговые, они все еще были загружены из C, поэтому они как «внуки» C. Такие языки, как LISP, FORTRAN, ML и (конечно) машинный код, являются настоящими контрпримерами, поскольку C никогда не участвовал в их создание.
Warbo
2
Стремление ко многим языкам, конечно же, должно быть реализовано, насколько это возможно, само по себе. Однако кажется, что большинство языков зависят от C, потому что большинство языков должны иметь возможность вызывать C, чтобы быть полезным; большинство API-интерфейсов современных операционных систем и полезных библиотек обычно имеют привязки к Си. Вы также должны быть осторожны с тем, что вы подразумеваете под «написано в». Языковая реализация обычно состоит из нескольких частей: по крайней мере, компилятор и система времени выполнения. Системы выполнения часто пишутся на C, чтобы лучше взаимодействовать с ОС.
Псевдоним
10

Нет, некоторые языки предшествуют C. И многие из них реализованы независимо от C, например, см. Http://en.wikipedia.org/wiki/Lisp_%28programming_language%29.

Офир
источник
2
Существует много реализаций Java, большинство написано на Java. GNU-реализация Objective-C написана на C (или C ++, я думаю, они недавно изменились), реализация LLVM написана на C ++, и раньше был интерпретатор, написанный на C #. Существует множество реализаций Python, одна написана на RPython, одна на Java, одна на C # и одна на C. PHP имеет шесть основных реализаций, две на Java, две на C #, одну на C и одну на C ++.
Йорг Миттаг
1
Нет. Языковые дизайнеры, безусловно, находятся под влиянием других языков, но они могут игнорировать эти влияния, если они того пожелают.
Йорг Миттаг
2
Языки @FaizanRabbani, по сути, представляют собой концепции и варианты парадигм, шаблонов и компромиссов - очень часто «язык создается / адаптируется из других языков», но это совершенно не связано с языком реализации его компилятора; язык X может быть получен из языка Y, но реализован в C или в чем-то совершенно другом - и это часто имеет место. И в этом случае «концептуальный предок» важен, но язык компилятора - это едва уместный технический нюанс, который со временем может измениться.
Петерис
3
Эта последняя ссылка, если она имеет сомнительную ценность - слишком много ошибок, чтобы действительно относиться к ней серьезно.
Неизвестный кодер
4
@SebastianGodelet: HotSpot не является реализацией языка Java. Это реализация языка байт-кода JVM. Это два совершенно разных языка. Наиболее широко используемые реализации языка Java взяты javacиз Oracle JDK / OpenJDK, написанного Мартином Одерским (из известности Scala) на 100% Java, компилятор Eclipse, написанный на 100% Java (производный от компилятора Jikes IBM ), компилятор из IBM J9, также производная от Jikes и 100% Java. AFAIK, единственный широко распространенный Java-компилятор, который не написан на Java, - это GCJ
Jörg W Mittag
4

Я хотел бы сделать это комментарий, если бы мог, но я не могу так здесь идет:

Одна из причин, по которой C кажется таким вездесущим, заключается в том, что он является одним из самых ранних разработанных языков, а огромное количество современных языков основано на его структуре (Java, Go, PHP, Perl и т. Д.), Что делает его больше мест, чем есть.

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

Сказав все это, ответ на ваш вопрос "Нет". C основан на языке под названием ALGOL, и было много конкурентов как с ALGOL (FORTRAN, Lisp, COBOL), так и с C (ни один не приходит на ум). Объектно-ориентированное программирование, возможно, самый большой сдвиг парадигмы в дизайне программирования, возникло не в C, несмотря на то, что C ++ был очень популярным языком ООП (сначала он появился в Lisp или Simula 67, в зависимости от того, кого вы спрашиваете). К тому времени, когда появился ООП, C стал настолько популярным языком, что ему не нужно было быть первым - он был настолько популярен, что «расширение» C ++, так сказать, стало одним из основных языков ООП. Он остается в современном использовании главным образом благодаря его мощным функциям управления памятью (вы можете напрямую выделять и освобождать память, создаваемую вашими структурами), позволяя ему создавать программы с ограниченным бюджетом памяти (например, видеоигры) и его высоко оптимизированный компилятор (очевидно, в зависимости от компилятора). По общему признанию, даже эти функции теряют свои позиции, поскольку компиляция Java JIT и языковые менеджеры памяти становятся более продвинутыми.

WannabeCoder
источник
1
кажется, это не дает ничего существенного по сравнению с замечаниями, сделанными и объясненными в предыдущих ответах, особенно в верхнем , за исключением сомнительного утверждения, что «C основан на языке под названием ALGOL»
gnat
4
Основа Си в ALGOL вряд ли сомнительна ... См. Cm.bell-labs.com/who/dmr/chist.html , en.wikipedia.org/wiki/C_%28programming_language%29 )
WannabeCoder
фактическая история гораздо сложнее и интереснее , чем это; Я бы сказал, что то, как все изложено здесь, вряд ли поможет читателям
комнат
3

Очевидно нет. Как мог первый компилятор C быть написан на C, если C не было раньше? Это не проблема курицы и яйца.

Есть много способов написать первый компилятор языка, который называется начальной загрузкой

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

phuclv
источник
12
Первый компилятор Oberon был написан на Oberon. Это прекрасно, если вы профессор и у вас много учеников, которые вручную переведут компилятор для вас (который был у профессора Вирта).
Йорг Миттаг,
@Jorg, о котором говорилось в статье о начальной загрузке, ссылки на которую приведены выше, поэтому я не буду писать ее, потому что этот вопрос касается C, а компилятор C не был написан таким образом
phuclv
14
@ JörgWMittag - первый автоматический компилятор Oberon был написан на Oberon. Фактически первый компилятор Oberon был группой студентов.
nnnnnn
4
@nnnnnn: я бы посчитал эту «группу студентов» интерпретатором, а не компилятором.
Паŭло Эберманн
4
@ Paŭlo Ebermann Чтобы добавить еще один человеческий элемент: «компьютер» изначально был названием должности .
Чукс
2

Вот список некоторых языков программирования, которые не записываются в C, наряду с языками они будут реализованы в:

  • Haskell - Haskell
  • Идрис - Хаскелл
  • Адга - Хаскелл
  • Clash - Haskell
  • PureScript - Haskell
  • Вяз - Хаскелл
  • Меркурий - Меркурий
  • Rust - Rust (изначально OCaml)
  • Go - Go
  • Кристалл - Кристалл
  • OCaml - OCaml
  • Фреге - Фреге + Ява
  • Haxe - OCaml + Haxe
  • Скала - Скала
  • Футарк - Хаскелл
  • ATS - ATS

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

Во-вторых, ответить на ваш вопрос о том, является ли C «матерью / отцом всех языков программирования», - не совсем. Язык C был хорошо продуманным в то время, когда он появился, и это, без сомнения, повлияло на разработчиков языков, которые затем продолжали делать совсем другие вещи. Но, в конце концов, Хаскелл отходит от Си практически всеми возможными способами. С 45 лет, и это не удивительно, что мы научились делать лучше за это время.

Наконец, чтобы ответить на ваш третий вопрос, это просто не тот случай, когда C реализует «все концепции». В частности, попытка реализовать некоторые продвинутые концепции из функционального программирования (такие как метаморфизмы или, не дай бог, синхроморфизмы) в C будет чудовищно трудной. Я не особенно знаком с объектно-ориентированным программированием, но я точно знаю, что некоторые объектно-ориентированные языки имеют типы сумм.


источник
Си никогда не был «невероятно хорошо продуманным языком». Бородавки, которые мы видим сегодня, были известны как бородавки с самого начала. Но это было достаточно хорошо, чтобы быть родным языком дружественной к разработчикам операционной системы Unix, и после того, как Bell Labs выдвинула Unix в университеты, C / Unix стала любимым языком / ОС для поколения компьютерных профессионалов.
Соломон Слоу
PS. В Си было не так много оригинальных идей. Если вы ищете мать / отца всех блочно-структурированных, процедурных языков программирования, возможно, вы захотите взглянуть на ALGOL .
Соломон Слоу
Макросы Lisp были намного лучше, чем C, а у ALGOL и Smalltalk были блоки, замыкания и вложенные функции, помогающие упорядочить код. Действительно, Лисп мог бы использоваться в качестве макропроцессора для ассемблера и создавать код, который был короче и быстрее (пользовательская обработка S-выражений), чем ранняя версия C. Simula, появившаяся до того, как C имел полиморфизм. У Lisp, APL и Smalltalk были «оболочки», которые были полностью функциональны (тот же код между оболочкой и программами), в отличие от Unix «sh» против «C», позволяющего чередовать интерпретированный и скомпилированный код. В Лиспе указатели были проще (rplaca / rplacd).
aoeu256
Самым большим преимуществом C было то, что было проще создавать «компиляторы» для C, и поэтому он мог распространяться легче ... как вирус, и благодаря C современные программисты не имеют понятия о том, как создавать программы модульные (изменчивость вредит модульности), не имею понятия о наречиях / комбинаторах / функциях высшего порядка [каждый раз пишите свои циклы вручную], и наши процессоры ограничены узким местом "von neumann", потому что наша ОС написана на C, поэтому нам нужны наши CPU для запуска кода C для обратной совместимости.
aoeu256
1

Языки программирования - это спецификации (не программное обеспечение!), Обычно написанные в каком-то английском документе (с некоторой формализацией, например, EBNF для большей части синтаксиса; иногда их семантика также частично формализована).

Например, C11 определяется n1570 (который вы должны прочитать). Какой-то диалект схемы определяется R5RS (который вы также должны прочитать, он очень хорошо написан).

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

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

Часто (но не всегда) система времени выполнения частично написана на C (в частности, сборщик мусора ).

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

Кстати, удобно использовать C в качестве целевого языка компиляторов .

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

Василий Старынкевич
источник