Как стать автором
Обновить

Комментарии 57

Круто! Языки программирования — моя любимая тема.
Язык выглядит красиво и юзабельно. Желаю вам продолжать работу над своим детищем.
var a = 1
while(a < 10)
    if(a % 2 == 0)
        print "{0} is even" a
    else
        print "oops, {0} is odd" a
    a = a + 1


После чтения данное кода, отказ от фигурных скобок мне показался сомнительным.
А что в нем не так? Вроде красиво выглядит. Ещё б в if и while скобки убрать.
Когда будет готов новый парсер, скобок там не будет.
Такой синтаксис выглядит непривычно, но со временем понимаешь, что и у него есть свои преимущества.
ещё добавить двоеточия в конце условий и определение функций как def -))
Гвидо, перелогинтесь ;)
Может лучше, что бы изначально синтаксис был привычным? И не надо будет «понимать» преимущества.
Или это мода такая, на каждый проект — свой скриптовый язык?
Изначально привычным для кого? Тем, кто писал на Python или F#, такой синтаксис вполне знаком. А всем сразу угодить нельзя.
Я не знаю что такое «красиво», но код непонятный.
a = a + 1 — это в теле цикла или уже нет?
Спасибо, кэп. Ладно если намёки не понимаете, скажу прямо: я понимаю, что лавры Python-а спать не дают и всё такое, но наверное не стоило бы вот так прямо тащить наиболее странные идеи, придуманые по обкурке одним известным голландцем.

Я понимаю, что все минусанувшие — аццкие монстры и легко на глазок определяют четыре в коде отступа или пять, например, но вот в том же MS немного подумали и в F# кроме lightweight cтиля сделали еще и begin… end несмотря на «набившие оскомуну»(ну и аргумент, блин!).
Ну, по одному пробелу на уровень никто не заставляет ставить, а отступы по 4 пробела или по табу вполне хорошо различимы.
Зато в языках со скобками вообще всё в одну строку можно записать.

Хотя лучший вариант это дать пользователю выбор синтаксиса. Тут я с вами согласен.
В питоне такая фича была, надо только найти (:
from __future__ import braces

Вы об этом?)
Именно (:
Если у вас в коде за 5 уровней вложенности, то у меня для вас плохие новости.
Стоит отметить, что в F# синтаксис в точности такой же. И ничего, никто не жалуется — даже когда-то отказались от синтаксиса со скобками (который был дефолтным) в пользу синтаксиса с отступами и опциональными begin / end.
Основная задача — переписать парсер с F# на C#

Перепишите лучше с использованием Nemerle.Peg.

А почему вариант с CCI не рассматривался?
На данный момент мы стараемся как можно больше сократить количество внешних зависимостей. В идеале, чтобы всё было в одной сборке без использования ILMerge — встраиваемый же, всё-таки, язык. Предубеждений против Nemerle не имеем :)
Вариант с CCI не расматривался по двум причинам: необходимость почти все переписать с нуля и внешние зависимости.
Спасибо, интересная подборка средств разработки компиляторов под .NET.

К сожалению, предполагаемая у меня архитектура (которая только в начале обдумывания) очень далека как от Вашего подхода, так и от начала реализации.
Но есть пара идей, которые считаю достойными реализации:
— модель уровней доступа, основанная на модели взаимодействия открытых систем
— компилятор компиляторов с модульным описанием языка habrahabr.ru/qa/38765/
Очень нужная штука. Надеюсь на серьёзное развитие. Чтобы можно было использовать в production и реализовывать на этих скриптах более сложные и тяжёлые вещи.
Спасибо! Развитие однозначно будет. Если у вас есть какие-то примеры того, что бы хотелось описывать, буду очень рад послушать.

С другой стороны, описывать особо сложные вещи на встраиваемом языке неправильно. Его основное назначение — быть гибким связующим звеном между другими компонентами. Именно поэтому в языке никогда не планировалась поддержка классов и интерфейсов.
Именно поэтому в языке никогда не планировалась поддержка классов и интерфейсов.

«Кортежей» (tuples) в принципе будет достаточно.
А чем Вас Iron(%whatever%) языки не устраивают?
А Lua с дотнетом не дружит?
Для скриптов в .NET приложениях есть:

  • IronPython, IronRuby и ещё целый зоопарк Iron* — высочайшее качество, производительность лучше референса, опциональная глубокая интеграция с CLR, интеграция в две строчки;
  • PowerShell — более консольный язык, со специфическими для «команд» фишками, интеграция в две строчки;
  • C#, VB — в представлении не нуждаются, но компиляция дольше, интеграция в десять строчек;
  • Вагон и маленькая тележка других вариантов: Lua, JavaScript, CsScript...

Многие из этих вариантов произведены большими командами и корпорациями, имеют проверенное временем высочайшее качество и отличную производительность. Не представляю, зачем может понадобиться наколенная поделка бывшего студента, для которой написано «аж 200 тестов» и который гордится тем, что не последовал разумному совету одного из разработчиков C#, «потому что переписывать лень».

Написание своего языка — это, конечно, круто и интересно, но всё-таки забава в чистом виде, о чём сам автор в послесловии и говорит.
Полагаю, остальные поделки, проверенные опытом, начинались точно так же. Иначе хорошие вещи не пишутся. Для себя и в своё же удовольствие.
Чувак, который стоит у истоков Jython и IronPython, уже имел за плечами хороший багаж, это далеко не первые наколенные проекты. Чувак, который ваяет IronScheme, уже имеет за плечами заваленный IronLisp. *Lua* и *J*Script* — это обёртки над уже существующими реализациями (Lua, JScript, V8). В общем и целом, практически во всех случаях мы имеем реализации уже существующих языков (с некоторыми дополнениями, специфическими для платформ JVM, IL и др.), причём обычно разработчиками с богатым опытом. Из перечисленных языков изобретён с нуля разве что PowerShell, но с точки зрения программирования не для консоли язык — ужасен, если интересно моё мнение. :)

Вот когда автор выкинет два-три проекта (один выкинутый уже есть, второй на подходе) — уже может начать получаться что-то удобоваримое. Но для этого надо хотя бы начать слушать старших прислушиваться к мнению Эрика.
Если не вдаваться в холивар, то у любого решения есть свои плюсы и минусы. Если учитывать переносимость, скорость работы и объем требуемых зависимостей, может статься, что и поделка найдет свое применение.

Кстати, а почему вы употребили фразу «бывший студент» в негативном смысле? Мне стоит стыдиться того, что я закончил вуз?
C# уже встроен в фреймворк, поэтому переносимость 100% (.NET, Mono), скорость работы 100% (в рамках CLR), зависимостей нет (.NET или есть весь, или его нет вообще). Учитывая, что сам .NET весит метров 40, экономия в два мегабайта лишних зависимостей совершенно неуместна. Соревноваться с DLR по производительности в принципе возможно, но разница будет пренебрежимо мала. Скорее же всего, вам не хватит времени на оптимизацию реально всех случаев, поэтому побить DLR удастся в лучшем случае в 5% случаев. Команде IronPython, чтобы добиться производительности CPython, потребовалось несколько лет активной разработки, и то осталось несколько узких мест.

В свете этого реализация «ещё одного языка» полностью лишена практического смысла (разве что ради опыта). Новый язык реализуют тогда, когда ни один уже имеющийся не подходит. C# возник как «Java, но мощнее»; PowerShell — как конкуренция консоли *никсов; Go — как эффективная реализация динамического языка; F# — как функциональный язык для .NET. И так далее. А что у вас в требованиях перечислено — это всё уже давно есть.
Вывод — даже великие иногда ошибаются, а на Reflection.Emit можно сделать полнофункциональный компилятор. Правда, придется как следует попариться.
У System.Reflection.Emit есть один фатальный недостаток — он генерирует код только под ту версию рантайма, под которой запущен компилятор. С этим в частности столнулись разработчики упомянутого выше Nemerle. В результате нужно иметь отдельную версию компилятора под каждую версию .NET
Для встаеваемого языка это не важно, но для компиляторов «обычных» языков, типа C#/F#/VB.NET — это серьезный минус.
Не понимаю что тут такого страшного.
Ну, это страшно, если вы хотите реализовать кросскомпиляцию — с помощью компилятора под .NET4 делать бинарники для .NET2, например. Не уверен, насколько всё плохо в этом плане для пары 4 / 4.5, но, скорее всего, тоже не ахти.
т.к. язык для встраивания, то работать программа будет заведомо только на той версии рантайма, на которой запущен хост, поэтому ни о какой кросскомпиляции речи не идет
Отличная штука! В предыдущем компиляторе тоже использовал ее для вывода графиков. Сейчас почитаю вашу статью про нее — судя по скриншотам, я знал только об одном проценте возможностей :)
Эх, только какой это старичок уже. Я не следил пару лет за тем, что делается в этой области, наверное, уже появились другие более мощные и бесплатные библиотеки. Однако периодически народ пишет на почту, что-то спрашивает, я даже что-то вспоминаю :)
А каким компонентом выводятся графики в примере?
Прошу прощения, не прочитал комментарий выше.
Тут бы ещё и про Наггум написать :)

Статья однозначно замечательная, спасибо.
В каком состоянии сейчас проект? Наверняка есть про что написать хотя бы небольшую статью.
Ох тыж, у меня прямо сейчас задача для LENS есть!
А мне довелось делать скриптовый движок в одном проекте на базе .Net Framework 2.0,
синтаксис простейший — как у формул в Excel (собственно, в ячейках xls-документа и предполагалось записывать выражения),
но для удобства написания «невнутриэксельных» скриптов добавлены операторы:
* . (точка, передаёт левое выражение в качестве первого аргумента вызываемой справа функции);
* .. (двоеточие, аналогично, только вторым аргументом);
* а также объявлений массивов "{… }" и выборки по индексу "[n]".

