* formal array types and default values @ 2017-12-30 21:42 Mehdi Saada 2017-12-30 22:20 ` Niklas Holsti ` (3 more replies) 0 siblings, 4 replies; 13+ messages in thread From: Mehdi Saada @ 2017-12-30 21:42 UTC (permalink / raw) I have several questions more or less related. First: why aspect DEFAULT_COMPONENT_VALUE can apply only to components of scalar type ? It would be nice to be able to set a default value to an array type in a generic package, equal to a generic object parameter. type T_Vect_Coef is array (T_Degre range <>) of ELEMENT; gives that message: main.adb:21:22: unconstrained subtype not allowed (need initialization) main.adb:21:22: provide initial value or explicit array bounds ELEMENT and T_DEGRE are generic and declared like that: type ELEMENT is private; type T_DEGRE is range <>; Those two types are public. How can I give a default value, since DEFAULT_COMPONENT_VALUE doesn't apply to non scalar types. In the private part, the type type T_Polynome (Degre : T_Degre := 0) is -- type mutant record COEF : T_Vect_Coef (0..Degre) := (others => NULL_ELEMENT); end record; gives that warning: creation of "T_Polynome" object may raise Storage_Error. Why? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2017-12-30 21:42 formal array types and default values Mehdi Saada @ 2017-12-30 22:20 ` Niklas Holsti 2017-12-30 23:59 ` Mehdi Saada 2018-01-03 0:52 ` Randy Brukardt 2017-12-31 12:34 ` Jeffrey R. Carter ` (2 subsequent siblings) 3 siblings, 2 replies; 13+ messages in thread From: Niklas Holsti @ 2017-12-30 22:20 UTC (permalink / raw) On 17-12-30 23:42 , Mehdi Saada wrote: > I have several questions more or less related. > First: why aspect DEFAULT_COMPONENT_VALUE can apply only > to components of scalar type ? Don't know. Perhaps the thought was that if the component is a record type, then there is already a way to give default values to the components of the record type. However, the AARM explains that this is a representation attribute, and why that is so, and (therefore?) requires the default component value to be defined by a /static/ expression, which means that it can only be a scalar or a string. In principle, a string might define the default component value of an array with elements of a constrained String subtype, but that is probably not a very common case. > It would be nice to be able to set a default value to an array type > in a generic package, equal to a generic object parameter. Agreed. Possibly this case was forgotten, or prevented by such a generic object parameter not being a static value. > type T_Vect_Coef is array (T_Degre range <>) of ELEMENT; > gives that message: > main.adb:21:22: unconstrained subtype not allowed (need initialization) > main.adb:21:22: provide initial value or explicit array bounds I'm pretty sure that these messages don't come from the type declaration, but from some place where you declare a variable of this type, without giving bounds or an initial value, as in: Coef : T_Vect_Coef; As the index range of T_Vect_Coef is not constrained, the index bounds of Coef would be indeterminate. The messages are telling you to either provide index bounds, as in: Coef : T_Vect_Coef (0 .. 42); or to provide an initial value that then defines the index bounds, as in: Coef : T_Vect_Coef := (0 => 23, 1 => 66, 2 .. 15 => 0); > ELEMENT and T_DEGRE are generic and declared like that: > type ELEMENT is private; > type T_DEGRE is range <>; > > Those two types are public. Huh? If these types are generic formal types, I do not understand what you mean by "public". > How can I give a default value, since > DEFAULT_COMPONENT_VALUE doesn't apply to non scalar types. > > In the private part, > the type > type T_Polynome (Degre : T_Degre := 0) is -- type mutant > record > COEF : T_Vect_Coef (0..Degre) := (others => NULL_ELEMENT); > end record; > gives that warning: creation of "T_Polynome" object may raise Storage_Error. Why? Usually this error message means the following: - As an initial value was provided for Degre, it is possible to define unconstrained variables of type T_Polynome, and such a variable should be able to handle any value of Degre. - In order to handle any value of Degre, the variable will be sized according to maximum size that can be required, which here occurs for Degre = T_Degre'Last. (Some compilers will allocate the COEF component on the heap, according to the actual value of Degre, and then will not have this problem. However, GNAT uses the allocate-maximum-size method.) - But T_Degre'Last is (or can be) so large that it will be impossible to create a T_Polynome (Degre => T_Degre'Last), and therefore Storage_Error will be raised. The remedy is to place som reasonable upper bound on the maximum possible value of Degre, by defining the type of Degree with a reasonable 'Last. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2017-12-30 22:20 ` Niklas Holsti @ 2017-12-30 23:59 ` Mehdi Saada 2018-01-03 0:52 ` Randy Brukardt 1 sibling, 0 replies; 13+ messages in thread From: Mehdi Saada @ 2017-12-30 23:59 UTC (permalink / raw) > If these types are generic formal types, I do not understand what > you mean by "public". Sorry. The array is a public (as opposed to "private" ?) type, T_DEGRE and ELEMENT are formal generic parameters. > Some compilers will allocate the COEF component > on the heap, according to the actual value of Degre, and then will not > have this problem. However, GNAT uses the allocate-maximum-size method.) I would have liked to have the choice, through, say, an aspect Dynamic_Bounds_Checking, or somethin' > The remedy is to place som reasonable upper bound on the maximum > possible value of Degre, by defining the type of Degree with a > reasonable 'Last. It was indeed done initially in the package, but I thought I was smarter and removed it. Wrong... Thanks for your insight. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2017-12-30 22:20 ` Niklas Holsti 2017-12-30 23:59 ` Mehdi Saada @ 2018-01-03 0:52 ` Randy Brukardt 2018-01-03 8:33 ` Niklas Holsti 1 sibling, 1 reply; 13+ messages in thread From: Randy Brukardt @ 2018-01-03 0:52 UTC (permalink / raw) "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message news:faqhpnFljnfU1@mid.individual.net... > On 17-12-30 23:42 , Mehdi Saada wrote: >> I have several questions more or less related. > >> First: why aspect DEFAULT_COMPONENT_VALUE can apply only >> to components of scalar type ? > > Don't know. Perhaps the thought was that if the component is a record > type, then there is already a way to give default values to the components > of the record type. Correct; we didn't want multiple ways of doing the same thing. > However, the AARM explains that this is a representation attribute, and > why that is so, and (therefore?) requires the default component value to > be defined by a /static/ expression, which means that it can only be a > scalar or a string. In principle, a string might define the default > component value of an array with elements of a constrained String subtype, > but that is probably not a very common case. Correct again. We did worry a bit about there not being a good way to set a default for an array of arrays, but we decided those aren't very common and the default can always be set for the ultimate (non-array) element type. >> It would be nice to be able to set a default value to an array type >> in a generic package, equal to a generic object parameter. > > Agreed. Possibly this case was forgotten, or prevented by such a generic > object parameter not being a static value. Not really. All of these defaults for for a *type*, not a subtype, so there is only one per type. (There are thorny semantic problems with per-subtype defaults, we decided they were not worth the trouble.) Thus, it wouldn't make sense to specify it for generic formal parameters, as presumably the actual type already has such a default (and if it doesn't, you can't add one in the generic unit). Randy. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2018-01-03 0:52 ` Randy Brukardt @ 2018-01-03 8:33 ` Niklas Holsti 2018-01-03 20:53 ` Randy Brukardt 0 siblings, 1 reply; 13+ messages in thread From: Niklas Holsti @ 2018-01-03 8:33 UTC (permalink / raw) On 18-01-03 02:52 , Randy Brukardt wrote: > "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message > news:faqhpnFljnfU1@mid.individual.net... >> On 17-12-30 23:42 , Mehdi Saada wrote: >>> I have several questions more or less related. [snip] >>> It would be nice to be able to set a default value to an array type >>> in a generic package, equal to a generic object parameter. >> >> Agreed. Possibly this case was forgotten, or prevented by such a generic >> object parameter not being a static value. > > Not really. All of these defaults for for a *type*, not a subtype, so there > is only one per type. (There are thorny semantic problems with per-subtype > defaults, we decided they were not worth the trouble.) Thus, it wouldn't > make sense to specify it for generic formal parameters, as presumably the > actual type already has such a default (and if it doesn't, you can't add one > in the generic unit). I think that Mehdi Saada wanted to be able to set a default value for the components of an ordinary (not formal generic) array type declared /in/ the generic package, using a formal generic object as the default value. For example: generic type T is private; Null_Value : in T; package Foo is type Vector is array (Positive range <>) of T with Default_Component_Value => Null_Value; end Foo; Following the current rules, GNAT rejects this because Null_Value is not (always) a scalar. If the generic formal type T is changed to "type T is range <>", GNAT accepts the generic package declaration, but accepts an instantiation only if Null_Value is given a static expression (this is GNAT GPL 2012 on Mac). The drawback of the current restrictions (when T is private) is that the responsibility for the assignment of a default value for the components of the Vector type is placed on the /client/ of the generic package, who must set the default value for the actual type T. Moreover, it is now impossible to have different default component values for different arrays declared in the generic, because type T can have only one default value. One can imagine, for example, that T represents a value in some algebra that has both a "zero" value (neutral element for addition) and a "one" value (neutral element for multiplication), and that the generic package would like to use "zero" as the default component value for one array type ("array of sums") but use "one" as the default component value for another array type ("array of products"). -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2018-01-03 8:33 ` Niklas Holsti @ 2018-01-03 20:53 ` Randy Brukardt 2018-01-06 0:10 ` Niklas Holsti 0 siblings, 1 reply; 13+ messages in thread From: Randy Brukardt @ 2018-01-03 20:53 UTC (permalink / raw) "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message news:fb3iqsFnjd7U1@mid.individual.net... ... > generic > > type T is private; > > Null_Value : in T; > > package Foo is > > type Vector is array (Positive range <>) of T > with Default_Component_Value => Null_Value; > > end Foo; > > Following the current rules, GNAT rejects this because Null_Value is not > (always) a scalar. > > If the generic formal type T is changed to "type T is range <>", GNAT > accepts the generic package declaration, but accepts an instantiation only > if Null_Value is given a static expression (this is GNAT GPL 2012 on Mac). Correct. And you can't do it at all in the body (as a formal object will not be considered static there). I forget the reason that we required staticness, but I think it had something to do with when the default expression is evaluated. It seemed confusing to do it just once at the point of declaration (most Ada defaults are re-evaluated), but we didn't want to incur the expense of having to evaluate an expression for every initialization. (Plus, there are some points where that wouldn't be sensible.) So I think we just gave up and required staticness. (But I might be totally mis-remembering this.) > The drawback of the current restrictions (when T is private) is that the > responsibility for the assignment of a default value for the components of > the Vector type is placed on the /client/ of the generic package, who must > set the default value for the actual type T. Moreover, it is now > impossible to have different default component values for different arrays > declared in the generic, because type T can have only one default value. Defaults always belong to a type, so by definition, they are always set at the point of the type declaration. Subtype-specific defaults caused a nightmare of problems since not every object has a well-defined nominal subtype. Thus, if the client is defining the type, they have to define the defaults. QED. :-) As for the private type case, Ada is very strict about its contract model of generics, and we don't allow things that don't make sense. And defining a default component value of a non-scalar type doesn't make sense, because the component value can't be static. Thus it is never legal in a generic. We adopted the restrictions on these aspects (Default_Value and Default_Component_Value) in order to make them tractable. Had someone insisted on allowing subtypes and non-static values, they become too complex to describe and implement. (They have effects on parameter passing and in aggregates as well as the "obvious" effects). I most likely would have voted to kill them in that case, and I think others were leaning the same way. > One can imagine, for example, that T represents a value in some algebra > that has both a "zero" value (neutral element for addition) and a "one" > value (neutral element for multiplication), and that the generic package > would like to use "zero" as the default component value for one array type > ("array of sums") but use "one" as the default component value for another > array type ("array of products"). That problem is best solved by a reduction expression in Ada 2020, so no one will end up writing this generic anyway (they'll want to potentially parallel execution of a reduction expression). :-) In any case, a default value is a convinience feature; no one ought to be writing uninitialized object declarations in the first place. And the semantics of this is *very* complex in the general case (you want to remove both the staticness requirement and the scalar requirement). I don't think it is possibly worth the headaches. Randy. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2018-01-03 20:53 ` Randy Brukardt @ 2018-01-06 0:10 ` Niklas Holsti 2018-01-08 21:12 ` Randy Brukardt 0 siblings, 1 reply; 13+ messages in thread From: Niklas Holsti @ 2018-01-06 0:10 UTC (permalink / raw) While I am continuing this discussion of why the Default_Component_Value aspect is limited to scalars, and only to static scalar expressions, which is perhaps not of much interest, I first want to say that I am quite willing to believe the ARG if they reject or limit a new Ada feature because of implementation difficulty. The large effort required to implement and maintain an Ada compiler, compared to the relatively small market (whether paying or non-paying) for those compilers, is a challenge to the viability of the language. I would prefer to have more good compilers for the present language than to have nice new language features that are not generally implemented. On 18-01-03 22:53 , Randy Brukardt wrote: > "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message > news:fb3iqsFnjd7U1@mid.individual.net... > ... >> generic >> >> type T is private; >> >> Null_Value : in T; >> >> package Foo is >> >> type Vector is array (Positive range <>) of T >> with Default_Component_Value => Null_Value; >> >> end Foo; >> >> Following the current rules, GNAT rejects this because Null_Value >> is not (always) a scalar. >> >> If the generic formal type T is changed to "type T is range <>", >> GNAT accepts the generic package declaration, but accepts an >> instantiation only if Null_Value is given a static expression >> (this is GNAT GPL 2012 on Mac). > > Correct. And you can't do it at all in the body (as a formal object > will not be considered static there). > > I forget the reason that we required staticness, but I think it had > something to do with when the default expression is evaluated. From the discussion in AI05-0228, it seems to be related also to type freezing: Robert Dewar reported "huge problems" implementing the Default_Value aspect, and Randy Brukardt replied: "The key is to note that as these have to be static expressions, they can't involve the creation of any default-initialized objects (no user-defined function calls). Thus, I would suggest that the best approach would be to handle Default_Value aspects immediately *after* freezing of the type (but before anything else that depends on freezing." ... "If there is anything that would be a problem, the checking for a static expression will catch it." However, I found no discussion in the AI re *why* the AI was initially written to require a static expression for Default_Value, nor why Default_Component_Value is limited to scalars. > It seemed > confusing to do it just once at the point of declaration (most Ada defaults > are re-evaluated), but we didn't want to incur the expense of having to > evaluate an expression for every initialization. From the programmer's view, it would IMO have been preferable to make Default_Value and Default_Component_Value work more like the default values of record components. Of course that effect can still be achieved by wrapping the scalar values into single-component records, but that is rather inconvenient (in the AI, Bob Duff calls this wrapping "extremely painful"). Worrying about the expense should IMO have been left to the application designer, who can choose to use a static expression, or a precomputed non-static constant, if the expense would be important for the application. However, I do see that in a code-sharing generic, the expense of a non-static-expression Default_[Component_]Value, evaluated anew for every object or component to be initialized, could be quite a lot higher than for a static expression, for which the issue of evaluating once, or per each object/component, does not arise. Perhaps a good compromise, from the expense point of view, would have been to allow a non-static but constant expression, resulting in a single evaluation. >> The drawback of the current restrictions (when T is private) is that the >> responsibility for the assignment of a default value for the components of >> the Vector type is placed on the /client/ of the generic package, who must >> set the default value for the actual type T. Moreover, it is now >> impossible to have different default component values for different arrays >> declared in the generic, because type T can have only one default value. > > Defaults always belong to a type, so by definition, they are always set at > the point of the type declaration. Subtype-specific defaults caused a > nightmare of problems since not every object has a well-defined nominal > subtype. Yes, we already discussed that default values are per type and not per subtype. I did not mean to imply, above, that the "different arrays" would be merely different subtypes. They would be different array types, as in the example that followed. > Thus, if the client is defining the type, they have to define the > defaults. QED. :-) IMO the party who defines a type should be responsible for the initial default value. Here it is the _generic_ that defines the _array_ type, not the client, and the issue is the Default_Component_Value for the _array_ type. (Sorry, I don't know a suitable Latin acronym for "not QED".) > As for the private type case, Ada is very strict about its contract model of > generics, and we don't allow things that don't make sense. And defining a > default component value of a non-scalar type doesn't make sense, because the > component value can't be static. Thus it is never legal in a generic. That is not the question. The question that started this thread is *why* the Default_Component_Value must be (a) static and (b) a scalar, and the question was raised *because* these rules prevented the OP from writing the generic they wanted to write. > We adopted the restrictions on these aspects (Default_Value and > Default_Component_Value) in order to make them tractable. Had someone > insisted on allowing subtypes and non-static values, they become too complex > to describe and implement. (They have effects on parameter passing and in > aggregates as well as the "obvious" effects). I read the relevant ARM parts on parameter passing and aggregates and Default_[Component_]Value, but could not see anything that would require staticity or scalarity. For parameter passing, the issue seems to be only that the initial value of a formal "out" parameter passed by copy is now required to be the Default_Value of the actual parameter, implicitly "copied in" (RM6.4.1(5.1/4..5.3/4 and 13.1/4..13.4/4)). For aggregates, the issue seems to be only that a <> expression should use the Default_Component_Value, if specified for this array type (RM4.3.3(23.1/4)). > I most likely would have voted > to kill them in that case, and I think others were leaning the same way. Ok, as I said, if the issue was considered and the static scalar limitation chosen as the only feasible one, I certainly prefer to have the feature in this limited form, than not to have it at all. >> One can imagine, for example, that T represents a value in some algebra >> that has both a "zero" value (neutral element for addition) and a "one" >> value (neutral element for multiplication), and that the generic package >> would like to use "zero" as the default component value for one array type >> ("array of sums") but use "one" as the default component value for another >> array type ("array of products"). > > That problem is best solved by a reduction expression in Ada 2020, so no one > will end up writing this generic anyway (they'll want to potentially > parallel execution of a reduction expression). :-) You are diverting the discussion to a particular (poorly relevant) aspect of the example, rather than addressing the point. > In any case, a default value is a convinience feature; no one ought to be > writing uninitialized object declarations in the first place. I agree that uninitialized objects are poisonous, but I think that the ability to specify default initial values via the type system is an important means for avoiding such objects. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2018-01-06 0:10 ` Niklas Holsti @ 2018-01-08 21:12 ` Randy Brukardt 0 siblings, 0 replies; 13+ messages in thread From: Randy Brukardt @ 2018-01-08 21:12 UTC (permalink / raw) "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message news:fbaifmFd3gjU1@mid.individual.net... ... >> I forget the reason that we required staticness, but I think it had >> something to do with when the default expression is evaluated. > > From the discussion in AI05-0228, it seems to be related also to type > freezing: Robert Dewar reported "huge problems" implementing the > Default_Value aspect, and Randy Brukardt replied: "The key is to > note that as these have to be static expressions, they can't involve the > creation of any default-initialized objects (no user-defined function > calls). Thus, I would suggest that the best approach would be to handle > Default_Value aspects immediately *after* freezing of the type (but before > anything else that depends on freezing." ... "If there is anything that > would be a problem, the checking for a static expression will catch it." > > However, I found no discussion in the AI re *why* the AI was initially > written to require a static expression for Default_Value, nor why > Default_Component_Value is limited to scalars. My recollection was that it was more that the expressions involved had to be very restricted in order to avoid problems (perhaps the problems were with freezing). The easiest way to do that was to make the items static. BTW, if you want to follow all of the design issues that are recorded, you probably need to look at the meeting minutes as well as the AI. There is an index of meeting discussions on AIs found on the ARG Minutes page (http://www.ada-auth.org/arg-minutes.html). Randy. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2017-12-30 21:42 formal array types and default values Mehdi Saada 2017-12-30 22:20 ` Niklas Holsti @ 2017-12-31 12:34 ` Jeffrey R. Carter 2017-12-31 14:55 ` Mehdi Saada 2018-01-03 15:47 ` Mehdi Saada 2018-01-04 15:02 ` Mehdi Saada 3 siblings, 1 reply; 13+ messages in thread From: Jeffrey R. Carter @ 2017-12-31 12:34 UTC (permalink / raw) On 12/30/2017 10:42 PM, Mehdi Saada wrote: > > type T_Vect_Coef is array (T_Degre range <>) of ELEMENT; > gives that message: > main.adb:21:22: unconstrained subtype not allowed (need initialization) > main.adb:21:22: provide initial value or explicit array bounds I can't tell from the information you've provided (a small reproducer is usually a good idea), but this looks to me like the error msg GNAT gives for something like S : String; > type T_Polynome (Degre : T_Degre := 0) is -- type mutant > record > COEF : T_Vect_Coef (0..Degre) := (others => NULL_ELEMENT); > end record; > gives that warning: creation of "T_Polynome" object may raise Storage_Error. Why? Because the descriminant has a default, it's possible to declare V : T_Polynome; This initially has Degre => 0, but by full-record assignment, you can change the discriminant: V := (Degre => 42, Coef => (0 .. 42 => Something) ); There are 2 ways a compiler can implement this. Janus/Ada will put the Coef component on the heap (with bounds 0 .. 0), so that the part of the record that is on the stack will be a constant size. If you change the discriminant, it will deallocate the existing Coef and allocate a new one with the new bounds. This approach is easier to use, but adds some overhead. For most application domains on most modern computers, the difference is not significant. GNAT allocates space for the largest variant on the stack, and only uses the part needed by the current discriminant. When the discriminant changes, the part of the allocated space being used changes also. The stack is usually much smaller than the heap, and if T_Degre'Last is large, the amount of space to be allocated may exceed the size of the stack, resulting in Storage_Error. This approach avoids the overhead of heap allocation and deallocation, but is a bit less user friendly. Some people claim that Ichbiah (the designer of Ada 83) intended this to be implemented the way Janus/Ada does. The Alsys and Meridian compilers also did this, and Alsys was Ichbiah's company, so perhaps they're correct. On the other hand, the DEC compiler used the same technique as GNAT, and when I heard Ichbian talk about the DEC compiler he had only praise for it. In the absence of a requirement or even advice on how to implement this in the ARM, either approach is correct. There are application domains in which implicit heap allocation cannot be tolerated, but for most applications on modern computers with GB of RAM, the developer doesn't care where in RAM objects go, and it would be nice if compilers for such systems had a mode in which objects too large to fit on the stack would be automatically allocated on the heap. -- Jeff Carter "Of course, one couldn't think properly in Paris-- it was so uncomfortable and the houses were central heated." Clouds of Witness 153 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2017-12-31 12:34 ` Jeffrey R. Carter @ 2017-12-31 14:55 ` Mehdi Saada 0 siblings, 0 replies; 13+ messages in thread From: Mehdi Saada @ 2017-12-31 14:55 UTC (permalink / raw) No mystery, then. Indeed there a declared variable without initial value nor a constrained anonymous subtype. I saw it just before reading your precedent message, wrote a new, lost it, rewrote it, then forgot saying it again ! ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2017-12-30 21:42 formal array types and default values Mehdi Saada 2017-12-30 22:20 ` Niklas Holsti 2017-12-31 12:34 ` Jeffrey R. Carter @ 2018-01-03 15:47 ` Mehdi Saada 2018-01-03 21:16 ` Randy Brukardt 2018-01-04 15:02 ` Mehdi Saada 3 siblings, 1 reply; 13+ messages in thread From: Mehdi Saada @ 2018-01-03 15:47 UTC (permalink / raw) Let's make it a proposal for the next norm then. I'm half serious: depending on the difficulty, which I know nothing of, I am ok to help, however I can. Such a nice (and logical) feature, would a shame not to do. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2018-01-03 15:47 ` Mehdi Saada @ 2018-01-03 21:16 ` Randy Brukardt 0 siblings, 0 replies; 13+ messages in thread From: Randy Brukardt @ 2018-01-03 21:16 UTC (permalink / raw) "Mehdi Saada" <00120260a@gmail.com> wrote in message news:5c75fcdd-c965-4d03-9161-3576212e674d@googlegroups.com... > Let's make it a proposal for the next norm then. I'm half serious: > depending on the difficulty, > which I know nothing of, I am ok to help, however I can. > Such a nice (and logical) feature, would a shame not to do. You mean a useless feature. :-) (See my response to Niklas about the difficulty.) The primary purpose of Default_Value is to detect errors. Specifically, most enumeration types have (or could have) a value that means Unknown or Uninitialized. For instance: type My_Color is (Unknown, Black, Red, Green, Blue, White) with Default_Value => Unknown; With this declaration, any programming errors that fail to set an object of My_Color will show up as a value of "Unknown". Which can be reliably detected. Other uses of default values are evil, because they hide an operation that should always be explicit. For instance: type Evil_Integer is new Integer with Default_Value => 0; Since 0 is a legal, useful value of type Evil_Natural, some code might work by accident when an uninitialized object happened to get the right value by default. That sort of thing will not help future readers. Randy. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: formal array types and default values 2017-12-30 21:42 formal array types and default values Mehdi Saada ` (2 preceding siblings ...) 2018-01-03 15:47 ` Mehdi Saada @ 2018-01-04 15:02 ` Mehdi Saada 3 siblings, 0 replies; 13+ messages in thread From: Mehdi Saada @ 2018-01-04 15:02 UTC (permalink / raw) > Other uses of default values are evil, because they hide an operation that > should always be explicit. For instance: > type Evil_Integer is new Integer > with Default_Value => 0; > Since 0 is a legal, useful value of type Evil_Natural, some code might work by accident when an uninitialized object happened to get the right value by default. Indeed, I can see it makes sense. Instead of default value it's better to provide a constructor method to the package's client. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2018-01-08 21:12 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-12-30 21:42 formal array types and default values Mehdi Saada 2017-12-30 22:20 ` Niklas Holsti 2017-12-30 23:59 ` Mehdi Saada 2018-01-03 0:52 ` Randy Brukardt 2018-01-03 8:33 ` Niklas Holsti 2018-01-03 20:53 ` Randy Brukardt 2018-01-06 0:10 ` Niklas Holsti 2018-01-08 21:12 ` Randy Brukardt 2017-12-31 12:34 ` Jeffrey R. Carter 2017-12-31 14:55 ` Mehdi Saada 2018-01-03 15:47 ` Mehdi Saada 2018-01-03 21:16 ` Randy Brukardt 2018-01-04 15:02 ` Mehdi Saada
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox