// currently collection and map only
svoid pnlStruct(O o) {
  if (o cast Collection) pnlStruct(o);
  else if (o cast Map) pnlStruct(o);
  else if (o != null) pnlStruct(ll(o));
}
static > B pnlStruct(B l) {
  pnlStruct((Iterable) l);
  ret l;
}
static  Iterable pnlStruct(Iterable l) {
  ret pnlStruct("", l);
}
static  Iterable pnlStruct(S prefix, Iterable l) {
  int i = 0;
  if (l != null) for (A a : l) print(prefix + (++i) + ". " + struct_noStringSharing(a));
  ret l;
}
static  A[] pnlStruct(A[] l) {
  pnlStruct(asList(l));
  ret l;
}
static  Map pnlStruct(Map map) {
  pnl(map(map, func(A a, B b) { sfu(a) + " = " + sfu(b) }));
  ret map;
}