Pull to refresh

Comments 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? В последнем варианте получится в нативный код компилировать.
Чтобы донести Ваш язык в массы, Вам нужны инвестиции. Попробуйте запостить презентацию на кикстартер.
Спасибо за идею, а что это реально работает для подобных проектов?
UFO just landed and posted this here
Не понимаю, почему заминусовали alesto. Совсем ошалели?
Не понимаю, почему заминусовали alesto.

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

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

как обстоят дела с утечками и сбором мусора?
как вообще оно устроено, понятно что это требует отдельной статьи…
UFO just landed and posted this here
не знаю как пишется тег [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 следует ставить ; чтобы однозначно отделить синтаксис.
>Поэтому после 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 тому пример!

Интересно будет взглянуть через год, если не заглохнет!
если честно с запятыми и точками с запятой как-то легче воспринимать код
>> «А зачем там собственно запятая?»

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

Что касается скобок — нужно всё в меру. В 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 данными

Но в то же время, любые разумные предложения приветствуются, предложения и способы реализации.
преобразует значение в простой тип данных, я расскажу об этом и др. специальных операторах в следующей статье
Тоесть аргумент — это значение? Просто по аналогии с 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, а там уже пёс его знает что быстрее будет.
Sign up to leave a comment.

Articles

Change theme settings