Monday, September 30, 2013

Injecting DBDriver/Logger, AOP in Dart

In order to have GUI component, each component should not have a direct dependency to a specific driver. For instance, in the sample app, AppController has reference to CouchDBClientDao, but we if want to allow other DB driver later, that should not be directly defined in the component class.
This issue can be handled in Java as annotation based injection. JPA entity factory etc can be injected through annotation.

In order to support this, there will be a few approaches.
One approach is to simulate Java's approach. but it requires a special run time lib support for actual injection. So these are actually not within an ordinal programming control, and create some opaqueness for the code behavior, so I actually do not like this idea much.

The other approach is to delegate this injection job to code(programmer) itself. Anyway entry program needs to do some environment setting job normally, adding a task to inject code to appropriate library is not much big deal. and it will allows programmer 100% control over what is happening in program execution time.

then how can we find the location of the class(instance) to inject db driver.
sometimes that component are in deeply nested from top level component node.

That time we may use query feature defined at Component class.
This approach is similar to query in Dart.
To inject to annotated filed for an instance, whenever instance is created, this injection code must be applied. So instance level injection is a bit costly operation.

Or the other hand, static class level injection can be done only once, so this should be efficient.
for instance, dbdriver, logger can be injected to a  static filed.



Saturday, September 28, 2013

Generic GUI Library in Dart (Part 3)

I could run the generic GUI lib application on browsers(in javascript mode).
Since Dart does not support mirror in JavaScript mode, I needed to do this kind of things(see previous post).
The following snapshot shows running the app on Dartium , Chrome and Firefox:


In order to achieve this, I re-factored the code so that it eliminates the direct reference to 'dart:mirrors' by introducing minimal mirror interfaces.

 library mirror_api;

typedef IClassMirror CMirrorFun(Type type);

class ClassMirrorFactory {
  static CMirrorFun _cmf;
  static IClassMirror create(Type type) => _cmf(type);
  static void register(CMirrorFun cmf) { _cmf = cmf; }
}

//
abstract class IClassMirror {
  IInstanceMirror newInstance();
  IInstanceMirror reflect(Object obj);
 
  Map<Symbol, IFieldType> get fieldTypes;
}

abstract class IFieldType {
  Symbol get symbol;
  String get name; // convert symol to string
  Type get type;
}

//
abstract class IInstanceMirror {
  IClassMirror get cmirror;
  Object get reflectee;
 
  IField getField(Symbol name);
}

abstract class IField {
  Symbol get symbol;
  String get name; // convert symol to string
 
  Object get value;
  void set value(Object obj);
 
  Type get type;
}
 Then I provided two implementations of this interfaces:
  •  mirror_dynamic_lib.dart
  •  mirror_static_lib.dart
 mirror_dynamic_lib will use 'dart:mirrors', so this will be useful to run on server side, and no extra information are required to use this lib.
the second one is for javascript mode, it require additional meta  information for the class which is to be used in a generic class.
Following dart file is to provide such information for Expense class.  As shown in the last part, there is a dart2js compiler bug, I could not use the simpler version(commented one), but if we use this code, I could avoid the compiler bug(compiler was crashed).(this bug was fixed after I reported this issue in rev 28044)

library sample_mirror;

import 'mirror_libs/mirror_api_lib.dart';
import 'mirror_libs/mirror_static_lib.dart';
import 'shared/models.dart';

/*
 * This must be invoked before calling any of these simple mirror APIs.
 */

void initClassMirrorFactory() {
  ClassMirrorFactory.register((Type type)=>(type == Expense)?
      new StaticClassMirror(()=>new Expense.Default(), expenseFieldInfo)
  :null);
}

Type _String = String;
Type _ExpenseType = ExpenseType;
Type _DateTime = DateTime;
Type _num = num;
Type _bool = bool;

Map<Symbol, FieldInfo> expenseFieldInfo =
[
 new FieldInfo(const Symbol('id'), _String, (Expense e)=>e.id, (Expense e, String value) { e.id = value; }),
 new FieldInfo(const Symbol('rev'), _String, (Expense e)=>e.rev, (Expense e, String value) { e.rev = value; }),
 new FieldInfo(const Symbol('expenseType'), _ExpenseType, (Expense e)=>e.expenseType, (Expense e, ExpenseType value) { e.expenseType = value; }),
 new FieldInfo(const Symbol('date'), _DateTime, (Expense e)=>e.date, (Expense e, DateTime value) { e.date = value; }),
 new FieldInfo(const Symbol('amount'), _num, (Expense e)=>e.amount, (Expense e, num value) { e.amount = value; }),
 new FieldInfo(const Symbol('detail'), _String, (Expense e)=>e.detail, (Expense e, String value) { e.detail = value; }),
 new FieldInfo(const Symbol('isClaimed'), _bool, (Expense e)=>e.isClaimed, (Expense e, bool value) { e.isClaimed = value; })
 ].fold({}, (Map map, FieldInfo fh) => map..[fh.symbol] = fh);

/*
//
// This works for DartVM, but it fails dart2js.
//
Map<Symbol, FieldInfo> expenseFieldInfo =
    [
     new FieldInfo(const Symbol('id'), String, (Expense e)=>e.id, (Expense e, String value) { e.id = value; }),
     new FieldInfo(const Symbol('rev'), String, (Expense e)=>e.rev, (Expense e, String value) { e.rev = value; }),
     new FieldInfo(const Symbol('expenseType'), ExpenseType, (Expense e)=>e.expenseType, (Expense e, ExpenseType value) { e.expenseType = value; }),
     new FieldInfo(const Symbol('date'), DateTime, (Expense e)=>e.date, (Expense e, DateTime value) { e.date = value; }),
     new FieldInfo(const Symbol('amount'), num, (Expense e)=>e.amount, (Expense e, num value) { e.amount = value; }),
     new FieldInfo(const Symbol('detail'), String, (Expense e)=>e.detail, (Expense e, String value) { e.detail = value; }),
     new FieldInfo(const Symbol('isClaimed'), bool, (Expense e)=>e.isClaimed, (Expense e, bool value) { e.isClaimed = value; })
     ].fold({}, (Map map, FieldInfo fh) => map..[fh.symbol] = fh);
*/
From the top level dart file, we can change the  library by just switching to import file as following. I'll attach the entire main dart file for this app. this is  all required codes  to run this application using the generic GUI library. the layout of several components like table, buttons etc, and the controlling logic  are defined here.


 library sample_generic_gui;

import 'dart:html';
import "shared/models.dart";
import "gui_generic_lib/gui_generic_lib.dart";
//import "mirror_libs/mirror_dynamic_lib.dart"; // <== use 'dart:mirrors'
import "sample_mirror_impl.dart";; // <== no use of 'dart:mirrors'

class AppController extends Component {
  static const String APP = "g_app_ctlr";
  final DivElement _uiRoot;
  DivElement _content;
  DivElement _actions;
 
  Table<Expense> table;
  Form<Expense> form;
  ButtonComp newButtom;
  ButtonComp saveButtom;
  ButtonComp deleteButtom;
 
  AppController(Component parent, this._uiRoot, {List<Expense> expenses}): super(parent, const[APP]) {
    table = new Table<Expense>.fromModelType(this, Expense, formatFunctionMap: {ExpenseType: ExpenseTypeComp.format});
    form = new Form<Expense>(this, Expense,
        specialInputCompMap: {ExpenseType: ExpenseTypeComp.inputCompFactory},
        adhocCompMap: {'detail': 'textarea'}  // temp
    );
  
    Expense e = null;
    newButtom = new ButtonComp(this, "New", (_) {
      e = form.create();
      _changeButtonState(false, create: true);
    
    });
    saveButtom = new ButtonComp(this, "Save", (_) {
      Expense e0 = form.save();
      if (e0 != null) {
        e = e0;
        table.addOrUpdate(e);
        _changeButtonState(true);
      }
    });
    deleteButtom = new ButtonComp(this, "Delete", (_) {
      Expense e = form.delete();
      if (e != null) {
        table.delete(e);
        _changeButtonState(true);
      }
    });
    _changeButtonState(true);
  
  
   table.row_listeners.add((ev, row){
      //print("row clicked.. ${ev}, row: ${row}");
      e = row.e;
      form.load(e);
      _changeButtonState(false);
    });
  
    if (expenses != null) {
      table.load(expenses);
    }
    _uiRoot.nodes.add(element); // this 'element' tiggers DOM node creation!
  }
 
