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

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

Интересненько!
Вы разработчик, в одиночку?
И язык соответсвует каким нибудь стандартам, ну, изначальная основа я так понимаю ECMAScript или он как раз и задуман как отдельная основа/стандарт?
Разработчик, в одиночку, начал работать над языков 8 августа 2012 года, правда до этого я уже писал несколько др. языков программирования. Стандартам не знаю соответствует или нет, просто знаю много языков и пишу постоянно на разных, смотрел и новые веяния от гугла типа Go и Dart и решил опубликовать свои мысли по этому поводу в виде языка ObjectScript.
Не плохо. Есть уже замеры по скорости работы и требуемой памяти? Сравнивая с теми же Lua, JS и PHP.
И что-ли в for и в if скобки обязательны?
Присоединясь. Было бы неплохо реализовать 20 тестовых программ с http://shootout.alioth.debian.org/ и сравнить производительность с указанными выше языками.
Да тестил кое что, первая версия виртуальной машины меня вообще не впечатлила ни по скорости ни по памяти. Сейчас используется полностью переписанная VM версии 2 так сказать, что выражается в текущей версии OS 0.93-vm2. Стало лучше на порядок, приемлемо для начала разработок под мобильные платформы, на что собственно и был изначально нацелен проект. Поэтому сейчас я делаю упор над выпуском примеров, например, те что в видео в конце статью. Ну а в перспективе вернусь к VM.
А что если транслировать в байткод Java VM, .NET или LLVM? В последнем варианте получится в нативный код компилировать.
Чтобы донести Ваш язык в массы, Вам нужны инвестиции. Попробуйте запостить презентацию на кикстартер.
Спасибо за идею, а что это реально работает для подобных проектов?
А почему бы и нет? :)
НЛО прилетело и опубликовало эту надпись здесь
Не понимаю, почему заминусовали alesto. Совсем ошалели?
Не понимаю, почему заминусовали alesto.

Думаю по тому, что чтобы проект получил поддержку на Кикстартере он должен быть чем-то реально уникален и кому-то нужен. Данный проект красив со спортивно-образовательной точки зрения, но лично я что-то не понял почему бы кто-то мог его особо захотеть — не вижу в нём «фишки» кроме «легковесности», которая сейчас не входит в число насущных проблем сколько-нибудь широкой аудитории.

PS: Я не минусовал, плюсанул даже, если что-то такое получится — буду очень рад.
Это Хабр. Кто-то поставил минус, кто-то добавил и понеслась…
Здесь это ни при чём. См. комментарий выше.
Возможность написания одной и той же конструкции кучей вариантов отношу к минусам, код должен быть построен однородным образом. Слишком много сахара.
+1. Это раздражает (отчасти) и в CoffeeScript, на который это ну очень сильно похоже, кстати.
А мне еще и Питон напомнил, с его перегрузкой методов и операторов.
А мне ruby чем-то напомнил.
Это где в python перегрузка функций? PEP:3124 заморозили www.python.org/dev/peps/pep-3124/
Я не точно выразился, я имел ввиду все эти штучки с __имя__, тут абсолютно тоже, только подчеркиваний в конце нету.
Это скорее из магических методов PHP выросло.
Согласен. Тут я пошел по пути языка Lua. Там в описании объектом можно использовать и запятую и точку с запятой, да и равно между парой ключ — значение мне нравится. В то же время я не хотел отказываться от нативной поддержки JSON формата.
И чем же это плохо? Хотите, пишите как угодно. Хотите, пишите одним вариантом. Если есть проблемы с коллегами — договоренность все решит.
write-only code
Дебажить чужой код становится сложнее.
Вы молодец!
осталось внедрить в node.js и браузеры!

как обстоят дела с утечками и сбором мусора?
как вообще оно устроено, понятно что это требует отдельной статьи…
НЛО прилетело и опубликовало эту надпись здесь
не знаю как пишется тег [sarkazm]
поздно выкручиваться
то что, тут народ шутки не всегда понимает, я уже привык
Просто примите тот факт, что ваши «шутки» ни капельки не смешны. Не надо валить всё на «народ», «стадо» и т.п., как это любят делать подобные горе-шутники и прочие «жертвы непонимания». Признайте своё поражение и спокойно идите своей дорогой.
мог промолчать, но пошел своей дорогой…
node.os — это обязательно, если дойдут руки, может кто присоединиться к разработке, посмотрим. И компиляция OS в JS также изначально была записана в плане.
Вот это хорошо, я так думаю, серьёзно. Это akalend напрасно сардонически иронизировал сарказмом. Было бы полезно иметь возможность скриптовать на ObjectScript с той же лёгкостью, что и на CoffeeScript, например.
Я наверное никогда не пойму отказ от точек с запятыми.
Питонщики смотрят на вас с немым укором.
Толку от них? Все приличные программисты следуют принципу «одна стока — одно выражение». Точка с запятой нужна машинам, а не людям. А машины сейчас умные, могут сами понять, где один оператор, а где второй.
function a {
...
return
{a: 'b'}
}