Формируется «шитый» код с вызовом «пользовательских» функций (синхронные/асинхронные, с побочными эффектами и без, макрофункции, всё реализовано через вызовы функций), поддерживается «ленивость», «асинхронность» (на основе собственного «велосипеда» по мотивам шаблона AsyncEnumerator), «прозрачное» применение скалярных функций к IList-векторам (например, "{1,2,3}.sin()"). Язык безтиповый, все значения передаются как Object.
Все именованные значения вычисляются однократно и «лениво», константные выражения вычисляются при «компиляции», имеется базовая поддержка замыканий.

Из недостатков: .Net 2.0 (в 4-м можно было бы использовать встроенные возможности для реализации асинхронности), сложный код писать трудновато без интеллектуального редактора, также приходится ограничивать параллелизм семафорами, иначе память кушается много))

Изначально задумывался «движок» для построения отчётов/организации вычислений на основе шаблонов/алгоритмов, описанных в Excel-документе, без использования ПО Excel по следующему принципу: на основе Excel-шаблона внутрипрограммно формируется скрипт для построения отчёта, после чего «компилируется»/запускается, запрашивает требуемые параметры и делает отчёт/вычисления в фоновом режиме.

Пример «внешнего» скрипта:
(
	let(endTime, NOW()),
	let(begTime, endTime-366*3),
	let(strFmt, '{0}' & CHAR(9) & '{1}' & CHAR(9) & '{2}' & CHAR(13) & CHAR(10)),
	let(semaObj2Txt, Semaphore(256)),
	let(wells,
		ReadRaw(treeAction,'spr@all@full_well')
			.RawToFullWellTable()
			.SelectRows('fieldId=110001')
			.RowAsDict()
	),
	let(fLPV, func(well,paramInfo, LoadParamValues(treeAction, well.FullWellItemToWellPath(), paramInfo, begTime, endTime) )),
	_ForEach(
		paramInfo, ParamStorage(),
		(
			let(outFile, NewFileStreamWriter('Out\' & paramInfo & '.tsv')),
			outFile.StreamWriterAppendText('WellId' & CHAR(9) & 'Time' & CHAR(9) & 'Value'),
			_ForEach(
				well, wells,
				_EvalWithSemaphore
				(	semaObj2Txt,

					let( wellId, well['wellId'] ),
					fLPV(well, paramInfo) .. let(vector),
					IF(	AND( NotNull(vector), COLUMNS(vector)>0 ),
						(
							outFile.StreamWriterAppendText( _JoinStr(CHAR(13) & CHAR(10) & wellId & CHAR(9), vector) ),
							COLUMNS(vector)
						),
						0
					)
				)
			)
			.SUM()..let(sum),
			outFile.StreamWriterClose(),
			sum
		)
	)..let(result),
	{
		start(), 
		COLUMNS(result), SUM(ISNUMBER(result)), SUM(result), MAX(result), MIN(result), 
		_TimeOf(result).MAX()._TimeToStr(), _TimeOf(result).MIN()._TimeToStr(), 
		result.stop() 
	}
)
Оно именно компилируется в байткод .net, не интерпретируется?
Оно компилируется в «дерево» вызовов функций, вычисляемых в заданном контексте.
Т.е., по факту, никакого нового кода не создаётся, лишь структуры данных, связывающие функции между собой через входы/выходы.
Больше всего похоже на "Шитый код".
let description = if(age < 21)
«child»
else
«grown-up»

Это аналог нижеследующего выражения?
var description = age < 21? «child»: «grown-up»;

Мне кажется что вряд ли стало более удобочитаемо.
Можно записать и в одну строку:
let description = if(age < 21) "child" else "grown-up"
У меня вопрос любителям. Как видно, на планете есть тысячи языков, которые компилятся в одни и теже машинные коды. Меня всвязи с этим волнует вопрос: есть ли какой-то более-менее общий язык, который легко компилится во все эти тысячи?
Пояснение: я пишу специфическую библиотеку, например, алгоритм, который нужен редко и малому кругу лиц, а все эти лица пишут свои хорошие программы на всяких разных языках, получается что алгоритм придется кодить на всех тех языках, а я не хочу. Я хочу написать его на самом примитивном языке с самыми примитивными фичами, но так, чтобы по нажатию кнопки всё расплодилось в тысячу исходников на разных языках.
Есть пара языков, которые транслируются в другие: Haxe и Monkey.
Если кто-то знает ещё такие, напишите.
У F# есть такая возможность как цитирование, позволяющее манипулировать кодом в runtime и, например, скомпилировать его в JS или выполнить на GPU.
Цитирование, наверно, не похоже на то, что мне надо. Я не смог понять что это:)
Начал смотреть про Манкей, на русском сайте как-то странно шутят:

Важно! С помощью данной версии вы сможете собирать только HTML5 версии игр.
Для получения возможности сборки под все доступные платформы вам необходимо приобрести лицензию на официальном сайте.
Стоимость лицензии составляет $99.
Лицензия на 2-d framework вроде. Сам Monkey бесплатен. Хорошо написано тут
В похожей ситуации мне порекомендовали препроцессор M4 Кернигана+Ритчи
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории