Как создается или создается новый язык программирования?

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ерса.