Как бы выглядел ваш собственный (я предполагаю, идеальный) язык программирования? Приведите небольшой пример и объясните свои идеи романа!
Мне очень нравится синтаксис.
Как бы выглядел ваш собственный (я предполагаю, идеальный) язык программирования? Приведите небольшой пример и объясните свои идеи романа!
Мне очень нравится синтаксис.
Джон прав, говоря, что "[d] ifferent задачи подходят для разных языков и парадигм". Однако есть несколько соображений, которые в значительной степени не зависят от домена. В основном это касается синтаксиса, но поскольку код читается чаще, чем написанный, я действительно думаю, что синтаксис имеет значение.
С одной стороны, и что-то, что многие языки делают неправильно, он совершенно произволен, чтобы закрепить синтаксис C. C. На самом деле имеет исключительно плохой синтаксис. Я просто возьму два примера.
Первое довольно непротиворечиво: точки с запятой не нужны. Возьмите следующий код; грамматика полностью однозначна и легко анализируется для компилятора. Не нужны ни точки с запятой, ни явные линии.
answer = 42
fraction = answer * 2 /
(answer + 1)
Console.WriteLine(
"Some funny number: {0}",
fraction
)
Это на самом деле очень похоже на Python, но еще более разрешительное: определение fraction
охватывает несколько строк. Это логично, так как первая строка еще не завершена.
Другая кость, которую я должен выбрать с синтаксисами типа C, - это их в основном неявные объявления переменных. Вместо того, чтобы ясно объявлять "я объявляю variable
типа Foo
", все они застенчиво шепчут: "Foo var
". Поскольку Foo
в большинстве случаев не является даже зарезервированным словом, программисту здесь не предлагается один визуальный намек. Я предпочитаю VB явный Dim var As Foo
, даже думал, что его ключевое слово используется здесь, ну, довольно тусклое.
(С++ на самом деле делает многое гораздо хуже, вводя много почти идентичных и часто двусмысленных синтаксисов, которые означают совершенно разные вещи, от переменных инициализаций до деклараций функций).
Еще одна вещь, которую должен иметь мой язык - это статическая типизация. Это правда, что динамическая типизация имеет свои применения, но они удивительно редки. Даже большинство "скриптовых языков" им действительно не нужны. Я думаю, что это часто путают с неявной типизацией, которая имеет больше возможностей использования. Возьмите (снова) пример Python. Почему он не предлагает статическую типизацию? Он уже строго типизирован, проверка статического типа будет только следствием, и немного покончит с отладкой. То же самое относится к явному объявлению переменной. Я не вижу, какие преимущества подразумевают предложения объявления переменных.
Итак, у нас уже есть схема для языка:
Кроме того, я являюсь огромным поклонником некоторых концепций С++, таких как шаблоны общего назначения, RAII (т.е. избегая мусора, а не его сбора), неизменности и концепции диапазонов значений, определенных с помощью итераторов. Я сказал в другом месте, что считаю, что итераторы являются одним из самых фундаментальных новшеств. Дайте немного помады, и вы даже не узнаете уродливого зверя, который является С++:
for i in MyVector:
print(i)
а не
for (typename vector<T>::const_iterator i = MyVector.begin();
i != MyVector.end();
++i)
cout << *i << endl;
Конечно, я знаю, что вышеупомянутый синтаксис предлагается многими языками. Но все они предлагают только остывшие версии сильной итераторской концепции С++ (для использования терминологии С++ единственный тип итераторов, который знает большинство языков, - это итераторы ввода, которые в основном являются наименее мощными итераторами).
На этом этапе я, вероятно, должен сказать, что единственным авторским правом для всех этих идей является мой, патенты, ожидающие рассмотрения (в частности, для MayOrMayNotBe
operator, который действительно не сравнивает ссылки на объекты).
Немного загадочный, но это то, что мне бы хотелось:
У меня нет понятия "идеального" языка программирования, потому что нужно выполнить не одну задачу.
Различные задачи подходят для разных языков и парадигм.
Это будет выглядеть как С#. Я хотел бы иметь Microsoft!
Мой идеальный язык позволил бы мне улучшить функциональность, поскольку мне это нужно. Если мне нужно написать небольшую прямолинейную служебную программу без классов, я бы мог. Если мне нужно было использовать классы, я тоже мог бы это сделать, и если бы я захотел написать полностью объектно-ориентированное решение, я тоже смог бы это сделать. Компилятор был бы достаточно умен, чтобы позволить мне создавать небольшие быстрые утилиты командной строки (без зависимостей во время выполнения) или самого большого раздутого графического приложения OOP, которое я мог себе представить.
Проблема в том, что то, что мне нравится, имеет противоположные цели, и поэтому я всегда был вынужден использовать совершенно разные языки. В настоящее время я не использую ни один особый порядок PowerShell, VBScript, PowerBasic, Java и С# (а иногда и VB.NET, VB 6, С++, Python и Perl).
Теперь, если бы я мог сделать все это с одним С#, как язык, который имел глобальные функции без зависимостей во время выполнения при создании этих небольших приложений, но позвольте мне в полной мере использовать возможности .NET Framework и Java SDK, когда мне нужно было, Я был бы счастлив.
Идеальные языки программирования, как правило, можно найти в научно-фантастических романах. Например:
Все это доходит до того же основного затруднения. Любой язык программирования, который не заставляет человека учиться навыкам, как правило, ограничивает свободу мысли. Естественный язык тоже не хорош, поскольку он имеет много двусмысленностей.
Я бы не возражал против того, чтобы сочетать свободу с силе и минимальный синтаксис. Недавно я начал изучать lisp, и пока это кажется очень хорошим.
Массивный parallelism уполномоченный Amazon Mechanical Turk.
job = "Upvote this answer"
@price = "$0.01"
fork(10000, job, @price)
Я большой поклонник макросов C, но я подумал, что было бы неплохо, если бы вы могли писать макросы или мета-код на том же языке, который вы используете. (C - плохой пример, это может быть хорошо на языках сценариев.)
В этих примерах я использую фигурные скобки для идентификации метакода. Вы могли бы запустить источник через "препроцессор", чтобы расширить метакод. В противном случае он просто будет расширяться один раз во время выполнения.
print "Your product ID is: ", { print '"', generateGUID(), '"' }
или
lookupTable[] = {
/* insert code to generate table here
*
* This lets you modify the algorithm easily
* but speeds up the final program.
*
* This would be especially appropriate in
* cases where you would otherwise type out
* the table as a literal (yuck)
*/
}
Время от времени мы должны писать несколько строк очень повторяющегося кода; не может придумать хороший пример прямо сейчас, но этот вид мысли также будет очень полезен в таких ситуациях.
Это не будет сильно отличаться от лучших идей Эйфеля и С# (потому что, я просто не знаю, как лучше придумать, я не изучил CS).
Однако моя основная практическая задача заключалась в том, чтобы выйти за рамки классического подхода "текст исходного кода" . Я знаю, что это (или звучит) вещь IDE, но почему я не могу иметь настраиваемый вид кода с такими столбцами, как preconditions/body/postconditions вместо "линейной" формы (i):
function f
// f preconditions
// f body
// f postconditions
end
function g
// g preconditions
// g body
// g postconditions
end
Почему бы не (ii) - представьте, что это таблица (с границами):
f f parameters f prec f body f postc f comments
g g parameters g prec g body g postc g comments
А также почему я не могу выбрать, как функции "начинаются" и "заканчиваются" (фигурные скобки, ключевые слова...) в стиле (i)? Почему я не могу сразу показать или скрыть частных или защищенных членов? Почему я не могу сразу увидеть "плоскую версию" со всеми унаследованными функциями внутри? и др.
Точка не будет иметь один файл священного кода, где вы редактируете, а затем несколько "классных просмотров", но чтобы иметь возможность редактировать и добавлять код как в (i), (ii), так и в любую форму, наиболее полезную для вы.
В некотором смысле, говорить о "IDE" может показаться не по теме. Но OTOH Я думаю, что это изменит способ написания и чтения кода рано или поздно. И это в конечном итоге повлияет на развитие языков. Будущие цели состоят в том, чтобы повысить не только читаемость, но также "понятность" и интерактивность.
Я бы предположил, что мой будет где-то между Brainf * ck и LOLCODE, кроме как с A LOT больше круглые скобки.
Мультимедийная.
Я хочу, чтобы иметь возможность рисовать некоторые графические символы, быстро эскизировать соединения, а затем переходить в другие режимы, такие как ввод текста, где необходима точность.
Я также считаю, что программирующие языки должны поддерживать людей, которые не думают по-английски (да, даже американцы..... шутя!). Я изучил достаточное количество японцев и попытался забрать некоторых индонезийцев - я бы хотел, чтобы люди, поддерживающие язык, имели разные грамматические конструкции и заказы.
Я поднял вопрос на недавнем форуме, в котором я участвовал в будущем сети, спрашивая у китайского профессора, если он считает, что китайский письменный язык будет более правдоподобным для обеспечения работоспособной семантической сети, чем английский. Он был заинтригован этим понятием.
Много SF, которое я читаю, рассказывает о будущем интерфейсе для взаимодействия с компьютером:
Python довольно близок к идеалу для меня... Я бы просто избавился от некоторых неприятностей, таких как наличие ключевого слова self... но с хорошим редактором Python может делать удивительные вещи очень быстро...
Я представляю себе язык, которому должны быть указаны точные ограничения на вход и переменные и порядок выполнения, и поэтому их можно скомпилировать в быстрое многопоточное (или кластерное) программное обеспечение.
И вот интересная идея: представьте, что все "утверждения" внутри "функции" могут быть выполнены в любом порядке вообще. Если что-то зависит от чего-то другого, вам нужно "явно вызвать" зависимость. Это сделало бы конструкцию для parallelism неотъемлемой составляющей языка.
К сожалению, я не инвестировал достаточно воображения, чтобы придумать что-то более конкретное.
Clojure приближается...
Я не уверен, как будет выглядеть мой язык моей мечты, но у меня есть небольшое улучшение для языков C-стиля. Сколько раз я писал что-то вроде этого:
Node foundNode = null; // need stupid null value here to keep track if it was not found
foreach (Node testNode in nodes) {
if (testNode.YesItsMe) {
foundNode = testNode;
break;
}
}
if (foundNode == null) {
// create new instance
foundNode = new Node(blabla);
}
Я знаю, что для этого есть более элегантные функциональные способы, но иногда у вас все еще есть такой код. Простое выражение "охранник" поможет здесь:
Node foundNode; // no need to initialize anymore
foreach (Node testNode in nodes) {
if (testNode.YesItsMe) {
foundNode = testNode;
break;
}
} guard { // we get here if break was never called
// create new instance
foundNode = new Node(blabla);
}
Язык, который не имеет структуры или переменных, только одна функция.
doEverything();//автоматическая генерация всего содержимого на основе уже прогнозируемого ввода
Мой идеальный язык программирования, код был бы умным, он сказал бы мне, если бы у него была проблема с другим фрагментом кода, мы бы сесть и поговорить, и это скажет мне, в чем проблема, чтобы мы могли это решить... Я называю это "EmotionPeople ++"
Мне нужен язык программирования, который делает инструменты очень легкими для записи правильно. Метод извлечения, раскраска, автозаполнение, компиляция и т.д.
Я хочу, чтобы это произошло, когда все еще легко писать и читать легко.
Он будет выглядеть точно так же, как Scheme. Только он скомпилировал бы как IL, так и Java байт-код, и сборку, чтобы я мог использовать все эти библиотеки.
Один язык разрабатывает для достижения конкретных целей. Синтаксис и семантика должны следовать желаемой функции.
В моем случае мне нужен язык с мелким зерном parallelism, то есть очень низкие накладные расходы на зерно, чтобы позволить небольшие куски код, который должен быть распараллелен.
Я разработал и реализовал его на x86-системах SMP, и он использовался в течение примерно 10 лет в качестве основы для крупномасштабных инструменты анализа программного обеспечения.
Главное - позволить мне (нам) указать parallelism легко:
(|| A B)
выполняет A и B параллельно, и пусть компилятор генерировать всю краду, которая делает это возможным. Нам неважно, был ли синтаксис infix или нет, поэтому мы пошли LISP стиль, чтобы избежать аргументы.
Документ, описывающий язык и ряд параллельные приложения можно найти в http://www.semanticdesigns.com/Company/Publications/parallelism-in-symbolic-computation.pdf
В документе кратко обсуждается, как мы не удастся избежать аргументов по синтаксису несмотря на наше решение.
Я начну с ключевых функций:
В настоящее время наиболее близким к моему списку пожеланий является Clojure, что указывает на большинство этих требований.
Поскольку OP ссылается на синтаксис, я приведу несколько примеров кода:
Собственные функции переменной arity с поддержкой больших списков аргументов:
(+ 1 2 3 4 5)
=> 15
(apply + (range 10000))
=> 49995000
Интерактивный доступ к компилятору во время выполнения:
(def function-string "+")
(def function (compile-string function-string))
(function 7 8 9)
=> 24
Выполнение распределенного кода (стиль MapReduce). Обратите внимание, что это означает, что язык/библиотека может принимать локально определенный some-long-running-function
и прозрачно распространять его на все узлы в кластере для выполнения во время выполнения.
(def my-cluster
(create-compute-cluster :nodes 100 :service "Amazon"))
(defn some-long-running-function [input]
....)
(def reduction-function
(fn [a b]
(do-something-to-reduce a b)))
(def lots-of-inputs (range 10000))
(distributed-map-reduce
my-cluster
some-long-running-function
inputs
reduction-function)
=> (whatever the result of the mapreduce is over the cluster)
Правильный вывод типа (т.е. компилятор выясняет, что моя функция всегда возвращает строку и соответственно делает оптимизацию/выводы:
(def my-function [name]
(str "Hello " name "!"))
(my-function "Bob")
=> "Hello Bob!"
(compile-time-type my-function)
=> [java.lang.String :not-null]
Мой оптимальный язык будет выглядеть так же, как Nemerle (минус произвольные ограничения). На самом деле это сводится к средствам метапрограммирования; Я должен иметь возможность произвольно расширять или модифицировать язык любым способом, который я считаю подходящим (период), чтобы идеально подойти к домену.
Дайте мне макросы, которые позволяют мне работать над АСТ всего кода, как я желаю, и я могу построить свой идеальный язык.
Он был бы машиносчитываемым/записываемым, и он был бы написан интеллектуальным программным обеспечением, которое берет инструкции голосом.
Хм. Это сложный вопрос. Мои вкусы бегут к легко понятным для человека и легким сценариям (хотя я считаю, что это может работать для более крупных приложений). См. Фрагмент кода:
function Foo takes x as string, y as boolean //can add returns [return type] if one wishes to be explicit
//explicit variable declaration
z as number
//explicit cast from boolean to number
z is y as number
//implicit variable declaration
bar is 3 * 5
//function call
print x
return z / bar //since we casted z to a number, it returns a number
Я хотел бы видеть средство для функции, которое включает произвольное количество параметров для ссылки и передает их во вложенный вызов функции. В .net это можно сделать для любого фиксированного числа общих параметров через что-то вроде (показан вариант с двумя дополнительными параметрами):
// I forget the C# syntax for delegates, since I normally code in vb delegate void RefAction<T1, T2, T3>(ref T1 p1, ref T2 t2, ref T3 p3); Point myPoints[]; void DoSomethingWithIndexedPoint<XT1, XT2>(int index, RefAction<Point, XT1, XT2) theAction, ref XT1 xp1, ref XT2 xp2) { theAction(myPoints[index], xp1, xp2); }
Мой предпочтительный синтаксис будет выглядеть примерно так:
delegate void RefAction<T1, T2, T3>(ref T1 p1, ref T2 t2, ref T3 p3); Point myPoints[]; void DoSomethingWithIndexedPoint<ref ...>(int index, RefAction<Point, ref ...>, ref ...) theAction, ref XT1 xp1, ref XT2 xp2) { theAction(myPoints[index], ...); }
где "..." автоматически будет расширяться компилятором любым способом. Такой механизм позволит использовать Lambdas во многих ситуациях без необходимости генерации экземпляров замыкания, а также позволит сделать код следующим образом:
Interlocked.CompareExchange(SomeObject["George"], SomeValue, SomeOtherValue);
который компилятор мог переписать как нечто похожее на:
SomeObject.ActUponProperty("George", (ref dest, ref p1, ref p2) => {Interlocked.CompareExchange(dest, p1, p2);}, SomeValue, SomeOtherValue);
Обратите внимание, что поскольку выражение лямбда не будет использовать какие-либо члены экземпляра или переменные, отличные от тех, которые были переданы как параметры ref, его можно было бы реализовать как статическую функцию и не нужно было бы создавать закрытие.