  void _changeButtonState(bool isEmpty, {create: false}) {
    (newButtom.element as ButtonElement).disabled = !isEmpty;
    (saveButtom.element as ButtonElement).disabled = isEmpty;
    (deleteButtom.element as ButtonElement).disabled = (create)?true:isEmpty;  
  }

  Element createElement() => addSubComponents0(newElem("div"));
 
  Element update() => addSubComponents0(initElem());
    
  Element addSubComponents0(Element elm) => addListeners(
      elm
      ..classes.add("section")
      ..nodes.add(new Element.html("<header class='section'>${table.modelType} Table</header>"))
      ..nodes.add(_content = new Element.tag("div")
        ..nodes.add(table.element))
      ..nodes.add(_actions = new Element.tag("div")
        ..id = "actions"
        ..classes.add("section")
        ..nodes.add(newButtom.element)
        ..nodes.add(saveButtom.element)
        ..nodes.add(deleteButtom.element))
      ..nodes.add(form.element)
      ..nodes.add(new Element.html("<footer class='section' id='footer'></footer>")));
}

class ExpenseTypeComp extends SelectComp<ExpenseType> {
  static const String EXPENSE_TYPE_INPUT = "g_expense_type_input";
 
  static final Map<String, ExpenseType> _expenseTypes = {
    "TRV": const ExpenseType("Travel","TRV"),
    "BK": const ExpenseType("Books","BK"),
    "HT": const ExpenseType("Hotel","HT")                        
  };
 
  ExpenseTypeComp(Component parent, String label, {List<String> classes: const [SelectComp.SELECT_INPUT, EXPENSE_TYPE_INPUT]})
    : super(parent, label, ExpenseType, classes: classes);
 
  static ExpenseTypeComp inputCompFactory(Component c, String name, Type t)=>new ExpenseTypeComp(c, name);
  static String format(ExpenseType et) => (et == null)?'':et.name;
 
  Map<String, ExpenseType> get entityTypes => _expenseTypes;
 
  String getCode(ExpenseType et) => et.code;
  String getName(ExpenseType et) => et.name;
}