«Умная машина» не вернёт объект, она подумает, что имелось ввиду «return;»
Потрудитесь объяснить, какой смысл переносить выражение на новую строку?
В питоне это пишется так:
return {
    1: 42,
    "foo": "bar",
}
Вы же про умность машин, я привёл пример, когда машина не поймёт, как верно.

Язык в первую очередь для людей создаётся. Это один из примеров, случайно enter нажался, например. Машина ошибку не покажет, отловить сложно.
Так что не писать ; лишь потому, что язык это разрешает — зло (это в большей степени про JavaScript и про этот ObjectScript).

Про Pythin вообще другой разговор, в языке вообще же нет ;.
ObjectScript на такую конструкцию не споткнется, будет возвращен объект как и задумано.
А такой пример?

if (a == 0) return
b = f(c)
...


Вернёт b или нет?
Будет синтаксическая ошибка, попытается вернуть b, а там равно, равно в OS не возвращает значение. По крайней мере в текущей версии, тут прямой аналог — Lua, и нужно это для множественного присваивания, когда значение вынимается из стека, чтобы корректно присвоить следующее значение. Поэтому после return следует ставить ; чтобы однозначно отделить синтаксис.
if (a == 0) return
f(c)

? ;)
Точно )
>Поэтому после return следует ставить; чтобы однозначно отделить синтаксис.
Вот главная мысль из которой должен следовать вывод, что вообще нельзя позволять опускать ;, чтобы всегда всё было однозначно.
Я сделал вывод для себя, что не стоит писать такие конструкции
не знаю как в Pythin (Владимир Владимирович?), а в Python есть точка с запятой:

>>> a = 1; b = 2
>>> print a, b
1 2
>>> 
В питоне точка с запятой встречается крайне редко. И первую строку питонщик напишет так:
a, b = 1, 2
1) Машина ошибку покажет, unreachable code же.
2) Есть в питоне точка с запятой, ставьте хоть после каждого оператора.
А кто вам сказал, что точки с запятой лишние. Нет, не так… Кто вам сказал, что только точка с запятой лишняя. Слово return в вашем примере тоже явно лишнее. ;)
Ruby, например, и без этого слова вернет значение последнего вычисленного внутри функции выражения.
def a

{a: 'b'}
end
Смотрите сюда =)

Ex(it + 1, ix, iy, iz) =

	                (1.0-SIGMA*DT/2.0/EPS/EPS0)/(1.0+SIGMA*DT/2.0/EPS/EPS0)*Ex(it, ix, iy, iz)
	                + DT/(1.0+SIGMA*DT/2.0/EPS/EPS0)/EPS/EPS0*(
	                (Hz(it+0.5, ix, iy+0.5, iz) - Hz(it+0.5, ix, iy - 0.5, iz)) / dy
	                -
	                (Hy(it+0.5, ix, iy, iz+0.5) - Hy(it+0.5, ix, iy, iz - 0.5)) / dz
	                );
Брр. Траектория полета ракеты?)
Уравнения Максвелла.
Вижу. И что? Почему-то питон прекрасно понимает многострочные выражения без точек с запятой.
Конечно понимает, просто неправильно посчитает и всё. Посчитает половину выражения, а вторая половина может внезапно в воздухе повиснуть. Одно неловкое движение и всё.
А можно не смотреть? о_О
Или как-то так:

(ex (+ 1 it) ix iy iz) =
  (let ([some-value (/ (* sigma dt) 2.0 eps eps0)]
        [fn1 (lambda (__) (hz (+ it 0.5) ix __ iz))]
        [fn2 (lambda (__) (hy (+ it 0.5) ix iy __))])
    (+ (* (/ (- some-value 1.0) (+ some-value 1.0)) (ex it ix iy iz))
       (* (/ dt (+ some-value 1.0) eps eps0)
          (- (/ (- (fn1 (+ iy 0.5)) (fn1 (- iy 0.5))) dy)
             (/ (- (fn2 (+ iz 0.5)) (fn2 (- iz 0.5))) dz)))))

Имена some-value, fn1 и fn2 были выбраны наобум, т.к. я не знаю, как назвать эти величины и функции (не разбираюсь в предметной области).

Кого напрягают скобочки, тем сообщаю, что в Dr. Racket есть умная подсветка:

Перенесите плюсы не в начала строк, а в конец — и будет вам счастье. А ещё в большинстве языков в конце строки можно поставить символа переноса
Это смотря каким людям. Мне точка с запятой (и Сишный синтаксис в целом) нравится, она чётко показывает где конец чего, в сочетании с фигурными скобками создаёт эдакие хорошие «рамки».
Не в порядке возражения, но в порядке дополнения Вашей реплики я укажу ещё тут же, что точка с запятою встречается и в языках с несишным синтаксисом — например, в Паскале и в некоторых его наследниках.
Убирать запятые — это очень смело)

