login  home  contents  what's new  discussion  bug reports     help  links  subscribe  changes  refresh  edit

Edit detail for ReferenceSemantics revision 2 of 2

1 2
Editor: test1
Time: 2019/06/13 20:42:16 GMT+0
Note:

changed:
-(apropriate pointer operations).  In pure functional at logical level there is no
(apropriate pointer operations).  In pure functional language at logical level there is no

changed:
-created and reference to this integer is stored in variable.  To optimize small enough
created and reference to this integer is stored in variable.  To optimize, small enough

changed:
-distinguish references from integers.  At higher level user sees the same bahaviour,
distinguish references from integers.  At higher level user sees the same behaviour,

added:
Sometimes for efficiency FriCAS functions modify data pointed to by references.  By convention
functions doing this have '!' at the end on name.  When function is generic exact nature
of modification and if it is beneficial depends on actual types.  In such cases function
return possibly new value (reference).  It may point to old modified data, or may be new.
For such functions users should use returned value, treating argument as possibly mangled.
In terminology of [Design By Contract] contract of function involves returning reference
to correct data, but function makes no promise about future usability of argument.

Traditional imperative languages like C, Pascal etc. have value semantic: variables store possibly complicated compound values. Normal calling sequence copies values of function parameters so that assignment to parameters do not affect values inside calling function. Value semantic is easy to understand, but copies may be costly both due to extra space and time needed for copying. Sometimes correct behaviour is to modify shared value. To get effect of sharing classical languages use pointers (at lowest level pointers are just machine addresses).

In imperative languages data structures may be modified at almost any time, so to avoid unwanted modification one has to copy data. Value semantics plays nicely with need to copy: by default one gets safe behaviour and to get sharing one need an explicit action (apropriate pointer operations). In pure functional language at logical level there is no modification of data, so one can safely share data structures. Internally implementation of pure functional language may use pointers, but they are invisible to programmer. Nice side effect of hidden pointers is that all data appears to be of the same size: for example list of 100 numbers is represented via pointer and the pointer can be stored in place of single number. When functional programming is mixed with imperative constructs sharing via hidden pointers becomes visible as changed semantics. This is called reference semantics. For example:

fricas
a1 := new(3, 1)$Vector(Integer)

\label{eq1}\left[ 1, \: 1, \: 1 \right](1)
Type: Vector(Integer)
fricas
a2 := a1

\label{eq2}\left[ 1, \: 1, \: 1 \right](2)
Type: Vector(Integer)
fricas
a2(2) := 3

\label{eq3}3(3)
Type: PositiveInteger?
fricas
a1

\label{eq4}\left[ 1, \: 3, \: 1 \right](4)
Type: Vector(Integer)

Above, modification to a2 is visible as modification to a1. This is because variable merely store reference to actual data. Assigment "a2 := a1" just copies reference, without any change to data.

In FriCAS all data have reference semantics. Integers are considered to be immutable objects so conceptually assigning new integer value to variable means that new integer value is created and reference to this integer is stored in variable. To optimize, small enough integers are stored directly in variables and implementation uses low-level tricks to distinguish references from integers. At higher level user sees the same behaviour, integers behave the same regardless if they are stored directly in variables or they are stored separately and variables only contains references. Similarly, boolean values are stored directly in variables. OTOH records, unions, lists and arrays always store actual data in separate area and variables just reference this extra data.

Reference semantics works well with functional style: as long as data is not modified after creation it can be safely shared and reference semantics means that in many cases sharing will be automatic. When modifying data one have to be careful to avoid unwanted modification. In particular, normally modification is applied to copy. Copying have to be explicit:

fricas
a3 := copy(a2)

\label{eq5}\left[ 1, \: 3, \: 1 \right](5)
Type: Vector(Integer)
fricas
a3(1) := 7

\label{eq6}7(6)
Type: PositiveInteger?
fricas
a1

\label{eq7}\left[ 1, \: 3, \: 1 \right](7)
Type: Vector(Integer)
fricas
a2

\label{eq8}\left[ 1, \: 3, \: 1 \right](8)
Type: Vector(Integer)
fricas
a3

\label{eq9}\left[ 7, \: 3, \: 1 \right](9)
Type: Vector(Integer)

Sometimes for efficiency FriCAS functions modify data pointed to by references. By convention functions doing this have ! at the end on name. When function is generic exact nature of modification and if it is beneficial depends on actual types. In such cases function return possibly new value (reference). It may point to old modified data, or may be new. For such functions users should use returned value, treating argument as possibly mangled. In terminology of Design By Contract contract of function involves returning reference to correct data, but function makes no promise about future usability of argument.