Быстро делать web UI для кровавого энтерпрайза, как?

psm-home

Есть такой класс веб приложений, которые представляют собой CRUD фронтенд к БД и состоят из большого количества гридов с фильтрами и форм для создания/редактирования записей. Нормальные люди этого всего не видят, а невидимые миру слезы т. н бизнес пользователей мало кого волнуют, поэтому юзабилити может быть скажем так, неидеальным. Зато важно запиливать фичи как можно быстрее (дешевле).
Как делать правильно такие штуки в 2014 году? Есть какой-нибудь набор полуфабрикатов для этого?
Раньше было понятно что "накидать формочек и гридов" быстрее всего в Delphi, но это было до эпохи победившего веба, а теперь что взамен?

apl13

Хотел предложить Qt с MVС, но ты меня напугал эпохой.
А так портативность была бы...

psm-home

Увы, есть требование такое, что строго веб.

viktor954

Кстати, присоединяюсь к вопросу/
Чего-то ничего лучше
http://www.formbreeze.com/freehtmleditor/formbuilder_editor....
http://www.sigmawidgets.com/
не нашёл/ :(

Dimon89

А чем не устраивают автоматически сгенерированные формы во всяких джангах и ASP.NET MVC? CRUD они умеют и пишутся за полчаса-час (который занимает описание профиля БД).

Dasar

во всяких джангах и ASP.NET MVC
гриды в них по умолчанию убогие (по сравнению даже с древней delphi)

Dimon89

гриды в них по умолчанию убогие (по сравнению даже с древней delphi)
Гриды - да, я для гридов юзал http://www.datatables.net/

mbolik1

Как делать правильно такие штуки в 2014 году? Есть какой-нибудь набор полуфабрикатов для этого?
Есди БД — Oracle, то Oracle APEX.

abur

Мы занимаемся ровно такими вещами http://www.curs.ru.. Разрабатываем свою платформу, она бесплатна, решения платны. При этом база данных может быть одной из 4 типов (Orakle, mssql, postgres? mysql это не важно.

agaaaa

Ни разу не пользовался, но по обрывочной информации кажется, что вот эта штука специально предназначена для указанной цели: Visual Studio LightSwitch

tokuchu

У гугла же был какой-то тулкит, который позволял отпрототипиравть на хосте приложение и сгенерировать его web-версию. Ну там жаба правда.
google web toolkit кажется. Но я правда не уверен, что правильно понимаю зачем он.

bav46

google web toolkit кажется. Но я правда не уверен, что правильно понимаю зачем он.
да gwt. только надо одну хрень предусмотреть, что разрабатывать на нем строго юзая бестпрактики и без сторонних библиотек типа шарана или smartgwt иначе потом эта штука станет не управляемой и проще будет ее выкинуть

elenangel

без сторонних библиотек типа шарана или smartgwt иначе потом эта штука станет не управляемой и проще будет ее выкинуть
люто плюсую, smartgwt то еще г., не писал, но осуждаю - видел результат использования, который потом пришлось выкинуть и переписать на простом js со всякими либами (kendo, leaflet)

6yrop

простом js
от gwt вроде многие отказываются

luna89

гриды в них по умолчанию убогие (по сравнению даже с древней delphi)
Что по-твоему требуется от грида?

yroslavasako

а OLAP как поставщик гридов тебе не пойдёт? То что касается отображения, не редактирования, там вроде хорошо поставлено

psm-home

Это больше похоже на админку, чем на BI, так что нет.

Dasar

Что по-твоему требуется от грида?
одновременно большое кол-во функционала и отсутствие глюков

kill-still

Теперь для этого мозилла зул:
http://developer.mozilla.org/ru/docs/XUL
Это как раз тулза под те задачи, которые ты описал.
Берёшь, описываешь на xml формочку

<window id="vbox example" title="Example 3">
<vbox>
<button id="yes1" label="Yes"/>
<button id="no1" label="No"/>
<button id="maybe1" label="Maybe"/>
</vbox>
</window>

А он на основе этого генерит тучу html и яваскрипта. Естественно можно создать свой компонент-наследник myButton и т.д...
Тут можно потыркать примеры:
http://www.amplesdk.com/examples/markup/xul/
На нём куча всякого кровавого энтерпрайза написано - например вёбредактор для JBPM.

kill-still

GWT имхо немного другие цели преследует - для тех разработчиков, которые хотят сделать вёб приложение, не не хотят разбираться со всякой фигнёй типа js и вёрсткой. И на выходе получить приложение, кторое одинаково выглядит и работает под всеми браузерами и т.д. При этом type safe и все прочие прелести нормального языка.
Но как говориться, не получилось, не взлетело. :(

kill-still

ещё примеры:
http://komodoide.com/ о.О
http://sourceforge.net/projects/xul-amarok/
ChatZilla

luna89

<window id="vbox example" title="Example 3">
<vbox>
<button id="yes1" label="Yes"/>
<button id="no1" label="No"/>
<button id="maybe1" label="Maybe"/>
</vbox>
</window>
А он на основе этого генерит тучу html и яваскрипта. Естественно можно создать свой компонент-наследник myButton и т.д...
А что делать если набор кнопок должен быть динамическим? В XML нет никаких средств встраивания кода. На джаваскрипте можно сделать так (я воспользуюсь синтаксисом coffeescript чтобы меньше печатать):

window
id: 'vbox example'
title: 'Example 3'
vbox:
button id: 'yes', label: 'Yes'
button id: 'no', label: 'No'

Динамическая генерация кнопок:

window
id: 'vbox example'
title: 'Example 3'
vbox: for i in [1..100]
button id: 'button'+i, label: "Button #"+i

Таким образом, неясно зачем генерить джаваскрипт из XML, в котором нет никаких средств декомпозиции.

luna89

Увы, есть требование такое, что строго веб.
А что ты бы выбрал если бы не такое требование?

kill-still

Таким образом, неясно зачем генерить джаваскрипт из XML, в котором нет никаких средств декомпозиции.
:facepalm: Блин, двже отвечать не охота.

kill-still

А что делать если набор кнопок должен быть динамическим? В XML нет никаких средств встраивания кода.
Через xml ты определяешь какие компоненты у тебя будут на форме (как в delfi ты в графическом редакторе клепаешь dfm файл). Помимо того поведения, которое имеет каждый экземпляр компоненты определенного типа (например кнопку можно нажать, а грид - отсортировать ты конечно можешь задать и индивидуальное поведение, которое имеет только эта кнопка.

bansek

afaik для этого есть вот этот монстрик http://github.com/spring-projects/spring-roo
там command line тулза, которая смотрит на базу и сама генерит админку
щупал сам довольно давно и поверхностно
еще думаю всякие RoR тулзы должны уметь

luna89

На джаве это записывалось бы так

new Window{{
this.id = "vbox example";
this.title = "Example 3";
this.vbox = new Vbox(
new Button{{this.id = "Save";this.label="Save";}},
new Button{{this.id = "Save";this.label="Save";}},
new Button{{this.id = "Save";this.label="Save";}},
);
}}

Что по синтаксису несильно дерьмовее XML, но зато дает тайпчек и возможность избежать мозгоебства с кодогенератором.

luna89


:facepalm: Блин, двже отвечать не охота.

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

6yrop

Блин, двже отвечать не охота.
А ты всё-таки ответь. Вот, например, майкрософт породил из XML монстрика XAML, и многие признают, что XML для этого отстой и нужен нормальный язык. Нормальный язык это либо generic proposal language с синтаксическим сахаром типа groovy-style builders, либо DSL.

mbolik1

Представь тебе нужна форма, в которой несколько виджетов, при этом один виджет разный в разных местах.
Говоришь что это не энтерпрайз и не делаешь.

kill-still

А документацию почитать не судьба?
Ну или картинки посмотреть про примеры, которые я приводил (JBPM, Komodo).
Окошко с настройками в фаерфоксе, я так понимаю, тоже на зуле написано. (просто контекстное меню выпилено)
Естественно любой компонент можно и на клиенте создать из яваскрипта.

bav46

от gwt вроде многие отказываются
от него вроде как отказывется гугла, но при этом у них все беки сделаны на нем и работают вполне шустро

psm-home

но при этом у них все беки сделаны на нем и работают вполне шустро
Вот это откровение для меня. Вроде сами они GWT почти не пользовались ни для чего. Можно пруф?

bav46

новый адмоб бек для монетизатора и рекламодателя сделан на Gwt
консоль разработчика android тоже gwt

kokoc88

Представь тебе нужна форма, в которой несколько виджетов, при этом один виджет разный в разных местах. С XML ты такое не реализуешь
Почему это? Реализовать можно:
... <widget_def id="special_button"/> ... <widget id="special_button"/>

kokoc88

новый адмоб бек для монетизатора и рекламодателя сделан на Gwt
консоль разработчика android тоже gwt
Так вот почему оно так работает! :smirk:

6yrop

для JBPM.
тк ты под кровавым энтерпрайзом имеешь ввиду распил больших сумм бабла, я то по наивности подразумеваю классическое понятие софта

psm-home

Да, нагуглился список :
Some Google products that use Google Web Toolkit that you may not know about:
AdWords http://google.com/adwords
AdSense http://google.com/adsense
Flights http://flights.google.com
Hotel Finder http://www.google.com/hotelfinder
Offers http://www.google.com/offers
Wallet http://wallet.google.com
The New Blogger http://www.blogger.com/
Chrome Webstore http://chrome.google.com/webstore (Actually done in Closure, but embeds GWT checkout code)
Product Search http://www.google.com/prdhp?hl=en&tab=mf
Public Data http://www.google.com/publicdata/home
New Google Groups http://groups.google.com
Orkut http://www.orkut.com
Google Health (discontinued)
Google Wave (discontinued)
PlayN (basis of Angry Birds)

bav46

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

bansek

можно добавить YouTube Analytics =)
youtube.com/analytics

apl13

new Button{{this.id = "Save";this.label="Save";}}
new Button{{this.id = "Save";this.label="Save";}}
new Button{{this.id = "Save";this.label="Save";}},
И главное, это должно быть три раза. Три раза, запомни, Ганс, три раза!

6yrop

на чем остановились?

psm-home

ни на чем пока, думаем

luna89

Главное, поменьше джавы, побольше джаваскрипта. Ни в коем случае не связывайтесь с GWT или c JSF. Если обязательно надо использовать джаву на бэкенде, то никаких фреймворков, только голый servlet API.

Frtati

Со Spring roo насколько помню иногда приходилось сильно погружаться, когда хотелось чего-то нестандартного.
Из того что видел с максимальной скоростью клепания и минимальным порогом вхождения был dhtmlx .

6yrop

побольше джаваскрипта

Я не люблю все динамические типизированные языки программирования — Python, Perl, JavaScript. У меня очень плохая память, а программы на них требуют, чтобы человек много всего запоминал. Нужно держать в голове какую-то информацию о типах, которой нет в коде. На самом деле, условно говоря, мне с ними совсем тяжело, потому что у меня плохая память. Людям, у которых хорошая память, просто тяжело.
http://habrahabr.ru/company/yandex/blog/230775/

В кровавом энтерпрайзе это уже становится вопросом выживаемости. Держать в голове энтерпрайзную информацию — человек просто не выживет.

khachin

Угу.
Степан Кольцов
Программирует 10 лет. В Яндексе — 7 лет.

Джавист, кстати.
А вот вырезка оттуда же:
Григорий Бакунов
Программирует 25 лет. В Яндексе — 10 лет.
Вопрос, как всегда, очевидный. У меня любимых языков программирования, наверное, много. Больше всего я в последнее время пишу на Питоне — просто в силу того, что это язык, который позволяет мне максимально быстро выразить то, о чем я думаю. Но, конечно, он не единственный, и иногда приходится довольно много писать на JavaScript. Это не самое приятное развлечение в моей жизни. Наверное, больше всего кода и с наибольшим удовольствием я написал на Лиспе.
Так что каждому своё. Но если желаете, лэт зе холивар бегин.

annetAnohina

такая еще вот есть платформа
oreodor.com

6yrop

а
oreodor.com
на довольно простую форму 727К — в топку

luna89

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

class User{
String name;
String surname;
Date birthdate;
}

нельзя использовать на том же месте, что и

class User{
String name;
String surname;
}

Для энтерпрайза нужна структурная типизация, которая при наличии вывода типов и типа any строго лучше динамики. Идеальная система типов для энтерпрайза - язык roy:
http://roy.brianmckenna.org

6yrop

нельзя использовать на том же месте, что и
Если придерживаться immutable объектов, то проблема только в том, чтобы дать имя классу и написать переливку. В хорошей IDE переливка пишется, не напрягаясь. Переливка, конечно, увеличивает объем кода, но это не критично, при чтении такие фрагменты кода легко пропускаются глазом.
Подозреваю, что корень, тобою описанной проблемы “приходится описывать типы”, кроется в том, что ты пытаешься выражения на компьютерном языке приблизить к выражениям на естественном. Это иногда дает свои плюсы. Но не стоит это переоценивать. Процитирую Дейкстру: On the foolishness of "natural language programming".
Пиши в рамках существующего языка так, как тебе надо, завтра для этого сделают синтаксический сахар, и так будут писать все. :)

Dasar

В хорошей IDE переливка пишется, не напрягаясь.
в текущих статически-типизированных языках это достаточно геморройно.
например, задача написать(и использовать далее в коде) N-функций, каждая из которых берет произвольный тип и добавляет к нему поле Ni - выглядит на статике ужасно. Это из-за того, что в статитике сейчас нет операции вида: вернуть объект, имеющий те же поля, что и исходный, но с добавлением поля Ni.

6yrop

например, задача написать(и использовать далее в коде) N-функций, каждая из которых берет произвольный тип и добавляет к нему поле Ni - выглядит на статике ужасно. Это из-за того, что в статитике сейчас нет операции вида: вернуть объект, имеющий те же поля, что и исходный, но с добавлением поля Ni.
особой остроты такой проблемы не чувствуется (для immutable)
а так, конечно, языки стоит развивать

Dasar

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

6yrop

в смысле, у тебя такой задачи не возникает? или в смысле, что ты не считаешь, что способ решения получается ужасный?
В моих задачах эта проблема не стоит остро. В моих задачах решение не могу охарактеризовать словом "ужасное" .

6yrop

Энтерпрайзная специфика - много кода который перекладывает данные из одного формата в другой (например сделать запрос к базе, сунуть данные в HTML).
Да, да, всё именно так! И просто удивительно сколько бабла на это сливается. Я как-то писал вот это:
Во многих корпоративных приложениях используется реляционная модель данных. Реляционная модель имеет крайне простую структуру. Если использовать неформальные термины, то реляционная модель это набор таблиц. Таблица состоит из набора колонок. Как постепенно построить или вырастить реляционную модель? Какие элементарные операции для этого требуются? Создание и удаление таблиц и колонок. Таким образом, добавление (и удаление) колонки является базовой (а значит крайне важной операцией) для построения реляционной модели и, тем самым, всей информационной системы. Удивительно, но часто добавление поля требует от разработчика значительных усилий. Вот, что об этом пишет Фаулер: "Схема расслоения обладает и определенными недостатками. Слои способны удачно инкапсулировать многое, но не все: модификация одного слоя подчас связана с необходимостью внесения каскадных изменений в остальные слои. Классический пример из области корпоративных программных приложений: поле, добавленное в таблицу базы данных, подлежит воспроизведению в графическом интерфейсе и должно найти соответствующее отображение в каждом промежуточном слое."
Т.е. когда-то давно всех обманули, закрыв глаза на проблему добавления колонки. А если иметь механизм program slicing-а по колонке от БД и по всему приложению, то в энтерпрайзе вполне можно жить. Program slicing по колонке базируется на статической типизации. И плевать, что кода много.

Dasar

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

class CN1<T>
{
public CN1(T value, string n1)
{
this.Value = value;
this.N1 = n1;
}
public readonly T Value;
public readonly string N1;
}

public CN1 N1<T>(T value)
{
return new CN1<T>(value, bla-bla-зависящее- от-value);
}

class CN2<T>
{
public CN2(T value, int n2)
{
this.Value = value;
this.N2 = n2;
}
public readonly T Value;
public readonly int N2;
}

public CN2 N2<T>(T value)
{
return new CN2<T>(value, bla-bla-зависящее- от-value);
}

и т.д.

//и использование

var x = N2(N3(N5(4;

Console.WriteLine(x.Value.N3);
Console.WriteLine(x.Value.Value.N5);

agaaaa

Приведи пример как улучшить следующий код так, чтобы он не выглядел ужасным.
Использовать F# или Roslyn.

Dasar

Использовать F#
там это как будет выглядеть?

luna89

например, задача написать(и использовать далее в коде) N-функций, каждая из которых берет произвольный тип и добавляет к нему поле Ni - выглядит на статике ужасно. Это из-за того, что в статитике сейчас нет операции вида: вернуть объект, имеющий те же поля, что и исходный, но с добавлением поля Ni.
Это в явах и сишарпах так. Вот пример на языке elm:
 
assignAge = \person -> {person | age = 20}

bob = {name = "bob", surname = "smith"}
alice = {name = "alice", occupation = "programmer"}

aliceWithAge = assignAge alice
aliceAge = aliceWithAge.age
bobWithAge = assignAge bob
bobAge = bobWithAge.age

Попробовать можно тут http://elm-lang.org/try
У выражения aliceWithAge - тип {name:String, occupation: String,age: Integer}
У выражения  bobWithAge - тип {name:String, surname: String,age: Integer}

Dasar

assignAge = \person -> {person | age = 20}
удобно. интересно когда добавят в main-stream (C++, Java, C#)?

apl13

Вроде, в питоне это уже много-много лет, так что никогда.
Хотя в языках на JVM есть, конечно.
Для безумных педантов: "никогда" в данном контексте есть решение задачи "как быстро они это сделают, поглядев на соседний язык", а не указание срока реализации.

apl13

Ну и да, в Qt на вполне себе :) C++ уже много лет динамические методы у объектов. Аналогично можно сделать и динамические поля.
Объектная система on top of встроенной в язык вместе с кодогенерацией творят чудеса.

Dasar

Вроде, в питоне это уже много-много лет, так что никогда.
лямбды тоже давно существуют, но в mainstream их добавили буквально на днях.
так что надежда есть )

apl13

Ну там, наверное, slight distinctions.
Жалобы не "а вот у них это давно есть, а у нас нет", а "а вот пятьдесят лет назад такое вообще придумали, и у них давно есть, а у нас нет".
До того пытались проблему решить анонимными классами. Типа, вот посмотрите, у нас почти такие же замыкания, но Java-way.
Пока не поняли, что херней страдают.

istran

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

apl13

Но вообще, надежда, да, она такая. Мир слишком быстро меняется, и языку просто надо успевать соответствовать надеждам, чтобы не стать мертвым. :)

apl13

А.
Я уже писал, по-моему, тут, что не слежу за дискуссией. :)
Насчет статических, Scala, поди-ко, наименее статичный.

6yrop

Roslyn
Как он тут поможет? Расширять синтаксис языка и допилить самому компилятор?

luna89

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

({a=1, b=2}).c

не компилится

apl13

Спасибо, Капитан! Спасибо, Капитан!

agaaaa

Как он тут поможет? Расширять синтаксис языка и допилить самому компилятор?
Там уже есть нужный тебе синтаксис. Надеюсь, зарелизят.

6yrop

Там уже есть нужный тебе синтаксис. Надеюсь, зарелизят.
Какой синтаксис? Покажи.
Если ты про primary constructors, то они полностью проблему не решают.

karkar

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

Вот рабочий пример на D. Правильные шаблоны и вывод типов рулят.
 
import std.stdio;

class Data {
string name;
this(string nm) { name = nm; }
}

class Ext(Old, New, string fldname) {
Old value;
New n;
mixin("New " ~ fldname ~ " { return n; }");
alias value this;
this(Old oldval, New newval) { value = oldval; n = newval; }
}

auto addField(string fldname, Old, NewOld oldval, New newval) {
return new Ext!(Old, New, fldnameoldval, newval);
}

void main(string[] argv) {
auto org = new Data("John");
auto b = org.addField!("surname""Doe");
auto c = b.addField!("age"33);
auto d = org.addField!("height"180).addField!("weight"77.7);
writefln("%s %s aged %s", c.name, c.surname, c.age);
writefln("%s of height %s and weight %s", d.name, d.height, d.weight);
}

Результат запуска:
http://dpaste.dzfl.pl/2836766de1cb

Dasar

Классно, что всё это отрабатывает на компиляции!
в нюансах - это не совсем то, что хочется.
над типами не выполняется коммутативность и ассоциативность
тип_выражения(org.addField!("age"33).addField!("surname""Doe" не равен типу_выражения(org.addField!("surname""Doe").addField!("age"33
тип выглядит страшновато: type 'f58.Ext!(Ext!(Data, string, "surname" int, "age").Ext'
функции с такими типами замаешься описывать
ps
хочется тип вида structure<field-name-1:field-value-1, field-name-2:field-value-2, ...>
c операцией вида structure<args1> + structure<args2> = structure<args1+args2>, поддерживающей законы коммутативности и ассоциативности
и с возможностью частично конкретизировать такой тип при описании функции

auto F(structure<age:int, name:string, args:...> item)
{
return new structure(age:item.age + (item.name == "Маша" ? 2 : 4 name:item.name, args);
}

и с возможностью вызвать такую функцию для обычных структур

class S
{
public readonly int age;
public readonly string name;
}

auto x = F(new S(10, "Маша";


pps
сам язык ведет себя "странно"

auto org = new Data("John");
auto b = org.addField!("surname""Doe");
auto c = b.addField!("age"33);

c = org.addField!("age"13).addField!("surname2""Doe2"); //*

writefln("%s %s aged %s", c.name, c.surname, c.age);

присваивание со звездочкой не выдает никаких ошибок (ни компиляции, ни runtime-а но при этом c.age остается равным 33, а поля surname2 не появляется. По идее срабатывает какой-то оператор конвертации типов, но ведет себя он очень странно.

apl13

над типами не выполняется коммутативность и ассоциативность
тип_выражения(org.addField!("age"33).addField!("surname""Doe" не равен типу_выражения(org.addField!("surname""Doe").addField!("age"33
А должна?
Как сравнить два анонимных типа вообще?
Я уж не говорю, что
struct S1 {}; struct S2 {};

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

marat7256

Ты хочешь вектор с данными разных типов.

Dasar

есть два вида сравнения типов: duck typing и классическая(номинальная).
с точки зрения DT типы S1, S2 и structure<> эквиваленты, с классической - типы S1, S2 являеются наследниками structure<> и не эквиваленты между собой
для чистой DT объявления функций эквивалентны между собой: auto F(S1 auto F(S2 auto F(structure<>)
для номинальной системы типов функцию F удобнее записать как:

auto F<T>(T item) where T:structure<>
{
bla-bla;
}

и тогда для каждого типа S1, S2 или structure<> возможен свой вариант перегрузки.

Dasar

Ты хочешь вектор с данными разных типов.
да, но корректность обращения к которому обрабатывается на этапе компиляции
ps
не совсем.
у вектора элементы упорядочены по порядку вставки, а в структуре элементы неупорядочены между собой (или упорядочены по названию полей/хэшу от названия поля)

luna89

есть два вида сравнения типов: duck typing и классическая.
Называется - структурная и номинальная.

marat7256

да, но корректность обращения к которому обрабатывается на этапе компиляции
Зачем устанавливать это требование?

Dasar

чтобы получить все плюсы, которые идут от статически-типизированных языков.

marat7256

А мы о каких конкретно языках говорим?

Dasar

в смысле?

luna89

Какие элементарные операции для этого требуются? Создание и удаление таблиц и колонок. Таким образом, добавление (и удаление) колонки является базовой (а значит крайне важной операцией) для построения реляционной модели и, тем самым, всей информационной системы. Удивительно, но часто добавление поля требует от разработчика значительных усилий. Вот, что об этом пишет Фаулер: "Схема расслоения обладает и определенными недостатками. Слои способны удачно инкапсулировать многое, но не все: модификация одного слоя подчас связана с необходимостью внесения каскадных изменений в остальные слои. Классический пример из области корпоративных программных приложений: поле, добавленное в таблицу базы данных, подлежит воспроизведению в графическом интерфейсе и должно найти соответствующее отображение в каждом промежуточном слое."
Т.е. когда-то давно всех обманули, закрыв глаза на проблему добавления колонки. А если иметь механизм program slicing-а по колонке от БД и по всему приложению, то в энтерпрайзе вполне можно жить. Program slicing по колонке базируется на статической типизации. И плевать, что кода много.
Тред начинался с того, что топикстартеру надо было нагенерить интерфейсов для отображения гридов. Как я себе представляю, у него есть много таблиц, надо быстро добавлять просмотр таблиц. Если решать эту задачу в таком стиле, как описываешь ты, то получится миллион прослоек, код, который перекладывает данные из одной прослойки в другую, IDE для написания этого кода, которая тормозит и глючит, application server который долго и мучительно редеплоит это код. Любые попытки облегчить этот процесс будут утыкаться в отсутствие средств метапрограммирования в языках типа C# или Java.
При этом в изначальной постановке задачи - показать грид с такими-то полями, наполняемый из такой-то таблицы - есть один тип

data Grid = Grid {table::String, columns::[String]}

который не особо тебе облегчает программирование.
На джаваскрипте можно сделать так, что ты описываешь декларативно, какой у тебя грид, из какой таблицы он берется, какие там столбцы, какие права доступа. Этот код у тебя исполняется и в браузере, и на сервере (в джаве есть встроенный высокопроизводительный интерпретатор джаваскрипта сразу давая тебе REST API endpoint для твоего грида, который делает запросы к базе и выдает json, плюс интерфейс для просмотра этого грида. Скрипты перечитываются с диска на каждый запрос, не надо ничего редеплоить и перекомпилировать (в продакшене можно читать их один раз на старте).

apl13

В применении к языкам сишного семейства твое "есть" нужно заменить на "а вот хорошо было бы ввести..."

karkar

хочется тип вида structure<field-name-1:field-value-1, field-name-2:field-value-2, ...>
и с возможностью частично конкретизировать такой тип при описании функции
и с возможностью вызвать такую функцию для обычных структур
По-хорошему нужен конечно row polymorphism а-ля Elm или Haxe. А в D для этого есть static duck typing:
 

auto f(TT x) {
writefln("f name=%s age=%s", x.name, x.age);
}

или если хочется более культурной проверки наличия нужных полей

auto g(TT x) if (hasFields!(T, "age", int, "name", string {
writefln("g name=%s age=%s", x.name, x.age);
}

где hasFields пишется как-то так:
http://dpaste.dzfl.pl/76384d8570ba
С такими предикатами требования ассоциативности и пр. выполняются автоматически (ибо совпадение типов нужно с точностью до hasFields).
Поменять одно поле, скопировав все остальные неупомянутые, в данной имплементации низя, но если немного репу почесать, то тоже реализуемо.

Kira

на сярпе, если не стоит особых ограничений на производительность, можно воспользоваться библиотечками типа AutoMapper. Думаю нечто подобное должно быть и для явы.

6yrop

application server который долго и мучительно редеплоит это код
это что-то джававское энтерпрайзное?
в ASP.NET просто билд классов; если правится только вью, то и билдить не надо. А в VS2014 билда вообще не будет, и, говорят, всё в памяти будет делаться.

6yrop

AutoMapper
есть, но пользоваться не надо

Kira

есть, но пользоваться не надо
почему?

6yrop

теряется основная фича статической типизации — program slicing по полю, от базы до любого слоя: UI и т.п.

luna89

это что-то джававское энтерпрайзное?
в ASP.NET просто билд классов; если правится только вью, то и билдить не надо. А в VS2014 билда вообще не будет, и, говорят, всё в памяти будет делаться.
Расскажи, как выглядит процесс разработки? Сколько требуется времени после сохранения файла, чтобы сделать запрос новой html страницы?
Я считаю, что быстрый ребилд/редеплой важнее типизации.
Опишу свой опыт разработки под разные платформы:
1)Java, сервер приложений собранный из open source компонентов (Tomcat, ActiveMQ, JAX-WS). Несколько миллионов строк кода, не считая кода сгенеренного из метаданных (технология генерации - конкатенация строк). Сервер стартует около минуты. Клиент на swing стартует около двух минут. Там в режиме разработки можно было бы загружать не все модули, а только те, которые отлаживаешь, но для этого потребовалось бы рефакторить код инициализации приложения, билд систему, и думать о том, как сынтегрировать билд систему с IDE, на что эффективные менеджеры не могли выделить время.
2)Браузерный джаваскрипт. Максимальный размер одного модуля - около мегабайта минифицированного джаваскрипта. Страница открывается, слава хрому, 2-3 секунды. Модули загружаются лениво, в божественном джаваскрипте это так просто как

button.on 'click', ->
require 'someModule', (module) ->
module.start

3)Хранимые процедуры (plsql, plpgsql). Лучшее, из того что видел. Фактически репл внутрь запущенной СУБД, можно писать и компилировать по одной процедуре за раз.

6yrop

Тред начинался с того, что топикстартеру надо было нагенерить интерфейсов для отображения гридов. Как я себе представляю, у него есть много таблиц, надо быстро добавлять просмотр таблиц. Если решать эту задачу
...
data Grid = Grid {table::String, columns::[String]}
...
описываешь декларативно,
...
Бля, как же это реально заебало. Вот просто реально это портит мне жизнь. Сейчас есть вменяемый заказчик, готов платить нормальные деньги, только вот в начале проекта был вот такой же горя архитектор что-то там себе представлял и видел задачу. А теперь до продакшена довожу я, и развивать должен я. Было бы написано просто в лоб, без всякой этой декларативности, я был бы сейчас с нормальным проектом и был бы счастливым человеком. Пиши то что есть на текущий момент не надо "представлять себе" и "видеть задачу". Вот статическая типизация и позволяет двигаться спокойной и счастливо в итеративной манере.

luna89

Бля, как же это реально заебало. Вот просто реально это портит мне жизнь. Сейчас есть вменяемый заказчик, готов платить нормальные деньги, только вот в начале проекта был вот такой же горя архитектор что-то там себе представлял и видел задачу. А теперь до продакшена довожу я, и развивать должен я. Было бы написано просто в лоб, без всякой этой декларативности, я был бы сейчас с нормальным проектом и был бы счастливым человеком. Пиши то что есть на текущий момент не надо "представлять себе" и "видеть задачу". Вот статическая типизация и позволяет двигаться спокойной и счастливо в итеративной манере.
Ботай convention over configuration
Например, ты пишешь общий файл для браузера и сервера с метаданными

customersGrid =
name: 'customer'
columns: ['firstname','lastname','age']

Теперь ты можешь в коде сервера вызывать функцию

generateRestApi(customersGrid)

которая имплементирвана как-то так:

generateRestApi = (grid) ->
httpServer.route 'GET /api/:name?limit=:limit&offset=:offset', ({name,limit,offset}) ->
# TODO fix sql injections
sqlQueryAsJSON """
select
#{grid.colums.join ' '}
from
#{grid.name}
limit #{limit} offset #{offset}
"""

Тебя никто не заставляет вызывать на сервере функцию generateRestApi для этого грида, ты можешь реализовать rest api сам, к примеру:

httpServer.route 'GET /api/customer', ->
[
{name: 'Bob', lastName: 'Smith', age: 20}
{name: 'Alice', lastName: 'Smith', age: 25}
]

У тебя обычные структуры данных и функции, ты делаешь с ними что хочешь, тем не менее это декларативное программирование в каком-то смысле.

6yrop

Ботай
так ты еще студент? Тогда это всё объяснит.
Оставить комментарий
Имя или ник:
Комментарий: