Comments 146
Интересненько!
Вы разработчик, в одиночку?
И язык соответсвует каким нибудь стандартам, ну, изначальная основа я так понимаю ECMAScript или он как раз и задуман как отдельная основа/стандарт?
Вы разработчик, в одиночку?
И язык соответсвует каким нибудь стандартам, ну, изначальная основа я так понимаю ECMAScript или он как раз и задуман как отдельная основа/стандарт?
Разработчик, в одиночку, начал работать над языков 8 августа 2012 года, правда до этого я уже писал несколько др. языков программирования. Стандартам не знаю соответствует или нет, просто знаю много языков и пишу постоянно на разных, смотрел и новые веяния от гугла типа Go и Dart и решил опубликовать свои мысли по этому поводу в виде языка ObjectScript.
Не плохо. Есть уже замеры по скорости работы и требуемой памяти? Сравнивая с теми же Lua, JS и PHP.
И что-ли в for и в if скобки обязательны?
И что-ли в for и в if скобки обязательны?
Присоединясь. Было бы неплохо реализовать 20 тестовых программ с http://shootout.alioth.debian.org/ и сравнить производительность с указанными выше языками.
Да тестил кое что, первая версия виртуальной машины меня вообще не впечатлила ни по скорости ни по памяти. Сейчас используется полностью переписанная VM версии 2 так сказать, что выражается в текущей версии OS 0.93-vm2. Стало лучше на порядок, приемлемо для начала разработок под мобильные платформы, на что собственно и был изначально нацелен проект. Поэтому сейчас я делаю упор над выпуском примеров, например, те что в видео в конце статью. Ну а в перспективе вернусь к VM.
Чтобы донести Ваш язык в массы, Вам нужны инвестиции. Попробуйте запостить презентацию на кикстартер.
Спасибо за идею, а что это реально работает для подобных проектов?
Не понимаю, почему заминусовали alesto.
Думаю по тому, что чтобы проект получил поддержку на Кикстартере он должен быть чем-то реально уникален и кому-то нужен. Данный проект красив со спортивно-образовательной точки зрения, но лично я что-то не понял почему бы кто-то мог его особо захотеть — не вижу в нём «фишки» кроме «легковесности», которая сейчас не входит в число насущных проблем сколько-нибудь широкой аудитории.
PS: Я не минусовал, плюсанул даже, если что-то такое получится — буду очень рад.
Это Хабр. Кто-то поставил минус, кто-то добавил и понеслась…
Возможность написания одной и той же конструкции кучей вариантов отношу к минусам, код должен быть построен однородным образом. Слишком много сахара.
+1. Это раздражает (отчасти) и в CoffeeScript, на который это ну очень сильно похоже, кстати.
А мне еще и Питон напомнил, с его перегрузкой методов и операторов.
А мне ruby чем-то напомнил.
Это где в python перегрузка функций? PEP:3124 заморозили www.python.org/dev/peps/pep-3124/
Согласен. Тут я пошел по пути языка Lua. Там в описании объектом можно использовать и запятую и точку с запятой, да и равно между парой ключ — значение мне нравится. В то же время я не хотел отказываться от нативной поддержки JSON формата.
И чем же это плохо? Хотите, пишите как угодно. Хотите, пишите одним вариантом. Если есть проблемы с коллегами — договоренность все решит.
Вы молодец!
осталось внедрить в node.js и браузеры!
как обстоят дела с утечками и сбором мусора?
как вообще оно устроено, понятно что это требует отдельной статьи…
осталось внедрить в node.js и браузеры!
как обстоят дела с утечками и сбором мусора?
как вообще оно устроено, понятно что это требует отдельной статьи…
UFO just landed and posted this here
node.os — это обязательно, если дойдут руки, может кто присоединиться к разработке, посмотрим. И компиляция OS в JS также изначально была записана в плане.
Я наверное никогда не пойму отказ от точек с запятыми.
Питонщики смотрят на вас с немым укором.
Толку от них? Все приличные программисты следуют принципу «одна стока — одно выражение». Точка с запятой нужна машинам, а не людям. А машины сейчас умные, могут сами понять, где один оператор, а где второй.
function a {
...
return
{a: 'b'}
}
«Умная машина» не вернёт объект, она подумает, что имелось ввиду «return;»
Потрудитесь объяснить, какой смысл переносить выражение на новую строку?
В питоне это пишется так:
В питоне это пишется так:
return {
1: 42,
"foo": "bar",
}
Вы же про умность машин, я привёл пример, когда машина не поймёт, как верно.
Язык в первую очередь для людей создаётся. Это один из примеров, случайно enter нажался, например. Машина ошибку не покажет, отловить сложно.
Так что не писать ; лишь потому, что язык это разрешает — зло (это в большей степени про JavaScript и про этот ObjectScript).
Про Pythin вообще другой разговор, в языке вообще же нет ;.
Язык в первую очередь для людей создаётся. Это один из примеров, случайно enter нажался, например. Машина ошибку не покажет, отловить сложно.
Так что не писать ; лишь потому, что язык это разрешает — зло (это в большей степени про JavaScript и про этот ObjectScript).
Про Pythin вообще другой разговор, в языке вообще же нет ;.
ObjectScript на такую конструкцию не споткнется, будет возвращен объект как и задумано.
А такой пример?
Вернёт b или нет?
if (a == 0) return
b = f(c)
...
Вернёт b или нет?
Будет синтаксическая ошибка, попытается вернуть b, а там равно, равно в OS не возвращает значение. По крайней мере в текущей версии, тут прямой аналог — Lua, и нужно это для множественного присваивания, когда значение вынимается из стека, чтобы корректно присвоить следующее значение. Поэтому после return следует ставить ; чтобы однозначно отделить синтаксис.
не знаю как в Pythin (Владимир Владимирович?), а в Python есть точка с запятой:
>>> a = 1; b = 2
>>> print a, b
1 2
>>>
1) Машина ошибку покажет, unreachable code же.
2) Есть в питоне точка с запятой, ставьте хоть после каждого оператора.
2) Есть в питоне точка с запятой, ставьте хоть после каждого оператора.
А кто вам сказал, что точки с запятой лишние. Нет, не так… Кто вам сказал, что только точка с запятой лишняя. Слово return в вашем примере тоже явно лишнее. ;)
Ruby, например, и без этого слова вернет значение последнего вычисленного внутри функции выражения.
def a
…
{a: 'b'}
end
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
);
Брр. Траектория полета ракеты?)
Вижу. И что? Почему-то питон прекрасно понимает многострочные выражения без точек с запятой.
А можно не смотреть? о_О
Или как-то так:
Имена some-value, fn1 и fn2 были выбраны наобум, т.к. я не знаю, как назвать эти величины и функции (не разбираюсь в предметной области).
Кого напрягают скобочки, тем сообщаю, что в Dr. Racket есть умная подсветка:
(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, когда в нем нет необходимости:
Кроме того в JS иногда очень не хватает типов-перечислений (Enum), было бы удобно не задавать значения без необходимости:
Задумка очень интересная. Раз уж расширять возможности языка и упрощать синтаксис — было бы удобно писать анонимные функции в стиле C#, без слова function и оператора return, когда в нем нет необходимости:
x => x*x;
(y, z) => y*z;
Кроме того в JS иногда очень не хватает типов-перечислений (Enum), было бы удобно не задавать значения без необходимости:
Enum CarTypes = {
Truck,
Sedan,
Wagon
}
//Использование: CarTypes.Truck
Насчет запятых — семейство Lisp-подобных языков с вами не согласится.
enum пока зарезервировано как служебное слово.
В последнем обновлении добавлен сокращенный синтаксис для функций:
это полный аналог:
{|y z| y*z}
это полный аналог:
function(y, z){ return y*z }
evgeniyup, а вы знакомы с Ruby?
Если уж говорить об упрощении синтаксиса и следовании объектно-ориентированной парадигме, то стоит посмотреть в сторону замены процедур и функций на методы классов.
Например, цикл for на рельсах пишется, по-моему, очень элегантно:
Если уж говорить об упрощении синтаксиса и следовании объектно-ориентированной парадигме, то стоит посмотреть в сторону замены процедур и функций на методы классов.
Например, цикл for на рельсах пишется, по-моему, очень элегантно:
10.times do
// your code
end
Гетеры, сетеры и пр. — это из Питона, видимо. А Вы оценивали уже скорость работы языка? Интересно.
Немного не ясна цель создания этого языка, собственно, как и его целевая аудитория.
Всякие фишечки типа «запятую можно не ставить» или «вместо ':' можно поставить '='», не прибавляют языку простоты. Кроме того, наследование в стиле JavaScript — тоже не самая очевидная штука, особенно для новичков.
ObjectScript позиционируется как встраиваемый скриптовый язык для С++-приложений. IMHO, если уж не устраивает чем-то тот же Lua и JS, то существуют варианты и поприятнее. Нужен простой ОО-язык с достаточно «привычным» синтаксисом? Окей, получите Squirrel. Прототипное наследование не пугает, но хочется очень маленькую виртуальную машину + не перегруженный лишними символами синтаксис? — Получите Io.
А у Вас что? Куча неоднозначностей в лучших традициях JS + парочка сомнительных синтаксических фишек.
Всякие фишечки типа «запятую можно не ставить» или «вместо ':' можно поставить '='», не прибавляют языку простоты. Кроме того, наследование в стиле JavaScript — тоже не самая очевидная штука, особенно для новичков.
ObjectScript позиционируется как встраиваемый скриптовый язык для С++-приложений. IMHO, если уж не устраивает чем-то тот же Lua и JS, то существуют варианты и поприятнее. Нужен простой ОО-язык с достаточно «привычным» синтаксисом? Окей, получите Squirrel. Прототипное наследование не пугает, но хочется очень маленькую виртуальную машину + не перегруженный лишними символами синтаксис? — Получите Io.
А у Вас что? Куча неоднозначностей в лучших традициях JS + парочка сомнительных синтаксических фишек.
Изначально язык нацелен на аудиторию лояльную к C-подобным языкам, к ним я отношу JavaScript, PHP, Lua ну и некоторые другие.
А в целом я работаю над реализацией движка для написания кросс платформенных приложений по типу Corona SDK, но на ObjectScript и Marmalade SDK. Не отказался бы от интеграции с др. платформами, например, Irrlicht, Shiva3D и др. В принципе область применения может быть довольно большой, тот же node.os (как аналог node.js).
Насколько мне известно, от русскоязычного комьюнити мировому сообществу пока не предложено языков высокого уровня. Что я предлагаю — завершить спецификацию ObjectScript, создать комьюнити, может быть найти инвестиции.
А в целом я работаю над реализацией движка для написания кросс платформенных приложений по типу Corona SDK, но на ObjectScript и Marmalade SDK. Не отказался бы от интеграции с др. платформами, например, Irrlicht, Shiva3D и др. В принципе область применения может быть довольно большой, тот же node.os (как аналог node.js).
Насколько мне известно, от русскоязычного комьюнити мировому сообществу пока не предложено языков высокого уровня. Что я предлагаю — завершить спецификацию ObjectScript, создать комьюнити, может быть найти инвестиции.
Круто! Реализованы многие вещи, появление которых я давно ждал! Правда слишком много информации для одного поста!
Ждем ответов на вопросы выше. Ну и название, как-то не слишком, но, это уже дело вкуса.
Ждем ответов на вопросы выше. Ну и название, как-то не слишком, но, это уже дело вкуса.
То, что вы делаете — это интересно, прикольно. Но ничего серьезного не вырастет. Ну с точки зрения создания чего «такого, что перетянет на себя программистов XXX» (подставить java, ruby, python, C#).
Потому что неправильно поставлена проблематика.
Проблема не стоит упростить синтаксис.
Нужно сочетание предельной строгости и простоты.
Чтобы глядя на код однозначно понимать что он делает. При этом хочется иметь JSON и динамическую типизацию.
Также нужно, чтобы исполняющая среда была изначально дружна с потоками. И производительна.
Нужно иметь помимо ручного управления памятью и автоматическое тоже…
Короче, тут можно долго распространяться.
Потому что неправильно поставлена проблематика.
Проблема не стоит упростить синтаксис.
Нужно сочетание предельной строгости и простоты.
Чтобы глядя на код однозначно понимать что он делает. При этом хочется иметь JSON и динамическую типизацию.
Также нужно, чтобы исполняющая среда была изначально дружна с потоками. И производительна.
Нужно иметь помимо ручного управления памятью и автоматическое тоже…
Короче, тут можно долго распространяться.
Очень неплохо, но:
— в скрипт-языках очень важна привязка к нижним языкам (здесь C++), например что бы подключить какой-нибудь модуль X с интерфейсом в ObjectScript. Так вот привязка здесь хромает пока — недавно подключал CryptoPP для tcl, прикинул как было бы в ObjectScript и сломал мозг; Посмотрите хотя бы на реализацию этого в других скриптах, или хотя бы на critcl.
— «объектно ориентированный» это очень сильно сказано — где publiс, private и как с этим бороться при наследовании не совсем понятно. Выглядит как простой hash-struct расширеный до функций (методов). Множественное наследование, миксины и др. вкусные плюшки современных объектно ориентированных языков не проработаны или отстутствуют полностью.
— практически не понятно как организован интерпретер (например возможен ли N interp per M threads), Jit (если вообще Jit) и т.д. Есть ли например возможность расшарить объектный код между interp и/или threads.
— сборщик мусора для скрипт-языка IMO не обязателен (можно вполне обойтись ReferenceCount).
— и как уже говорили другие синтакс «слишком сладкий», хотя это на любителя;
Хотя скорее зачет, чем нет.)
— в скрипт-языках очень важна привязка к нижним языкам (здесь 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++, позволит мне максимально расширить интерфейс к этому всему в скрипте.
Теперь сравните ваше:
с тем же например на tcl:
Вроде похоже, но вот что мне не хватает и не понятно:
— почему нет какой-нибудь clientData, т.е. внутренние референсы мне в глобальных переменных передовать? Хотя нет, нашел pushCFunction с user_param — это оно?
— нифига не ясно, как у вас связаны сишная функция test и имя «test» (который через setGlobal...);
— как мне удалить clientData если удалим команду из интерпретора (не увидел что-то типа callback deleteTestProc);
— как передаются/навесить аргументы в test функцию (tcl — objc, objv)?
— слишком много push, pop — это подавляет.
и тд и тп.
Кроме того интересны вызовы типа 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 — это подавляет.
и тд и тп.
Первый пример с Box2d кстати готов, можно посмотреть видео тут youtu.be/3RHek-UhkCk, как это работает — видимо это тоже тема для новых статей.
Исходники в одном полумегабайтном файле?!
Слишком все в кучу и функциональность, и внутренняя реализация, и примеры. Получается довольно запутанно.
1. Замена «запятых» на «пробелы» еще воспринимается нормально, а вот «точка-с-запятой» да еще в смешанном варианте -совершенно не читабельно. Я бы ограничил использование одного типа разделителя в пределах вызова. Именованные параметры через «двоеточие» или «равно» также в пределах одного вызова.
2. Конкатенация строк чище при использовании переменных внутри строки
можно использовать как локальные переменные, так и передачу параметров или словаря
3. "
4.
Зачем столько кода, как же лямбды? :)
5. Такой код сработает?
Как вывести только порядковые индексы (не ключи) из obj?
6. При общей тенденции к упрощению кода, описание класса через функции слишком громоздкое.
Чем не устраивают конструкторы, свойства, методы, операторы, на худой конец через лямбды.
7.
тут можно было бы Добавить backingField, defaultValue, notifications или еще что-то по желанию
Просто __get(empty/dim) и __set(empty/dim) — это расширенные индексаторы, в c# есть синтаксис
8. delete a.color — удаляет значение или свойство?
Что будет после этого при вызове a.color = «green»
Запишется новое значение или появится новое свойство?
9. Использование двойной точки и двойного подчеркивания, двойной звездочки (как и вообще парное использование одного и того же символа) плохо читается.
10. В языке есть null-safe синтаксис? Посмотрите в Kotlin
Вообще довольно интересно получилось!
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. дело в том, что
эквивалентен объекту на JS
поэтому
4. в OS (ObjectScript) изначально все функции — лямбды, запись с ключевым словом function на мой взгляд воспринимается более читабельно
5. код
6. 7. согласен
см. director.os — это из 2d движка, который я пишу для мобильных платформ на ObjectScript. Данный синтаксис пока не добавлен в описание объекта.
8. delete работает также как в JS, т.е. удаляется не само значение, а ссылка на него или свойство в данном случае. Сам же объект разрушается в процессе сбора мусора
9. согласен
10. есть например такой язык objective-c, который используется в продуктах Apple (по сути все не кроссплатформенные приложения для Apple App Store написаны на objective-c), там можно вызвать метод для null объекта и это будет проглочено молча без единного предупреждения, что произойдет? да ничего, просто метод (там это называется событие) не будет вызван. Текущая версия OS поведет себя так же, но я планирую более детально проработать этот момент. Например, в текущий момент при разработке на OS мне очень сильно помогает лог доступа к необъявленым свойсвам и делается это средствами самого же OS. Например, посмотрим файл core.os
Весь вывод через
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]
выведет one4. в 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 проще найти в тексте, но нагромождение скобок после него начинает путать
Где закончилось описание функции и начался вызов с параметрами, зачем тут return?
Или вот такое:
Можно кроме привычного
7. Когда get и set внутри свойства проще читается. Можно добавить fieldof(property) и избавиться от явного указания полей для свойств, применение ограничить в пределах класса. Можно добавить default и заранее задать нужное значение, в том числе при первом обращении (lazy properties, default => 10). Можно добавить raise для событий. Как-то так
raise также можно использовать внутри описания событий как в VB.NET
10. Да null object pattern вполне годный вариант.
11. Switch, pattern matching?
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:
Чуть выше тут сказали, что лучше бы отказаться от function() и return, последняя строка в функции это return, как в Erlang:
add(A,B)->A+B.
Мне кажется надо сменить название. ObjectScript уже достаточно давно существует.
Пинцет
Интересная разработка, много интересных идей. И много, увы, неудачных, которые перечёркивают всё.
Отмечу такой момент: запутанность кода. Код должен быть простым и понятным. У вас код удобно писать, но не очень удобно читать. Этим же иногда страдает и CoffeeScript.
Ведь не зря же создатели C ввели скобки?
Отмечу такой момент: запутанность кода. Код должен быть простым и понятным. У вас код удобно писать, но не очень удобно читать. Этим же иногда страдает и CoffeeScript.
Ведь не зря же создатели C ввели скобки?
Пример запутанности и неоднозначности кода. Вот такой код:
func('abc' val 'abc')
Вот интересно, чему это эквивалентно:
func('abc', val, 'abc');
// или
func('abc' + val + 'abc');
// или
func('abc' + val, 'abc');
// или
func('abc', val + 'abc');
А если ещё и скобки функции опустить, то ещё 20 вариантов придумать можно…
func('abc' val 'abc')
Вот интересно, чему это эквивалентно:
func('abc', val, 'abc');
// или
func('abc' + val + 'abc');
// или
func('abc' + val, 'abc');
// или
func('abc', val + 'abc');
А если ещё и скобки функции опустить, то ещё 20 вариантов придумать можно…
Не взлетит. На embedded-системах роль встраиваемого языка уже давно прочно закрепилась за lua, на десктопах есть питон. А тут вы со своим мешком сахара.
Хм… На каких конкретно системах Луа?
Питон вроде более чем бодренько работает на эмбеддед, на Мипс 400 МГц х 32 метра рам — полновесный питон у меня без проблем стартует.
Питон вроде более чем бодренько работает на эмбеддед, на Мипс 400 МГц х 32 метра рам — полновесный питон у меня без проблем стартует.
На iOS, android и других. Lua занимает мало место в памяти, удобен и достаточно быстр в сравнении с другими языками, особенно после JIT.
Что-нибудь типа такого реализуется? Динамическая модификация итератора в процессе работы. В то же шарпе дает ошибку в рантайме.
foreach (Foo foo in bar<Foo>)
{
if (foo==smth) {bar[foo].RemoveItem}
}
Модификация контейнера в foreach?
Обсуждение такой идеи мне кажется пустозвонством, ибо слишком много вопросов. Foreach используется не только для массивов и списков, а для любого обьекта, что реализует интерфейс IEnumerable. Что если у вас не просто список, элементы которого будут добавляться в конец, а упорядоченный список?
Добавляя элементы мы можем напороться на нехорошую ситуацию — если элемент попадёт не в конец списка, а в начало, то IEnumerator уже не пройдёт по нему. Как быть в таком случае?
А если заменяется текущий элемент? Что тогда предпринимать? Делать ещё одну итерацию специально для него или идти дальше?
Слишком много вопросов. Кто-то будет считать, что тако-то делать неправильно, или неоптимально, или неожиданно, или ещё что-нибудь. Получается неочевидность результатов работы с такой фишкой. Мне кажется, что в случае, если вы хотите менять коллекцию во время её перебора, нужно использовать не foreach.
Обсуждение такой идеи мне кажется пустозвонством, ибо слишком много вопросов. Foreach используется не только для массивов и списков, а для любого обьекта, что реализует интерфейс IEnumerable. Что если у вас не просто список, элементы которого будут добавляться в конец, а упорядоченный список?
Добавляя элементы мы можем напороться на нехорошую ситуацию — если элемент попадёт не в конец списка, а в начало, то IEnumerator уже не пройдёт по нему. Как быть в таком случае?
А если заменяется текущий элемент? Что тогда предпринимать? Делать ещё одну итерацию специально для него или идти дальше?
Слишком много вопросов. Кто-то будет считать, что тако-то делать неправильно, или неоптимально, или неожиданно, или ещё что-нибудь. Получается неочевидность результатов работы с такой фишкой. Мне кажется, что в случае, если вы хотите менять коллекцию во время её перебора, нужно использовать не foreach.
Да. Приходится городить костыли (например, в одном цикле запоминать индексы искомых элементов, с которыми работать уже во втором). Но хотелось бы иметь язык, который такие ситуации не запрещает, а описывает и разруливает.
Я могу лишь сказать, что изменение/удаление итератора для стандартных типов (array, object) не приведет к падению, более того отработает как задумано программистом. Но я бы не применял такую практику.
С августа, тоесть по большому счету прошло 2 месяца?
Тянуть такую громадину в одиночку вполне реально, Angel Script тому пример!
Интересно будет взглянуть через год, если не заглохнет!
Тянуть такую громадину в одиночку вполне реально, Angel Script тому пример!
Интересно будет взглянуть через год, если не заглохнет!
a = {x=1, y=3; "zero" "one", "two" last:7,}
Боже…
если честно с запятыми и точками с запятой как-то легче воспринимать код
>> «А зачем там собственно запятая?»
А зачем там, собственно, открывающая и закрывающая скобки?
А зачем там, собственно, открывающая и закрывающая скобки?
А зачем там, собственно, код?
Просто я к тому, что есть языки, в которых скобки не обязательны. Как по мне, это отличная идея…
Да не, не обращайте внимания на мой коммент, это я так бредю.
Что касается скобок — нужно всё в меру. В if или for скобки убрать неплохо, а вот например в создании хэша — плохо. Читаемость кода очень понижается
Что касается скобок — нужно всё в меру. В if или for скобки убрать неплохо, а вот например в создании хэша — плохо. Читаемость кода очень понижается
А почему бы не добавить что-то вроде perl-овского «$_»?
Соскучились по радостям Перла вроде www.linux.org.ru/forum/development/392747?
Интересная затея конечно (= Кстати, если у вас большой опыт в экспериментировании с написанием своих языков, почему бы вам не присоединиться к проекту 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
Вашу бы энергию да в благое русло!
Я попробовал реализовать tri-color incremental garbage collector, иначе говоря сборка мусора делается не за один проход, а за много во избежании высокой нагрузки самого сборщика на систему. Что из этого получилось? Работает и не падает, все что надо удаляет, удалось затюнить сборщик для максимально возможного fps на моем мобильнике HTC Desire (в тех демках, что я делаю на OS). Тем не менее, я не доволен тем, что fps не ровный, но пока не уверен в чем именно проблема, в сборщике мусора или в чем-то другом.
Больше интересует это moving или non-moving этот GC.
non-moving (например ref-counting) GC удобен при встраивании в C++ но имеет известные проблемы в плане cyclic references и частых аллокаций типа
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 следующим образом
Выведется:
super вызывает метод родительского класса (прототипа) с именем метода, из которого он был вызван! Тут речь идет о любом методе, нужно просто вызвать super с нужными параметрами.
Ручная передача this в функцию
Чтобы вызвать функцию и передать в нее нужный нам
Выведется:
Метод
Выведется:
P.S. заодно проверил и исправил баг в apply, если вы уже клонировали репозиторй, обновитесь пожалуйста
Инкапсуляции
Класс
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 и т.п., например:
в JavasScript часто пишут так:
что полностью допустимо в ObjectScript, а в сочетании с objectof дополнительная проверка типа.
Простые типы это: number, string, boolean, null. Оператор valueof преобразует аргумент в простой тип.
Но на практике часто используются др. сопутствующие операторы, например, numberof и т.п., например:
function setOptions(options){
options = objectof options || {}
....
}
в JavasScript часто пишут так:
function setOptions(options){
options = options || {}
....
}
что полностью допустимо в ObjectScript, а в сочетании с objectof дополнительная проверка типа.
Вот вы говорите что писали для вставки в приложение C++.
А под C# не планируете доработать?
А под C# не планируете доработать?
C# сам по себе может использоваться для скриптинга. Компилятор доступен прямо из языка, а генерированный таким образом код можно запускать, закрыв ему доступ к файловой системе с помощью атрибутов безопасности.
Не соглашусь — для скриптинга лучше применять специально сделанные для этого языки, которые пусть и менее функциональны, но быстрее исполняются, и проще в синтаксисе.
Sign up to leave a comment.
ObjectScript — новый язык программирования