Please note that, at least for now, devoting my full effort to a Java
IOC. I am redoing the wiki pages shown at the bottem of Benjamins
message in xhtml with revisions for Java. I hope to have this ready in a
few days.
One note about array support. The Java version will only support an
array type that is a 1 dim array. Multi-dimensional arrays will be
supported via a structure that has fields defining the number of array
attributes and an array field that holds the data. This greatly
simplifies arrays.
Benjamin Franksen wrote:
Hello All,
The current proposal for the definition of array fields in structs and
records [1] seems more complicated than necessary to me, while being in
some cases not expressive enough. I would like
to propose some simplifications and one addition.
I first describe my proposal and how it differs from the current
proposal. I will give detailed rationale below.
Proposal
========
1. Remove capacity declarations.
The current proposal allows array field declarations to fix a capacity
(or more than one capacity, for multi-dimensional arrays). I propose to
remove this from the dbd syntax. The current proposal for record
instance syntax already provides for setting capacities in addition to
initialization of array elements.
2. Disallow un-specified (variable) dimension.
The current proposal allows to leave the array's dimension un-specified.
I propose to forbid this.
Proposals (1) and (2) can be viewed and judged independent from the
following (3), (4) and (5). It is debatable whether (5) is very useful,
but if it is not and (3) is adopted, than (4) is a necessity, I think.
3. Disallow un-specified base type.
The current proposal allows to leave the type of the elements of an
array unspecified. I propose to disallow this. See proposals (4) or 5)
for a replacement.
4. Allow field types to be type variables.
I propose to allow struct and record declarations to specify one or more
type variables, over which the struct or record is parameterized. Type
variables that have been declared as parameters to a struct or record
may be used by subordinate field declarations everywhere a field type
is expected. Type variables must be instantiated (a) when defining a
record instance and (b) when a struct is used as a field type (in this
case, possibly with another type variable).
5. Add type 'any' to use for scalar fields as well as array base types.
I propose to add a base type 'any' that represents a union of all the
simple scalar types, i.e. all of {octet, bool, int16, int32, int64,
float32, float64, string}.
The resulting syntax is a lot simpler; the field type of an array field
always has the form:
array(dimension,baseType)
where
dimension: a positive integer, giving the array's dimension
baseType: type of the array's elements
Examples:
field type of 1-dimensional array of doubles
array(1,float64)
field type of 3-dimensional array of strings
array(3,string)
I propose to use angular brackets <a,b,c,...> for specifying type
parameters and arguments, as familiar from C++ 'templates' and Java
'generics'. Examples:
field type of 2-dimensional array of structs of type displayLimit<a>,
where type variable 'a' is instantiated to 'int32'
array(2,struct(displayLimit<int32>))
field declaration of 1-dimensional array of structs of type
displayLimit<a> where type variable 'a' is instantiated to anotehr type
variable 'b'
field(my2dimLimits, array(1,struct(displayLimit<b>)))
field declaration of a scalar field of type 'a' (which must be a
parameter to the surrounding struct or record):
field(x,a)
Declaring type parameters:
I propose that type parameters are specified like this
struct(name)<type-parameters> {
field...
}
resp.
record(name)<type-parameters> {
field...
}
where 'type-parameters' is a comma separated list of identifiers. Type
variables scope over the following {}-delimited block. It may be useful
to classify field types into categories such as 'scalar', 'number',
'integral', and 'floating', in order to allow type variables to be
constrained to belong to one of these categories. This could be done
using a syntax like
struct(name)<a:numeric, b:integral, c:scalar> {...}
with the following (predefined) categories:
integral = {int16, int32, int64}
floating = {float32, float64}
numeric = integral U floating
scalar = {octet, bool, string, any} U numeric
(where 'U' means 'set union'). Constraints propagate outwards, e.g. if
we have struct(displayLimits)<a:numeric> then every instantiation must
be constrained to 'numeric' or a subset thereof (including a concrete
element of 'numeric'). In particular, an unconstrained type variable
cannot be used as argument to a constrained type parameter. (These are
just the minimal conditions under which the system is sound). Note: I
am /not/ proposing that the user can add new categories. There will
only be a handfull of predefined ones.
To support instantiation of type variables at the record instance level,
the record instance syntax [2] must be extended like this:
waveform<float64> foo:bar:wave = {
...
}
Of course, the angular brackets can be left out in all cases where there
are not type variables to be declared or instantiated.
Rationale
=========
1. Remove capacity declarations.
I just don't see any justification for this. I would be very much
surprised if anyone can come up with an example of a record or struct
where it is /better/ to fix capacities statically for all times, as
opposed to dynamically, either at init time or at even during runtime.
The possibility to restrict the capacity from the outset reminds me of
the trouble we had in all existing EPICS version with string sizes that
had to be fixed in the record definition. Also, I can't see any
advantage for efficiency, since memory allocation for arrays has to be
dynamic anyway.
2. Disallow un-specified (variable) dimension.
Same as (1): I have great difficulties to imagine a real-world example
where this is useful or even necessary. Even in case someone actually
comes up with a convincing example, this could most probably be solved
by using separate fields for each possible dimension (i.e. one field
for 1-dimensional array, another for 2-dimensional, etc..); note that
memory overhead is insignificant for array fields that are not used
(i.e. with zero capacity).
3. Disallow un-specified base type.
4. Allow field types to be type variables.
These proposals actually belong together. My rationale is that this is
what the user really wants! There are very few situations where it
makes sense to have the type of a record field change at runtime. In
almost all cases, we really want to have the field types (whether array
or scalar) fixed at runtime, but nevertheless want to decide /per
record instance/ what the actual type will be. For structs, what we
want is to create generic re-usable building blocks for records (see
[3]). This is going to be an error-prone and annoyingly repetitive
exercise whithout the possibility to parameterize over field types.
5. Add type 'any' to use for scalar fields as well as array base types.
The rationale for this is that /if/ we think we must support field types
that change at runtime (which is, IMO, open to debate), then it is
inconsistent to allow this only for arrays and not for scalars, thereby
introducing additional syntax that applies only for arrays. The
additional type 'any' would solve the problem in a more systematic way
with no extra case for arrays (e.g. array(1,any) would be a valid field
type).
A last remark: I have deliberately not said anything about
implementation, in order to focus first on what we want, and also
because this message is already quite long. That said, I don't believe
implementation will cause great difficulties, even in languages that do
not have the concept of type variables built in, such as C. (Remember
that most of the code will be generated anyway.)
[1]http://www.aps.anl.gov/epics/wiki/index.php/V4_DBD_Statement_Syntax
[2]http://www.aps.anl.gov/epics/wiki/index.php/V4_DB_Record_Instance_Syntax
[3]http://www.aps.anl.gov/epics/wiki/index.php/V4_Design:_Assembling_Record_Support
Ben
- References:
- DBD Syntax (Arrays) Benjamin Franksen
- Navigate by Date:
- Prev:
DBD Syntax (Arrays) Benjamin Franksen
- Next:
3.15 C++ Exception classes Andrew Johnson
- Index:
2002
2003
2004
2005
<2006>
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
DBD Syntax (Arrays) Benjamin Franksen
- Next:
3.15 C++ Exception classes Andrew Johnson
- Index:
2002
2003
2004
2005
<2006>
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|