Если бы вы разработали язык программирования, как бы вы это сделали? Какие функции вы бы добавили? Что бы вы оставили? Статически или динамически типизировано? Сильно или слабо напечатано? Скомпилировано или интерпретировано? Обоснуйте свои ответы.
Если бы вы разработали язык программирования, как бы вы это сделали? Какие функции вы бы добавили? Что бы вы оставили? Статически или динамически типизировано? Сильно или слабо напечатано? Скомпилировано или интерпретировано? Обоснуйте свои ответы.
Ответы:
Я определенно думаю, что функциональные языки программирования будут популярны, поэтому мой язык будет функциональным. См. Эффекты укрощения с помощью функционального программирования
Я думаю, что процессоры скоро будут иметь огромное количество ядер, а потоки будут ему чертовски управляемы. Таким образом, модель актера обязательна, а не темы. Посмотрите Erlang - программное обеспечение для параллельного мира
Я также думаю, что ООП не удалось, связь между объектами предполагалась асинхронной . Поэтому я думаю, что нам нужна передача сообщений с неизменными сообщениями. Отправь и забудь. Как в актерской модели. См. Объектно-ориентированное программирование: неправильный путь?
Я думаю, что было бы хорошо иметь статическую типизацию , чтобы ошибки улавливались ранее в цикле разработки. Но я бы использовал вывод типа, как в Haskell, так что разработчику не нужно писать тип везде в коде, как в C, C # и Java. См. Learn You A Haskell для большого блага
Я также разработал бы отличную библиотеку пользовательского интерфейса с декларативным макетом , как в WPF и Android. Но я бы хотел, чтобы это было как в функционально-реактивном программировании .
Таким образом, мой язык был бы похож на параллелизм в Erlang, но с типизацией, как в Haskell, и структурой GUI, как в WPF.NET.
Примечание: я использовал C-подобный синтаксис для описания функций в этом посте, но я не придирчив к самому синтаксису, если он не является чем-то нелепым, как все ключевые слова, являющиеся CAPS.
1. Печатная система
Функцией номер один, которую я хотел бы видеть в языке, является статическая типизация с необязательной динамической типизацией. Причина в том, что статическая типизация позволяет вам: а) отлавливать ошибки раньше, чем поздно, и б) большая часть кода неявно статически типизируется, независимо от того, делает это различие в языке. Тем не менее, есть несколько случаев, когда динамическая типизация чрезвычайно полезна. Например, при чтении данных из файла у вас часто есть поля разных типов, а динамическая типизация упрощает разнородные контейнеры. Итак, мой идеальный язык будет выглядеть примерно так:
//variable declarations
int anInt = 42 //anInt is now irrevocably an integer and assigning another type to it is an error
vartype aVariable = 42 //aVariable is currently an integer, but any type can be assigned to it in the future
//function definitions
int countElements(Collection c)
{
return c.count();
}
//c HAS to be a collection, since countElements doesn't make sense otherwise
void addToCollection(Collection& c, vartype v)
{
c.append(v)
}
//c is passed by reference here
2. Скомпилировано и интерпретировано
Мне бы хотелось, чтобы язык был либо скомпилирован заранее, либо скомпилирован JIT, но не просто интерпретирован, причина в скорости. Это связано с пунктом 1 , поскольку оптимизирующему компилятору / джиттеру будет гораздо проще оптимизировать статически типизированный код, а динамически типизированный код можно просто оставить как есть.
3. Закрытия
Язык должен поддерживать функциональные программные конструкции, а функции должны быть первоклассными объектами.
4. Объектно-ориентированный
Язык должен позволять вам писать объектно-ориентированный код, но должен быть разрешен и простой императивный код. то есть должна быть возможность написать программу hello world примерно так:
int main(string<> args=null)
{
printf("hello, world");
return 0;
}
// this code also demonstrates two other features,
// default arguments for functions (not explained further)
// and immutable lists like string<> (see 6. Built-in datatypes)
5. Пространства имен
Пространства имен это хорошая вещь. Очень мало вещей должно войти в глобальное пространство имен. Но если вы должны поместить вещи в глобальное пространство имен, вы можете (ала C ++).
6. Встроенные типы данных
Язык должен иметь в качестве встроенных типов данных следующие конструкции:
int
Тип данных или типов. Если есть только один int
тип, он должен иметь неограниченный диапазон. Если их больше, должно быть неявное преобразование в наименьший тип, способный хранить результат вычисления, причем тип неограниченного диапазона является наибольшим.float
тип, который эквивалентен IEEE 754double
list
тип, который реализован либо как двусвязный список, либо как блок непрерывной памяти, содержащий указатели на каждый элементlist
тип, который действует как массив, но размер которого не может быть изменен после созданияstring
типы, по умолчанию неизменяемые.map
или dict
тип, который является изменяемым и содержит неизменяемые ключи и изменяемые и / или неизменяемые значения.vartype
при необходимости их можно использовать d.boolean
типаnull
или none
тип, который может быть назначен переменной любого типа.set
типыdecimal
Тип , который реализует десятичных чисел с плавающей точкой переменныеfixed
Тип, который реализует фиксированной запятойdecimal
,float
и fixed
типы должны делиться точной такой же публичный интерфейс (либо через наследование или утиной типизации), что позволяет им быть прозрачно передается и возвращается из функции. Родительский тип может быть вызван real
.
7. Звоните по значению и по ссылке
Вы должны иметь возможность вызывать функции как по значению, так и по ссылке, причем значением по умолчанию является значение (т. Е. Копия функции создается и обрабатывается в функции).
8. Указатели
Язык должен иметь указатели и разрешать арифметику указателей. Указатели могут быть набраны только статически (чтобы избежать кошмара void*
).vartype
указатели явно запрещены. Наличие указателей и арифметики указателей позволяет серьезно использовать этот язык в качестве языка системного программирования.
9. Встроенная сборка
В связи с 8. Язык должен разрешать встроенный ассемблерный код для тех ситуаций, где это необходимо.
10. Безопасность
Язык должен быть в основном безопасным для использования, поддерживающим обработку исключений и т. Д. Арифметика указателей и встроенная сборка могут передаваться частям кода, явно помеченным как небезопасные. Небезопасный код разрешен, но настоятельно не рекомендуется.
11. Неопределенное поведение
Стандарт языка должен указывать, как программа должна вести себя при любых обстоятельствах, за исключением кода, явно помеченного как небезопасный, т. Е. Не должно быть неопределенного поведения вне небезопасных блоков. Это позволяет использовать этот язык в качестве жизнеспособного языка разработки приложений, в то же время позволяя сказать, что вы пишете ОС на нем.
Это все, что я могу придумать в данный момент, но я буду редактировать / обновлять пост по мере того, как буду думать о других вещах.
decimal
тип здесь.
Вот как должен выглядеть язык программирования моей мечты:
yield
в Smalltalk? Должен быть максимально чистым в использовании.
Я бы разработал его почти как C #, но Microsoft опередила меня. :)
(За исключением, конечно, что мой был бы менее продуманным и более любительским.)
Я не возражаю против того, компилируется ли это или интерпретируется, поэтому мне не нужно оправдывать это.
Что касается строгой статической типизации, мне трудно понять, почему это даже требует обоснования. Статическая типизация - это функция, которая улавливает ошибки во время компиляции. Динамическая типизация является недостатком этой функции и откладывает ошибки до времени выполнения. По моему личному опыту у меня было несколько случаев, когда динамическая диспетчеризация имела смысл и была полезна, поэтому извилины, которые мне пришлось пройти в C # до 4.0, чтобы получить ее, были легко оправданы. С C # 4.0 мне даже не нужно больше это оправдывать, потому что сейчас у нас динамическая отправка.
Тем не менее, я, вероятно, создал бы новый синтаксис вместо того, чтобы придерживаться столь же религиозно старого синтаксиса C, как C #. Оператор switch особенно ужасен, и мне также не нравится синтаксис приведений (он неправильный). Я не особо суетюсь о деталях синтаксиса, поэтому мне не нужно подробно его обосновывать, за исключением того, что я не хочу, чтобы он был столь же многословным, как Visual Basic.
Что еще вы хотели бы, чтобы я оправдал?
Вот список функций, которые я бы добавил:
Лисп стиль
Плюсы :
(eval "your data files")
Минусы :
Стиль Haskell
Плюсы :
Минусы :
Стиль Python
Плюсы :
Реализация :
Разрешить перегрузку функций на основе типов, аналогичных CL defgeneric
:
(define (+ (a <int>) (b <int>))
(ints-add a b))
(define (+ (a <string>) (b <string>))
(string-concat a b))
(define (+ a b)
(add-generic a b))
Плюсы :
Минусы :
Стиль С
Плюсы :
Минусы :
Плюсы :
Минусы :
Если подумать, это более или менее определяет схему, за исключением бит компиляции и системного программирования. Это можно обойти, используя libguile и записав эти биты в C.
car
функция и cdr
аргументы - у вас есть объект, name
поле которого является методом, а arguments
поле которого является аргументами. И вместо вложения у вас есть prev
и next
поля указателя.)
Есть несколько языков, которые я считаю чертовски хорошими (C # - мой любимый в настоящее время). Так как это мой фэнтезийный язык, вот что я действительно хочу иметь:
Я не в себе, потому что не очень разбираюсь в языковом дизайне, но думаю, что функция, о которой я говорю, называется подсказками на других языках. Подсказки компилятораМожет ?
Я не знаю, читал ли я это в черновике Perl6 или в тот момент был просто высок, но я представляю себе язык, на котором все по умолчанию выглядит неопрятно и автоматически. Но если вы действительно хотите повысить производительность и сказать: «Эй, это значение всегда целое число или оно никогда не равно нулю, или оно может быть параллельным, или это состояние без состояния, и тому подобное ... Что компилятор может автоматически отправиться в город» на этих специально отмеченных областях.
E: Я был бы признателен за комментарии, разъясняющие то, что я прошу, или за примеры, где это уже существует
safety
и speed
значения, вы можете часто либо имеют проверку компилятора и приведении в исполнение (чтобы найти проблемы) или предположим , что вы говорите, правда (и компилировать быстрый код).
Чтобы попробовать новые идеи:
Я бы сделал функциональный язык программирования с динамической типизацией, он позволяет вам выполнять все трюки с выражениями операторов и простейший лямбда-синтаксис с сопоставлением с образцом. Правило офсайта включено.
// a view pattern (or Active Pattern in F#)
default = \def val: !!val.Type val def
// usage of the pattern
greet = \name<(default "world") `and` hasType Str>:
p "Hello, \{name}!"
(p "Enter your name", .input).greet // (, ) is a sequence expression, returning the last value
Вот объяснение:
default =
устанавливает хранилище, \def val
начинает карри функцию с двумя аргументами, val.Type
аналогично Type[val]
, !!
преобразует в логическое, и может применяться логическое, val
иdef are after it.
f x
= f[x]
= x.f
.f
=f[]
и в greet
, он использовал name<(default "world")
и hasType Str>
, это означает, что шаблон default "world"
будет использоваться и привязан к name
. Шаблон по умолчанию определяет значение по умолчанию.
and
это еще один шаблон, который связывает два шаблона вместе. default
шаблон не может потерпеть неудачу , а hasType
может потерпеть неудачу. В этом случае он создает исключение.
Переменные на самом деле являются хранилищами, которые можно функционально передавать, а таблицы хранилищ могут быть ссылками, создаваемыми и уничтожаемыми по мере изменения областей.
Хеши и тому подобное будут как в Lua и JavaScript.
Если я собираюсь сделать скомпилированный язык, я собираюсь сделать F # для Java с функциями, подобными Haskell. Это чисто функциональный язык, за исключением того, что есть функция, которая смешивает цитаты и выражения Comp вместе, чтобы достичь императивного программирования путем написания псевдокодоподобных блоков.
Принимая во внимание, что единственные языки, которые я знаю, это PHP и javascript, и что я действительно должен выучить еще несколько, прежде чем создавать язык:
Синтаксис: Тщательно продумайте имена функций и порядок аргументов (т. Е. Будьте менее беспорядочными, чем PHP).
Особенности:
Имеют набор string
функций, которые работают с переменными в виде последовательности байтов, но не понимают текст, и набор text
функций, которые понимают множество кодировок и могут работать с UTF-8 и другими многобайтовыми строками. (И встроенные в язык проверки работоспособности кодирования с такой функцией, какtext.isValidEncoding(text, encoding)
которая сообщит вам, если последовательность байтов искажена и небезопасна для восприятия как текста.
Мне кажется, мне нравится идея строгой статической типизации, но я никогда не использовал ее, поэтому не могу сказать точно.
Прежде чем приступить к разработке языка программирования, я нашел бы хороший ответ на вопрос: зачем нам нужен еще один язык программирования? Розетта Код на момент написания этой статьи перечисляет 344 языка. Если ни один из них не отвечал моим потребностям, специфика того, почему они этого не сделали, определила бы отправную точку (наиболее близкие языки) и что было бы к ней добавлено.
Если бы я выиграл в лотерею и по какой-то причине мне было нечего делать, я бы начал с Liskell и сделал его полноценным языком в отличие от внешнего интерфейса GHC, а затем упростил (и автоматизировал) FFI, чтобы я мог использовать любой C / C ++ библиотека.
Хороший язык - это язык, который:
Довольно сложно превратить это в список функций, но я думаю, что функциональное программирование, несмотря на то, что оно не кажется естественным , ближе к этому, чем императивное программирование (особенно в сокрытии мельчайших деталей)
На данный момент языком ближе к этому списку, вероятно, является Haskell:
На ваш первый вопрос «как бы вы это сделали» - короткий ответ, я бы не стал. У меня недостаточно теории парсера / компилятора, чтобы это осуществить. Но я программирую уже 25 лет, поэтому у меня есть некоторые идеи и мнения, которыми можно поделиться.
Прежде всего, я бы попытался придумать подход ООП, который позволит вам создавать действительно связанные модели. Под этим я подразумеваю, что модели - это одна из самых важных вещей практически в любом программном проекте: для их правильной работы всегда требуется много работы и постоянный рефакторинг, и я виню в этом отсутствие реальной связи в ОО языки.
Позвольте мне продемонстрировать. Допустим, у класса House есть свойство Door.
var door = house.Door;
Теперь у вас есть локальная переменная со ссылкой на экземпляр Door.
Но подумайте о том, что только что произошло: вы только что сорвали Дверь с Дома, и теперь вы совершенно счастливы, передавая Дверь вокруг, а остальная часть вашего кода не знает о том факте, что эта Дверь фактически прикреплена к Дому.
Для меня это в корне неправильно.
И да, я знаю, это «легко» исправить в каждом конкретном случае - в данном случае путем сохранения обратной ссылки от каждой двери в дом, к которому она в настоящее время прикреплена. Это, конечно, открывает вашу модель для ошибок, так как теперь ваша обязанность точно поддерживать две обратные ссылки, поэтому вы делаете свойства House.Doors и Door.House закрытыми и добавляете такие методы, как House.AddDoor (), House.RemoveDoor ( ), Door.SetHouse () и т. Д. И подключите все это, а также выполните модульное тестирование, чтобы убедиться, что оно действительно работает.
Разве это не начинает казаться большой работой, чтобы смоделировать такие прямые отношения? Много кода для поддержки? Много кода для рефакторинга по мере развития модели?
Проблема в указателях. Каждый язык ОО, который я видел, по своей природе страдает от того факта, что ссылка на объект на самом деле является указателем, потому что это то, что используют компьютеры.
Указатели не являются хорошим способом моделирования реального мира. Независимо от того, какой мир вы пытаетесь смоделировать, почти гарантировано, что любые отношения в этом мире будут двусторонними. Указатели указывают только в одном направлении.
Я хотел бы видеть язык, где фундаментальной моделью данных является граф - где все отношения, по умолчанию, имеют два конца. Это почти наверняка обеспечило бы гораздо более естественную пригодность для моделирования реального мира, и это действительно единственное, для чего нам в первую очередь нужны компьютеры. (это и видеоигры.)
Я понятия не имею, как будет выглядеть синтаксис для такого языка или его можно даже выразить с помощью текста. (Я задавался вопросом, должен ли такой язык быть графическим, так или иначе ...)
Я также хотел бы, чтобы все формы случайного состояния были устранены.
Например, в веб-разработке мы тратим много времени на формирование данных из баз данных, в бизнес-модели, в модели представления для представления ... затем некоторые из этих данных представляются в формах, что на самом деле является еще одним преобразованием. ... и состояние возвращается из форм-постов, а затем мы изменяем эти данные и проецируем их обратно на модель представления, например, связыватели модели представления и т. д. Затем мы проецируем из модели представления обратно на бизнес-модель. модель ... затем мы используем объектно-реляционные картографы (или грубую работу) для преобразования данных из модели представления и проецирования их в реляционную базу данных ...
Это начинает звучать избыточно? В какой момент во время всего этого безумия мы действительно совершили что-то полезное? И под полезным я подразумеваю нечто материальное - то, что конечный пользователь может понять и заботиться о нем. В конце концов, часы, которые вы потратили на создание чего-то, что пользователи могут понять, на самом деле являются единственными часами, проведенными с пользой. Все остальное - побочные эффекты.
Я хотел бы очень динамичный язык. Цикл записи / компиляции / выполнения - это утомительная трата времени. В идеале язык должен просто выяснять, что изменилось, и прозрачно компилировать / загружать в фоновом режиме, по мере необходимости.
В идеале вам даже не нужно нажимать «выполнить» - все должно происходить на экране, когда вы вносите изменения, немедленно отражая сделанные вами изменения. Проблема с циклом записи / компиляции / выполнения или даже с более прямым циклом записи / запуска заключается в том, что вы слишком оторваны от того, что делаете, - чтобы чувствовать связь с нашей работой, мы нужна немедленная обратная связь, мгновенные результаты. Любое ожидание слишком долго!
Опять же, я даже не знаю, можно ли это сделать с помощью традиционной IDE или для этого потребуется совершенно новый интерфейс.
Вы должны быть в состоянии использовать сочетание слабой и строгой типизации, что наиболее подходит для проблемы, над которой вы работаете.
Государство вообще должно быть чем-то, что язык полностью управляет для вас. Почему вы должны полагаться на базу данных для сохранения? В идеале я хотел бы иметь возможность просто указать срок жизни любой переменной в модели: один веб-запрос, один сеанс, 24 часа, навсегда.
Почему мы должны выбирать между целым рядом решений для хранения данных для разных носителей и сроками жизни? - не говоря уже о преобразовании и формировании данных для каждого носителя; кеш браузера, база данных, память, диск, кому какое дело! Данные есть данные. Где вы храните свои данные (и как долго) должен быть простой выбор, а не битва против богов!
Ну, удачи тебе в этом.
Вероятно, это будет мультипарадигмальный язык, поддерживающий следующее:
Почему эти? Объектно-ориентированный, потому что это отличный способ организации больших программ, особенно для организации данных. Структурированный, потому что вы не всегда хотите / нуждаетесь в этом (ООП), у людей должен быть выбор. Функциональный, поскольку он облегчает отладку программистам и делает программы более понятными.
Я бы использовал модель Python с отступом блоков, чтобы пометить блоки кода. Это очень приятно и приятно читать.
Я бы украл довольно много идей из Python, потому что Python - очень хороший язык. Я бы взял это для утверждения, и я бы скопировал его карты, список и кортежи.
Теперь я бы, вероятно, не взял бы динамические концепции из Python: во-первых, это, вероятно, было бы явно и статически типизировано. Я думаю, что программы становятся более понятными с этим. Все переменные, вероятно, будут объектами с методами, тогда вы можете сделать что-то вродеstr.length()
получения длины строки. В определениях функций вы должны будете указать тип возвращаемого значения и типы аргументов (поддерживая также некоторые типы универсальных типов).
Вернемся к копированию с Python ;-). Мне нравится, что у этого способа есть необязательные аргументы процедуры, так что я бы, вероятно, имел это Однако Python не поддерживает перегрузку процедур, я бы этого хотел.
Давайте посмотрим на классы, я бы отказался от множественного наследования; легко злоупотреблять. Я бы реализовал частные и подобные области и, вероятно, реализовал бы так, как это делается в C ++. У меня также были бы абстрактные классы и интерфейсы; Я не верю, что у Python есть это.
Он будет поддерживать внутренние классы, на самом деле, мне нужен очень мощный объектно-ориентированный язык.
Это, вероятно, будет интерпретировано. Можно получить его очень быстро, используя хорошую JIT-компиляцию (я бы хотел быстрый язык, хотя продуктивность программиста была бы на первом месте), и компиляция во многих случаях просто вредна для производительности. Интерпретируемые языки также способствуют независимости платформы, что каждый день приобретает все большее значение.
Это будет иметь встроенную поддержку Unicode; В наши дни интернационализация имеет большое значение.
Это определенно будет сбор мусора. Черт, я ненавижу заниматься управлением памятью самостоятельно; не хорошо для производительности либо.
Наконец, у него будет хорошая стандартная библиотека.
Вау, только что понял, как сильно я люблю Python.
Interpreted languages also promote platform independance
? Я предполагаю, что есть больше кроссплатформенных интерпретаторов, а не компиляторов (в процентах), но не мог понять, почему это предложение должно быть правдой? Я думаю, что нет никакой разницы между ними в отношении кроссплатформенных возможностей.
Прежде всего, я бы купил несколько книг по компиляторам, несколько стандартов и взял бы курс или два по языкам и компиляторам. Я бы поспособствовал PEP и посещал заседания комитета по стандартам C ++. Я бы добавил патчи к компиляторам, которые я использую, надеюсь, как для функций, так и для ошибок.
Тогда я бы вернулся и с ужасом посмотрел на этот список, который я сейчас составил, в котором указано, в каком направлении я бы пошел с языком, если бы начал прямо сейчас:
Видя, что даже эти довольно широкие моменты, вероятно, быстро изменятся, если я начну внедрять язык, поэтому я думаю, что вдаваться в дальнейшие детали не нужно.
Если бы у меня было время, я бы разработал локализуемый язык программирования, основанный на Scala, поэтому он имел бы большинство своих функций, за исключением, вероятно, XML. Моя цель - сделать язык, который почти естественным образом читает на языках с иной структурой, нежели английский, например арабский (мой родной язык). Я думаю о следующих особенностях:
#lang
Директива препроцессора , используемая для информирования препроцессора о человеческом языке, используемом для программирования. Например: #lang ar
позволит использовать слово فئة
вместо class
, عرف
вместо def
, и так далее. Ключевые слова для человеческого языка будут определены в стандартных файлах препроцессора.class MyClass is composed of {
чтобы стать class MyClass {
, и удалить «как», def MyMethod(x: Int) as {
чтобы стать def MyMethod(x: Int) {
. На некоторых (человеческих) языках это сделает код намного проще для понимания, особенно для студентов.اعرض طول اسم محمد
, что эквивалентно английскому на языке print(length(name(Mohammad)))
программирования. (Скобки для ясности.)Я считаю, что эти минимальные изменения в препроцессоре и компиляторе сделают программирование намного проще для не говорящих по-английски.
print
) не повредит.