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

Edit detail for ReferenceSemantics revision 1 of 2

1 2
Editor: test1
Time: 2016/11/14 21:49:22 GMT+0
Note:

changed:
-
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 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:
\begin{axiom}
a1 := new(3, 1)$Vector(Integer)
a2 := a1
a2(2) := 3
a1
\end{axiom}
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 bahaviour,
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:
\begin{axiom}
a3 := copy(a2)
a3(1) := 7
a1
a2
a3
\end{axiom}


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 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 bahaviour, 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)