Re[6]: Веб фрэймворк для Nemerle
От: WolfHound  
Дата: 14.02.11 22:00
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Чтож. Буду краток! Когда?

Я это делать даже не начинал.
И если я начну делать это то ПЕГ будет делать некому.
Так что если есть желающие то готов оказать моральную и идеологическую поддержку.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Веб фрэймворк для Nemerle
От: Воронков Василий Россия  
Дата: 14.02.11 22:47
Оценка: 9 (3)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Воронков Василий, Вы писали:


ВВ>>Нет, я говорю с позиции практика. И на практике постоянно возникает необходимость спуститься на уровень ХТМЛ-я. Поэтому все абстракции, которые строятся над ним, попросту вредны. Я не знаю, как еще это объяснить. Это веб, это UI. В любой момент может возникнуть требование типа "все хорошо, ну тут надо фон поменять на серо-буро-малиновый, а здесь черточку дорисовать". И чего мне делать с этим Menu.builder?


VD>Дык Menu.builder это не более чем фунция. Подставь свою и вызови из нее все что нужно с нужными параметрами.


Подставить свою? И переписать весь код генерации меню что ли? А я же только самую малость подправить хочу.

ВВ>>Причем тут рекурсивность?

VD>Ну, право странно слышать это от человека который так ревностно отстаивал принципы ФП и хвалил ХСЛТ.

Принципы ФП — это такие принципы, которые есть в ФП, а не мантра, согласно которой слово за слово надо повторять "рекурсия, рекурсия". Ты новый подход описываешь, должен показывать его отличия. А рекурсию и в веб-контролах никто не отменял.

ВВ>>Контрол — это просто метод void Render(HtmlTextWriter). Все. Что там внутри — одному черту известно. Хочешь будет рекурсия, хочешь не рекурсия.

VD>Не контрол — это класс с кучей хрени вокруг. События рендереры, вьюстэйт и т.п.
VD>А метод есть метод. Создать метод — это пара нажатий на кнопку. А контрол создают только для отдельных случаев и очень редко.

"Хрень" — это то, что вешается уже сверху. Кстати, совершенно необязательная хрень. Для реализации контрола достаточно определить лишь Рендер. И он-то как раз и является костяком контрола. Чем это кардинально отличается от "просто функции" я не вижу.

ВВ>>Если же ты имеешь в виду, что веб-контрол обязан возвращать ХТМЛ, а не может вернуть, скажем, набор шаблонов, то да, это разница есть.

VD>Ага. И это очень большая разница.

На основе чего ты сделал такой вывод? Т.е. нет. Разница может и большая, вот только положительная ли? Я вот сомневаюсь, что нужны шаблоны, порождающие шаблоны и пр. Это ж ты какие каскадные зависимости ввести хочешь. В одном шаблоне что-то поправил — и бац, все дети тут же отвалились к ядреной матери. Не похоже это на будущее веб-фреймворков.

ВВ>>Но мне кажется, что ты преувеличиваешь значение этого дело.

VD>Ага, кажется это очень точное слово.

Не, точным словом было "преувеличиваешь".

ВВ>>Все равно ты сделал веб-контрол, пусть и более навороченный.

VD>Он тебе мерещится. Поверь. Забудь про молоток и все перестанет казаться гвоздями.

Ну пока ты демонстрируешь молоток, что-то иное увидеть очень сложно. Единственное отличие от веб-контролов — "шаблоны порождающие шаблоны". Все. Даже если предположить, что это мировая фича, то тут все равно есть одна тонкость. Проблемы в том, что веб-контролы в веб формах возвращюсь ХТМЛ и не могут возвращать разметку АСП.НЕТ в общем-то не было. Зато были другие проблемы. Возникает вопрос — а что ты, собственно, лечишь-то?

ВВ>>МС уже ходила по этому пути, посмотри к чему они пришли после веб-формов — это уже *совсем* не веб-контролы.

VD>МС часто ходят черт знает куда. Не будем про них. Я тебе уже свое мнение высказал. Повторяться не хочу.

МС потратила много лет и ресурсов, прошла довольно длинный путь. Я не думаю, что отметать чужой опыт, даже не задумываясь, это правильный подход.

ВВ>>А ты, сдается мне, попросту не понимаешь, в чем *реальная* проблема у веб-форм.

VD>Я просто понимаю, что ты сейчас борешься со своим воображением.

Вообще-то по факту я борюсь как раз с твоим воображением. Ибо ты тут представляешь свою умозрительную концепцию, и она-то как раз и подвергается "обозрению".

ВВ>>Контрол — это тоже функция трансформации. Render называется. Логика формирования у контрола тоже может переопределяться как хочешь — через виртуальные методы, через свойства, хотя лямбды там ему в эти свойства подсовывай. Разница-то в чем?

VD>В простоте создания. В возможности использовать общий класс представления. В возможности вернуть все тот же набор тегов которые сами раскроются как надо. В отсутствии вьюстейта. Ну, в общем — это мягко говоря другой подход.

Контрол создать очень просто. Попробуй. Или большая проблема class с фигурными скобками вокруг функции написать?
Общий класс представления — ну как ты сам, надеюсь, понимаешь, этого никто даже в веб-формах не запрещает.
Возможность возвращать шаблоны — это да, новое слово в науке. Вопрос лишь, насколько это нужно.
Вью-стейт тебя в веб-контролах никто юзать не заставляет, можешь вообще забыть о нем.

Не похоже на другой подход. Правда не похоже.

ВВ>>Я предлагаю подумать. А мега-идей у меня с прошлого раза так и не появилось. Если появятся — обязательно расскажу.