Задумка очень интересная. Раз уж расширять возможности языка и упрощать синтаксис — было бы удобно писать анонимные функции в стиле C#, без слова function и оператора return, когда в нем нет необходимости:
x => x*x;
(y, z) => y*z;


Кроме того в JS иногда очень не хватает типов-перечислений (Enum), было бы удобно не задавать значения без необходимости:
Enum CarTypes = {
   Truck,
   Sedan,
   Wagon
}
//Использование: CarTypes.Truck
Насчет запятых — семейство Lisp-подобных языков с вами не согласится.
Семейство лисп-подобных языков в первую очередь не согласится с С-подобным синтаксисом. А запятые это уже дело второе :)
Да и Haskell, насколько я знаю, тоже (:
enum пока зарезервировано как служебное слово.
В последнем обновлении добавлен сокращенный синтаксис для функций:

{|y z| y*z}

это полный аналог:

function(y, z){ return y*z }

evgeniyup, а вы знакомы с Ruby?
Если уж говорить об упрощении синтаксиса и следовании объектно-ориентированной парадигме, то стоит посмотреть в сторону замены процедур и функций на методы классов.

Например, цикл for на рельсах пишется, по-моему, очень элегантно:
10.times do // your code end
надо пользоваться чаще предпросмотром… прошу прощения, хотел написать:
10.times do
// your code
end
Комменты начинаются ж со знака #, не?
Причём здесь рельсы? Чистый руби.
Это как «программист на jQuery».
Гетеры, сетеры и пр. — это из Питона, видимо. А Вы оценивали уже скорость работы языка? Интересно.
Я напишу отдельную статью про оценку производительности.
Немного не ясна цель создания этого языка, собственно, как и его целевая аудитория.

Всякие фишечки типа «запятую можно не ставить» или «вместо ':' можно поставить '='», не прибавляют языку простоты. Кроме того, наследование в стиле JavaScript — тоже не самая очевидная штука, особенно для новичков.

ObjectScript позиционируется как встраиваемый скриптовый язык для С++-приложений. IMHO, если уж не устраивает чем-то тот же Lua и JS, то существуют варианты и поприятнее. Нужен простой ОО-язык с достаточно «привычным» синтаксисом? Окей, получите Squirrel. Прототипное наследование не пугает, но хочется очень маленькую виртуальную машину + не перегруженный лишними символами синтаксис? — Получите Io.

А у Вас что? Куча неоднозначностей в лучших традициях JS + парочка сомнительных синтаксических фишек.
Изначально язык нацелен на аудиторию лояльную к C-подобным языкам, к ним я отношу JavaScript, PHP, Lua ну и некоторые другие.

А в целом я работаю над реализацией движка для написания кросс платформенных приложений по типу Corona SDK, но на ObjectScript и Marmalade SDK. Не отказался бы от интеграции с др. платформами, например, Irrlicht, Shiva3D и др. В принципе область применения может быть довольно большой, тот же node.os (как аналог node.js).

Насколько мне известно, от русскоязычного комьюнити мировому сообществу пока не предложено языков высокого уровня. Что я предлагаю — завершить спецификацию ObjectScript, создать комьюнити, может быть найти инвестиции.
Про MoonScript слышали? Его можно с Corona SDK и Moai SDK использовать.
Круто! Реализованы многие вещи, появление которых я давно ждал! Правда слишком много информации для одного поста!
Ждем ответов на вопросы выше. Ну и название, как-то не слишком, но, это уже дело вкуса.
Спасибо!
То, что вы делаете — это интересно, прикольно. Но ничего серьезного не вырастет. Ну с точки зрения создания чего «такого, что перетянет на себя программистов XXX» (подставить java, ruby, python, C#).

Потому что неправильно поставлена проблематика.

Проблема не стоит упростить синтаксис.

Нужно сочетание предельной строгости и простоты.

Чтобы глядя на код однозначно понимать что он делает. При этом хочется иметь JSON и динамическую типизацию.

Также нужно, чтобы исполняющая среда была изначально дружна с потоками. И производительна.

Нужно иметь помимо ручного управления памятью и автоматическое тоже…

Короче, тут можно долго распространяться.
Так распространитесь :) Я, вот, например, не знаю, что людям нужно от новых языков.
Очень неплохо, но:
— в скрипт-языках очень важна привязка к нижним языкам (здесь C++), например что бы подключить какой-нибудь модуль X с интерфейсом в ObjectScript. Так вот привязка здесь хромает пока — недавно подключал CryptoPP для tcl, прикинул как было бы в ObjectScript и сломал мозг; Посмотрите хотя бы на реализацию этого в других скриптах, или хотя бы на critcl.
— «объектно ориентированный» это очень сильно сказано — где publiс, private и как с этим бороться при наследовании не совсем понятно. Выглядит как простой hash-struct расширеный до функций (методов). Множественное наследование, миксины и др. вкусные плюшки современных объектно ориентированных языков не проработаны или отстутствуют полностью.
— практически не понятно как организован интерпретер (например возможен ли N interp per M threads), Jit (если вообще Jit) и т.д. Есть ли например возможность расшарить объектный код между interp и/или threads.
— сборщик мусора для скрипт-языка IMO не обязателен (можно вполне обойтись ReferenceCount).
— и как уже говорили другие синтакс «слишком сладкий», хотя это на любителя;

Хотя скорее зачет, чем нет.)
Сейчас я подключаю Box2d, видимо скоро покажу демку. OS изначально был ориентирован на простую интеграцию с C++
Вы меня не совсем поняли на счет интеграции: не как сам язык интегрируется (это как раз вторично), а как можно расширить интерфейс (примитивы, функции, классы) за счет готового сишного функционала с отображением в ObjectScript.
Кроме того интересны вызовы типа C++->OS->C++, с полной передачей объектов и примитивов туда-сюда.
Лучщий в этом смысле будет скрипт язык, который в идеале, при наименьших телодвижениях, т.е. наименьшом количестве действий в C++, позволит мне максимально расширить интерфейс к этому всему в скрипте.

