# Proposal for objects:

Type:

  object_type -> 'object' '{' {method} '}'
               | 'class' ['<' type_exprs '>'] qid

  method -> type_expr ID '(' {type_expr ID (sep ',')} ')' ';'

  Example:
    'a get(object {'a get();} o) (o->get())

  class-form is shortcut to listing all methods from named class.
  

Top-level declaration:

  'class' '<' tyvars '>' ID [inherit] '{' {class_decl} '}'

  inherit ->  ':' {['<' type_exprs '>'] qid (sep ',')}
  
  class_decl ->
  	  attr function_decl
	| var_def
	| 'virtual' ['protected'] method

  attr -> 'private' | 'protected'


Class interface:

'class' '<' tyvars '>' ID [inherit] '{' {method_spec} '}'

method_spec -> ['virtual'] ['protected'] method


Example:

class <'a>foo {
	void init('a x);
	void set('a x);
	'a get();
	protected *('a, 'b) pair_with('b y);
}

// we don't need foo definition here
class <'a>bar : <int>foo {
	// 'a get() would be illegal
	int get() ((this as foo)->get() + 3)

	'a data;	// no ambiguity here, bar cannot access foo::data
	
	void init(int x, 'a a) : foo(x)
	{
		// (this as foo)->init(x); // same as `: foo(x)'
		data = a;
	}
}

class <'a>foo {
	'a data;
	
	// init is special method
	void init('a x)
	{
		data = x;
	}

	void set('a x)
	{
		data = x;
	}

	'a get() (data)

	protected *('a, 'b) pair_with('b y) ((data, y))

	// private methods are in fact bound statically and cannot be
	// declared in class interface
	private void frobnicate() {}
}

typedef class <int>foo FOO;

FOO f = new foo(5);
class <string>bar x = new bar(10, "ble");
_ y = new bar(10, f);

*(int ()) lambda = y->get;
int i = y->get();

/*
class <'a>foo is the same as 
object <'a> { 
	void init('a x); 
	void set('a x); 
	'a get(); 
	*('a, 'b) pair_with('b y);
}
*/

Class interface is *only* relevant in inheritance.  

Inheritance has *nothing* to do with subtyping.

If module inherits from class from outside this very module, it's marked as
one that needs initialization.  This prevent mutually recursive inheritance,
as well as ensures proper order of initialization.

There is no method overloading.

Types of methods can be only more general, then their types in base class.


Compilation issues:

All method names found in program are assigned unique integer ids.  Maximal
number of such id is size of v-table.  V-table is organized as follows:

struct method {
	word id;
	word offset;
}

struct inherited {
	word offset;
	// name?
}

word (SIZE * 2);
method methods[SIZE];
word N_INHERITED;
inherited base_classes[N_INHERITED];
name? whatever?