VD>Ну, давай думать. Из разумных (возможно!) идей я вижу только предложение вольфхаунда использовать MVVM (аля Нокаут) и некий набор макросов для автоматизации и статической типизации этого дела.

Начинать лучше думать с того, что делать с клиентским кодом. Большая часть формирования UI в современном вебе именно там, так что польза даже от самых крутых шаблонов может быть не такой уж значительной.

ВВ>>Дело в том, что ХМТЛ, размазанный по коду на Немерле, абсолютно ничем не лучше. Ты вообще веб-страницу когда-нибудь делал сам-то?

VD>Писал. Даже на АСП без нет умудрился поработать.
ВВ>>Как, ты думаешь, люди это будут писать? Прям вот так вот, с чистого листа, взял и набросал таблички, стили — раз-раз и готово? Все равно сначала все будет писать в отдельном файлике, проверяться в браузере после каждого изменения (и не в одном, а во всех целевых), а потом уже переноситься в код. И вот когда держишь в голове такой юзкейс крутотень от ХМЛ-литералов как-то исчезает.
VD>Что все плохо я услышал. Что хорошо — нет.

А я тебе говорю — я не знаю, что хорошо. Подходов в общем много. Я вижу, что веб-приложения постепенно все больше и больше переплывают на клиента, а там уже клиентский темплейт энжин нужен и всякие Лифты тут не сильно помогут. Я вижу то, что на создание собственно UI в вебе уходит 60-90% времени от всей разработки. Потому что там единых стандартов нет — нарисовали дизайнеры хрень в фотожопе и надо воспроизвести один-в-один. Считай каждый проект делаешь UI, который раньше не делал, ибо фантазия у этих товарищей ого-го. И надо чтобы черточка к черточке сходилась. Тут в любом случае начинается все с того, что сидишь в блокноте и "рисуешь". От того, что у меня потом будет какая-то там статическая типизация этого ХТМЛ-я... вообще говоря, не очень ясно, что это мне даст-то. Больше гемороя блин, придется этот ХТМЛ еще по коду как-то размазывать.

Все это на бумаге хорошо выглядит и с тестовыми примерами, а на практике не очень-то и хорошо. Единственное, где мне ХТМЛ-литералы бы не помешали — это в ДжаваСкрипте. Ибо "из коробки" там только одна альтернатива — хреначить все через ДОМ. По сравнению с этим литерал — это конечно круто. Ну так может и делать компилятор в ДжаваСкрипт. Может и не нужен вообще традиционный серверный фреймворк? Можно написать сколь угодно сложное приложение, в котором UI формируется *только* на клиенте, а сервер лишь выдает данные — JSON там или XML. Может и двигать в таком направлении.
Re[7]: Веб фрэймворк для Nemerle
От: Ziaw Россия  
Дата: 15.02.11 04:39
Оценка:
Здравствуйте, WolfHound, Вы писали:

Z>>Чтож. Буду краток! Когда?

WH>Я это делать даже не начинал.
WH>И если я начну делать это то ПЕГ будет делать некому.
WH>Так что если есть желающие то готов оказать моральную и идеологическую поддержку.

Вопрос был скорее риторический. Ситуацию я и сам вижу. И понимаю, что после пега будет компилятор Н2 с кучей хитрых алгоритмов требующих твоего внимания. Я бы занялся, на досуге, но сейчас стоит проблема сайта.

С одной стороны nemerle нужен сайт сейчас, с другой с таким view engine его можно будет на выставках показывать. Я склоняюсь к тому, что писать надо сейчас на том, что есть.
Re[8]: Веб фрэймворк для Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.02.11 07:49
Оценка: -1
Здравствуйте, Ziaw, Вы писали:

Z>С одной стороны nemerle нужен сайт сейчас, с другой с таким view engine его можно будет на выставках показывать. Я склоняюсь к тому, что писать надо сейчас на том, что есть.


А мне сдается, что время потраченное на хороший движок приведет к резкому уменьшению объема работы по тому самому сайту. Так что в худшем случае результат получится за одно время. Но так мы поимели бы хотя бы приличный движок.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Веб фрэймворк для Nemerle
От: WolfHound  
Дата: 15.02.11 14:00
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>С одной стороны nemerle нужен сайт сейчас, с другой с таким view engine его можно будет на выставках показывать. Я склоняюсь к тому, что писать надо сейчас на том, что есть.

С таким view engine немерле и без сайта с руками и ногами отрывать будут.
Это какраз то самое KillerApplication про которое твердят большевики.

Для того чтобы довести это до версии без наворотов типа comet и клиентской многозадачности как в Ur/Web много времени не надо. Нужно только иметь их в виду.
На парсер благодаря ПЕГу уйдет несколько часов.
И несколько дней на то чтобы создать трансляторы в жабаскрипт и серверный код.
С серверным кодом вообще все просто. Там будет практически тупая трансляция методом что вижу то пою. Тут немерле рулит.
С жабаскриптом посложнее там реактивность нужно приделать но ПМ и рекурсия сильно облегяат задачу.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Веб фрэймворк для Nemerle
От: Mamut Швеция http://dmitriid.com
Дата: 15.02.11 14:39
Оценка:
VD>Особенно потому, что это идея в первую очередь адресуется ему как создателю НРельсов.

VD>Я тут посмотрел Lift (фиговенький передов книги по нему) и нашел его идеи по рендеренгу (точнее его подход к реализации паттерна MVC) вполне милым, логичным для ФЯ и (что самое важное) легко реализуемым на базе макросов немерла.


VD>В качестве средства упрощения работы с БД можно использовать Nemerle on rails созданный Ziaw. Рельсы по всей видимости нужно еще доводить до ума, но как основа они точно потянут.


VD>Остается только движок рендеренга HTML/XML-я и JSON. JSON опять же уже смастерил Ziaw.


VD>Так вот чтобы получить действительно законченные Nemerle on rails нужно смастерить движок рендеренга HTML/XML.


VD>Предлагаю повторить Lift (естественно, с учетом особенностей немерла).



Эххх, если бы кто-то еще повторил и webmachine Но это так — просто в общую копилку идей


dmitriid.comGitHubLinkedIn
Re[9]: Веб фрэймворк для Nemerle
От: Ziaw Россия  
Дата: 15.02.11 14:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Для того чтобы довести это до версии без наворотов типа comet и клиентской многозадачности как в Ur/Web много времени не надо. Нужно только иметь их в виду.

WH>На парсер благодаря ПЕГу уйдет несколько часов.
WH>И несколько дней на то чтобы создать трансляторы в жабаскрипт и серверный код.
WH>С серверным кодом вообще все просто. Там будет практически тупая трансляция методом что вижу то пою. Тут немерле рулит.
WH>С жабаскриптом посложнее там реактивность нужно приделать но ПМ и рекурсия сильно облегяат задачу.

Боюсь мне понадобится на порядок больше времени, просто потому, что опыта написания трансляторов у меня нет.
Кроме самой трансляции нужна еще куча инфраструктурных моментов. Скорее всего он не ляжет как yet another view engine for asp.net mvc. Но, в принципе, его можно использовать параллельно.

Пока я оцениваю создание движка и создание сайта как задачи примерно равной мощности. Менее чем через 2 месяца ни то ни другое не будет иметь более или менее законченный вид.

Сказкам Влада про то, что на таком движке сайт напишется намного быстрее я не верю. Переход от сверстанного шаблона к коду на view engine задача совсем не сложная и сколько ее ни сокращай, заметного выигрыша не получится.

Основной фичей этого движка должна стать прозрачное общение между сервером и клиентом, типизированность и краткость кода. В первую очередь это уменьшение сложности. А никак не скорость создания сайтов, в которых вопросы дизайна, юзабилити и серверной логики все равно никуда не денутся.
Re[2]: Веб фрэймворк для Nemerle
От: Ziaw Россия  
Дата: 15.02.11 14:59
Оценка:
Здравствуйте, Mamut, Вы писали:

VD>>Особенно потому, что это идея в первую очередь адресуется ему как создателю НРельсов.


VD>>Я тут посмотрел Lift (фиговенький передов книги по нему) и нашел его идеи по рендеренгу (точнее его подход к реализации паттерна MVC) вполне милым, логичным для ФЯ и (что самое важное) легко реализуемым на базе макросов немерла.


VD>>В качестве средства упрощения работы с БД можно использовать Nemerle on rails созданный Ziaw. Рельсы по всей видимости нужно еще доводить до ума, но как основа они точно потянут.


VD>>Остается только движок рендеренга HTML/XML-я и JSON. JSON опять же уже смастерил Ziaw.


VD>>Так вот чтобы получить действительно законченные Nemerle on rails нужно смастерить движок рендеренга HTML/XML.


VD>>Предлагаю повторить Lift (естественно, с учетом особенностей немерла).



M>Эххх, если бы кто-то еще повторил и webmachine Но это так — просто в общую копилку идей


А можно вкратце про суть? Я понял только, что это роутинг, сопоставляющий каждый маршрут некоему набору функций, возвращающих разные части запроса. Но это общая идея, в том, что тут функции, а не методы объекта я пока не вижу профита. Получается рест, что с ним делать дальше непонятно.
Re[2]: Веб фрэймворк для Nemerle
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 15.02.11 15:09
Оценка: +1 :)
Здравствуйте, Mamut, Вы писали:

M>Эххх, если бы кто-то еще повторил и webmachine Но это так — просто в общую копилку идей


Webmachine is an application layer that adds HTTP semantic awareness on top of the excellent bit-pushing and HTTP syntax-management provided by mochiweb, and provides a simple and clean way to connect that to your application's behavior.


Так прям как знал. Вольхаунду с Владом выделенное — точно понравится
Автор: kochetkov.vladimir
Дата: 11.02.11
(см. там вверх и вниз по ветке)

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[3]: Веб фрэймворк для Nemerle
От: Mamut Швеция http://dmitriid.com
Дата: 15.02.11 15:46
Оценка:
VD>>>Я тут посмотрел Lift (фиговенький передов книги по нему) и нашел его идеи по рендеренгу (точнее его подход к реализации паттерна MVC) вполне милым, логичным для ФЯ и (что самое важное) легко реализуемым на базе макросов немерла.

VD>>>В качестве средства упрощения работы с БД можно использовать Nemerle on rails созданный Ziaw. Рельсы по всей видимости нужно еще доводить до ума, но как основа они точно потянут.


VD>>>Остается только движок рендеренга HTML/XML-я и JSON. JSON опять же уже смастерил Ziaw.


VD>>>Так вот чтобы получить действительно законченные Nemerle on rails нужно смастерить движок рендеренга HTML/XML.


VD>>>Предлагаю повторить Lift (естественно, с учетом особенностей немерла).



M>>Эххх, если бы кто-то еще повторил и webmachine Но это так — просто в общую копилку идей


Z>А можно вкратце про суть? Я понял только, что это роутинг, сопоставляющий каждый маршрут некоему набору функций, возвращающих разные части запроса. Но это общая идея, в том, что тут функции, а не методы объекта я пока не вижу профита. Получается рест, что с ним делать дальше непонятно.