Теперь сравните ваше:
int test(OS * os, int, int, int, void*)
{
    os->pushNumber(123);
    return 1;
}
int main(int argc, char* argv[])
{
    OS * os = OS::create();
    os->pushCFunction(test);
    os->setGlobal("test");
}

с тем же например на tcl:
int test(void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
   Tcl_SetObjResult(interp, Tcl_NewIntObj(123));
   return TCL_OK;
};
int main(int argc, char* argv[])
{
   Tcl_Interp * interp = Tcl_CreateInterp();
   //clientData = this;
   Tcl_CreateObjCommand(interp, "::test", test, clientData, deleteTestProc);
}


Вроде похоже, но вот что мне не хватает и не понятно:
— почему нет какой-нибудь clientData, т.е. внутренние референсы мне в глобальных переменных передовать? Хотя нет, нашел pushCFunction с user_param — это оно?
— нифига не ясно, как у вас связаны сишная функция test и имя «test» (который через setGlobal...);
— как мне удалить clientData если удалим команду из интерпретора (не увидел что-то типа callback deleteTestProc);
— как передаются/навесить аргументы в test функцию (tcl — objc, objv)?
— слишком много push, pop — это подавляет.
и тд и тп.
да user_param, но вопрос очень интересный и требует описания, видимо это тема для отдельной статьи
Первый пример с Box2d кстати готов, можно посмотреть видео тут youtu.be/3RHek-UhkCk, как это работает — видимо это тоже тема для новых статей.
Исходники в одном полумегабайтном файле?!
Слишком все в кучу и функциональность, и внутренняя реализация, и примеры. Получается довольно запутанно.

1. Замена «запятых» на «пробелы» еще воспринимается нормально, а вот «точка-с-запятой» да еще в смешанном варианте -совершенно не читабельно. Я бы ограничил использование одного типа разделителя в пределах вызова. Именованные параметры через «двоеточие» или «равно» также в пределах одного вызова.

2. Конкатенация строк чище при использовании переменных внутри строки
"my name is %(name) and I like %(pet)" или "my name is $(name) and I like $(pet)"
можно использовать как локальные переменные, так и передачу параметров или словаря

3. "print a[1] выведет one" — не понял почему?

4. var test = function(){ return 1, 2 }
Зачем столько кода, как же лямбды? :)

5. Такой код сработает?
obj = { null awesome={1,2} {12, 24}} for({k, v} in obj){ print( k " --> " v ) }
Как вывести только порядковые индексы (не ключи) из obj?

6. При общей тенденции к упрощению кода, описание класса через функции слишком громоздкое.
Чем не устраивают конструкторы, свойства, методы, операторы, на худой конец через лямбды.

7. __get@field мне напоминает помесь python и c++, более читабельно смотрится единый блок описания свойства как в C#
type field { get {...} set {...} }
тут можно было бы Добавить backingField, defaultValue, notifications или еще что-то по желанию
Просто __get(empty/dim) и __set(empty/dim) — это расширенные индексаторы, в c# есть синтаксис
type this[...] { get {...} set {...} }

8. delete a.color — удаляет значение или свойство?
Что будет после этого при вызове a.color = «green»
Запишется новое значение или появится новое свойство?

9. Использование двойной точки и двойного подчеркивания, двойной звездочки (как и вообще парное использование одного и того же символа) плохо читается.

10. В языке есть null-safe синтаксис? Посмотрите в Kotlin

