<md>

# Properties

In the context of a programming language, property is an entity that looks like a variable/field but allows performing actions on read or write. Functions implementing these actions are called "accessors". The read accessor is called a "getter", and the write accessor is called a "setter". Each property has a single getter and optionally one or more setters. 

If a setter is overloaded then the selection of particular setter function will be performed according to the same rules that apply to regular overloaded functions. If a property has no setters then it is a "read-only" ("const") property. 

Jancy provides two methods of declaring a property: simple and full.

## Simple Property Declarations

Jancy supports what we believe to be the most natural syntax for declaring properties:

<div class='new_frame snippet'>
<code name="jancy">
int property g_simpleProp;
</code>
</div>
<br>

This syntax is ideal for declaring interfaces or when the developer prefers to follow the C++-style of placing definitions outside of a class:

<div class='new_frame snippet'>
<code name="jancy">
int g_simpleProp.get ()
{
	return rand () % 3;
}

g_simpleProp.set (int x)
{
	// set property value
}
</code>
</div>
<br>

Read-only properties can use a simple declaration syntax:

<div class='new_frame snippet'>
<code name="jancy">
int const property g_simpleReadOnlyProp;

int g_simpleReadOnlyProp.get ()
{
	return rand () % 3;
}
</code>
</div>
<br>

For obvious reasons, this simple syntax is only possible if a property has no overloaded setters, in which case you should use the second method: full property declaration.

## Full Property Declarations

A full property declaration looks a lot like a declaration for a class. It implicitly opens a namespace and allows for overloaded setters, member fields, helper methods, constructors/destructors etc.

<div class='new_frame snippet'>
<code name="jancy">
property g_prop
{
	int m_x = 5; // member field with in-place initializer

	int get ()
	{
		return m_x;
	}

	set (int x) 
	{
		m_x = x;
		update ();
	}	
		
	set (double x); // overloaded setter
	update (); // helper method
}
</code>
</div>
<br>

A body of a method can be placed on the right (Java-style) or outside (C++-style).

## Indexed Properties

Jancy also supports 'indexed' properties, which are properties with array semantics. Accessors for such properties accept additional index arguments. Unlike with real arrays, a property index doesn't have to be of the integer type, nor does it mean 'index' exclusively -- it is up to the developer how to use it.

Simple indexed property declaration syntax:

<div class='new_frame snippet'>
<code name="jancy">

int g_x [2];

int indexed property g_simpleProp (unsigned i);

// here the index argument is really used as the array index

int g_simpleProp.get (unsigned i)
{
	return g_x [i];
}

g_simpleProp.set (
	unsigned i,
	int x
	)
{
	g_x [i] = x;
}

</code>
</div>
<br>

A similar property declared using full syntax:

<div class='new_frame snippet'>
<code name="jancy">

property g_prop
{	
	int m_x [2] [2];

	// more than one index argument could be used

	int get (
		unsigned i,
		unsigned j
		)
	{
		return m_x [i] [j];
	}

	set (
		unsigned i,
		unsigned j,
		int x
		)
	{
		m_x [i] [j] = x;
	}

	// setters of indexed property can be overloaded

	set (
		unsigned i,
		unsigned j,
		double x
		)
	{
		m_x [i] [j] = (int) x;
	}
}
</code>
</div>
<br>

Accessing indexed properties looks like accessing arrays

<div class='new_frame snippet'>
<code name="jancy">

int indexed property g_prop (
	unsigned i,
	unsigned j
	);

foo ()
{
	int value = g_prop [10] [20];

	// ...

	g_prop [30] [40] = 100;

	// ...
}

</code>
</div>

## Autoget Properties

In most cases a property getter is supposed to return a variable value or field, and all of the property logic is contained in the property setter. Jancy takes care of this common case by providing autoget properties. Such properties do not require a getter implementation: the compiler will access the data variable/field directly if possible, or otherwise generate a getter to access it.

Simple syntax for declaring autoget property:

<div class='new_frame snippet'>
<code name="jancy">

int autoget property g_simpleProp;

g_simpleProp.set (int x)
{
	m_value = x; // by default, the name of compiler-generated field is 'm_value'
}

</code>
</div>
<br>

The same property declared using full syntax:

<div class='new_frame snippet'>
<code name="jancy">
property g_prop
{	
	int autoget m_x; // declaring an 'autoget' field implicitly makes property 'autoget'

	set (int x)
	{
		m_x = x;
	}

	// setters of autoget property can be overloaded

	set (double x)
	{
		m_x = (int) x;
	}
}
</code>
</div>
<br>

Autoget and indexed property modifiers are mutually exclusive.

## Bindable Properties

Jancy supports bindable properties which automatically notify subscribers 
when they change. Bindable properties play crucial role in the [reactive programming](reactive.html).

Simple bindable property declaration syntax:

<div class='new_frame snippet'>
<code name="jancy">

int autoget bindable property g_simpleProp;

g_simpleProp.set (int x)
{	
	if (x == m_value)
		return;

	m_value = x;
	m_onChanged (); // by default, the name of compiler-generated event is 'm_onChanged'
}

onPropChanged ()
{
	// ...
}

int main ()
{
	// ...

	bindingof (g_simpleProp) += onPropChanged;
	g_simpleProp = 100; // <-- onPropChanged will get called
	g_simpleProp = 100; // <-- onPropChanged will NOT get called

	// ...
}
</code>
</div>
<br>

Similar property declared using full syntax:

<div class='new_frame snippet'>
<code name="jancy">

property g_prop
{	
	autoget int m_x; // declaring an 'autoget' field implicitly makes property 'autoget'
	bindable event m_e (); // declaring a 'bindable' event implicitly makes property 'bindable'

	set (int x)
	{
		m_x = x;
		m_e ();
	}
}

</code>
</div>

## Bindable Data

Jancy offers fully compiler-generated properties: getter, setter, back-up field and on-change event are all generated by the Jancy compiler. These 'degenerate' properties are designed to track data changes: they can be used as variables or fields that automatically notify subscribers when they change.

<div class='new_frame snippet'>
<code name="jancy">

int bindable g_data;

onDataChanged ()
{
	// ...
}

int main ()
{
	// ...

	bindingof (g_data) += onDataChanged;
	g_data = 100; // <-- onDataChanged will get called
	g_data = 100; // <-- onDataChanged will NOT get called

	// ...
}
</code>
</div>

---
Proceed to Jancy [multicasts &amp; events](multicasts.html)
</md>