Во-первых, они полностью реализуют логику HTTP, http://webmachine.basho.com/diagram.html

Что это дает?

Предположим, у нас есть некий ресурс (он же модуль, он же контроллер) с некой функциональностью. Например, показывает инфу о пользователе по GET. Пишу в псвдокоде, чтобы не смущать Эрланговским синтаксисом


// На все, что не GET webmachine вернет 405 Method Not Allowed
function allowed_methods() {
  return ['GET'];
}

// по умолчанию считается, что ресурс возвращает html
function to_html(ReqData, Context){
  UserID = ...
  return что-угодно-в хтмл
}


Хотим расширить это дело. Например, хотим показать 404 Not Found если пользователя нет. Просто добавляем resource_exists


// На все, что не GET webmachine вернет 405 Method Not Allowed
function allowed_methods() {
  return ['GET'];
}

// по умолчанию считается, что ресурс возвращает html
function to_html(ReqData, Context){
  UserID = ...
  return что-угодно-в хтмл
}

// если возвращаем false, то webmachien автоматом генерит 404 Not Found
function resource_exists(ReqData, Context){
  UserID = ...
  return UserID != 0
}


Эта же страница стала отвечать... Ну за создание пользователей. Нужен метод, отвечающий на POST:

// На все, что не GET webmachine вернет 405 Method Not Allowed
function allowed_methods() {
  return ['GET', 'POST'];
}

// по умолчанию считается, что ресурс возвращает html
function to_html(ReqData, Context){
  UserID = ...
  return что-угодно-в хтмл
}

// если возвращаем false, то webmachien автоматом генерит 404 Not Found
function resource_exists(ReqData, Context){
  UserID = ...
  return UserID != 0
}

// обрабатываем данные, пришедшие через POST
function process_post(ReqData, Context){
  db.query(...)
  return true; // 201 Created или мало ли что еще
}


Внезапно оказывается, что надо страницу прятать с глаз долой

// На все, что не GET webmachine вернет 405 Method Not Allowed
function allowed_methods() {
  return ['GET', 'POST'];
}

// по умолчанию считается, что ресурс возвращает html
function to_html(ReqData, Context){
  UserID = ...
  return что-угодно-в хтмл
}

// если возвращаем false, то webmachien автоматом генерит 404 Not Found
function resource_exists(ReqData, Context){
  UserID = ...
  return UserID != 0
}

// обрабатываем данные, пришедшие через POST
function process_post(ReqData, Context){
  db.query(...)
  return true; // 201 Created или мало ли что еще
}

function is_authorized(ReqData, Context){
  return true; // или false для 401 Unathorized
}



Ну и т.п. Ресурс доступен в виде другого content-type или разных content-type? Добавляем соответствующие функции. То есть вся REST-овая или REST-оподобная функциональность вынесена в отдельные функциональные блоки и легко расширяема в нужные стороны.

Самое главное, что порядок вызова этих функций в модле строго предопределен, и не нужно делать дополнительных теложвижений типа

// стандартный момент практически в любом сайте

function someAction(){
   if (not user is authentified) return
   if(request is Post){ do_smth }
   else {do something_else }
}


dmitriid.comGitHubLinkedIn
Re[3]: Веб фрэймворк для Nemerle
От: WolfHound  
Дата: 15.02.11 17:01
Оценка: 24 (1)
Здравствуйте, WolfHound, Вы писали:

В прошлый раз я все описал на интуитивном уровне.
Сейчас попробую формализовать.
Главное что нужно запомнить это ДСЛ, а не полноценный немерле.
Таким образом используется только часть конструкций и подмножество типов.
Типы и конструкции выбираются так чтобы не мешать реактивности.
Иначе каменный цветок не выдет.

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

Вьюхи имеют 2 синтаксических контекста.
1)Код
2)Тег
По умолчанию используется контекст код.
Когда встречается тег то мы переходим в режим тег. В этом режиме все что внутри тега считается тегом или текстом.
Тег как {} задает область видимости переменных.
Чтобы внутри тега перейти в режим код нужно перед началом кода написать "$".
Он съест одно выражение. Причем будет есть пока дают.
Каждое выражение может вернуть ноль или несколько значений одного типа.
Если эти значения теги то они оставляются как есть. Все другие типы конвертируются в строку и эскейпятся.

Выражения могут быть:
Объявление переменной. Всегда возвращает ноль значений типа тег.
    def itemToAdd = "";

Присваивание. Всегда возвращает ноль значений типа тег.
    itemToAdd = "ыввыаыва";

Просто выражение. Всегда возвращает одно значение того типа который имеет это выражение.
Тип строка. Эскейпим.
    "ыввыаыва" + "123432542";

Тип int конвертируем в строку и эскейпим. Да я знаю что в инте эскейпить нечего. Но это вопрос оптимизации, а не семантики.
    123 + 234;

Тип тег. Возвращаем как есть.
    <p>Your values:</p>


if/else. Обе ветки должны возвращать выражение одного типа.
Выражения могут быть одиночными или списками.
Если одна ветка возвращает одиночное выражение, а другая список то одиночное выражение считается списком.

match правила теже что и для if/else только веток может быть больше.

when и unless всегда возвращают список выражений.
Если условие обломилось то возвращают пустой список.

foreach возвращает конкатенацию списков которые вернула каждая итерация.
Особая форма foreach/between
between вызавается после каждой итерации кроме последней.
Может быть очень полезно для генерации списков с разделителем.
    foreach (item in selectedItems)
        <text>$item.Value</text>
    between
        <text>, </text>