Вообще довольно интересно получилось!
1. в Lua работают и запятые и точки с запятой, тут я не усмотрел криминала, хотя и соглашусь с тем, что лучше использовать один синтаксис

2. согласен

3. дело в том, что
	a = {x=1, y=3; "zero" "one", "two" last:7,}

эквивалентен объекту на JS
	a = {x:1, y:3, 0:"zero", 1:"one", 2:"two", last:7}

поэтому print a[1] выведет one

4. в OS (ObjectScript) изначально все функции — лямбды, запись с ключевым словом function на мой взгляд воспринимается более читабельно

5. код obj = { null awesome={1,2} {12, 24}} for({k, v} in obj){ print( k " --> " v ) } не совсем валидный в части for({k, v}, тут требуется writeable, а {k, v} не writeable и компилятор будет ругаться

6. 7. согласен get color { return .... } выглядит лучше. Я хочу лишь отметить, что это все равно будет скомпилировано в метод с именем __get@color, а это нужно программисту теоретически знать. Сейчас уже есть синтаксис вида:
var alphaBlending
function get alphaBlending(){ return alphaBlending }
function set alphaBlending(a){
	alphaBlending = a
	if(a){
		glEnable(GL_BLEND)
		glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST)
	}else{
		glDisable(GL_BLEND)
	}
}

см. director.os — это из 2d движка, который я пишу для мобильных платформ на ObjectScript. Данный синтаксис пока не добавлен в описание объекта.

8. delete работает также как в JS, т.е. удаляется не само значение, а ссылка на него или свойство в данном случае. Сам же объект разрушается в процессе сбора мусора

9. согласен

10. есть например такой язык objective-c, который используется в продуктах Apple (по сути все не кроссплатформенные приложения для Apple App Store написаны на objective-c), там можно вызвать метод для null объекта и это будет проглочено молча без единного предупреждения, что произойдет? да ничего, просто метод (там это называется событие) не будет вызван. Текущая версия OS поведет себя так же, но я планирую более детально проработать этот момент. Например, в текущий момент при разработке на OS мне очень сильно помогает лог доступа к необъявленым свойсвам и делается это средствами самого же OS. Например, посмотрим файл core.os
function __get(name){
	echo("global property \""name"\" is not declared\n")
	echo "back trace\n"
	printBackTrace(1)
	echo "\n"
}

function Object.__get(name, autoCreate){
	if(autoCreate) return;
	echo("object property \""name"\" is not declared\n")
	echo "back trace\n"
	printBackTrace(1) // skip current function
	echo("=======\ntarget "this"\n\n")
}

function Userdata.__set(name, value){
	echo("userdata property \""name"\" is not declared, set value "value"\n")
	echo "back trace\n"
	printBackTrace(1) // skip current function
	echo("=======\ntarget "this"\n\n")
}

function assert(a, message){
	if(!a){
		print(message || "assert failed")
		printBackTrace(1)
		terminate()
	}
}

setErrorHandler(function(code message file line){
	var type = "ERROR"
	if(code == E_WARNING)
		type = "WARNING"
	else if(code == E_NOTICE)
		type = "NOTICE"
	echo("["type"] "message"\n")
	echo "back trace\n"
	printBackTrace(1) // skip current function
})

function printBackTrace(skipNumFuncs){
	for(var i, t in debugBackTrace(skipNumFuncs + 1)){ // skip printBackTrace
		echo("======= ["i"]\n")
		// echo("  line: "t.line", pos: "t.pos", token: "t.token", file: "t.file"\n")
		echo("  line: "t.line", pos: "t.pos", file: "t.file"\n")
		echo("  function: "t.name", arguments: "t.arguments"\n")
		// print concat("  object: "(t.object === _G && "<<GLOBALS>>" || t.object)"\n")
	}
}

Весь вывод через echo & print перехватывается в виртуальной функции унаследованного от класса ObjectScript и записывается в файл. Таким образом я всегда вижу наличие проблемы, printBackTrace при этом дампит детальный call stack, поэтому я могу понять от куда был вызов и с какими параметрами.
B Objective-C не вызов метода, а посылка сообщения. Не путайте, пожалуйста, два эти метода обращения к методам, они очень разные :)
3. Честно говоря не встречал, чтобы не именованные свойства получали имена в виде индекса в порядке следования = помесь словаря и массива. Мне кажется совсем не очевидное поведение. Я бы не смешивал, все таки массив имеет фиксированный порядок следования элементов, словарь может менять порядок следования элементов в зависимости от внутренней реализации (грубо говоря сортировки ключей), в объекте порядок следования свойств вообще не применим.
4. Да само слово function проще найти в тексте, но нагромождение скобок после него начинает путать
alert((function(x){ return x*x; })(10));
Где закончилось описание функции и начался вызов с параметрами, зачем тут return?
Или вот такое:
(function(){( return function(){( ... {( return function(){ return stuff }() )} ... )}() )}() )
Можно кроме привычного x=>x*x подумать над вариантом var f = { x,y => x*y }, тогда избавляемся от лишних круглых скобок, в простом случае скобки можно опустить, но появятся другие проблемы.
7. Когда get и set внутри свойства проще читается. Можно добавить fieldof(property) и избавиться от явного указания полей для свойств, применение ограничить в пределах класса. Можно добавить default и заранее задать нужное значение, в том числе при первом обращении (lazy properties, default => 10). Можно добавить raise для событий. Как-то так
type property = 10 // 1 вариант значения по умолчанию
{
  // 2 вариант значения по умолчанию
 default = 10
 get { return fieldof(property) } // сокращенный вариант get =>  fieldof(property)
 set { fieldof(property) = value; raise(property) }
 // далее при желании raise { ... }
}

