EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: DBD Syntax (Arrays)
From: Marty Kraimer <[email protected]>
To: Benjamin Franksen <[email protected]>, [email protected]
Date: Tue, 07 Feb 2006 06:27:28 -0500
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  <20062007  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  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·