Таким образом можно писать так:
view BetterListView(model : BetterListModel)
{
    def itemToAdd = "";

    <form submit -> model.addItem(itemToAdd); >
        Add item: <input type = text; value <-> itemToAdd; valueUpdate = afterkeydown; />
        <button type = submit; enable <- !itemToAdd.IsEmpty; >Add</button>
    </form>

    def selectedItems = [];

    <p>Your values:</p>
    <select multiple = multiple; height = 5; options <- model.items;  selectedOptions <-> selectedItems; />

    <div>Selected items:
        $foreach (item in selectedItems)
            <text>$item.Value</text>
        between
            <text>, </text>
    </div>

    <div>
        <button click -> model.removeItems(selectedItems); enable <- !selectedItems.IsEmpty; >Remove</button>
        <button click -> model.items.sort(); enable <- items.Length > 1; >Sort</button>
    </div>
}


Также доступна такая форма записи:
foreach размножает тег по числу элементов в коллекции.
when/unless включают/выключают в зависимости от условия.
        <li foreach (person in model.people)>
        </li>
        <li when (asdqew)>
        </li>
        <li unless (hafdhas)>
        </li>
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Веб фрэймворк для Nemerle
От: Ziaw Россия  
Дата: 15.02.11 17:03
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Самое главное, что порядок вызова этих функций в модле строго предопределен, и не нужно делать дополнительных теложвижений типа


M>
M>// стандартный момент практически в любом сайте

M>function someAction(){
M>   if (not user is authentified) return
M>   if(request is Post){ do_smth }
M>   else {do something_else }
M>}
M>


Да нет, обычно делается что-то типа (тоже псевдокод):

route post /some_action, Some.somePostAction()
route get /some_action, Some.Action()

[RequireRole("User")]
function somePostAction()
{
   do_smth
}

[RequireRole("User")]
function someAction()
{
   do something_else
}
Re[4]: Веб фрэймворк для Nemerle
От: Ziaw Россия  
Дата: 15.02.11 17:33
Оценка:
Здравствуйте, WolfHound, Вы писали:

Идея контекстов отличная, мне очень нравится. Получаем лучшие стороны razor и spark.

WH>Каждое выражение может вернуть ноль или несколько значений одного типа.

WH>Если эти значения теги то они оставляются как есть. Все другие типы конвертируются в строку и эскейпятся.

Может сделать так: каждое выражение может вернуть ноль или больше значений любых типов имеющих конвертор в тэг (строки будут конвертиться в псеводтэг text). Конверторы и будут эскейпить все что нужно.

WH>if/else. Обе ветки должны возвращать выражение одного типа.


тогда можно будет делать такое:
if (needParagarph)
  <p>Hello world</p>
else
  "Hello world"


Нужно еще дать простую возможность сделать такое:

<div data-${dataName}="someValue">


Нужна динамическая генерация списка атрибутов.

В принципе можно реализовать все это без реактивности, получится view-engine, а потом уже добавлять реактивность и все такое.

Остается еще проблема передачи параметров, очень хотелось бы "именованные туплы".
Re[9]: Веб фрэймворк для Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.02.11 17:49
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>С таким view engine немерле и без сайта с руками и ногами отрывать будут.

WH>Это какраз то самое KillerApplication про которое твердят большевики.

Такой движок, при условии качественной реализации, несомненно будет большим плюсом. Но боюсь я разочарую тебя, но киллером он не станет просто потому, что не все зациклены на вебе, а многие из тех кто зациклен привязаны (марально и социально) к разным недотехрологиям вроде АСП.НЕТ МВЦ с Разором, а то и к более тухлым.

WH>Для того чтобы довести это до версии без наворотов типа comet и клиентской многозадачности как в Ur/Web много времени не надо. Нужно только иметь их в виду.


Согласен. Думаю, что для реализации данной библиотеки нужно где-то человеко-месяц (с запасом). Так что если объеденить усилия, то можно и недели в две уложиться. Главное не пытаться сделать внешний ДСЛ. Он тут совершенно не нужен.

WH>На парсер благодаря ПЕГу уйдет несколько часов.


Ты все же хочешь лепить внешний ДСЛ? Мне кажется, что это ошибка.
Можно сделать так. Ввести лексерные макросы которые позволят широко трактовать синтаксис. Ну, а ПЕГ использовать уже для повторного разбора чтобы не писать парсер на основе лексем немерла.

WH>И несколько дней на то чтобы создать трансляторы в жабаскрипт и серверный код.

WH>С серверным кодом вообще все просто. Там будет практически тупая трансляция методом что вижу то пою. Тут немерле рулит.
WH>С жабаскриптом посложнее там реактивность нужно приделать но ПМ и рекурсия сильно облегяат задачу.

А в чем проблема то? Можно использовать тот самый Нокаут и генерить код уже под него. Ну, а прочесть АСТ немерла и сгенерировать по нему жабаскрип это задача элементарная и много раз проделанная (аналогичный код есть в LINQ и Late).

Вопрос только в том как оформлять сами конструкции. Внешний ДСЛ мне категорически не нравится. Можно сделать внешние шаблоны ХМЛ-я но без вставок кода (как в Лифте). Их можно будет использовать для генерации разных статических частей.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Веб фрэймворк для Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.02.11 18:00
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Боюсь мне понадобится на порядок больше времени, просто потому, что опыта написания трансляторов у меня нет.


Мы тебе поможем. Я постараюсь тратить на эту задачу некоторое количество времени. Заведи себе наконец скайп (все остальные давно общаются в нем). И в месте это это дело сварганим довольно быстро.

Z>Кроме самой трансляции нужна еще куча инфраструктурных моментов. Скорее всего он не ляжет как yet another view engine for asp.net mvc. Но, в принципе, его можно использовать параллельно.