main() {
  // register reflection factory
  initClassMirrorFactory();
 
  List<Expense> expenses = [
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random()];
  Element uiContainer = document.query("#sample_generic_gui");
  AppController app = new AppController(null, uiContainer);
  app.table.load(expenses);
-------------------------------

here is the implementation classes:

library dynamic_mirror;

import 'dart:mirrors';
import 'mirror_api_lib.dart';

/*
 * This must be invoked before calling any of these simple mirror APIs.
 */
void initClassMirrorFactory() {
  ClassMirrorFactory.register((Type type)=>new DynamicClassMirror.reflectClass(type));
}

//
// IClassMirror implementations
//
class DynamicClassMirror implements IClassMirror {
  static Map<Type, DynamicClassMirror>  cmirrs = {};
 
  final Type type;
  ClassMirror _cmirror;
  MethodMirror _ctor;
  Map<Symbol, IFieldType> _fieldTypes = {};
 
  DynamicClassMirror(this.type) {
    _cmirror = reflectClass(type);
   
    reflectClass(type).constructors.forEach((k, v){
      if (v.parameters.length == 0 && (_ctor == null || getSymbolName(k) == "${type}.Default")) {
        _ctor = v;
      }
    });
   
    _cmirror.getters.forEach((Symbol symbol, MethodMirror md){
      _fieldTypes[symbol] = new DynamicFieldType(symbol, md);
    });
  }
 
  factory DynamicClassMirror.reflectClass(Type type) {
    DynamicClassMirror cmirr = cmirrs[type];
    if (cmirr == null) {
      cmirr = new DynamicClassMirror(type);
    }
    return cmirr;
  }
 
  IInstanceMirror newInstance() =>
      reflect(_cmirror.newInstance(_ctor.constructorName, []).reflectee);

  IInstanceMirror reflect(Object obj) => new DynamicInstanceMirror(this, obj);

  Map<Symbol, IFieldType> get fieldTypes => _fieldTypes;

}

class DynamicFieldType implements IFieldType {
  Symbol _symbol;
  String _name;
  MethodMirror _md;
 
  DynamicFieldType(this._symbol, this._md) {
    _name = getSymbolName(_symbol);
  }
 
  Symbol get symbol => _symbol;
  String get name => _name;
  Type get type => (_md.returnType as ClassMirror).reflectedType;
}

//
// IInstanceMirror implementations
//
class DynamicInstanceMirror implements IInstanceMirror {
  Map<Symbol, DynamicField>  dfs = {};
 
  final IClassMirror _cmirror;
  InstanceMirror _imirror;
 
  DynamicInstanceMirror(this._cmirror, Object obj) {
    _imirror = reflect(obj);
  }
 
  IClassMirror get cmirror => _cmirror;
 
  Object get reflectee => _imirror.reflectee;
  IField getField(Symbol name) => new DynamicField.create(name, this);
}

class DynamicField implements IField {
  DynamicInstanceMirror _parent;
  Symbol _symbol;
  String _name;
 
  DynamicField(Symbol this._symbol, this._parent) {
    _name = getSymbolName(_symbol);
  }
 
  factory DynamicField.create(Symbol symbol, DynamicInstanceMirror _parent) {
    DynamicField df = _parent.dfs[symbol];
    if (df == null) {
      _parent.dfs[symbol] = df = new DynamicField(symbol, _parent);
    }
    return df;
  }
 
  Symbol get symbol => _symbol;
  String get name => _name;
 
  Object get value => _parent._imirror.getField(_symbol).reflectee;
  void set value(Object obj) { _parent._imirror.setField(_symbol, obj); }
 
  Type get type => _parent._cmirror.fieldTypes[_symbol].type;
 }

//
// utils
//
String getSymbolName(Symbol symbol) => symbol.toString().substring('Symbol("'.length, symbol.toString().length-2);
 ----------------------------
 library static_mirror;

import 'mirror_api_lib.dart';

//
// IClassMirror implementations
//
typedef Object Getter(Object entity);
typedef void Setter(Object entity, Object value);

class FieldInfo implements IFieldType {
  final Symbol _symbol;
  String _name;
  final Type _type;
 
  final Getter getter;
  final Setter setter;
 
  FieldInfo(this._symbol, this._type, this.getter, this.setter) {
    _name = getSymbolName(_symbol);
  }
 
  Symbol get symbol => _symbol;
  String get name => _name;
  Type get type => _type;
}

typedef Object DefaultConstructor();

class StaticClassMirror implements IClassMirror {
  final DefaultConstructor ctor;
  final Map<Symbol, FieldInfo> fieldInfos;
 
  StaticClassMirror(this.ctor, this.fieldInfos);
 
  IInstanceMirror newInstance() => reflect(ctor());
  IInstanceMirror reflect(Object obj) => new StaticInstanceMirror(this, obj);

  Map<Symbol, IFieldType> get fieldTypes => fieldInfos;
}

//
// IInstanceMirror implementations
//
class StaticInstanceMirror implements IInstanceMirror {
  Map<Symbol, StaticField>  dfs = {};
 
  final IClassMirror _cmirror;
 
  final Object _obj;
 
  StaticInstanceMirror(this._cmirror, Object this._obj);
 
  IClassMirror get cmirror => _cmirror;
 
  Object get reflectee => _obj;
  IField getField(Symbol name) => new StaticField.create(name, this);
}

class StaticField implements IField {
  StaticInstanceMirror _parent;
  Symbol _symbol;
  String _name;
 
  StaticField(Symbol this._symbol, this._parent) {
    _name = getSymbolName(_symbol);
  }
 
  factory StaticField.create(Symbol symbol, StaticInstanceMirror _parent) {
    StaticField df = _parent.dfs[symbol];
    if (df == null) {
      _parent.dfs[symbol] = df = new StaticField(symbol, _parent);
    }
    return df;
  }
 
  Symbol get symbol => _symbol;
  String get name => _name;
 
  Object get value => _cmirror.fieldInfos[symbol].getter(_parent.reflectee);
 
  void set value(Object obj) { _cmirror.fieldInfos[symbol].setter(_parent.reflectee, obj); }
 
  Type get type => _cmirror.fieldInfos[symbol].type;
 
  StaticClassMirror get _cmirror => (_parent._cmirror as StaticClassMirror);
 }

//
// utils
//
String getSymbolName(Symbol symbol) => symbol.toString().substring('Symbol("'.length, symbol.toString().length-2);

Entity annotations for GUI/Persistence

It is useful to use annotations to excludes hints information from the main source code and to avoid cluttering files which are used in program but not integrated in language source code file system.
Such files will become maintenance problem later.

There are mainly two usage cases for entity class.
  • GUI annotation. for instance, we may want to use customized label name other than default field name, we can attach such information as annotation for the getter definition.
  • Persistence mapping. This is essentially the same as JPA. we may want to more info how OR or DB scheme is associated with the entity.


CouchDB and generic DAO class

Generic GUI and CouchDB will be a good match.
Since Couch does not require scheme definition, it will be possible to develop generic  class to support CRUD features.

class DAO<T> {
 void  save(T t);
 void update(T t);
void delete(T t);
Iterable<T> query(String condition);

}

In particular, such application will be running on server side, we will not have constraint using mirror.

Actually I already created such library for DartExpenseServer mentioned in earlier post.
One of the issue was to support a mapping to/from Json object for the entity class.
In the application, this mapping methods were hand coded. But it is desireble to automate this step by a library.

Such Library should be easily implemented with mirror.

Restriction of Mirror in JS mode

I almost finished developing CRUD features for generic GUI library.



It just consists from Table and Form, and additional supporting components for Input.
Although there are more rooms for refinements, but it's working and written as I hoped.

The size of code is quite small, and is general enough.
For this type of library to be meaningful, it must be easily customized without touching the library itself.
In order to do so, it provides mechanism to inject features from outside.

Also it defines some basic patterns, like create, update to follow so that recursive operation would work properly.

But when I tried running it with javascript mode, I found out it does not run.
It looks like such mirror features are not yet supported in javascript mode.(there is a note on 5/2013).

Also there is an issue for the generated javascript code.
if we include dart:mirrors, the current code generates  7238 total methods!(impressive, I will never able to write such lines(methods) of javascript code)

Out of it,  5318 methods retained for use by dart:mirrors.
(But still my codes generated 2000 methods!)

So it seems not good idea to use dart:mirror for javascript mode.

One of the approach to overcome this restriction, and run generic GUI library application on browser is to avoid using mirror library itself.
This can be done if we generate an implementation class for some mirror like API  from concrete classes which is used in a application.

And we can also use two versions of implementations, one is for Dartium mode using the mirror library,  and the other is for javascript mode, the implementation classes are to be generated by a Dart application in Dartium mode.

Sunday, September 22, 2013

Generic GUI Library in Dart (Part 2)

In the Part 1 of this post, I used Polymer to create the web page, or to construct the page DOM object.(here is Part3)
In this revised version(generic-gui-v1), I removed such dependency to Polymer, and directly created DOM in Dart classes.



The major reason for doing this was to support component style GUI development.
In Polymer, or some other template mechanism based on some extension of HTML, the logic associated with such GUI element and actual code which would be implemented in a Dart class are separated, and basically things are getting messy.

Component will keep such DOM creation logic in itself. therefore we can construct a new component using the DOM associated with the sub components. This is the power of integrating them rather than delegating to a separate template files.

Another idea introduced here is automatic component management.
when components are created, implicitly corresponding tree node structure is created. This will provide better Query feature against components.
Although DOM can be found by Dart's query method for DOM, but we cannot identify a component associated with the DOM node. So this should be very useful.
On the other hand, if we have a component, we can have the corresponding DOM node immediately.

Following Component and TopComponent classes were introduced to support such abstract component structures.
The Component class will be used as super class of all UI component class like Table, Row etc.
It contains DOM element and its sub components.

The management of these structure are almost automatic, so each component class need not have to aware of these underlying structure building.

Fine point is the order of component creation and Element creation. To create a component, the parent component must be created first, but in order to create a DOM element, we need to create from the children.

So this means we cannot create element inside of component constructor.
But this will be taken care by init method in TopComponent. Namely this class is top level component, and only for this object, init is supported. The constructor of the subclass of TopComponent should invoke init in the end of the constructor.

 /*
 * Component should be created from top down, while DOM node should be created from bottom up
 */

abstract class Component {
  static int _gid = 0;
 
  final int id = _gid++;
  final List<String> classes;
  Element _element;
 
  final Component parent;
  final List<Component> children = [];
 
  Component(Component this.parent, List<String> this.classes) {
    if (parent != null) parent.children.add(this);
  }
 
  // DOM
  Element get element => (_element == null)?_element = _createElement():_element;
   
  // invoked from top level node.
  void _init() {
    children.forEach((Component child)=>child._init());
    _element = _createElement();
  }

  Element _createElement() =>
    createElement()
      ..id = "id-${id}"
      ..classes.addAll(classes);

  // this should not be invoked execpt from _init!
  Element createElement();
 
  //
  // utils
  //

  TopComponent topComponent() =>  (parent == null)?(this as TopComponent):parent.topComponent();
 
  Component findById(int id0) {
    if (id0 == id) {
      return this;
    }
    for (Component c in children) {
      Component c0 = c.findById(id0);
      if (c0 != null) {
        return c0;
      }
    }
    return null;
  }
 
  dynamic fold(var initialValue, dynamic combine(var previousValue, Component child)) =>
    children.fold(combine(initialValue, this), (pr, child) => child.fold(pr, combine));

}

abstract class TopComponent extends Component {
  static const String TOP_NODE = "g_top";
 
  TopComponent(): super(null, [TOP_NODE]);
 
  void init() {
    _init();
  }
}
The Table classes have been revised as followings:

class HeaderCell extends Component {
  static const String HCELL = "g_hcell";
  TableHeader tableHeader;
  Symbol symbol;
  Type type;
 
  // GUI
  String label;
 
  HeaderCell(TableHeader parent, this.symbol, this.type, this.label, {List<String> classes: const [HCELL]}): super(parent, classes), this.tableHeader = parent;
 
  factory HeaderCell.fromSymbol(TableHeader tableHeader, Symbol symbol, Type type) =>
    new HeaderCell(tableHeader, symbol, type, MirrorSystem.getName(symbol));
 
  RowCell defaultRowCell(Row row) => new RowCell(row, this);
 
  // DOM
  Element createElement() => new Element.td()..text = label;
}

class RowCell extends Component {
  static const String RCELL = "g_rcell";
  HeaderCell headerCell;
  Object value = null;
 
  RowCell(Row parent, this.headerCell, {Object init, List<String> classes : const [RCELL]}): super(parent, classes) {
    value = init;
  }
 
  // DOM
  Element createElement() => new Element.td()..text = (value == null)?'':value.toString();
}

class TableHeader<E> extends Component {
  static const String TH = "g_th";
  final Table<E> table;
  final List<HeaderCell> headerCells;
 
  TableHeader(Table parent, this.headerCells, {List<String> classes: const [TH]}): super(parent, classes), table = parent;
 
  factory TableHeader.fromType(Table parent, Type modelType) {
    var th = new TableHeader(parent, []);
    reflectClass(modelType).getters.forEach((Symbol symbol, MethodMirror md){
      //print(">> symbol: ${symbol}, returnType: ${(md.returnType as ClassMirror).reflectedType}");
      th.headerCells.add(new HeaderCell.fromSymbol(th, symbol, (md.returnType as ClassMirror).reflectedType));
    });
    return th;
  }
 
  // DOM
  Element createElement() => headerCells.fold(new Element.tag("thead"), (Element thead, HeaderCell hc)=>thead..nodes.add(hc.element));
}

class Row<E> extends Component {
  static const String TR = "g_tr";
  final Table<E> table;
  final E e;
  final List<RowCell> rowCells = [];

  Row(Table parent, this.e, {List<String> classes: const [TR]}): super(parent, classes), table = parent;
   
  factory Row.defaultRow(Table<E> _table) =>
    table.theader.headerCells.fold(new Row(table, null), (Row row, HeaderCell hc) => row..rowCells.add(hc.defaultRowCell(row)));
 
  factory Row.fromEntity(Table<E> table, E e) {
    InstanceMirror imirr = reflect(e);
    return table.theader.headerCells.fold(new Row(table, e), (Row row, HeaderCell hc) => row..rowCells.add(new RowCell(row, hc, init: imirr.getField(hc.symbol).reflectee)));
  }
 
  // DOM
  TableRowElement createElement() => rowCells.fold(new Element.tag("tr"), (TableRowElement row, RowCell rc)=>row..nodes.add(rc.element));
}

class Table<E> extends Component {
  static const String TABLE = "g_table";
  Type modelType;
  String name;
  TableHeader theader;
  final List<Row<E>> rows;
 
  Table(Component parent, this.modelType, {List<String>  classes: const [TABLE]}): super(parent, classes), rows = [];
 
  factory Table.fromModelType(Component parent, Type modelType) =>
    [new Table(parent, modelType)].fold(null, (p, tbl)=>tbl..theader = new TableHeader.fromType(tbl, modelType)); 
 
  //
  void newRow() => rows.add(new Row<E>.defaultRow(this));
 
  void addRow(Row<E> row) {
    // check row.tabel == this
    if (row.table != this) {
      print(">> addRow error");
      throw new Exception("Table<1>");
    }
    rows.add(row);
    element.nodes.add(row.element);
  }
 
  void addRowFromEntity(E e) => addRow(new Row<E>.fromEntity(this, e));
 
  void clear() {
    element.nodes.clear();
    element.nodes.add(theader.element);
    rows.clear();
  }
 
  void load(Iterable<E> es) {
    clear();
    es.forEach(addRowFromEntity);
  }
 
  // DOM
  Element createElement() => rows.fold(new Element.tag("table"), (Element tab, Row row)=>tab..nodes.add(row.element));
}
This is the sample application using these library.
 class AppController extends TopComponent {
  final DivElement _uiRoot;
  DivElement _content;
  DivElement _actions;
 
  Table<Expense> _table;
 
  AppController(this._uiRoot, {List<Expense> expenses}) {
    _table = new Table<Expense>.fromModelType(this, Expense);
    if (expenses != null) {
      _table.load(expenses);
    }
    init();
    _uiRoot.nodes.add(element);
  }

  Element createElement() =>
    new Element.tag("div")
      ..classes.add("section")
      ..nodes.add(new Element.html("<header class='section'>Generic Table</header>"))
      ..nodes.add(_content = new Element.tag("div")
        ..nodes.add(_table.element))
      ..nodes.add(_actions = new Element.tag("div")
        ..id = "actions"
        ..classes.add("section"))
      ..nodes.add(new Element.html("<footer class='section' id='footer'></footer>"));
 
  Table<Expense> get table => _table;
}

main() {
  List<Expense> expenses = [
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random()];
  Element uiContainer = document.query("#generic_table");
  AppController app = new AppController(uiContainer);
  app.table.load(expenses);

}
 The html file is very simple.
<html>
  <head>
    <meta charset="utf-8">
    <title>Sample app</title>
    <link rel="stylesheet" href="generic_table.css">
  </head>
  <body>
    <div id="generic_table"></div>
    <script type="application/dart" src="generic_table.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>


Saturday, September 21, 2013

Generic GUI library in Dart (Part 1)

Most of Web application depend on  table view, and edit view.
Often these are related to database application.

These views are used to support CRUD operation.
The table view is essentially for query, to find a data.
The editor view is to create a new entity or edit existing entity.
Often these entities  reside in a remote database.

To achieve these thing, like Ruby on Rails, often code generation approach has been used. But this approach is not component oriented since generating code make it difficult to reuse codes

The better approach would be to develop generic GUI library.

The reason why this has not been used had several reasons coming from language short coming.

In order to support this approach, following language features are essential.
  • Class
  • Generics
  • Reflection
  • Annotation
  • direct DOM manipulation
Essentially, Java cannot  support direct DOM manipulation, and JavaScript doe not have all of class related feature as standard language feature.

So only Dart can support all of this.
In Java, it might be possible to use Pivot and running with Applet on browser.
But applet is not popular these days, and if we have more suitable language for web application, this approach is not so attractive. The Dart's concise syntax, and server side usage make it much simpler to develop web application than Java.

So I developed  first such application(generic-table-v1) in Dart.
Since this is rather primitive level of implementation, it will be easier to understand the basic of this approach.
In order to add more feature, it will be better not to rely on polymer.
These improvement will be the next step.

The following short code is all we need to have a class specific table view.
 main() {
  List<Expense> expenses = [
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random(),
                            new Expense.random()];
  Table table = new Table.fromModelType(Expense)
    ..load(expenses)
    ..newRow()
    ;
 
  query('#tmpl').model = table;
}
and I used polymer to create corresponding template:
  <body>
    <h1>Generic table</h1>
    <template id="tmpl" bind>
      <table border="1"> 
        <tr>    
          <th template repeat="{{ theader.headerCells }}">
            {{label}}
          </th> 
        </tr>         
        <tr template repeat="{{ rows }}">
          <td template repeat="{{ rowCells }}"><input type="text" value="{{value}}"></td>
        </tr>
      </table>
    </template> 
    <script type="application/dart" src="generic_table.dart"></script>
  </body>
This is the shapshot of this table.


The point of this approach is if we have some entity class like Expense, we just need to pass this class to have different Table view.

A specific table view associated with an entity class is  implemented by the same generic class. So no code generation are required.
Even if we have 500 of entity tables, we still don't need to generate 500 of JSP files or something similar. just a single generic class can handle all of these cases.
This would reduce the build time as well as code size.

But the main advantage of this approach  is to allow developing component based GUI library.  If properly designed, subcomponents of table, like row, cell may be specialized using separate GUI libraries.
Reusing code will be as usual as normal software development.

This Table class was written to prove the feasibility of generic GUI approach in Dart,  but there are more potentials in this approach to enhance sophisticated interaction between GUI DOM node operations,  entities and GUI views. Also these can be combined with backend server as well.

 Since the code is still manageable size, I will show all the codes.
 library generic_gui;

import 'dart:mirrors';


class Cell {
}


class HeaderCell extends Cell {

  TableHeader tableHeader;
  String label;
  Type type;
  Symbol symbol;
 
  HeaderCell(this.tableHeader, this.symbol, this.type, this.label);
 
  factory HeaderCell.fromSymbol(TableHeader tableHeader, Symbol symbol, Type type) =>
    new HeaderCell(tableHeader, symbol, type,MirrorSystem.getName(symbol));
 
  RowCell defaultRowCell() => new RowCell(this);
}

class RowCell extends Cell {

  HeaderCell headerCell;
  Object value = null;
  RowCell(this.headerCell, {Object initv}) {
    if (initv != null) {
      value = initv;
    } else {
      // we may introduce  default value assignment depending on the type.
    }
  }
}

class TableHeader<E> {

  Table<E> table;
  List<HeaderCell> headerCells;
 
  TableHeader(this.headerCells);
 
  factory TableHeader.fromType(Type modelType) {
    var th = new TableHeader([]);
    reflectClass(modelType).getters.forEach((Symbol symbol, MethodMirror md){
      th.headerCells.add(new HeaderCell.fromSymbol(th, symbol, (md.returnType as ClassMirror).reflectedType));
    });
    return th;
  }
}

class Row<E> {

  final Table<E> _table;
  final E e;
  final List<RowCell> rowCells;

  Row(this._table, this.e, this.rowCells);

    
// I like this kind of single expression style. 
factory Row.defaultRow(Table<E> _table) => new Row(_table, null,

    _table.theader.headerCells.fold([], (rowCells, HeaderCell hcell)=>rowCells..add(hcell.defaultRowCell())));
// '..' syntax is perfect match with this fold function.
  // Sometimes, we need to declare variable, then we must use block statement, but if Dart supports FAMOUS 'let' syntax of ML(or F#), then this can be written as a single expression, s.t. ' => let var imirr = ... in ... end;'
  factory Row.fromEntity(Table<E> table, E e) {
    InstanceMirror imirr = reflect(e);
    return new Row(table, e, table.theader.headerCells.fold([], (cells, HeaderCell hc)=>
        cells..add(new RowCell(hc, init: imirr.getField(hc.symbol).reflectee))));
  }

  Table get table => _table;

}

class Table<E> {

  Type modelType;
  String name;
  TableHeader _theader;
  final List<Row<E>> rows;
  List<E> _es;
 
  Table(this.modelType, this._theader): rows = [], _es = [] {
    _theader.table = this;
  }
 
  factory Table.fromModelType(Type modelType) {
    TableHeader th = new TableHeader.fromType(modelType);
    Table tbl = new Table(modelType, th);
    th.table = tbl;
    return tbl;
  }
   
  TableHeader get theader => _theader;
 
  void newRow() => rows.add(new Row<E>.defaultRow(this));
 
  void addRow(Row<E> row) {
    // check row.tabel == this
    if (row.table != this) {
      print(">> addRow error");
      throw new Exception("Table<1>");
    }
    rows.add(row);
  }
 
  Row<E> addRowFromEntity(E e) {
    addRow(new Row<E>.fromEntity(this, e));
  }
  // there should be more methods like these, but they should be associated with DOM operation.
  void clear() {
    _es.clear();
    rows.clear();
  }
 
  load(Iterable<E> es) {
    clear();
    _es.addAll(es);
    for (E e in es) {
      addRowFromEntity(e);
    }
  }
}

//

String getMethodName(MethodMirror md) =>MirrorSystem.getName(md.simpleName);

List<Symbol> getSymbols(Type t) => reflectClass(t).getters.values.

  fold([], (List symbs, MethodMirror mtd) =>(mtd.isGetter)?(symbs..add(mtd.simpleName)):symbs);


Polymer for component based Web development?

I investigated polymer.
First I tried all samples in dart-plolymer-dart-examples.

The thing I found was the last half of samples are not working.
The typical error is:

Exception: The null object does not have a method 'callSync'.

NoSuchMethodError : method not found: 'callSync'
Receiver: null
Arguments: [GrowableObjectArray len:0]
  Object.noSuchMethod (dart:core-patch/object_patch.dart:20:25)
  context (dart:js:9:58)
  PolymerElement._shimCss (package:polymer/polymer_element.dart:185:16)
  PolymerElement._initShadowRoot (package:polymer/polymer_element.dart:162:15)
  PolymerElement.created (package:polymer/polymer_element.dart:125:20)
  _initCustomElement (package:custom_element/custom_element.dart:584:18)
  registerCustomElement (package:custom_element/custom_element.dart:53:25)
  registerPolymerElement (package:polymer/polymer_element.dart:27:24)
  _loadLibrary (package:polymer/polymer.dart:109:31)
  initPolymer.<anonymous closure> (package:polymer/polymer.dart:63:19)
Essentially this  problem has been introduced after dart.js removed interop.js.
So I needed to add <script src="packages/browser/interop.js"></script> for most of index.html as following:

    <script src='packages/polymer/boot.js'></script>
    <script src="packages/browser/interop.js"></script>
Since boot.js is always used, it would be simpler to include this in boot.js.

After this fix, I still observered two errors, which I will append to teh end of this post.

Polymer is several useful features like model binding and jps like control extentions in html.
So basic idea is actually closer to traditional extended html approach.

Some interesting feature is  synchronization mechanism through Observable.(using annotation for observable field).
Although it looked good, but when I used this feature in dynamically allocated entity, it did not work.

So overall, I was a bit dis illusioned for polymer.
Essentially, these approach may be useful for more static type of application.
But if we want to do something more dynamic and/or generic, polymer will not be useful approach.
For instance, Apache Pivot has it own XML like GUI definition language(this seems sort of popular approach these days). it has similar problem as Polymer for generic GUI class development.

Still Polymer be useful to package such a generic library even that library may not be using Polymer.

But if we want to take more programatical approach for GUI development, it may not be so useful at all.

==========================================
[interop_with_polymer_elements]
Uncaught TypeError: Cannot call method 'querySelectorAll' of undefined
  inlinePolymerElements (http://127.0.0.1:3030/opt/dart-workspace/dart-polymer-dart-examples/web/interop_with_polymer_elements/packages/polymer/boot.js:83:25)
  inlinePolymerElements (http://127.0.0.1:3030/opt/dart-workspace/dart-polymer-dart-examples/web/interop_with_polymer_elements/packages/polymer/boot.js:92:7)
   ....
==========================================
[nested_templates]

Uncaught Error: EvalException: variable not found: name in 91145084
Stack Trace:
#0      Scope.[] (package:polymer_expressions/eval.dart:169:7)
#1      IdentifierObserver._updateSelf (package:polymer_expressions/eval.dart:406:19)
#2      ExpressionObserver._observe (package:polymer_expressions/eval.dart:252:16)
#3      Updater.visitExpression (package:polymer_expressions/eval.dart:268:15)
....

Saturday, September 14, 2013

Functional Program for compilers(language processors)

Compiler/Interpreter has been used since assembler/FORTRAN era.
It was one of most powerful software.
But the behavior is rather different from typical programs which takes a limited pattern of data structure as input and return  also limited pattern of data.
for instance typical method/function takes some data like int, and returns another object or data like if you put a coin to a vendor machine and push selection button, you get candy etc. quite mechanical.
On the other hand compiler can take million of line code code and generate something which can perform very complex thing as output, this is more like something only human can do.

the interesting nature is in compiler,  in the tree like data structure, each node is mapped to a closure recursively and the top node behavior can be constructed from these behaviors.
So this is quite good fit for functional programming language.
Often there are a but none standard interpretation between compiler and interpreter from none computer science oriented people.
for latter, interpreter mean tree traversing program, i.e, it take program(tree) as input and return some result.
The compiler mean it return some closure(function) from input program(tree), and no specific result is not yet given. the result can be only available by applying the function some context.
so if in compiler, we don't have to traverse program many times for different program inputs. just compile once and get function, and the different values can be obtained by just applying the function with different input values. in this function evaluation, no tree node data used.

for instance, a very simple compiler program will be as following:
typedef Object Code(RContext ctx);

class AddNode implements INode {
  INode node1;
  INode node2;

  Code compile(Context ctx) {
    Code c1 = node1.compile(ctx);
    Code c2 = node2.compile(ctx)
    return (RContext rctx)=>(add(c1(rctx), c2(rctx)));


var addNode = new AddNode(new IntNode(1), new IntNode(2));
Context ctx = new Context();
Code code = addNode.compile(ctx);

RContext rctx = new RContext();
var v1 = code(ctx);
 In fact, Dart does not support overloading, so this will use overriding of methods(even if it supports overloading, this  overriding approach is better though).
Subsequently the metaphor is changed in object oriented way, i.e, a node object has a compile method which  generates a compiled closure.
 This  is actually a good example of usefulness of mixing  two object oriented approach and functional approach.(although it became a matter of course nowadays for javascript programmers, but early days in 80's, many people were not much interested in such impure approach. Probably their target application(e.g, 5th generation Hardware) were different. but from pragmatic programming point of view, this should have been more emphasized. Some Lisp dialects were actually advocated these things, but Lisp had too poor syntax to be accepted by normal people, so there were no impact for general programmers.

------------
There were  bit of digression,  but bottom line is Dart will assist to write such compiler like application in wide range.
These are the reason to have appropriate syntax to express a conceptual idea directly in a language without any technical transformation(see anonymous object in Java). I remember Gosling called Java as functional language since it supports anonymous object. I thought what a silly statement it was..

Also functional approach has also very good fit with asynchronous programming.
Since we need to generate a function which will be called later time. So this requires to generate a  functions from combining other functions to be executed in later time. (many Stream program depend on then method, which is essentially Future to Future function.)

Asynchronous approach and  Compilation can be also combined further to have a distributed compiler at fine grained level. This will be discussed in another post.

Json Mapping tool for Dart

In Java, there is a tool called Jackson which handles a mapping between Java;s object and JavaScript's json data. The idea is similar to XStream for Java and XML mapping.
For Web application, json's concise data representation is more preferable than verbose XML representation, in Dart this type of mapping tools are quite in need.

In particular, if we use a rest full API like CouchDB, we often need to serialize Dart's object object into Json data, and vice versa. but the mapping requires either direct mapping (for simple case) or need to implements an interface and implement serialization method like toJson. This allows to serialize a nested Dart objects.

But if we can avoid these recurring task by delegating a tool like Jackson, it is quite productive.

So I looked for such tool in existing Dart libraries (including third-party libs), but there seems no such tools yet available.
One reason for this status is probably due to the lack of reflection in Dart language.
But it will be soon supported, so eventually it would be possible to have this kind of tool.

But Dart seems already supporting annotation, so it might be possible to support it by adding such annotations in Dart's class definition.
Also Dart syntax for getter/setter is quite easy to spot these property definitions, it would be easy to provide a tool to insert these annotations for given Dart class file.

In this type of annotation feature will  be still useful after reflection are introduced since sometime, we may want to customized handling mapping like JPA for instance.

One also interesting prospect for the Dart implementation is it might be possible to use Dart's new Stream feature in innovative ways.

Wednesday, September 11, 2013

Dart's fold method for Stream

Dart M5(probably)  re-designed of Collection/Stream related classes.

Although it created  lots of incompatibility, but they were worth  doing.
They should be considered as basic contribution for Dart language although they are library level enhancement.

One interesting action was they removed super Collection class.
Dart replaced it by Iterable.
for ORM mapping, if we have relationship among entiries, such relationship are represented by List, but if it is mapped to database with huge number of relatioship, it is quite inappropriate to fetch all elements in that property. Often some lazy approach is used, but actually caching is also not so good idea as default behavior, it should be just an Iterable object.
Then the default behavior will not fetch anything, nor will not cache anything.

It is interesting to compare Iterable, Collection and Stream.
Here I'm not so much following the actual Dart class library, but at more conceptual level.

Iterable are often considered as read only finite collection with synchronous iterate operation.
this means whenever we calls 'next', we will get next object immediately. Also user can control when he call  'next'.

On the other hand, Stream is some thing like iterable, but it is something more asynchronous.
and conceptually, stream is something external system is associated. and we cannot know when next data/event come. stream is a unpredictable sequence of events.
the event may be just one character, or line of string, an event object,etc.
We can just passively receive these events when it become available.
This concepts fits well for receiving radio signals. these event are not persistent, they just come and gone.
Also the number of events may not be finite, or predefined. we may expect almost infinite number of signal from a star over infinite period time. so infinite means 'potentially' no limit.

The notion of Collection is similar to stream in a sense both they can iterate over the element, but we assume it entirety at any moment. it it should be finite set of elements.
the synchronous nature to access its elements come from this model.

Although there are some differences,  if we want to iterate all the elements in either synchronous or asynchronous way, they are very similar.
Actually similar methods were introduced for them in Dart.

fold, reduce are the 'MOST' famous functions in functional programming language.
often it is used in a text book of functional programming language.

fun foldr(as as (a::as0), b, f: (B, A)->B):B=> (as == [])? b: f(folder(as0, b, f), a);
Essentially, it allows to do sigma like operator in math.
1+2+3+..+n
we can write: fold([1...n], 0, add);

in Dart's new Stream class(actually I don't know when this feature was introduced though), it supports this fold for asynchronous stream iteration.
this is interesting idea.

we can write a code to convert the input of stream to a string .

stream.fold(new StringBuffer(), (StringBuffer sb, String  line){ sb.write(line); return sb;})
.then((StringBuffer sb)=>sb.toString()).
then((text){
....
});

The above code is not the exact  code in dart, but we see the  similar pattern in many places.

Anyway, it is interesting to see commonality of these iterator classes  beyond synchronous and asynchronous differences.

Dart's 'Future'

Overall, Dart language is very powerful and the language nature is very familiar to me as long time functional language advocates.(actually mixture of functional and object oriented).

Essentially it is very powerful to abstract procedure.
Often other none functional programming languages are very weak at abstracting procedure.
Since refactoring common process can not be done easily, and it ends up writing repetitive procedure again and again.
Because of this, Dart program are tend to become very short compared to corresponding code in Java.
short, concise, abstract code is the trait of functional programming.(Thus the title of this blog, 'Zen')


Shortness is just one aspect of it, but more important aspect is to change the way to think of problem.
Also functional style will clarify the basic aspect of asynchronous programs.

the Future class of Dart is in this respect very important.
The basic  idea is to allow to write a sequential steps of asynchronous call  in sequential way.
implicitly Future is hiding some event based trigger mechanism inside the class, because of that, the code using Future looks just a sequence of functions.

Future<A> fu = f();
fu
.then((A a)=>b())
..then((B b1)=>c())
...
.then((e){...})
.then.((i)=>i);

These 'then' method (of Future class) creates another Future(of different parametric type determined by the return type of the function passed to the then method).
So essentially with 'then' future takes a function and create another future .
this is asynchronous version of function combination function from two function.

fun then('X->'Y f, 'Y-'Z g): 'X->'Z =>('X x)=>g(f(x)); // pseudo code
Although Dart does not have this kind of type scheme(see ML)) or generic type specification, but it is achieving similar things.

but in case of Future, it is not ordinarily sequence of function calls, but it determines the sequence of function calls triggered by internal events.
if all functions in the parameter are written without asynchronous call, these functions are invoked immediately in a cascade way. One after another function call, the return value is used to trigger next future.
But if there is a asynchronous call in the function body, then we can control the  triggering timing using completer.
Future<A> fu = f();
fu
.then((A a)=>{
  Completer<B> c = new Completer<B>();
  B b = new  B();
...
  stream.open(..., onDone: {
     c.complete(b); // this allows to controls when the next function(f1) is to be triggered.
  });
  return c.future; // the action must return a future which is triggered by the complete invocation above.
  }
)
..then(f1);

Prototype web app using Dart M5

I just completed porting of a sample app DartExpenseServer project associated with chap 14 of 'Dart in Action' to Dart M5.
Although I started this as porting effort to Dart M5,  I ended up rewriting whole code.
The reason was the original sample app was not fully functional and not well designed as a realistic database application.

DartExpenseServer_v1.tar.gz

This sample project will be useful to start writing realistic web app.
It demonstrates basic idioms to write client/server side web application.
Namely the basic patterns of HttpRequest in client side, and HttpServer/HttpClient in server side as well as new bidirectional asynchronous WebSocket based communication method.
Also this covers basic CRUD operations over CouchDB through HttpClient in Dart. The adaptor class was made into a generic class so that it can be used to access different entity classes.

  • supporting CRUD operation in browser client app.
    Original sample did not support delete operation. and Also the entity id handling was unrealistic hack. This was fixed by using CouchDB's id generation feature.
  • supporting websocket which allows to push an event to multiple connected clients as well as asynchronous calling(by sending message) to server.
    this feature is used to updating the number of currently connected clients to all clients from server, and synchronizing list item changes to other browsers (web clients).
    this is actually using HttpClient to update the change to server, and server use websocket to the changes to all other browsers.

    But this type of communication mechanism is not almighty. sometime we want to receive message from server after sending message. For this purpose, we can use HttpClient as explained in next item.
  • HTTPClient usage for create/update/delete/read operations.
    The original Sample code was using persistent id created in a client side and used websocket to communicate with server for saving an object in database. this may be OK  to simplify code, but it is not realistic solution.
    If we want to insert(save) a new row in  a database, that db may generates the id, and we need the id in the client side.
    In such a case, websocket based message passing is not effective way. Since the websocket listener in client side has no knowledge over which object was saved in database. it may just receive this id, and it needs to find the  saved object in client side memory. but unless client side maintains local ids for the temporarily transient objects, it will be impossible to find such object.
    In this case, we should use HttpClient instead of websocket.
  • CouchDB access using server side HttpClient, this supports CRUD operations.
    there are not much good source of information for how to use CouchAPI from http level, I needed to several trials and errors and need to find some trick to achieve CRUD operation.
  • supporting both Dartulium and JS execution. (JS was not working before)
    Since Dart has a bug for handling Element.html, I need to find workaround to have the same result on both clients.
  • Since there were many layer and several problems, debugging were not easy.In particular, logging info by print function from client and server side cleared other side of output, so essentially there are very few info remained the terminal.
    So I switched to use logging library of Dart. This is also mandatory practice in Dart app.
Todo list
There are still a few things to be done even this level of app.

  • some common library dart file should be properly packaged.
  • Although this need not be done for this sample app, but it will be interesting to use Polymer for making GUI. This will be an another project.
  • CouchDB is a bit special DB, it is sort of cloud type DB. It is interesting to replace this with PostgresSQL. there is a driver for Dart now. 
  • When we write a code using websocket, code for sending message/receiving messages are splitted in client and server side. and it will become difficult to maintain  them  consistent.
    Since Dart support same language in both server/client, the nature is better than other approach using totally separate language on each sides. For instance, these websocket message names should be defined as constants in shared files. There may be more approach for this.

Since there are so many change in Dart, this application needed a lot of change.

  • Big change of HttpRequest, HttpClient etc.
  • difficulty to understand/use CouchDB through REst API(associated with choice for put/post/get, and handling of responseText etc) 
  • bugs in Dart(setter bug, Element.html bug) and some design  pattern of modeling and websocket.)
  • no logging lib feature original code.
Some of these issues came from the obviously early state of language development.

Interesting aspects of Dart is the new way to write asynchronous program.
Future is quite powerful idiom.
Also the new Stream library in M5 support more seems less use of Future.
If you compare the original DartExpenseServer code with the new Stream based code, you will see the difference.
In new version we don't need to use Completer class(almost).

I will describe these issues in separate posts.

Dart Element.html bug

I found a bug in dart2js for handling Element.html.
when we run an app using this feature, Dartium can run properly, but js version, the  result is not correct.
It expects to show items in a table, but they are not shown in the js version.
I thought this comes from a problem handling Element.html, so I replaced it with Element.tag, and it worked on both ways.
In fact, Element.html looks too heavy way to construct page elements, so there might be a better way, (not go the other end of using tag constructors), but such difference are very annoying problem if we decide to use Dart.
So this problem should be fixed.

this is  the projects to test this problem.

I created simple test projects.
here is a snipe of code what cause the problem and how we can avoid the problem..
------------------------
// this is buggy version

  refreshUi(List<Expense> expenses) {
    _updateRootElement();

    Element tableElement = new Element.tag("table");
    Element head = new Element.html("""
          <thead>
            <td class="type">Type</td>
            <td class="date">Date</td>
            <td class="detail">Item</td>
            <td class="amount">Amount</td>
            <!--<td class="claimed>Claimed?</td>-->
            <td class="edit">&nbsp;</td>
          </thead>""");

     tableElement.nodes.add(head);

     for (Expense ex in expenses) {
       tableElement.nodes.add(_getRowElement(ex));
     }

    rootElement.nodes.add(tableElement);
  }
=====>
// this is a workaround.

  refreshUi(List<Expense> expenses) {
    _updateRootElement();

    Element tableElement = new Element.tag("table");
    rootElement.nodes.add(tableElement);
    Element thead = new Element.tag("thead");
    thead.nodes.addAll([
        newTd('type', 'Type'),
        newTd('date', 'Date'),
        newTd('detail', 'Item'),
        newTd('amount', 'Amount'),
        newTd('edit', ''),
        newTd('delete', '')
        ]);
 
    tableElement.nodes.add(thead);
    for (Expense ex in expenses) {
      tableElement.nodes.add(_getRowElement(ex));
    }
  }
Element newTd(cls, txt) {
  Element td = new Element.td();
  td.attributes['class'] = cls;
  td.text = txt;
  return td;
}


Tuesday, September 10, 2013

Dart Compiler bug

There is a strange behavior in Dart's setter declaration.
It should detect an error at compilation time(dart2js) or editing time using Eclipse dart plugin (or Dart Editor), but it is only detected at runtime.

let see following class definition.
In the class A, rev0 is defined without parameter type specification.
but only possible type allowed 'void' since the type of expression '_rev = value' must be equal to the setter's return type 'void', and that assignment expression's type is the type of value. so teh value type must be void.
This already quite ridiculous situation for setter  since we cannot declare type of a variable as void!
but aside from this issue, if we call a function in which  the return type is 'void', it works as (3).
and the null value's type seems void! anyway null is assigned to _rev.

So these things does not make sense, and practically, it introduce an error which can be detected at compilation time, but defered at the runtime.
Since this is so wird, people may not easily spot the bug in the setter definition!
As a workaround, we should always define type for the setter parameter(no dynamic also).

String _rev = null;
class A {
  String get id => _id;
  void set id(String i) { _id = i; }
  String _id = null;

  String _rev = null;
  String get rev => _rev;
  void set rev(String value) { _rev = value; }// (0) normal way..

  // void a; // compilation error

  void f(_) {}
  void set rev0(value) => _rev = value; // buggy, but no compile time error
  void set rev00(dynamic value) => _rev = value; // buggy, but no compile time error
  void set rev1(String value) => f(value); // (1) this is OK
  void set rev2(String value) => f(_rev = value); //(2)
  // void set rev3(String value) => _rev = value;  // compilation error
  String rev3(String value) => (_rev = value);

  factory A.fromJson(String json) {
    var map = parse(json);
    return new A.fromMap(map);
  }
....
}
main() {
    A e = new A.fromJson('{"id":null, "_rev":"NNNNN"}');
    log.info("1===> ${e.toJson()} ${e.rev}");
    e.id = e.rev = "ooo";
    log.info("2===>  ${e.toJson()} ${e.rev}");
    e.rev0 = e.f(1); // works!! but wird.. (3)
    log.info("3===>  ${e.toJson()} ${e.rev}");
    e.rev1 = "aa"; // works!! but wird..
    log.info("4===> ${e.toJson()} ${e.rev}");
    e.rev2 = "aa"; // works!! but wird..
    log.info("5===> ${e.toJson()} ${e.rev}");

    e.rev0 = "aa"; // runtime error!!

}
}

----------------------
The following is the execution logs.
when 'e.rev0 = "aa";' is called, it causes runtime error.
this error message "type 'String' is not a subtype of type 'void' of 'function result'." is also not easy to understand, but the reason is this rev0 is expecting void argument type!

dirt_server.log [INFO]: 1===>  {"id":null,"_rev":"NNNNN"} NNNNN
dirt_server.log [INFO]: 2===>  {"id":"ooo","_rev":"ooo"} ooo
dirt_server.log [INFO]: 3===>  {"id":"ooo"} null
dirt_server.log [INFO]: 4===>  {"id":"ooo"} null
dirt_server.log [INFO]: 5===>  {"id":"ooo", "_rev":"aa"} aa

Unhandled exception:
type 'String' is not a subtype of type 'void' of 'function result'.
#0      A.rev0= (file:///opt/A.dart:28:28)
#1      main (file:///opt/A.dart:138:34)

-----------------


Wednesday, September 4, 2013

language changes



https://www.dartlang.org/articles/m1-language-changes/


http://news.dartlang.org/2013_02_01_archive.html


check the IO changes, there are huge changes.

 We have done a full re-design of the dart:io API (file, network, directories, etc) to use the classes and concepts in the core library and in dart:async. This means that there is almost no callback registration in dart:io any more. All async operations now use streams and futures.

(These changes are available in bleeding_edge as of today, and should show up in a weekly build soon.)





We think this is a great step forward in aligning all of the “dart:” API's and for you to have fewer concepts to learn when using Dart for different tasks.

However this is a breaking change which requires rewriting code using dart:io. The good news is that most of these changes should be mechanical. The following sections describe these changes in more details and give some examples on how to migrate code to the new API. For more information take a look on the API documentation for dart:io.

Streams in dart:io
The classes InputStream and OutputStream are gone and have been replaced with classes implementing IOSink and Stream<List<int>>.

When reading from a Stream<List<int>> just use the listen method which have arguments matching the callbacks previously used. This shows how to migrate code using an InputStream to the streams-based API:

dart:io v1 code
InputStream stream = ...
stream.onData = () {
 var data = request.inputStream.read();
 /* Process data. */
};
stream.onClosed = () {
 /* All data received. */
};
stream.onError = (e) {
 /* Error on input. */
};

dart:io v2 code
Stream<List<int>> stream = ...
stream.listen(
 (data) { /* Process data. */ },
 onDone: () { /* All data received. */ },
 onError: (e) { /* Error on input. */ });

As the InputStream class is now gone so is the StringInputStream for turning a stream of bytes into strings and/or lines. Two new stream transformers StringDecoder and LineTransformer have been added to address this. The StringDecoder transforms a stream of List<int> to a stream of String and the LineTransformer transforms a stream of String to a new stream of String where each string is a line.

dart:io v1 code
InputStream stream = ...
StringInputStream stringStream = new StringInputStream(stream);
stringStream.onLine = () {
 String line = stringStream.readLine();
 /* Do something with line. */
};
stringStream.onClosed = () {
 /* No more lines */
};
stream.onError = (e) {
 /* Error on input. */
};

dart:io v2 code
Stream<<int>> stream = ...
stream
 .transform(new StringDecoder())
 .transform(new LineTransformer())
 .listen((String line) { /* Do something with line. */ },
         onDone: () { /* No more lines */ },
         onError: (e) { /* Error on input. */ });

The IOSink replaces OutputStream and this shows how to migrate code using OutputStream to use an IOSink:

dart:io v1 code
OutputStream stream = …
stream.write([72, 101, 108, 108, 111]);  // Hello
stream.writeString(", world!");
stream.close();

dart:io v2 code
IOSink sink = …
sink.add([72, 101, 108, 108, 111]);  // Hello
sink.addString(", world!");
sink.close();

The IOSink also allows you to pipe directly from a stream.

HTTP
The main changes to the HTTP server and client part of dart:io are the following:

* A new HttpServer listening for requests is created using the static method bind.
* An HttpServer is a stream of HttpRequests.
* The defaultRequestHandler setter and addRequestHandler method on HttpServer are gone.
* The HttpRequest and HttpClientResponse objects implement Stream<List<int>>.
* The HttpClientRequest and HttpResponse objects implement IOSink.

To create a new listening HTTP server use the static method bind which returns a future.

dart:io v1 code
HttpServer server = new HttpServer();
server.defaultRequestHandler = …
server.addRequestHandler(…);
server.listen(“127.0.0.1”, 8080);
// Now the HTTP server is bound and listening for requests.

dart:io v2 code
HttpServer.bind(“127.0.0.1”, 8080)
   .then((HttpServer server) {
     server.listen(
         (HttpRequest request) {
           // Handle the request.
         });
}

The request routing through defaultRequestHandler and addRequestHandler is gone and any routing to specific request handling methods should be added to the listen handling. The HttpResponse is available as the response property on the HttpRequest object.

For client side HTTP the HttpClient class still exists. The HttpClientConnection class is gone, and instead the request initiation methods get, post, open, etc. now returns a future for the HttpClientRequest object. The HttpClientRequest object has a response property which is a future for the HttpClientResponse. As a convenience the HttpClientRequest.close method also returns the future for the response. This shows how to migrate HTTP client code:

dart:io v1 code
HttpClient client = new HttpClient();
HttpClientConnection connection = client.get(...);
connection.onRequest = (HttpClientRequest request) {
 // Prepare the request.
 request.outputStream.close();
}
connection.onResponse = (HttpClientResponse response) {
 // Process the response.
}

dart:io v2 code
HttpClient client = new HttpClient();
client.get(...)
   .then((HttpClientRequest request) {
     // Prepare the request.
     return request.close();
   })
   .then((HttpClientResponse response) {
     // Process the response.
   });

Web Sockets
The web socket interface has been simplified and now uses the same class for web socket connections on both the client and the server. The WebSocket class is a stream of events.

On the server the web socket handling is implemented as a stream transformer. This transformer can transform a stream of HttpRequests into a stream of WebSockets.

dart:io v1 code
HttpServer server = new HttpServer();
server.listen(...);
WebSocketHandler handler = new WebSocketHandler();
handler.onOpen = (WebSocketConnection connection) {
 connection.onMessage = (Object message) {
   /* Handle message. */
 };
 connection.onClosed = (status, reason) {
   /* Handle closed. */
 };
};
server.defaultRequestHandler = handler.onRequest;

dart:io v2 code
HttpServer.bind(...).then((server) {
 server.transform(new WebSocketTransformer()).listen((WebSocket webSocket) {
   webSocket.listen((event) {
     if (event is MessageEvent) {
       /* Handle message. */
     } else if (event is CloseEvent) {
       /* Handle closed. */
     }
   });
 });

On the client connecting a web socket has become much simpler. Just use the WebSocket static method connect which returns a future for the web socket connection as shown here:

dart:io v1 code
HttpClient client = new HttpClient();
HttpClientConnection conn = client.openUrl(“https://127.0.0.1:8080”);
WebSocketClientConnection wsconn = new WebSocketClientConnection(conn);
wsconn.onMessage = (message) {
 /* Handle message. */
}
wsconn.onClosed = (status, reason) {
 /* Handle closed. */
};

dart:io v2 code

WebSocket.connect("ws://echo.websocket.org")
   .then((WebSocket webSocket) {
     webSocket.listen((message) {
         /* Handle message. */
       },
onDone: () {
         /* Handle closed. */
       });
   });

Process
The Process class uses Stream<List<int>> for stdout and stderr and IOSink for stdin. The exit code for the process is now available through the exitCode future.

dart:io v1 code
Process process = ...
process.stdout.onData = ...
process.stdout.onDone = ...
process.onExit = (exitCode) { /* do something with exitCode. */ }

dart:io v2 code
Process process = ...
process.stdout.listen(...);
p.exitCode.then((exitCode) { /* do something with exitCode. */ });

Likewise the types of the top level properties stdin, stdout and stderr have been changed. stdio is a Stream<List<int>> and stdout and stderr are IOSinks.

File and directory
Reading and writing a file also uses Stream<List<int>> and IOSink. To read a file change the use of openInputStream to openRead which returns a stream of type Stream<List<int>>. Likewise change the use of openOutputStream to openWrite which returns an IOSink.

The Directory.list function now returns a stream of FileSystemEntity objects. The FileSystemEntity is a superclass of both File and Directory. The previous DirectoryLister where callbacks were set is now gone.

dart:io v1 code
Directory dir = ...
DirectoryLister lister = dir.list();
lister.onDir = (Directory directory) { /* Do something with directory. */ };
lister.onFile = (File file) { /* Do something with file. */ };
lister.onDone = (bool complete) { /* Listing ended.*/ };
lister.onError = (error) { /* Listing error.*/ };


dart:io v2 code
Directory dir = ...
dir.list().listen(
   (FileSystemEntity fse) {
     if (fse is Directory) {
       Directory directory = fse;
       /* Do something with directory. */
     } else if (fse is File) {
       File file = fse;
       /* Do something with file. */
     }
   },
   onDone: () { /* Listing ended.*/ },
   onError: (error) { /* Listing error.*/ });

Sockets
The classes Socket and SecureSocket both implement Stream<List<int>> and IOSink as they support bidirectional communication. This replaces all the reading and writing previously provided through a combination of callbacks, read and write methods, and InputStream and OutputStream objects backed by sockets.

Connecting a socket now uses a static method returning a future instead of a callback.

dart:io v1 code
Socket socket = new Socket(host, port);
socket.onConnect = () { /* Socket connected. */ }

dart:io v2 code
Socket.connect(host, port).then((Socket socket) {
 /* Socket connected. */
};

The classes ServerSocket and SecureServerSocket now uses a static method returning a future when binding to an interface. A listening server socket delivers the socket connections as a stream instead of through the onConnection callback.

dart:io v1 code
ServerSocket socket = new ServerSocket(host, port);
socket.onConnection = (Socket clientSocket) {
 /* Do something with the clientSocket. */
}

dart:io v2 code
ServerSocket.bind(host, port).then((ServerSocket socket) {
 socket.listen((Socket clientSocket) {
   /* Do something with the clientSocket. */
 })
});

Raw sockets
In order to provide a low level socket API we introduced raw sockets. Raw sockets give you access to low-level socket events without giving you data in your hand (think of this as the events you get from epoll on a socket file descriptor on Linux systems). Based on the low-level events you can read out data from the socket and decide when to write more data to the socket. The high-level Socket and ServerSocket classes are built on top of the RawSocket and RawServerSocket classes. Check out the API documentation on the Raw* classes.