raise также можно использовать внутри описания событий как в VB.NET
10. Да null object pattern вполне годный вариант.
11. Switch, pattern matching?
Как по мне, CoffeeScript выглядит симпатичнее…
Одна лишняя запятая в коде, и ищи потом эту ошибку часами.

Чуть выше тут сказали, что лучше бы отказаться от function() и return, последняя строка в функции это return, как в Erlang: add(A,B)->A+B.
Интересная разработка, много интересных идей. И много, увы, неудачных, которые перечёркивают всё.

Отмечу такой момент: запутанность кода. Код должен быть простым и понятным. У вас код удобно писать, но не очень удобно читать. Этим же иногда страдает и CoffeeScript.
Ведь не зря же создатели C ввели скобки?
Пример запутанности и неоднозначности кода. Вот такой код:

func('abc' val 'abc')

Вот интересно, чему это эквивалентно:
func('abc', val, 'abc');
// или
func('abc' + val + 'abc');
// или
func('abc' + val, 'abc');
// или
func('abc', val + 'abc');

А если ещё и скобки функции опустить, то ещё 20 вариантов придумать можно…
Сорри, функцию concat не заметил.

Тогда да, я не прав.
Не взлетит. На embedded-системах роль встраиваемого языка уже давно прочно закрепилась за lua, на десктопах есть питон. А тут вы со своим мешком сахара.
Хм… На каких конкретно системах Луа?
Питон вроде более чем бодренько работает на эмбеддед, на Мипс 400 МГц х 32 метра рам — полновесный питон у меня без проблем стартует.
На iOS, android и других. Lua занимает мало место в памяти, удобен и достаточно быстр в сравнении с другими языками, особенно после JIT.
Я не спрашивал где она потенциально запускается. Я спрашивал где она конкретно используется в эмбеддед системах, в каких приложениях, для чего.
То что она запускается много где это и так понятно.
Что-нибудь типа такого реализуется? Динамическая модификация итератора в процессе работы. В то же шарпе дает ошибку в рантайме.

foreach (Foo foo in bar<Foo>)
{
if (foo==smth) {bar[foo].RemoveItem}
}
Модификация контейнера в foreach?
Обсуждение такой идеи мне кажется пустозвонством, ибо слишком много вопросов. Foreach используется не только для массивов и списков, а для любого обьекта, что реализует интерфейс IEnumerable. Что если у вас не просто список, элементы которого будут добавляться в конец, а упорядоченный список?
Добавляя элементы мы можем напороться на нехорошую ситуацию — если элемент попадёт не в конец списка, а в начало, то IEnumerator уже не пройдёт по нему. Как быть в таком случае?
А если заменяется текущий элемент? Что тогда предпринимать? Делать ещё одну итерацию специально для него или идти дальше?
Слишком много вопросов. Кто-то будет считать, что тако-то делать неправильно, или неоптимально, или неожиданно, или ещё что-нибудь. Получается неочевидность результатов работы с такой фишкой. Мне кажется, что в случае, если вы хотите менять коллекцию во время её перебора, нужно использовать не foreach.
Да. Приходится городить костыли (например, в одном цикле запоминать индексы искомых элементов, с которыми работать уже во втором). Но хотелось бы иметь язык, который такие ситуации не запрещает, а описывает и разруливает.
В таком случае, выход из описанной мною ситуации — добавить интерфейс IChangeableCollection или как-то так, который бы задавал методы, которые определяли бы поведение при изменении коллекции.
Я могу лишь сказать, что изменение/удаление итератора для стандартных типов (array, object) не приведет к падению, более того отработает как задумано программистом. Но я бы не применял такую практику.
С августа, тоесть по большому счету прошло 2 месяца?

Тянуть такую громадину в одиночку вполне реально, Angel Script тому пример!

Интересно будет взглянуть через год, если не заглохнет!
a = {x=1, y=3; "zero" "one", "two" last:7,}
Боже…
если честно с запятыми и точками с запятой как-то легче воспринимать код
>> «А зачем там собственно запятая?»