А вот как раз эти вью энжыны и не нужны. Тогда все будет быстро и просто. Плясать надо от HttpHendler-а.

Z>Пока я оцениваю создание движка и создание сайта как задачи примерно равной мощности. Менее чем через 2 месяца ни то ни другое не будет иметь более или менее законченный вид.


Ну, сайт за два месяца полноценный действительно не создать. Там только над перепроверкой оформлением контента надо будет работать на мало. В вот движок можно создать где-то недели за две. Только не надо делать неверных шагов и пытаться прилепить какого-то неуклюжего монстра.

Z>Сказкам Влада про то, что на таком движке сайт напишется намного быстрее я не верю.


Если ты не веришь, что движок о котором идет речь существенно ускорит разработку сайта, то не надо вообще работься за такие задачи.

Z>Переход от сверстанного шаблона к коду на view engine задача совсем не сложная и сколько ее ни сокращай, заметного выигрыша не получится.


Тода вообще не ясно о чем ты тут ведешь речь. Внешний вид — это задача Кочеткова. Нам же нужна функциональность вики (в первую очередь версионность), многоязычность, микро-форумы и блоги. Тут шаблоны вообще никакого влияния не будут оказывать, так как 99% функционала будет динамическим контентом.

Z>Основной фичей этого движка должна стать прозрачное общение между сервером и клиентом, типизированность и краткость кода. В первую очередь это уменьшение сложности. А никак не скорость создания сайтов, в которых вопросы дизайна, юзабилити и серверной логики все равно никуда не денутся.


Ты хоть подумай что ты говоришь. Как может быть так, что уменьшение сложности задачи и объемов кода не приведет к ускорению разработки?

А дизайн и юзабилити оставь Кочеткову. Он на это дело подписался. С него и спрос. Лично я ему в этом вопросе полностью доверяю. Наша задача будет сделать именно программную логику. Серверную логику конечно это не отменит. Но явное выделение ViewModel сделает ее чётко структурированной, а значит легко изменяемой. А именно это и нужно для ускорения разработки и упрощения сопровождения.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Веб фрэймворк для Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.02.11 18:10
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>В прошлый раз я все описал на интуитивном уровне.

WH>Сейчас попробую формализовать.
WH>Главное что нужно запомнить это ДСЛ, а не полноценный немерле.

Ты мне скажи, ты перед тем как все это писать на Nemerle.Xml посмотрел?

Это и есть то о чем ты говоришь с точностью до некоторых деталей. Причем эти детали, за исключением расширенного синтаксиса для биндинга, почти все являются проблемами которые в дальнейшем вылезут, если их проигнорировать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Веб фрэймворк для Nemerle
От: WolfHound  
Дата: 15.02.11 18:18
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Может сделать так: каждое выражение может вернуть ноль или больше значений любых типов имеющих конвертор в тэг (строки будут конвертиться в псеводтэг text). Конверторы и будут эскейпить все что нужно.

Можно и так. Но тут не все так просто.

WH>>if/else. Обе ветки должны возвращать выражение одного типа.

Z>тогда можно будет делать такое:
А что делать с таким кодом если мы все в тег превращаем?
def someInt = if (someThing)
  42
else
  24


Z>Нужно еще дать простую возможность сделать такое:

Z>
<div data-${dataName}="someValue">

Z>Нужна динамическая генерация списка атрибутов.
Вот это я не понял. Зачем?

Z>В принципе можно реализовать все это без реактивности, получится view-engine, а потом уже добавлять реактивность и все такое.

Можно и с этого начать.
Но нужно еще продумать описание интерфейса сервера.
Все подряд публиковать не смысла.
Более того нужно както отличать "data handler" от "view handler".
Первые отдают JSON вторые HTML.
Также нужен метод указания того какую вьюху на какую модель натягивать при вызове "view handler".

Z>Остается еще проблема передачи параметров, очень хотелось бы "именованные туплы".

Не понял ты о чем? Чего не хватает?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[11]: Веб фрэймворк для Nemerle
От: Ziaw Россия  
Дата: 15.02.11 18:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Заведи себе наконец скайп (все остальные давно общаются в нем).


У меня давно есть скайп, я даже писал его тут. alex_zimin

VD>Если ты не веришь, что движок о котором идет речь существенно ускорит разработку сайта, то не надо вообще работься за такие задачи.


Веришь не веришь это глупость. Я знаю сколько занимает создание вьюх по сравнению со всем остальным. На самом деле там важен не столько язык вьюхи, сколько поддержка IDE и время за которое можно увидеть результат.

И читабельность, очень важна читабельность когда ее надо поправить (т.е. всегда, имхо ни одна вьюха не дожила до релиза неправленной).
Re[6]: Веб фрэймворк для Nemerle
От: Ziaw Россия  
Дата: 15.02.11 19:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

Z>>Может сделать так: каждое выражение может вернуть ноль или больше значений любых типов имеющих конвертор в тэг (строки будут конвертиться в псеводтэг text). Конверторы и будут эскейпить все что нужно.

WH>Можно и так. Но тут не все так просто.

Основная сложность происходит от списка тегов. Может их оборачивать в один?

WH>>>if/else. Обе ветки должны возвращать выражение одного типа.

Z>>тогда можно будет делать такое:
WH>А что делать с таким кодом если мы все в тег превращаем?
WH>
WH>def someInt = if (someThing)
WH>  42
WH>else
WH>  24
WH>


А все не надо. Если тег и не тег, конвертим в тег.

Z>>Нужно еще дать простую возможность сделать такое:

Z>>
<div data-${dataName}="someValue">

Z>>Нужна динамическая генерация списка атрибутов.
WH>Вот это я не понял. Зачем?

Допустим я хочу сделать такой тег
<div data-id="10" data-text="some text">



Z>>В принципе можно реализовать все это без реактивности, получится view-engine, а потом уже добавлять реактивность и все такое.

WH>Можно и с этого начать.
WH>Но нужно еще продумать описание интерфейса сервера.
WH>Все подряд публиковать не смысла.
WH>Более того нужно както отличать "data handler" от "view handler".
WH>Первые отдают JSON вторые HTML.
WH>Также нужен метод указания того какую вьюху на какую модель натягивать при вызове "view handler".

Мне нравится как это решается в рор: маршруты вида "/{somePath}[.{format}]" формат по умолчанию html.
Контроллер получается такой:
def action
  @data = get_some_data

  respond_with do |format|
     format.html render  # тут вьюха
     format.xml  @data.to_xml  # тут возвращаем xml
     format.json  @data.to_json  # тут джейсон
     format.js     "$('#data-list').append('<li>#{data.name}</li>')" # тут js, который что-то делает на странице
  end
end

/action и /action.html вернут отрендеренную вьюху
/action.xml — xml и т.д.

Z>>Остается еще проблема передачи параметров, очень хотелось бы "именованные туплы".

WH>Не понял ты о чем? Чего не хватает?

Передача параметров во view, мне не нравится указывать все типы. В nrails я эту проблему решил автогенерацией классов контейнеров данных.
        public Show(id : int) : ActionResult
        {
            def doctor =  db.Doctors.Where(d => d.PersonID == id)
                .Select(d => new (
                    taxonomy = d.Taxonomy, 
                    name = new (
                        LastName = d.Person.LastName, 
                        MiddleName = d.Person.MiddleName, 
                        FirstName = d.Person.FirstName
                    )
                )).Single();

            def title = $"Doctor numer $id";
            View(viewmodel (doctor, title)); // Model : (doctor : (taxonomy : string, name : (LastName : string, MiddleName : string, FirstName : string)), title: string)
        }


Чтобы передать список вот таких туплов надо сильно много классов создать.
Re[4]: Веб фрэймворк для Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.02.11 19:30
Оценка:
Здравствуйте, WolfHound, Вы писали:

Задумка не плохая. Может взлететь, если подойти к реализации грамотно.

Главная ошибка этого дизайна заключается в том, что вместо того чтобы пользоваться мощньешими средствами создания встроенных ДСЛ-ей ты предлагаешь создать внешний ДСЛ и обречь себя на все тяготы связанные с реализацией интелисенса. На сегодня у нас нет ничего для создания внешних ДСЛ-ей, а значит единственный способ сделать интелисенс для него — это реализовать еще один LanguageService. А это довольно объемная работа. Причем это будет голимый хардкод для одного частного случая. А мне такие решения категорически не нравятся. Уж если делать, что-то то универсально.

Причем все это на фиг не нужно поскольку не вооруженным взглядом видно, что все отлично реализуется встроенными ДСЛ-ями. Причем большая часть кода уже есть в Nemerle.Xml. Там есть ПЕГ-парсер ХМЛ-я со встроенными управляющими конструкциями. Ввести в них биндинг не составляет труда. Хотя я бы отказался от использования <-> так как знаки < и > конфликтуют с ХМЛ-ем внутрь которого они должны вставляться. В прочем, это технический вопрос который наверно можно решить, если что.

WH>Также есть существует вопрос нужно ли делать язык чувствительным к регистру или нет.


Конечно стоит, так как и Немерле и ХМЛ к нему чувствительны. Ну, а ХТМЛ-ю будет просто по фигу.

WH>Вьюхи имеют 2 синтаксических контекста.

WH>1)Код
WH>2)Тег

Теги Nemerle.Xml как раз и являются таким контекстом.

WH>По умолчанию используется контекст код.


Он уже есть в немерле. Любой код немерле и есть такой контекст. По сему нет никакого смысла делать немерле отдельным внешним ДСЛ-ем для немерле же. Это просто бессмысленно.

WH>Когда встречается тег то мы переходим в режим тег. В этом режиме все что внутри тега считается тегом или текстом.


Я бы сказал конструкциями описывающим теги, их генерацию или контент. Причем не текст, а именно контент. Именно так и поступает Nemerle.Xml. Все что попадает в него из вне и не является тегом эскейпится.

WH>Тег как {} задает область видимости переменных.


Область видимости задают не теги, а управляющие конструкции.

Ниже я покажу как можно реализовать все описанное без создания внешних ДСЛ-ей и траты моря времени на его взлет (включая поддержку интелисенса).

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

WH>Тип тег. Возвращаем как есть.

WH>
WH>    <p>Your values:</p>
WH>


Вот это заменяется на конструкцию:
xml <# <p>Your values:</p> #>

или даже на:
XElement("Your values:")

так как до трансляции в жадбаскрипт ХМЛ можно представлять как АСТ объектов XLinq. Это уже реализовано в Nemerle.Xml. В приципе от промежуточного представления можно и отказаться, но смысла в этом нет.

WH>foreach возвращает конкатенацию списков которые вернула каждая итерация.

WH>Особая форма foreach/between
WH>between вызавается после каждой итерации кроме последней.
WH>Может быть очень полезно для генерации списков с разделителем.
WH>
WH>    foreach (item in selectedItems)
WH>        <text>$item.Value</text>
WH>    between
WH>        <text>, </text>
WH>


Управляющих конструкций в Nemerle.Xml три: when, unless, foreach. Я это сделал намеряенно, чтобы не было желания создать жутко выглядящий код. Если ктому-то нужно более хитро манипулировать ХМЛ-ем, то нужно просто использовать возможнсоти немерла (локальные функции и фунции высшего порядка). Преобразовать все это в жабаскрипт не представляет проблемы.

WH>Таким образом можно писать так:

WH>
WH>view BetterListView(model : BetterListModel)
WH>{
WH>    def itemToAdd = "";

WH>    <form submit -> model.addItem(itemToAdd); >
WH>        Add item: <input type = text; value <-> itemToAdd; valueUpdate = afterkeydown; />
WH>        <button type = submit; enable <- !itemToAdd.IsEmpty; >Add</button>
WH>    </form>

WH>    def selectedItems = [];

WH>    <p>Your values:</p>
WH>    <select multiple = multiple; height = 5; options <- model.items;  selectedOptions <-> selectedItems; />

WH>    <div>Selected items:
WH>        $foreach (item in selectedItems)
WH>            <text>$item.Value</text>
WH>        between
WH>            <text>, </text>
WH>    </div>

WH>    <div>
WH>        <button click -> model.removeItems(selectedItems); enable <- !selectedItems.IsEmpty; >Remove</button>
WH>        <button click -> model.items.sort(); enable <- items.Length > 1; >Sort</button>
WH>    </div>
WH>}
WH>


Вот как будет выглядеть все тоже самое, но в виде внутреннего ДСЛ-я:
[View]
BetterListView(model : BetterListModel)
{
    def itemToAdd = "";
    def selectedItems = [];

    def selectedItemsText = selectedItems.
    
    xml <#
    <form submit -> model.addItem(itemToAdd); >
        Add item: <input type = text; value <-> itemToAdd; valueUpdate = afterkeydown; />
        <button type = submit; enable <- !itemToAdd.IsEmpty; >Add</button>
    </form> 
  
    <p>Your values:</p>
    <select multiple = multiple; height = 5; options <- model.items;  selectedOptions <-> selectedItems; />

    <div>Selected items:
        ..$(selectedItems; ", ")
    </div>

    <div>
        <button click -> model.removeItems(selectedItems); enable <- !selectedItems.IsEmpty; >Remove</button>
        <button click -> model.items.sort(); enable <- items.Length > 1; >Sort</button>
    </div> #>
}

Я бы только еще переменные которые должны в биндинге использоваться дела бы полями, чтобы было понятнее что происходит.

WH>Также доступна такая форма записи:

WH>foreach размножает тег по числу элементов в коллекции.
WH>when/unless включают/выключают в зависимости от условия.
WH>
WH>        <li foreach (person in model.people)>
WH>        </li>
WH>        <li when (asdqew)>
WH>        </li>
WH>        <li unless (hafdhas)>
WH>        </li>
WH>

Вот их и нужно оставить. А совсем уж сложные конструкции исключить. Если надо пиши в коде выше и используй ХМЛ-фрагменты как значения.

Так же мне не очень гравится синтаксис биндинга. Но это уже отдельный технический вопрос.

То что описал я можно заставить взлететь менее чем за неделю.

Общий план реализации таков:
1. Берем ХМЛ-литералы (Nemerle.Xml) и допиливаем их чтобы они понимали синтаксис биндинга.
2. Делаем макро-атрибут View который бы вставлял в тело метода другой макрос. Назавем его ViewImpl.
3. ViewImpl тупо использует метод тайпера TransformWhenAllTypesWouldBeInfered() который позволяет дождаться окончания типизации фрагмента кода и в случае если типизация прошла успешно запускает функцию преобразования. Назовем ее ToJavaScript.
4. ToJavaScript получает на вход PExpr содержащий тело метода помеченного макро-атрибутом View и производит его анализ и трасформацию в JavaScript. При этом он может пользоваться квази-цитированием в паттерн-матчинге типами хранящимися в свойства PExpr.TypedObject. Это резко облегчит задачу трансформации и раннего выявления ошибок. Примерно так работает трансформация Linq-овских вызовов в деревья выражений.

Что мы теряем по равнению с оригинальным дизайном?
1. ХМЛ нужно обрамлять в xml <# #>.
2. Код представлений будет располагаться в обычных .n-файлах внутри классов.

Последнее на мой взгляд является преимуществом.

К подложенному Вольфхаундом дизайну я бы еще добавил одно мелкое, но очень мощьное расширение. Я бы позволил бы в генерируемом ХМЛ-е помещать ссылки на другие такие View, плюс задавать им параметры. Если выходной ХМЛ содержит ссылку на другой View, то она должна раскрыться подобно исходному вью.

Это позволит получить тот самый рекурсивный дизайн и инкапсуляцию. Выглядеть это может так:
[View]
BetterListView(model : BetterListModel)
{
    def itemToAdd = "";
    def selectedItems = [];

    def selectedItemsText = selectedItems.
    
    xml <#
    <form submit -> model.addItem(itemToAdd); >
        Add item: <input type = text; value <-> itemToAdd; valueUpdate = afterkeydown; />
        <button type = submit; enable <- !itemToAdd.IsEmpty; >Add</button>
    </form> 
  
    <p>Your values:</p>
    <!-- элемент ниже раскроется в то что было в исходном примере -->
    <controls.select options="model.items"  selectedOptions="selectedItems" /> 

    <div>Selected items:
        ..$(selectedItems; ", ")
    </div>

    <div>
        <button click -> model.removeItems(selectedItems); enable <- !selectedItems.IsEmpty; >Remove</button>
        <button click -> model.items.sort(); enable <- items.Length > 1; >Sort</button>
    </div> #>
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.