Как создается или создается новый язык программирования?
Fortran- > Algol- > Cpl- > Bcpl- > C- > С++ → Java.....
Кажется, что каждый язык построен на языке предков.
Мой вопрос: новые языки расширяют родительские или есть какой-то трюк?
например. System.out.print() в Java; это на самом деле printf() в C и т.д. (printf на самом деле.. в Cpl)?
Если это так, не делает ли это все последующие языки медленнее и нужно больше памяти? Что отделяет новый язык от структуры?
Ответы
Ответ 1
Каждый язык основывается на концепциях другого (дизайн языка). Каждый новый язык учит тому, что работает на предыдущих языках и что не работает. Также языки ориентированы на разные группы. Если вы пишете язык для долговременной ремонтопригодности и надежности, этот язык, вероятно, не подходит для сценариев оболочки.
Многие языки тестируют кровати для функций или концепций. Они, как правило, чрезвычайно гибкие и веселые и могут быть очень быстрыми в использовании. Basic был одним из них, как и Perl, Ruby,...
Другие языки сводятся к минимуму медведя и редко меняются - они фокусируются на обратной совместимости и согласованности. Новые функции можно было бы избежать, и когда они будут добавлены, они будут проверены в глубину до добавления в стандарт (да, они, как правило, основаны на стандартах больше, чем предыдущая группа). C, Java, Ada и С++. С#, возможно, является кроссовером с добавлением дополнительных функций, чем другие, но большей стабильности, чем предыдущая группа.
Теперь, помимо того, что создает языковые функции, существует способ создания языка. Lanuages часто изначально написаны на другом языке, но не так, как вы предполагаете. Java в основном написана на Java сейчас, но JVM, скорее всего, является сборкой с ручной кодировкой, однако вы можете быть уверенным, что C printf нигде не встречается в Java.
Скомпилированный язык обычно состоит из вашей программы, сведенной к определенному набору кодов (машинный язык или байт-код) и затем упаковывается с набором подпрограмм (например, System.out.println). Однако println не просто вызывает C println, а создается библиотека (написанная в некоторой комбинации Java, C, сборка), которая знает, как делать сам вывод.
В C библиотека будет сгенерирована одинаково, комбинация C и сборки, которая генерирует код сборки, который может выполнять "printf"
Ответ 2
Как создается или создается новый язык программирования?
Это многоступенчатый процесс:
-
Теоретики типа Pointy-head и другие профессионалы постоянно предлагают новые языковые возможности. Вы можете прочитать о них в таких местах, как материалы симпозиума ACM по принципам языков программирования (POPL), который проводится ежегодно с 1973 года.
-
Многие из этих предложений фактически реализованы на некотором языке исследований; некоторые языки исследований, которые я лично считаю перспективными, включают Coq и Agda. Haskell - это бывший исследовательский язык, который сделал его большим. Исследовательский язык, который получает 10 пользователей, часто считается его дизайнерами. Многие языки исследований никогда не заходят так далеко.
От исследования к развертыванию я знаю две модели:
-
Модель A: Наступает талантливый любитель и синтезирует целую кучу существующих функций, возможно, включая некоторые новые идеи, на новый язык. У любителя есть талант, харизма и, возможно, убийственное приложение. Таким образом, рождаются C, Perl, Python, Ruby и Tcl.
-
Модель P: Талантливый профессионал делает карьерные жертвы, чтобы построить и обнародовать новый язык. Профессионал обладает талантом, глубоким знанием области и, возможно, убийственным приложением. Таким образом, Haskell, Lua, ML, Pascal, Scala и Scheme рождаются.
Вы предлагаете другую модель:
-
Модель E: Талантливый человек, будь то любитель или профессионал, расширяет или модифицирует другой язык. Там есть встроенная пользовательская база, которая может быть заинтересована в расширении. Возможно, пользователи могут исследовать новые идеи, не заплатив больших затрат на переход. Таким образом, рождаются С# и С++.
Мое определение профессионала - это тот, кто получает знания о языках программирования, передает эти знания и развивает новые знания в языках программирования. К сожалению, это не то же самое, что разрабатывать и внедрять новые языки, и это не то же самое, что делать реализации, которые могут использовать многие люди. Вот почему большинство успешных языков программирования разработаны и созданы любителями, а не профессионалами.
Было немало интересных исследовательских языков, которые имели сотни или даже тысячи пользователей, но все же никогда не делали этого большим. Из этих моих фаворитов, вероятно, Icon. Я утверждал в другом месте, что никто не знает, почему языки становятся популярными.
Увеличивают ли новые языки родительские?
Это на самом деле очень редко. Наиболее популярным примером является С++, и, возможно, Algol-W или PL/S приблизились. Но гораздо шире использовать родительский язык только для вдохновения, а некоторые языки (на ум приходит Python) признают несколько "родителей" источниками вдохновения.
Разве это не делает все последующие языки медленнее и требует больше памяти?
Не обязательно. С++ медленнее и использует больше памяти не потому, что он происходит от C, а потому, что он был разработан с помощью аккреции со временем до такой степени, что только очень опытный пользователь может надежно писать код С++, который так же быстро, как и аналогичный C-код. (Я хочу быть предельно ясным: это не то, что С++ не может быть быстрым, потому что стоимость кода C всегда очевидна из чтения источника, а стоимость кода на С++ иногда вовсе не очевидна из чтения источника. ) Для получения дополнительной информации об эволюции С++ прочитайте книгу Джима Уолдо "Эволюция С++".
Java изначально была медленной из-за компиляции точно и вовремя и других дурацких вещей в реализации. Они также оседлали себя этой динамической загрузкой классов, которая очень тяжела, чтобы заставить вещи быть быстрыми (потому что класс может быть расширен динамически в любой момент). Кенни Задек, Роджер Гувер и Дэвид Чейз создали действительно быстрый компилятор с собственным кодом для Java без загрузки динамического класса.
Для контрпримера я думаю, что программы Scheme выполнялись быстрее и использовали меньше памяти, чем предыдущие программы Lisp, частично потому, что Guy Steele - блестящий дизайнер и блестящий разработчик. (Редкая комбинация, что.)
Но есть что-то, что вы говорите: люди, которым не хватает опыта для создания хорошего компилятора с нуля или которые не имеют опыта разработки целого языка с нуля, вполне могут взломать реализацию чего-то, не слишком отличающегося от родителя, В таких случаях вполне вероятно, что язык будет менее хорошо разработан, менее хорошо реализован, медленнее и использует больше памяти, чем его предшественник. (Тони Хоар классно сказал, что Алгол 60 был улучшением для большинства его преемников [sic]).
Также верно, что в последнее время язык разработан, тем больше вычислительных ресурсов доступно по той же цене. Ранним компиляторам C пришлось работать эффективно всего в 128 КБ ОЗУ. Сегодня компиляторы С++ не сталкиваются с такими ограничениями, и есть все основания для их использования большего объема памяти: на самом деле дешево заполнять машину гигабайтами ОЗУ, а ограничивать их до простых мегабайт ничего не сохраняет; большая память уже оплачена.
Резюме: Языки появляются, потому что люди хотят сделать программирование лучше, и у них есть новые идеи. Языки начинаются, когда кто-то берет целую кучу идей, некоторые новые и некоторые проверенные, и синтезирует их в единое целое. Это большая работа. Один из способов облегчить работу - это привлечь не только проверенные функции, но и проверенные образцы одного или нескольких языков предшественника. Такой дизайн создает впечатление "родительства", но фактическое расширение или близкое расширение (в случае С++, расширяющего C) встречается редко. Расходы времени и пространства не обязательно увеличиваются по мере развития языков, но часто случается, что люди создают языки, делая более сложные проекты, а чем сложнее дизайн, тем сложнее реализовать его эффективно. Поэтому нет ничего необычного в том, что программы, написанные на новом языке, кажутся медленнее или больше памяти, чем аналогичные программы, написанные на языке предков. Наконец, как и во всех других формах программного обеспечения, компиляторы, разработанные и построенные в последнее время, обычно используют больше оперативной памяти и процессора, чем компиляторы, созданные десять лет назад, просто потому, что большое количество циклов ОЗУ и ЦП доступно по ценам подзарядки.
Ответ 3
Языки не медленны, Реализации [созданные компиляторами для сборки] медленны. Теоретически, у вас мог бы быть интерпретатор С++, который работал медленнее, чем компилятор PHP или что-то еще. Языки также не потребляют память, реализация потребляет память.
Проект - это язык, когда грамматика (или синтаксис) отличается. (В одном проекте вы можете иметь как язык, так и структуру)
Языки формируются только общим творческим процессом. Кто-то видит что-то классное и думает, что это может быть лучше, поэтому они делают это так, и в конце концов вы получаете совершенно другой язык.
Ответ 4
Существует большая разница, которая может быть не очевидна, между тем, что язык построен на понятиях предшественника и фактически строится с ним. C компилируется в ASM, поэтому он построен на нем, но не обязательно с ним. Часто (большинство?) Компиляторов C на самом деле написаны на C. С++ построен на C, он поддерживает полный спектр C и добавляет к нему кучу вещей. Java - это совершенно другая вещь, также как и .NET. Они "компилируются" на псевдо ASM, называемые IL для .NET и ByteCode для Java. Оба требуют выполнить другой шаг или виртуальную машину (виртуальную машину).
Ответ 5
Языки могут (и часто) записываться с нуля. Но языки могут (и часто делать) основываться на концепциях предшествующих языков. Зачем изобретать колесо, когда у ваших ног есть идеально круглый?
Ответ 6
На поверхностном уровне языки растут от предшественников, потому что есть пользователи, которые уже знают синтаксис, и существует не так уж много разных способов сделать синтаксис.
На более значимом уровне предыдущие языки могут использоваться в повторяющихся способах, которые могут быть упрощены путем добавления некоторого синтаксиса и поведения. Я думаю о том, как сделать ООП в C до того, как С++ придет. Или различие между Fortran с GOTO и Algol с блочной структурой. Было больно делать метки, и их можно было автоматически сгенерировать.
Лично я мог ошибаться, но я не вижу языков общего назначения (GPL), которые развиваются гораздо дальше (не говоря уже о том, что небольшие языки не будут размножаться). Я думаю, что языки специального назначения (DSL) будут продолжать расти, и я думаю, что одной из ключевых особенностей любого GPL будет то, насколько она помогает создавать новые DSL.
Я думаю, это потому, что существует континуум представлений между конкретной структурой данных, с одной стороны, и языками программирования - с другой. Любые данные, которые читаются какой-либо программой, в некотором смысле выражены на языке, и эта программа является ее интерпретатором. Таким образом, единственное, что действительно разделяет крайности, - это степень сложности и общности его интерпретатора.
То, что я ищу в DSL, является свойством минимальной избыточности в отношении его предполагаемой проблемной области. Идея заключается в том, что есть некоторые требования, и если программа написана (человеком, на клавиатуре) для правильного воплощения этих требований, а затем, если в требования к единому согласованию внесены некоторые изменения, должно быть сделано для программы, чтобы правильно реализовать изменение, тогда избыточность языка по домен - это размер таких изменений, усредненный (каким-то образом) в пространстве возможных изменений. Очень простой способ измерить это - использовать программу diff между кодом до и после. Количество различий является мерой избыточности для этих изменений. Это немного затянуто, но я стараюсь свести к минимуму, говоря, что язык хорошо адаптирован к домену.
Если избыточность языка минимизирована, то это означает, что для изменения функциональных изменений требуется меньше изменений, и не только код может быть короче, но, следовательно, меньше шансов помещать ошибки.
Как программисты в настоящее время учатся, эти идеи в будущем. Сведение к минимуму избыточности исходного кода еще не серьезно оценено. То, что у нас есть, - это бандажи, такие как ООП, которые, несмотря на их очевидную ценность, ведут к значительно избыточному коду.
Одной из перспективных разработок является рост генераторов кода, но опять же им грозит стать самоцелью, а не служить цели сокращения избыточности исходного кода.
Ответ 7
Мне кажется, что есть два основных способа создания новых языков:
1) кто-то решает, что им нужно выполнить определенную работу, а язык специальных целей поможет им выполнить эту работу. Этот человек (наряду с некоторыми другими пользователями) находит язык полезным и начинает распространяться на другие цели. В конце концов, язык поддерживает достаточное количество материалов, что можно считать языком общего назначения.
2) кто-то, кто разбирается в языках программирования, решает, что существуют проблемы с текущим языком, который может быть решен с помощью нового подхода (что может быть радикальным изменением или постепенным изменением ранее). Новый язык разработан с нуля, чтобы быть языком общего назначения. Это может быть описание того, как появились Java или С#.
Большинство языков будут иметь сходство с другими (например, ваш пример печати), потому что эти операции очень полезны в большинстве контекстов.
Тогда существуют такие языки, как FORTH или APL, который я просто не могу объяснить...
Ответ 8
Языки программирования основываются на предыдущем опыте и знании дизайнера языка и сообщества в целом, так же, как новые автомобили построены с использованием того, что было изучено путем сборки автомобилей несколько лет назад.
Я не думаю, что это точно, чтобы сделать выражение о том, что все языки построены на каком-то другом языке, который ему предшествовал. Дизайнер нового языка, безусловно, должен иметь опыт работы с несколькими существующими языками, понимать свои сильные и слабые стороны для определенной цели, а затем создавать свой новый язык для включения всех сильных/отличных идей других и избегать слабых сторон других, возможное. Учитесь у других успехов и неудач. (Те, кто игнорирует историю, обречены повторять ее)
Как отмечалось в других ответах, создание нового языка никоим образом не связано с выполнением других языков. Новые языки и новые реализации одного и того же языка обычно заменяют, а не расширяют, предшествующие примеры. Даже производительность одной реализации языка по сравнению с другой реализацией может значительно различаться: рассмотрите компиляторы Borland С++, которые запускают круги вокруг других компиляторов С++ той же эпохи, или сравнивают производительность среды выполнения виртуальной машины 1.0 Java с более поздними реализациями, которые добавили производительность повышается подобно компилятору hotspot.
Чтобы использовать пример автомобиля: потому что Ford Model T был автомобилем и отрывистым черным дымом, а Tesla Roadster - это автомобиль и пришел после модели T, правда ли, что родстер Tesla также должен отрывать черный дым просто потому, что это машина, и она появилась после модели T? Конечно нет. Тесла - это совсем другая реализация идеи автомобиля. Его дизайн отражает много вещей, которые были изучены с момента создания модели T, но это не модель T.
Ответ 9
Разработчики языка должны учитывать популярность.
Я не сомневаюсь, что значительная часть популярности С# объясняется тем, что не так много отличается от синтаксиса Java, который не слишком отличается от C и т.д.
Это уже тяжелая работа по изучению нового языка, но это легче для всех, если синтаксис не слишком отличается от других языков.
Что касается скорости, это не зависит от языка, но и от компилятора, используемого для преобразования этого языка на другой язык, который может быть прямо из машинного кода или сборки, или в случае С#, Java и т.д., байт кода, который затем запускается на виртуальной машине.
Ваш последний вопрос также интересен. С# и .NET - совсем другие звери. Когда язык (например, С#) предназначен для .NET, создается компилятор, который может преобразовать этот язык в байт-код, который может работать на этой виртуальной машине. Это означает, что код С#.net вполне может с удовольствием вызвать сборки, написанные на VB.NET, например.
То же самое относится к Java и Scala, которые написаны для JVM. Scala - функциональный язык, а Java - язык ООП, но оба могут с радостью называть друг друга, поскольку в конце концов он просто байт-код работает на виртуальной машине.
Надеюсь, это ответит на ваш вопрос.
Ответ 10
Как человек, который работает в основном на языковых проектах, я думаю, что есть две важные причины создания новых языков: скука и разочарование. Когда программисты скучают, они придумают всевозможные смехотворно амбициозные проекты, чтобы заполнить свое время, а языки предоставляют почти бесконечно интересные новые проблемы. Когда программисты разочарованы существующими инструментами, они, как правило, создают новые, чтобы заполнить воспринимаемый пробел. От DSL к общедоступным языкам я нахожу, что все языковые проекты, которые я видел, сводятся к этим двум причинам.
Ответ 11
На самом деле новые языки могут быть намного быстрее. Например, C/С++ или даже Java может быть намного быстрее, чем рукописный ассемблер. Go/Haskell/... который легко разбивается на разделы, может быть намного быстрее, чем ассемблер на современном оборудовании, - то, что этот код ассемблера "на 25% быстрее", а затем сравнивает одну программу Haskell/Go, если вы можете включить переключатель, который делает Haskell/Идите в 4 раза быстрее (т.е. Затем 3х оптимизированный ассемблер) на Core Quad, не говоря уже о том, что код намного менее глючен?
Есть исследования, что платформы с GC на самом деле быстрее - поскольку программисты имеют больше времени для оптимизации программ/поиска других ошибок, а затем обнаружения утечек памяти, хотя "идеальные" программы будут медленнее.
Также у вас может быть много повторной реализации языка:
- На основе собственного кода (ассемблера)
- Основываясь на низкоуровневом языке (C, LLVM)
- На основе кросс-платформенной структуры (Java, попугай)
- На основе интерпретатора
- Основываясь на одноплатформенной структуре (.Net - да, я знаю о mono;), но она по-прежнему в основном одноплатная)
Например, Ruby имеют Ruby MRI (интерпретатор), JRuby (Java),.Net(IronRuby) и т.д. Они обычно сильно отличаются по скорости. C имеют многочисленные компиляторы и могут теоретически иметь переводчика. Haskell имеет встроенный генератор кода (GHC и co.), Низкоуровневый язык (GHC -fvia-c и новый GHC + LLVM) и intrereter (ghci).
Языки обычно создаются с помощью:
-
Авторы любят язык A и B, поэтому он объединяет его в язык C
-
У авторов есть совершенно новая идея (например, объекты, утка-типизация), которые не могут быть выражены в существующих языках/новая идиома, которая не может быть выражена как хорошая на существующих языках, поэтому они создают новый язык, который является новой функцией.
-
Авторы считают какую-то особенность ужасной и хотят избавиться от нее (по каким-либо причинам). Как enum
в старой Java.
В первом и третьем случае новый язык "наследует" от одного или нескольких языков (обычно много). Но обычно это их комбинация.
Ответ 12
Я проголосовал за некоторые ответы выше, но также обратите внимание, что класс языков Lisp на самом деле в некотором роде побуждает программиста эффективно создавать новую языковую функцию, когда это необходимо, создавая новый диалект lisp. Вы можете спорить о том, в чем разница между созданием новой собственной функции и созданием новой языковой функции, но это требование Lispерса.