var x = function X(a=1,b=0){
  //print("argv =",argv);
  assert 'array' === typename argv;
  assert 'function' === typename X;
  //print('"this" type =',typename this);
  return a + b;
};
assert 'function' === typename x;
assert 1 === x(1);
assert 3 === x(1,2);
//return;
assert 3 === x(1,2,3);

var o = { f: x };
assert -1 === o.f(0,-1,1);
unset o;

var y = 1 || proc(){skipped}(args,skipped,too);

// just to watch the dtor in debug output...
// print('unsetting func'); unset x; print('after unset');

unset x, y;
// Fixed :-D
//print('script location info from inside funcs will be wrong for a while:',
//      catch proc(){throw    __FLC}()
//);
assert __LINE+1 === catch {
  proc(){throw 0}()
}.line;

var recursive = proc r(a=1){
  return a>3 ? a : r(a+1);
};

assert 4 === recursive();

assert 4 === proc rec(a=1){
  return a>3 ? a : rec(a+1);
}();
assert 'undefined' === typename rec;

var x = function myfunc(a=myfunc.defaults.0, b=myfunc.defaults.1){
  return a + b;
};
x.defaults = [1,-1];
assert 0 === x();
assert 1 === x(2);

var o = {
  name: 'fred',
  f:function(){return this.name}
};
assert 'fred' === o.f();

scope {
  var x = 3, y = 4;
  var f = function(c){
    return a + b + c;
  }.importSymbols({a: x, b: y});
  assert 8 === f(1);
  f.a = 1;
  var counter = 0;
  f.eachProperty(proc(){
    counter = counter + 1;
    //print(argv);
  });
  assert 1 === counter /* making sure that the
         importSymbols sym is hidden here
  */;
  assert 'object' === typename f.'%imported%';
}

scope {
  var o = {a:1};
  var f = function(a){
    return this.a + a;
  };
  assert 2 === f.apply(o,[1]);
  assert 2 === f.call(o,1);

}

scope {

  // Make sure that skip mode is honored
  // for default parameters which are passed
  // in by the caller...
  var f = proc(a, c=(throw 'default param threw'), b=1){
    assert 1===b;
    assert 0===c;
    assert -1===a;
  };
  f(-1,0);
  assert 0 === catch{f(1) /* param c=throw... gets processed */}
         .message.indexOf('default param');
}