А зачем там, собственно, открывающая и закрывающая скобки?
А зачем там, собственно, код?
Просто я к тому, что есть языки, в которых скобки не обязательны. Как по мне, это отличная идея…
Да не, не обращайте внимания на мой коммент, это я так бредю.

Что касается скобок — нужно всё в меру. В if или for скобки убрать неплохо, а вот например в создании хэша — плохо. Читаемость кода очень понижается
В меру, и только.

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

doSmthWithClosure((function(x){ return function(){ return x } })(value))
Мне кажется можно гораздо проще:

doSmthWithClosure(function(){ return value });

И вообще я предпочёл бы вот так:

doSmthWithClosure( -> value );
А почему бы не добавить что-то вроде perl-овского «$_»?
Вообще ассоциации с пёрлом проскакивают при взгляде на этот язык.
Интересная затея конечно (= Кстати, если у вас большой опыт в экспериментировании с написанием своих языков, почему бы вам не присоединиться к проекту MRuby, чтобы и Lua похоронить, и принести всю мощь Ruby в качестве встраиваемого скриптового языка? (=
Дамы и господа! Предлагаю поиграть в угадайку. Ниже представлен код, который я попробовал выполнить на предоставленной автором виртуальной машине. Лишь один из вызовов операторов «print» выводит число 4. Угадайте какой ;)

var double = function( value ) { return value * 2 }
print double 2
print double {2}
print( double 2 )
print double {2}[0]
print double {1 + 1}()

Ответ
Вывод программы:

<function:477>
<function:477>  2
0
4
0
Угадал. Нули только не очевидны.
Вашу бы энергию да в благое русло!
Чем-то похоже на мой tiscript. У меня правда class, namespace и property «настоящие».

И VM с moving garbage collector. Что хорошо например в контексте code inside web page но несколько неудобно во встраиваемом языке. А как в OS сделано, какой принцип memory management используется?

Я попробовал реализовать tri-color incremental garbage collector, иначе говоря сборка мусора делается не за один проход, а за много во избежании высокой нагрузки самого сборщика на систему. Что из этого получилось? Работает и не падает, все что надо удаляет, удалось затюнить сборщик для максимально возможного fps на моем мобильнике HTC Desire (в тех демках, что я делаю на OS). Тем не менее, я не доволен тем, что fps не ровный, но пока не уверен в чем именно проблема, в сборщике мусора или в чем-то другом.
Больше интересует это moving или non-moving этот GC.

non-moving (например ref-counting) GC удобен при встраивании в C++ но имеет известные проблемы в плане cyclic references и частых аллокаций типа
var s = ""; for(...) s = s + "something"
В начале я планировал использовать ref-counting + GC для решения проблем с cyclic references, но в ходе реализации сборщика мусора ref-counting как таковой был убран, т.к. ничего не упрощал в процессе сбора мусора. В текущей реализации ref-count присутствует, но только как счетчик использования объекта где-то на стороне (за пределами OS) и зовется в коде external_ref_count. Иначе говоря сам OS ref-count не использует, а сборщик мусора не удаляет объекты с external_ref_count > 0. Cyclic references при этом разруливается без проблем.
У вас очень позитивно получилось, как с точки зрения идеологии, так и реализации. Спасибо за ссылку!
что с асинхронностью? если как js то закапывайте =="

сахара много, но решает ли этот язык хоть одну проблему, которую не решают другие языки? только из-за синтаксиса язык никто менять не будет.
Да и синтаксис мне показался странным: хошь делай так, а хошь делай так, хошь поставь запятую, не хошь, поставь джигурду. Представляю, каковым геморроем будет смена программиста на проекте. Любой программист со временем становится консерватором. С годами он обретает понятие красивого кода. А этот язык будет вызывать только когнитивный диссонанс и ненависть к предыдущему разработчику.
Какой хороший язык. Теперь можно устраивать холивары не только «пробелы или табуляция», но и «двоеточие или равно», «писать скобки/запятые/точки-с-запятыми или нет». Мне кажется тут гибкость уже порождает неопределённость. Уже бы отменили ";" как явление (см Basic, Python). Скобки тоже отменить, если нет возврата (см. Basic, Perl). Заодно и запятые (неопределённость скобками вокруг аргументов убирается).
и поддерживает ООП во всей своей красе.

Или я неправильно понял словосочетание «во всей своей красе», или я не нашел в вашей статье упоминаний инкапсуляции.
Наследование, как я понял, тоже не полностью реализовано. Например, как я смогу перегрузить метод родительского класса у дочернего и притом иметь возможность вызвать оригинальный, без написания дополнительных плагинов, а-ля Base.js?
Согласен. Продолжение статьи…

Инкапсуляции

Класс IvanPerson не знает, как реализован метод walk() из класса Person, но может использовать этот метод. В классе IvanPerson нет необходимости даже определять walk() до тех пор, пока не понадобиться изменить его. Все классы наследуют методы своих родителей и определяют только новые методы или те, которые нужно изменить — это называется инкапсуляция.

Перегрузка методов

Опишем класс IvanPerson следующим образом
	var IvanPerson = extends Person {
		__construct = function(){
			super("Ivan", "Petrov")
		}
		walk = function(){
			echo "Soneone named "
			super()
		}
	}
	var p = IvanPerson() // создадим экземпляр класса IvanPerson
	p.walk()
	print p

Выведется:

Soneone named Ivan Petrov is walking!
{"firstname":"Ivan","lastname":"Petrov"}


super вызывает метод родительского класса (прототипа) с именем метода, из которого он был вызван! Тут речь идет о любом методе, нужно просто вызвать super с нужными параметрами.

Ручная передача this в функцию

Чтобы вызвать функцию и передать в нее нужный нам this, воспользуйтесь методом call класса Function. Продолжая предыдущий пример:

	Person.walk.call(p)

Выведется:

Ivan Petrov is walking!

Метод call вызывает функцию с нужным нам this и остальными параметрами, с которыми call был вызван. Если остальные параметры собраны в масив, то воспользуйтесь методом apply класса Function.

	function foo(a, b){ return a + b }
	function bar(){ return foo.apply(null, arguments) }
	print bar(2 3)
	print bar(4 5)

Выведется:

5
9


P.S. заодно проверил и исправил баг в apply, если вы уже клонировали репозиторй, обновитесь пожалуйста
Ну вопрос-то был на самом деле про какой-то интерфейс для реализации приватных методов/полей. Просто если у вас тоже сделано замыканиями (как в js), то язык в изрядной мере напоминает js, где можно не ставить запятые.

Без обид, вы раз двадцать уже, наверное, слышали про то, что гибкость синтаксиса — скорее минус, чем плюс.
Важно понимать, что цели заменить С++ или другой подобный язык не было. JavaScript — замечательный язык программирования. Но после разработки на нем нескольких больших проектов, мне крайне стало не хватать более человеческого ООП. Когда в очередном мобильном проекте в очередной раз пришлось нагараживать пятиэтажные конструкции и писать кучу кода на C++ вместо одной строчки на JS-подобном языке, я все таки собрался и сделал ObjectScript, сделал для своих проектов, ну а в процессе уже решил выложить в паблик. При этом тянуть на с свои проекты V8 с теми недостатками JS, кот. я перечислил выше, Lua фактически с теми же недостатками или др. язык я просто не стал по идеологическим соображениям. Сделал ObjectScript, чтобы писать для мобильных платформ. Если вам кажется, что OS похож на JS, то правильно кажется, у них и названия похожи. Я планировал сохранить все, что есть в JS и добавить при этом то, чего не хватало.
Ну на мой вопрос вы не ответили. Приватность — только через замыкания?
Я вижу следующие причины по которым язык реализован как есть:

  • все функции в языке — это реально лямбда функции, т.е. по умолчанию они не принадлежат объекту
  • функции в протопите объекта могут быть перезаписаны позже, например, для расширения функционала
  • любую функцию всегда можно вызвать с нужным this и для любого объекта
  • объект всегда совместим с JSON данными

Но в то же время, любые разумные предложения приветствуются, предложения и способы реализации.
А какие у вас идеи насчет valueof?
преобразует значение в простой тип данных, я расскажу об этом и др. специальных операторах в следующей статье
Тоесть аргумент — это значение? Просто по аналогии с typeof, я думал это то же, только наоборот.
не совсем, typeof возвращает тип аргумента в виде строки, а именно одно из: number, string, boolean, null, array, object, function, userdata.

Простые типы это: number, string, boolean, null. Оператор valueof преобразует аргумент в простой тип.

Но на практике часто используются др. сопутствующие операторы, например, numberof и т.п., например:

function setOptions(options){
  options = objectof options || {}
  ....
}

в JavasScript часто пишут так:

function setOptions(options){
  options = options || {}
  ....
}

что полностью допустимо в ObjectScript, а в сочетании с objectof дополнительная проверка типа.
Вот вы говорите что писали для вставки в приложение C++.
А под C# не планируете доработать?
C# сам по себе может использоваться для скриптинга. Компилятор доступен прямо из языка, а генерированный таким образом код можно запускать, закрыв ему доступ к файловой системе с помощью атрибутов безопасности.
Не соглашусь — для скриптинга лучше применять специально сделанные для этого языки, которые пусть и менее функциональны, но быстрее исполняются, и проще в синтаксисе.
Ухты. Т.е. я так понимаю, python или lua исполняются быстрее, чем MSIL, который является продуктом компиляции кода на C#? Хотя, нужен remoting, а там уже пёс его знает что быстрее будет.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории