Language Change Specification for FunctionKnowsVectorSize Proposal

LCS Number: LCS-2016-072
Version: 13
Date: 21-Oct-2016 (Ver 1), 21-Nov-2016 (Ver 2), 21-Dec-2016 (Ver 3), 2016-Dec-30 (Ver 4), 2017-Jan-4 (Ver 5) 2017-Jan-16 (Ver 6), 2017-Feb-8 (Ver 7), 2017-Feb-14 (Ver 8), 2017-Feb-15 (Ver 9), 2017-Feb-24 (Ver 10), 2017-Mar-14 (Ver 11), 2017-Mar-15 (Ver 12), 2017-Mar-16 (Ver 13)
Status:
Author: Kevin Jennings
Email: KevinJennings
Source Doc: FunctionKnowsVectorSize
Summary: Allow for functions to have access to attributes of the target of a function.

Voting Results: Cast your votes here

Yes:

  1. Kevin Jennings - 2016-11-07 - Ver 13
  2. Thomas Preusser - 2016-11-21 - ver 10
  3. Morten Zilmer - 2016-12-11
  4. Martin Thompson - 2016-12-12
  5. Martin Zabel - 2017-03-16 . Version 13

No:

  1. Ernst Christen - 2016-12-15 . Reasons below
  2. Jim Lewis - 2017-03-16 . Version 13. See comments. Also see LCS_2016_072b as a suggested revision
  3. Patrick Lehmann - 2017-03-20 - ver 13
  4. Rob Gaddi - 2017-03-21 - ver 13 - Can't get behind a type that only behaves like a type in some aspects but not in others. See 072c as a suggested revision

Abstain:

  1. Brent Hayhoe - 2017-02-16 Version 9 - Abstain due to lack of personal time for review.
  2. Ryan Hinton - 2016-12-21 lack of time

Details of Language Change

Refer to attachments. Twiki was not kind in regards to font colors and strikethrough. Word and PDF versions are attached.

-- Kevin Jennings - 2016-10-21

Comments

Would it not be intuitive to access the attributes of the return value through the name of the function instead of introducing a new name for a target?

-- Thomas Preusser - 2016-11-21

The added section 16.2.3.2 Predefined attributes of scalars appears to be off-topic. Anyhow, it is still not fully adjusted: (a) Delete index with the remaining references to index range, and (b) Remove the indirections through functions when accessing attributes that originally applied to the individual array dimensions. So, A'LENGTH is of type universal_integer rather than being a function that yields a universal_integer.

-- Thomas Preusser - 2016-11-21

Reusing the function name rather than creating a new name could cause a problem distinguishing between a reference to the function's target and a recursive call to an impure function that has no parameters.

-- Kevin Jennings - 2016-11-21

Is the name of the target used for anything else than accessing attributes of the destined return value? Would it appear anywhere without a tick mark? So, would the tick mark not establish the context that would distinguish the querying for an attribute and a recursive call when the function name would be reused?

-- Thomas Preusser - 2016-11-21

The added section 16.2.3.2 Predefined attributes of scalars is not really off topic, just hidden a bit. In the last paragraph of the 'Requirements' section of the proposal, I did float out the proposal to allow for scalar attributes and where they would be useful. When I wrote the LCS, I included that change since it is part of the proposal, it's been out on the Twiki for over two years, nobody objected and the proposal was 'approved' during the meetings to go ahead with writing up an LCS. Adding scalar attributes also eliminates the need for two other proposals: 'New Predefined Attributes: actual, and formal' and 'Expressions in Bit String Literals' as I mentioned on the 'Collected Requirements' page. I agree that it could've been written as a separate proposal and LCS. If there is significant disagreement about the two main ideas here they could be separated but in reality it would likely mean that one of the ideas just doesn't get implemented so the offending portion would just get deleted from the LCS.

In regards to your comment about using 'range' rather than 'index range', I agree and have changed that with Version 2 of this LCS.

In regards to your comment "Remove the indirections through functions when accessing attributes", I agree and have changed that with Version 2 of this LCS.

-- Kevin Jennings - 2016-11-21

In regards to "So, would the tick mark not establish the context that would distinguish the querying", the meeting discussions that were held on this proposal came up with using 'target' as defined in the LCS. I think using the function name as you mentioned was discussed but do not recall for sure.

-- Kevin Jennings - 2016-11-21

@ Thomas, not every function call passes parameters. In that case a function is simply its name without parenthesis.

-- Patrick Lehmann - 2016-12-09

This is clever, but will it work in practice ? You will need to declare functions twice: one with target and one without. And to find two different names as 'target' doesn't change the profile.

I don't see why signatures should be changed. There is no need to have a target to solve ambiguities.

What is the visibility and scope of target ?

-- Tristan Gingold - 2016-12-12

1. Declare functions twice? Yes, but there is also a benefit.

2. To find two different names as 'target' doesn't change the profile: I'm not sure what this comment is addressing or concerned about

3. I changed signatures since the signature distinguishes between overloaded subprograms.

4. Visibility and scope of target? See new material in section 'Page 20 Add after the first paragraph'

If the LRM should be changed in some other fashion to accomplish the goal of the proposal, please specify so the LCS can be made to be correct. Thanks.

-- Kevin Jennings - 2016-12-13

Tristan, I think that the signature situation, in practice, resolves itself. The whole idea is to avoid having to pass explicit sizing parameters, which means that the signature of the targeted and untargeted functions will differ.

  function TO_SIGNED(X : INTEGER, SIZE : NATURAL) return SIGNED;
  function TO_SIGNED(X : INTEGER) return myreturnthing : SIGNED;
  ...
  function TO_SIGNED(X : INTEGER) return myreturnthing : SIGNED is
  begin
    return TO_SIGNED(X, myreturnthing'length);
  end function TO_SIGNED;

Now, I think that if you had two functions undifferentiated but for a known target, that would be an error, the same as it currently would be to have to undifferentiated functions. But that shouldn't require an explicit statement in the LRM, that's just keeping existing behavior.

  -- ERROR: conflicts with TO_SIGNED(X : INTEGER, SIZE : NATURAL) return SIGNED;
  function TO_SIGNED(X: INTEGER, OFFSET: INTEGER) return differenttarget: SIGNED;

-- Rob Gaddi - 2016-12-14

This would be a very convenient feature to have! But I must vote against it in its current form.

Rationale for "NO" vote:

  1. (Changes to page 28:) The LCS modifies the rules for signature matching, not for overload resolution. In particular, requiring "the output of the function is assigned directly to a signal or a variable" is meaningless since "[a] signature can [only] be used in a subprogram instantiation declaration, attribute name, entity designator, or alias declaration" (first paragraph of section 4.5.3). I agree that this section needs to change, but in a different way.
  2. The LCS should change the definition of "same _parameter and result type profile_" definition on page 26, first paragraph of 4.5.1. It probably needs some text in the second paragraph of page 27. There may be more to properly adjust overload resolution to pick this new form for direct assignment/initial value calculation.
  3. I think you want an identifier for your return formal instead of a target. The target production includes an aggregate, which doesn't make sense in this context. (In particular, it has no attributes.)
  4. Nowhere in the proposal does it mention changing the LRM so attribute references retrieve the value from the actual. I sent an email to the reflector to help (me at least) understand the origins and ramifications of the current arrangement.
  5. Attributes of an object are accessible via the subtype attribute, e.g. X'SUBTYPE'HIGH from Rob's example above will give the highest value of the subtype of the formal X in VHDL-2008. (In this case just INTEGER'HIGH.) So the proposed section 16.2.3.3 is unnecessary and should be removed.
  6. The latter change to page 28 makes a signature matching dependent on how it's used, whether in an expression or in a direct assignment. This makes the grammar context-sensitive.

    Most programming languages are designed to be context-free grammars (CFGs), and this is generally considered a good thing. If I remember correctly from the last round of changes, VHDL is not currently in the CFG class. Still, it signals to me that this is likely to require significantly more work in the parser.

    Suggestion for improvement:

  7. To be consistent, this feature should be available in an initial value for a constant, signal, or variable as well as for assignment.

    The following is a minor annoyance. The source proposal references "another (as yet unwritten) proposal" for adding scalar attributes. It's a stretch to call this "part of the proposal" and push it into the LCS. I did read this LCS during the two years that it was up, and I would have commented had it been part of the proposal, not just a notional reference to a to-be-written proposal. (You used stronger language in making a very similar argument in an email you sent 30 Apr 2014. smile

    -- Ryan Hinton - 2016-12-15

    Rob, I agree with you. So why do we need to have the target in the signature ? That's useless!

    -- Tristan Gingold - 2016-12-15

    Kevin, can we declare this function: function to_signed (a : integer) return a : signed; I think nothing in this proposal makes this declaration invalid. The problem is that target is not described.

    -- Tristan Gingold - 2016-12-15

    @Patrick: Your statement is true but I miss the relation to any of my comments. I would just rely on a function having a name and returning a value.

    -- Thomas Preusser - 2016-12-15

    This proposal seems to be incomplete, and it has several issues.
  • [target :] is in bold. According to the general convention, this would make target a new reserved word, but the LCS does not address this issue (i.e. there is no change to subclause 15.10). What does it mean for the colon and brackets to be in bold?
  • If the boldness of [target :] is an oversight and target is intended to be the name of a production, this production is missing, so it's not clear what form this target can take. Should it be [ identifier : ] with a semantic rule that states that this identifier is a symbolic name for the target of the function call?
  • If the target is in fact an identifier, how does it become visible in the subprogram body? There are currently no changes to clause 12 in this LCS.
  • A comma should be added after the text inserted in the first paragraph on p.20 (minor)
  • The new paragraph on p.20 has the form of a note, not a definition ( it can be used ). This is the place to state how the (symbolic) target gets the attributes of the real target.
  • The changes of p.21 are in the notes. These have no semantic meaning, and just changing a note cannot accomplish what is described there, that attributes of the actuals are being read instead of those of the formal as it is today.
  • If we are after the attributes of the actual, what if the actual is of type universal_integer or universal_real?
  • I second Ryan's comment on the need for the target in the signature: it has no business to be there.
  • The proposed change on p.28 bottom seems to apply to all function calls because for a signature to match the parameter and result type profile these two additional conditions have to be met. It now follows that no signature can match a function call that appears as a term in an expression.
  • Attributes on scalars: The symbolic prefix A for predefined attributes of scalars is misleading as A stands for an array object. Another symbolic prefix should be used.
  • It seems that this proposal allows functions to be defined that have restrictions where they can be called. This is highly undesirable.
    • What happens if a function that reads attributes of its (symbolic) target is called as a term in an expression
    • Similarly, what if an initial value expression of an object with an unconstrained type is such a function call?
  • Should there be restrictions for resolution functions?
  • How does this apparatus interact with the concept of generic subprograms? Let's postulate a generic subprogram reads attribute 'left of its first parameter. If the subprogram gets instantiated with a scalar type for this parameter, 'left denotes the left bound of the object. For an instantiation with an array type, 'left now denotes the left bound of the index range. If this isn't confusing, what if the instantiation occurs with a record type? I grant that this is an unlikely scenario, but there is nothing in the language today that precludes it.

    -- Ernst Christen - 2016-12-15

    Version 3 (still a draft at this time) changes:

    - @Several: Not sure what to do with Page 28 and 'Signatures'. The idea that I'm trying to get across is that there are known situations where this type of function cannot be used because the output of the function feeds into an expression. A simple example would be "My_uns := to_unsigned(1) + to_unsigned(2);". What needs to change in the LRM to define this limitation? Eliminated 'Signatures', I thought it belonged, but apparently not.

    - @Tristan: "function to_signed (a : integer) return a : signed; I think nothing in this proposal makes this declaration invalid. The problem is that target is not described". There could be a couple of different resolutions here, which one makes most sense? 1. Declare a warning or error if 'target' is not distinct from each of the parameters? 2. 'Target a' hides 'parameter a'. 3. Something else?

    - @Ryan #1 "To be consistent, this feature should be available in an initial value for a constant, signal, or variable as well as for assignment" KJ: In what way is what I've written make this not available to use for an initial value for a constant, signal, or variable?

    - @Ryan #2 "same _parameter and result type profile_", still figuring out what this means, list-o-things-to-do

    - @Ryan #3: "I think you want an identifier for your return formal instead of a target. You're probably right, list-o-things-to-do. KJ: Changed to identifier, 2016-12-20.

    - @Ryan #4: "Nowhere in the proposal does it mention changing the LRM so attribute references retrieve the value from the actual". KJ: Added change to section 4.2.2.2 Constant and variable parameters

    - @Ryan #5: "Attributes of an object are accessible via the subtype attribute". Getting the attributes of the subtype is not what is desired here. The proposal is trying to get at the attributes of the actual so if you have "signal x: integer range 5 to 10;", and x is passed into a function MyFunc (y:integer) as MyFunc (y > x), the proposal is trying to retrieve y'left as 5, y'right as 10. It is not trying to get the left and right attributes of the subtype integer.

    - @Ryan #6: "...change to page 28 makes a signature matching dependent on how it's used". KJ: Changes to 'Signatures' removed.

    - @Ernst #1: bold format on [target :] KJ: Removed, the bold was unintentional.

    - @Ernst #2: "target is intended to be the name of a production, this production is missing", list-o-things-to-do. KJ: Changed to identifier, 2016-12-20.

    - @Ernst #3: "become visible in the subprogram body? There are currently no changes to clause 12", list-o-things-to-do KJ: Added on page 186, 2016-12-20.

    - @Ernst #4: "A comma should be added" Should be added after "(if any)" in the text "retrieve attributes of the target (if any) the subtype of" or someplace else? KJ: Added a comma 2016-12-20

    - @Ernst #5: "The new paragraph on p.20 has the form of a note, not a definition", KJ: Not sure what are you referring to. If you meant page 21 instead, then the 'non-note' portion is addressed with changes to section 4.2.2.2 Constant and variable parameters

    - @Ernst #6: "The changes of p.21 are in the notes. These have no semantic meaning...", KJ: Added change to section 4.2.2.2 Constant and variable parameters

    - @Ernst #7: "If we are after the attributes of the actual, what if the actual is of type universal_integer or universal_real". If a literal such as the number 3 is passed in (which is the only way one could get universal_integer, right?), then the proposal would expect attributes of the 'actual', to be generated. So for function MyFunc (y:integer) as MyFunc (y => 3), the proposal would expect y'left = y'right = y'low = y'right = 3. Unless my changes to 4.2.2.2 do the trick, I'm not sure how/where to specify that behavior but that would be the intent of the proposal.

    - @Ernst #8, 9: "comment on the need for the target in the signature", KJ: Changes to 'Signatures' have been removed.

    - @Ernst #10: "The symbolic prefix A for predefined attributes of scalars is misleading". Changed to 'S' for scalar.

    - @Ernst #11: "It seems that this proposal allows functions to be defined that have restrictions where they can be called. This is highly undesirable.". KJ: It is also undesirable to have to provide parameters to a function to tell the function something that the user can clearly see (i.e. y < to_unsigned(3, y'length), and many use cases when using the fixed point package where one has to pass in ranges). The current practice can lead to latent design errors in addition to making the code less readable. Nobody has come up with a better way to accomplish the goal of the proposal yet which is to remove something that really shouldn't be needed.

    @ Ernst #11 sub-bullets "What happens if a function that reads attributes of its (symbolic) target is called as a term in an expression" KJ: Refer to changes to section 4.2.2.2

    - @Ernst #12: "Should there be restrictions for resolution functions?" KJ: I don't know, is there a reason that they should?

    - @Ernst #13: "what if the instantiation occurs with a record type?" KJ: I'm not sure I follow what you're getting at with this bullet and this question in particular. Scalar attributes would return the bounds of the scalar range (this is the new thing), array attributes would return the index range as they do today. Also available to the user today is the ability to get at the attributes of the subtype of a parameter. In all of these instances, these attributes are useful to the user. What exactly is your concern here?

    -- Kevin Jennings - 2016-12-16

    It appears that much of the red font marking changes has been lost. KJ: Fixed 2016-12-20, but no idea whether it will stick this time or not.

    - Reply to @Tristan: Can you point to the text that makes this invalid within existing interface lists? procedure foo(a:integer, a:integer);

    - Reply to @Ryan #3, applicable to several other comments by several authors (e.g. @Ernst #2): The target production is listed in Annex C (syntax summary) and references 10.5.2.1. So the grammar symbol is valid, but it allows for an aggregate, which seems wrong to me. That's why I suggested replacing the target symbol with the identifier symbol as in the other interface_list productions.

    - Reply to @Ryan #4: LRM 4.2.2.2 (page 21) discusses that parameters of class constant and variable can be passed by value in many cases. This tells me that the formal identifier in a subprogram declaration is its own object, not just an alias to the actual. So when you ask for x'subtype'left inside a subprogram, you get the attribute from the formal x, not from the actual associated with x. So changing 4.2.2.2 should be included in your list-o-things-to-do. See also the reflector discussion last week with subject "Subprogram attribute values come from formal".

    - Reply to @Ryan #5: LRM 6.3 states, "A subtype indication defines a subtype of the base type of the type mark." (Emphasis mine.) If you take a look at the signal declaration rule, signal x: integer range 5 to 10;, the integer range 5 to 10 is a subtype indication, and defines a subtype of integer. When the tool evaluates x'subtype'left, it will give 5, not integer'left. (I confirmed this in a tool that typically implements the standard correctly.) The mechanism is the same when x is declared as a constrained sfixed object: the constraints in its declaration infer a new subtype specifically for x (unless no constraints are applied).

    - Reply to @Ernst #7: We can't use type universal_integer on an interface list, so the actual coming in will already have an implicit conversion to integer. Right?

    -- Ryan Hinton - 2016-12-19

    Reply to @Ryan #5: LRM 6.3 states, "A subtype indication defines a subtype of the base type of the type mark." (Emphasis mine.) If you take a look at the signal declaration rule, signal x: integer range 5 to 10;, the integer range 5 to 10 is a subtype indication, and defines a subtype of integer. When the tool evaluates x'subtype'left, it will give 5, not integer'left. (I confirmed this in a tool that typically implements the standard correctly.)

    KJ reply: But this is not the case within a subprogram. In a subprogram, x'subtype'left returns the 'left attribute of the formal type integer (-2147483648), not the 'left attribute of the constrained actual (5). Below is sample code and output, using tool M, do you want to check it your tool?

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end foo;
architecture RTL of foo is
    signal a:   integer range 1 to 5;
    function foo_fn(x: integer) return integer is
    begin
        report "x'subtype'left=" & integer'image(x'subtype'left) & " x'subtype'right=" & integer'image(x'subtype'right);
        return(x);
    end function foo_fn;
begin
    process
        variable b: integer range 2 to 6;
    begin
        wait for 1 ns;
        report "a'subtype'left=" & integer'image(a'subtype'left) & " a'subtype'right=" & integer'image(a'subtype'right);
        report "b'subtype'left=" & integer'image(b'subtype'left) & " b'subtype'right=" & integer'image(b'subtype'right);
        b := foo_fn(b);
        wait;
    end process;
end RTL;
...
# Loading work.foo(rtl)
# ** Note: a'subtype'left=1 a'subtype'right=5
# ** Note: b'subtype'left=2 b'subtype'right=6
# ** Note: x'subtype'left=-2147483648 x'subtype'right=2147483647

-- Kevin Jennings - 2016-12-19

That's a great example of comments @Ryan #4 and @Ryan #5. (@Ryan #5:) You show that objects a and b can get their ranges (aka attributes, constraints, subtype information) directly from the scalar objects instead of from a scalar type. This means that your proposed section 16.2.3.2 is unnecessary. Also, you show (@Ryan #4) that object b is copied by value into function foo parameter x. x is an object of subtype integer. So evaluating its attributes give the range for the integer type. This is why I suggest that your next draft should include changes to 4.2.2.2 where the pass-by-value semantics are given. This will help achieve the effect you were trying to get by modifying the text of the note preceding 4.2.2.2.

-- Ryan Hinton - 2016-12-19

I don't see how you can conclude "This means that your proposed section 16.2.3.2 is unnecessary". The example shows that, within the function, there is currently no way to get at the actual bounds of a parameter (which is what I'm after), so some change is required to implement the proposal. While x'subtype'left returns the bounds of x within the context where x is declared, it does not work inside a subprogram that is called with the parameter set to x. If it did, then the last report statement would have printed "x'subtype'left=2 x'subtype'right=6" rather than printing the bounds of an integer.

The change I proposed is to allow scalar attributes to be accessible and one can access those attributes in the same manner regardless of context and does not break backwards compatibility (i.e. x'subtype'left would still return the bounds of the subtype of the formal when used within a function as it does today). Scalars already have these attributes so that bounds checking can be performed, they are just not called as such in the LRM at present.

-- Kevin Jennings - 2016-12-20

My point is that x inside the function is its own object. Calling x'subtype'left will give exactly the same thing as your proposed x'left. A scalar does not have attributes. It has a value and a subtype. Defining an attribute 'LEFT on a scalar will have to get its "return value" from the subtype of that scalar.

Defining attributes on scalars will not get you the attributes of the formal since constant and variable parameters are passed by value in many cases. You're working on the right problem, but the solution you propose is unrelated.

-- Ryan Hinton - 2016-12-20

RH: Calling x'subtype'left will give exactly the same thing as your proposed x'left. KJ: Not once this LCS gets written up correctly it won't.

RH:: A scalar does not have attributes KJ: But they could have attributes, that's what I'm trying to get added. Putting aside constants and expressions for the moment, a parameter input to a function will have a declaration associated with it. That declaration will define the attributes that are available to be used. The changes I've made to 4.2.2.2 and 4.2.2.3 now address what to do with constants, expressions as well as variables and signals.

RH: Defining attributes on scalars will not get you the attributes of the formal since constant and variable parameters are passed by value in many cases KJ: Did you mean to say formal in the above? If so, then getting the attributes of the formal would be the same as today (i.e. x'subtype'left for example), no change intended. If you meant actual instead of formal, then it's not clear to me how my solution is unrelated. Incomplete or incorrect, OK, but not seeing it as unrelated.

In any case, I've made several edits to address the concerns from you, Ernst and Tristan, summarized along with how I addressed the points in my updated comment above from 2016-12-16. Calling this Version 3. Please review and create new comments below. As you did previously, numbering the issues makes for a handy way to refer to them which in turn helps to get them all addressed.

-- Kevin Jennings - 2016-12-21

RHv3#1 Page 21. I hope one of the tool implementors will chime in here. KJ reply: I agree, Tristan has visited and commented, not sure who are other tool implementors that are in the audience. RH: As far as I know, attributes are never assigned. The attributes come from the subtype. For scalar formals, the subtype of the formal is given in its "declaration" in the interface list. It sounds like what you're asking for is to change the subtype from their declaration. It feels wrong to me to see an input x of subtype integer, but the tool changes its subtype for each call. I suppose it's not that different from what happens with unconstrained array formals. KJ reply: I'm not trying to change anything existing. I'm trying to get information that I know is currently available to the tool by virtue of the existing requirement on the tool to insure that function parameter actuals are within the range of the function parameter formals. I'm trying to use that information to perform something that is new and I think a useful function.

RHv3#2 general suggestion. I suggest you split off the scalar attributes and related changes into an independent LCS. The title of the proposal is "Method to allow functions to know the output vector size." I agree that this would be a great feature to have. I can remember only a handful of times where knowing the input subtype would be similarly useful. Really they are two different changes and deserve to be voted independently. For what it's worth, I like the 'actual and 'formal approach much better -- it seems a MUCH easier change to implement. (I would create one new attribute, 'subtype_actual to get access to the subtype of the actual similar to the current 'subtype which gives the subtype of the formal.) KJ reply: The ideas are a bit more linked than perhaps you've considered. When writing the proposal, and later the LCS, it immediately becomes apparent that one needs to have a mechanism to refer to the attributes of the target itself, not to the type/subtype of the target. What I used here as my mental model, is that the end user should think of the 'target' as being like another input that is available to the function, but an input where the only legal actions are to refer to attributes. The most straightforward way then to get at the length attribute (for example) then would be as "target'length" which would be the exact same form that one would use outside the function. Now, given this model that treats 'target' as being just another (but somewhat restricted) input parameter, it is a small leap to then say that if one were to want to refer to the attributes of the actual (not the subtype of the actual) that one would want to also use the same form "parameter'left". There are proposals such as NewPredefinedAttributeActual that do indicate demand for the same thing that I'm trying to get implemented here in this LCS with function parameters. I think it would be a mistake to require the end user to use different syntax to get at the attributes of the target (which is needed for this proposal/LCS) and the attributes of the parameters passed into a function which is also different than how one accesses the attributes of an object outside of the context of a function. If this LCS was split in two, then there would either have to be a dependency of this LCS on that new LCS (or some alternate proposal/LCS such as NewPredefinedAttributeActual) otherwise one risks coming up with different mechanisms for the end user to simply be able to access attributes of something. I don't think that's a good thing. I do all of this without introducing new keywords unlike NewPredefinedAttributeActual so that's a bonus as well. Because a new keyword is created, NewPredefinedAttributeActual is not going to be backwards compatible and could break existing code (although I admit it is probably not terribly likely).

RHv3#3 Page 21 editorial note. I suggest replacing the colon in the first new sentence with a comma and making the following "If" lower-case. This makes it correct grammatically and follows the pattern of the nearby paragraphs. KJ reply: Fixed.

RHv3#4 Page 21. I don't understand why you have distinct cases for "if the actual is an identifier" and "otherwise." In your big addition for page 20, you specify that only the "otherwise" attributes may be used. KJ reply: What I'm trying to get across is that when the parameter actual to a function is an identified object such as "signal FingerCount: natural range 1 to 10;" then the new attributes that get passed into the function are the attributes of FingerCount (i.e. left=1; right=10). I'm covering this situation with "the attributes of the parameter shall be assigned from the corresponding attributes of the actual". However, if the input to the function is an expression or a literal, then you don't immediately have those attributes. What I was covering with the "Otherwise..." is the case for when a literal is assigned to the parameter. In a sense, the tool is fabricating attributes for the literal in order to be able to pass them into the function, but I think what I specified is straightforward. I do see though that what I have does not cover the case where the function parameter comes from an expression. I'll have to ponder a bit on how to word that and add that into that same area of the LRM. If you have some preferred wording, feel free to suggest something.

RHv3#5 Page 244. You missed red markings on "scalar" in S'LEFT. Also, a scalar subtype doesn't have "ranges"; it has a "range" (singular, not plural). KJ reply: Instnaces of "ranges are" changed to "range is". Twiki keeps mangling and removing font coloring. I found a whole bunch of black font "scalar" that I know had been red. <RANT>I think we would have been far better off using PDF attachments for the LCS as I had originally done and not try to use a tool such as Twiki which destroys things randomly. The coloring is important and Twiki keeps messing it up for no apparent reason. I'm tired of having to recolor things that had been colored.</RANT>

RHv3#6 Page 244. The result type should be the base type of the scalar or scalar subtype. KJ reply: I'm not sure I follow or whether you're referring to all of the result types or just one. In any case, I think what I have is correct since it was based on existing LRM text and simply removing array referencing. Can you clarify a bit about what exactly is wrong? Is it actually 'wrong' or just not how you would word it?

RHv3#7 Section 16 changes. I still object to adding all this text because it doesn't provide anything not already available via S'SUBTYPE'attr. From my best guess of your intent, the subtype of the formal will be the subtype of the actual. So x'subtype'left will still be the same as x'left: both will refer to the subtype of the actual instead of the subtype of the formal (current behavior of the former). KJ reply: With the current LRM, x'subtype'left does not return what is needed, when used within a function. Please refer back to the sample code that I posted. Within the architecture and the process if one has signal xyz: integer range 1 to 5 then x'subtype'left = x'left = 1, but when xyz is passed into a function such as Func(x: integer) as Func(x=>xyz) then x'subtype'left returns the left bound of integer and there is no mechanism for the function to know that the left bound of the actual that is bound to x is actually 1. What I'm adding is that inside a function you will now be able to refer to xyz'left which is currently illegal so there will be no backwards compatiblity issues with doing so. Now it will be legal syntax in a function and will return the left bound of the actual that is assigned to parameter x which, in this case, is the left bound of xyz, which is 1. So this is providing something new and doing so in a way that makes currently illegal syntax legal and useful.

(#7 cont.) Perhaps you're intending x'subtype'left to continue to give the left bound of the subtype of the formal while x'left gives the left bound of the subtype of the actual. KJ reply: If you mean the '1' in signal xyz: integer range 1 to 10; and xyz is passed into a function then YES!" RH: I'll vote against that as against the "do it explicitly" spirit of VHDL. Nothing about x'left suggests to me that the tool is reaching outside the scope of the subprogram to grab attributes from the subtype of the actual. *KJ reply: x'left suggests to me the obvious which is that it is retrieving the left bound of x, not the left bound of the subtype of x. As you've already stated, you like the idea (but not the method) being presented here of being able to access the attributes of the actual and you have had very little use for accessing the attributes of the subtype which was added in 2008. That has been my experience as well. Based on the limited polling of two people, this suggests that what was added in 2008 is possibly of limited use to an end user. I think there is quite a bit of value for the end user in being able to use the exact same syntax (i.e. xyz'left) regardless of the context. It works the same whether you're in an architecture, a process or a subprogram. I can't sway you if your reason is 'against that as against the "do it explicitly" spirit of VHDL' but I will say that reason is not a technical one that can be resolved technically. That will take either gentle persuasion, arm twisting or pistols at 20 paces.

(#7 cont.) An object has a value and a subtype. "An object is a named entity that contains (has) a value of a type." (6.4.1) It does not have a range. (Point me to the LRM if I'm wrong.) KJ reply: But an object also has attributes hence xyz'left does return the left bound of an integer. RH: The text "Left bound of the range of S" is nonsense because a scalar object S has no range defined in the language. These changes reference concepts that don't exist. If you want x'left to return the left bound of the subtype of x (formal or actual), your changes are still incomplete. KJ reply: OK, so taking one sample, can you suggest wording that is correct?

Currently in LCS: "Result type: Type of the left bound of the Nth index range of SA"

Noting that section 5.2.1 Scalar Types - General does refer to 'range' which is the usage that I'm intending.

range_constraint ::= range range
range ::=
       range_attribute_name
     | simple_expression direction simple_expression

(#7 cont.) Arrays are fundamentally different in this respect. A scalar object of an appropriate integer subtype may contain the value 3. 3 doesn't have a range. On the other hand, an object of an appropriate bit_vector subtype may contain the value (4 to 7 => "1011"). An array value obviously has a length. In fact, the LRM gives array values an index range as well, as anyone who's used the fixed_pkg can attest. Scalar values in expressions are handled according to their base type (see the enhanced integer discussions). Array values keep their bounds in expressions. On assignment, an implicit subtype conversion occurs for arrays and a subtype check occurs for scalars (5.3.2.2, 10.6.2.1, 14.7.3.4, etc.). KJ reply: OK, but not seeing the relevance to this LCS so not seeing anything that is actionable here.

(#7 cont.) I don't see an easy way to change this difference between array and scalar values. That's why I would prefer a variant of the 'actual attribute proposal ( NewPredefinedAttributeActual). That's why I suggest splitting out the scalar attributes portion of this LCS that is supposed to be about vector sizes. KJ reply: OK, I prefer not to add keywords and possibly break backwards compatiblity and to provide the end user the same syntax to get at attributes regardless of context. Your preference is noted but is not a technical point that I can respond to so I think we will have to simply have to agree to disagree.

RHv3#8. You have specified in your page 20 changes when a function with a named return value should be called. This should be done instead by modifying the overloading rules and signature rules in 4.5. Possibly 12.5 may need to be changed also. KJ reply: To be blunt and honest, I don't know what the heck needs to change in order to get across the point that there can be instances where using this new form of function is not allowed. Not asking you in particular to do this, but I've taken two swings at it and missed both times so I think I need some help from somebody to define this limitation properly.

RHv3#9 Page 186. I would put the formal return identifier at position (d) in the list next to the formal parameter declaration. KJ reply: I put it at the end of the list so as not to break anything. There are LRM references to some of the labeled bullet items so I would prefer not to insert in the middle and shift the others down and then accidentally miss updating a reference. The list is not a priority order, there is a flow to it, but that flow is cosmetic.

KJ general: Thanks for all your input, it is helping. It appears to me that we are having fewer technical objections as the LCS gets revised which is good, progress is being made and hopefully get to a point of no technical disagreements. Can't help much with the non-technical other than to explain my reasoning and thought process.

-- Ryan Hinton - 2016-12-21

with KJ replies KevinJennings 2016-12-23

Version 4 created 29-Dec-2016. Changes are:

- Wording regarding the context where the new function type may be used.

- The section regarding attributes of scalars and accessing them within a function has been moved to a new LCS (LCS-2016-072a).

-- Kevin Jennings - 2016-12-30

Version 5 created. Changes are:

- Define that the types of targets includes scalar objects. This was inadvertantly dropped when the LCS was split to create LCS-2016-072a. This creates a dependency with LCS-2016-072a. The contingency if LCS-2016-072a is not approved is documented in the notes.

-- Kevin Jennings - 2017-01-05

Thanks for re-focusing on the return value. This looks very good now!

-- Thomas Preusser - 2017-01-13

Version 6 created, changes are: - Changed 'identifier' to 'return_identifier' - Clarified usage of 'return_identifier' to be as a prefix to retrieve object attributes rather than as a variable that is limited only retrieving attributes - Added RANGE and REVERSE_RANGE to the list of scalar object attributes that can be retrieved.

-- Kevin Jennings - 2017-01-16

LCS 072 - ver 6: If the target is an array, the target must meet one of the conditions…

PL: You shouldn’t refer to the target and ask if it’s an array. You already know the return type and it’s type class (scalar, array, ...). So your textual case list should use the return type’s type class. E.g. If the return type is an array type, the target should meet one of the conditions ... This particular function, wouldn't be selected, if the return types doesn't match the target type (=> overload resolution).

-- Patrick Lehmann - 2017-01-16

Extending on Patrick's last comment, the sentence "If the target is an array, the target must meet one of the conditions…" (page 20) must be reworded at all.

It is not the target which can meet one of the cases of `Determinable index range conditions' (9.3.3.3). At the moment, the list defines where an array aggregate with an others choice can be used. Thus, if you want to reuse it, then the list will also define where a function with an return identifier can be called. Just take a look at case f) which reads "as the expression defining the initial value [...]". Thus, the above mentioned sentence in your LCS should be reworded to:

If the return type denotes an array type, then the function call shall appear only in one of the conditions of ‘Determinable index range conditions’ as listed in section 9.3.3.3 -- Array aggregates.

The list also contains cases, where the target is not an object, e.g., case d). In this case the function can be called as follows:

function f (x : integer) return target : unsigned is
begin
    return to_unsigned(x, target'length);
end function f;

function g(x : integer) return unsigned(7 downto 0) is
  constant c : unsigned(7 downto 0) := f(7); -- here the target of f() is an object
begin
    return f(x); -- here the target of f() is a subtype
end function g;

Thus the prefix "x" in "x'left" in function f may denote a subtype as well. Ok, this example should actually work, because the predefined attributes for arrays are defined for array objects as well as fully constrained array subtypes. The other cases of `Determinable index range conditions’ must be checked as well (maybe I will find some time later on.)

I haven't yet checked the conditions when the result type denotes a scalar type because I'm still reasoning about LCS-2016-072a.

-- Martin Zabel - 2017-01-21

Version 7 created, changes are:

- Changed wording "If the target is an array" to "If return type denotes an array type" to address Martin (and Patrick's?) concern

@Martin:

- I can't really reference the list from 9.3.3.3 since sub-bullets j) and k) do not apply here.

- Your example "function g(x : integer) return unsigned(7 downto 0)" is not legal since the return type must be a type mark not a subtype indication.

- To your point about bullet d), in order to get "the corresponding function result type is a fully constrained subtype", one would need to define a new (sub)type that is fully constrained, not use something that is unconstrained like 'unsigned'. In any case, I think bullet d) does apply here for this LCS.

-- Kevin Jennings - 2017-02-08

Rev 7 EDIT2: page 20, first paragraph

Suggested simplification:

The reason the terminal "return_identifier" has a unique name is so you can reference it in the text. Hence, rather than "the name that the function body may reference to retrieve attributes of the target (if any)," you can simply say "return identifier (if any)". Note when you reference a EBNF term, you do not include the "_".

Rev 7: Edit 3: the added paragraph on page 20,

Potential Issue: I am not sure you can use the term target here as I usually associate that with the target of a assignment, however, I do note type conversions talk about the target of the conversion, so the language appears to have some degrees of freedom here.

Suggested simplification:

The return identifier allows access to the attributes of target of the function return value. It is an error if the attributes of a return identifier are accessed and the attribute values are not determinable. If the return type is an array type, the attribute values are determinable when the target meets one of the conditions listed in section 9.3.3.3 as "determinable index range conditions."

If the return type is a scalar type, the attributes are determinable when the target meets one of the following conditions:

  • your long list here.

    Issue: When is any scalar type not a fully constrained subtype? Objects that are type integer or a subtype of integer when used in an expression have the full range of type integer. Objects that are of an enumerated type can have any value of the enumerated type.

    Issue: I don't see any relationship between your long list in blue and LCS_2016_072a. For example, item "a)" talks about actual, but this is not the actual from the perspective of 72a - aka inside the subprogram, but instead the actual that is the target of your return value, and hence, the input to another function. The question "a)" is asking then is, since the constraints of the actual/target/return identifier are unknown can we determine them by looking at the formal parameters of the subprogram being called.

    It is not clear that "d)" applies here since we are talking about our output and "d)" talks about the output of some other function.

    edit 4: LRM 9.3.3.3 Text needs some work.

    Edit 5 12.2. Scope page 186 Issue: Not needed here. The reason parameters of subprograms are on this list is to allow you to reference the parameter name in a named association - which is outside the scope of the subprogram. Everything I have seen of your use model only used the return identifier inside of the function itself. This is already within the scope of a subprogram - by the first sentence of the paragraph that precedes the list.

    -- Jim Lewis - 2017-02-09

    JL: "the name that the function body may reference to retrieve attributes of the target (if any)," change to --> "return identifier (if any)"

    KJ: Agreed.

    JL: "If the specification of a function includes..." (entire added paragraph) change to --> "The return identifier allows access to the" (entire paragraph)

    KJ: Agreed.

    JL: When is any scalar type not a fully constrained subtype?

    KJ: Good point. Given that, I'm thinking the blue font stuff should be completely stricken, there are no special conditions that must be met if the target is a scalar. It does bring up a question regarding the interaction with LCS-2016-18: Given this...

function foo(x: integer) target return integer;

variable foo_out: integer range 5 to 10;

foo_out := foo(x);

According to LCS-2016-018, inside function foo, what would target'left evaluate to? Would it be 5 because that is the 'left of the actual? Or would it be integer'left because the function definition does not explicitly define a smaller range? Getting 5 was one of the reasons in my mind for needing 72a. My interpretation of LCS 18 is that since target'left is equivalent to target'subtype'left then that it would evaluate to integer'left since target is defined as 'integer' with no explicitly defined range...which is not what would be desired here. To be useful, one would want target'left to get at the attribute of the 'actual' again...which is what 72a is all about.

JL: LRM 9.3.3.3 Text needs some work.

KJ: Anything in particular?

JL: Scope page 186 Issue: Not needed here...

KJ: Agreed, will remove the changes to 12.2.

Thanks for the input.

-- Kevin Jennings - 2017-02-09

KJ: According to LCS-2016-018, inside function foo, what would target'left evaluate to?

MZ: Of course, foo_out'left which is 5. To cite from your own LCS: "The attributes returned are the attributes of the target to which the output of the function is assigning."

The target is an object and, thus, LCS-2016-018 is required to retrieve attributes like 'left from objects. If LCS-2016-018 is not approved, then this LCS cannot retrieve the attributes from the target.

KJ: My interpretation of LCS 18 is that since target'left is equivalent to target'subtype'left then that it would evaluate to integer'left ...

MZ: The attribute SUBTYPE is defined only on objects, thus this attribute can be taken only from the target, not from the return type. But then, target'subtype is "integer range 5 to 10" and thus target'subtype'left is 5 again. At the moment, target'subtype is not allowed by the LCS. This is ok, because otherwise the interference with clause 5.3.2.2 has to be checked, see definition of 'subtype.

KJ: Getting 5 was one of the reasons in my mind for needing 72a.

MZ: LCS-2016-072a is about retrieving attributes from actuals associated with subprogram parameters. It is not about retrieving attributes from the target. These two aspects are completely different.

I haven't yet completed my review of version 7. Thus, my vote is not updated.

-- Martin Zabel - 2017-02-09

Martin, thanks for clarifying.

-- Kevin Jennings - 2017-02-09

Splitting the original LCS into two definitely helps to clarify intent, and several of my previous objections no longer apply. I share JL's concerns about the use of the term "fully constrained subtype" in the blue list, but I disagree with KJ's statement that "there are no special conditions that must be met if the target is a scalar", at least not with the formulation in V7. Let's assume that we have function foo as defined by KJ on 2017-02-09. The question arises what an attribute x'left would return if f is called in an expression of the form term1 + f(3) (or similar forms). "Target" doesn't have a meaning here as it's a concept related to an assignment statement. I see two ways to address this concern

  • disallow such cases with a list similar to the blue list, but adapting the wording to reflect scalar types. In this case the leading text shouldn't refer to target but to the fact that the return type is a scalar type. For more information, see second bullet below.
  • define what the attributes would return in the situation I outlined.

    Regarding the proposed LRM text, a few suggestions:
  • "… as a prefix to retrieve object attributes." "Retrieve" has no defined meaning in the LRM; I propose to use "read".
  • "The attributes returned are the attributes of the target to which the output of the function is assigned." The list in 9.3.3.3 includes many list items that describe situations other than assignment, e.g. association, initial value expression. I don't know of an easy way to describe this succinctly, but what certainly could work is to use the list items of 9.3.3.3 in a new list here that uses the proper terminology for each case.
  • The named function ….": This is related to the previous bullet item: the different cases of the list are not consistent with the previous sentence.
  • … the target must meet …": Again the use of "target", but also, "must" is not an acceptable term in the LRM; it should be "shall".
  • "The attributes … that may be referenced" and another use of "referenced" further below, and bullet list in between: For consistency with other parts of the LRM, I propose something along the lines "For an attribute name whose prefix is the return identifier, if the result subtype of the function denotes a scalar type or subtype, the attribute designator shall be one of BASE, LEFT …." and similar for an array type.

    -- Ernst Christen - 2017-02-10

    @Kevin, to check whether the "Determinable index range conditions:" from clause 9.3.3.3 can be re-used, I have prepared 2 VHDL files and attached them to this topic. The file use_of_others.vhdl demonstrates where "others" can be used according to clause 9.3.3.3. The file application_of_lcs072.vhdl replaces these "others" by a function call which would know the target size (based on this LCS).

    EDIT: The main observation is: Not the target must meet one of the conditions of "Determinable index range conditions." It is the function call itself. That is, the list can be reused if it is preceded by "The function call shall appear only in one of the following contexts":

    Example:

    The function call shall appear only in one of the following contexts:

  1. As an actual associated with a formal parameter [...] where either the formal [...] is declared to be of a fully constrained array type [...]
  2. As the default expression defining the initial value of a port of a fully constrained array type
  3. As the default expression for a generic constant declared to be of a fully constrained array type
  4. ...

    Thus, the target is almost a "fully constrained array type".

    I want to point-out 2 unusual use cases which are allowed due to clause 9.3.3.3:

  • A function call as the operand of a qualified expression (item i).
  • A function call as a choice in a case statement (item j).

    *END OF EDIT*

    I haven't reviewed the blue text because according to your answer to Jim (2017-02-09), the blue text is likely to be removed.

    -- Martin Zabel - 2017-02-12

    Version 8 created to address comments from Jim, Ernst and Martin. The biggest change is to remove the list that was referenced from 9.3.3.3 and instead replace it with something much simpler. For array types, the allowed context where the function can be used is when the target of the function is declared with either an explicit range constraint or has a default initial value assignment. I think those are the only two cases where one can end up with a target that one can retrieve the needed attributes. For scalars, there are no constraints.

    -- Kevin Jennings - 2017-02-14

    *Regarding Version 8:*

    @Kevin, the LCS is better now, but it seems that you missed the point from my comment on 2017-02-12. If you want to read attributes from "the object to which the output of the function is assigning", then the context rules have to ensure that

  1. there is such an object
  2. that the object is
    • either of a fully constrained array type,
    • or of a scalar type.

      For example, if you want to use such a function call for the default expression or in an assignment, the first additional paragraph on page 20 must read as follows (red are your additions, blue are my modifications):

      The return identifier allows access to the subtype of the target of the function from within the function body. The only allowable action within the function body with return identifier is as a prefix to read object attributes. The attributes returned are the attributes of the object to which the output of the function is assigning. The function with return identifier shall only be used in one of the following contexts:
  3. As the expression defining the initial value of a constant or variable object, where that object is declared to be either of a fully constrained array type or of a scalar type.
  4. As a value expression in an assignment statement, where the target is a declared object (or member thereof), and the subtype of the target is either of a fully constrained array type or of a scalar type.

    You may add further items from the determinable index range conditions from clause 9.3.3.3. I am not sure about signal objects at the moment, because item g) in that list talks about the corresponding subtype. But why?

    -- Martin Zabel - 2017-02-15

    @MZ: The two conditions that I listed for the allowable contexts in Version 8 are mutually exclusive and define the two conditions where I want to define the specific context where the new form of function can be used (i.e. "If type mark is an array type" and "If type mark is a scalar type"). I think that the two conditions that you listed overlap since an expression involving an initial value (your 'a' condition) is a form of assignment statement (your 'b' condition). That then causes you to have to say "one of the following contexts" prior to the conditions, but I don't think you clearly say how to select which one. I do like your wording of "fully constrained array type" rather than my "object with an explicit range constraint or an object with a default initial value assignment" which is incorporated into Version 9 which is now available.

    -- Kevin Jennings - 2017-02-16

    Version 9 created, changes are:

    - Page 20 paragraph: Expanded that target can be an "array or scalar object or scalar expression"

    - Page 20 "If type mark is an array..." condition reworded to say "fully constrained array type" rather than "object with an explicit range constraint or an object with a default initial value assignment"

    -- Kevin Jennings - 2017-02-16

    Version 10 created. Changes are a rewrite to 'Page 20' which defines the allowable contexts that can use the new type of function.

    -- Kevin Jennings - 2017-02-24

    Please remove or broaden the restriction for attribute applications on the return identifier. This should be aligned with other LCS to allow e.g. attributes for returned access types.

    The list of attributes for scalars includes common attributes like BASE and SUBTYPE. By adding these to the scalar list, they are not usable with array return types. I suggest to create a separate paragraph for all return types (BASE, SUBTYPE), or list them for array types to.

    The list of scalar types lists e.g. RANGE, but not LENGTH.

    -- Patrick Lehmann - 2017-03-14

    Version 11 created to add BASE, SUBTYPE and LENGTH attributes as listed in Patrick's comment above.

    Not sure which LCS you are referring to just yet about expanding the scope for access types. Will look again later.

    -- Kevin Jennings - 2017-03-14

    Review: 1) Page 20 first paragraph:
    "the name that the function body may reference to retrieve attributes of return identifier (if any),
    It is sufficient to say:
    "its return identifier (if any),
    2) Page 20 Added paragraph
    Why limit the types to scalar and array types?
    Why not:

type complex is record 
   n : unsigned ;
   i : unsigned ; 
end type complex ; 

3) 2nd constraint: why not just:
The subtype T shall be a scalar type or a fully constrained composite.
4) what is "target identifier"? Did you mean "return identifier"?
5) How can the "return identifier"? be an "alias for a subtype"?
Perhaps something that allows the return identifier to be a prefix that is appropriate for the subtype T.
6) Why not any attribute that is appropriate for subtype T?

-- Jim Lewis - 2017-03-15

JL: It is sufficient to say: "its return identifier (if any),

KJ: OK, will wordsmith it into Version 12

JL: Why limit the types to scalar and array types? Why not type complex is record...

*KJ:* I hadn't considered this case and, until your post today, apparently nobody else had either.I don't think there is anything in the LCS as written which would prevent this new suggestion from being added in a future LRM.I don't feel that I can reliably add this new request in without impacting the release schedule for the standard which, as you know, is running a bit behind. At the same time, I don't think that lack of incorporation of the new suggestion is important enough to reject the LCS as written. Others may of course feel differently, to which I'll say I'm sorry that nobody (myself included) did not think of this use case until it was too late to add new features.

JL: why not just: The subtype T shall be a scalar type or a fully constrained composite

KJ: Composites would include records which is beyond the current scope of the proposal.While this might be a worthwhile suggestion, as with #2, the suggestion is just too late in the game to incorporate without taking on unnecessary technical risk (i.e. late changes that expand scope but do it wrong) and/or unnecessary schedule risk (since you have indicated that this standard revision is behind schedule at the moment).As with your suggestion for #2, I don't think there is anything in the current LCS that prevents your suggestion from being added to the next revision nor should the current LCS be rejected over lack of incorporation of this 'late to the party' suggestion however worthwhile it may be.

JL: what is "target identifier"? Did you mean "return identifier"?

KJ: Yes, will put that into version 12.

JL: How can the "return identifier"? be an "alias for a subtype"?

KJ: Martin Z helped out at one point and rewrote most, if not all, of the changes in this section. He appears to be far more skilled in the legalese than I so I'll defer to him and say that what he wrote is correct. My interpretation of the sentence in question "If the above conditions are met, then the target identifier is an alias for the subtype T." would be that T is an alias for the subtype of the target. So if you have variable abc: integer; function foo(...) return xyz:integer; abc := foo(...); than within the subprogram body, 'xyz' is an alias for the subtype of 'abc' which, in this case, is 'integer'.

JL: Why not any attribute that is appropriate for subtype T

KJ: Because not all appropriate attributes of T (in the general case) are also appropriate for use within the subprogram (i.e. this specific case), so I specifically called out only the attributes that are appropriate in this scenario and I also excluded ones that were not required to met the scope of the proposal. I did this in order to not have an issue with some attribute that I don't care about becoming an issue for why this change should not go forward. Attributes that I think are questionable to include would be 'IMAGE (since it requires knowing the dynamic value of the target itself). Other attributes are of no value since they can easily be obtained today: 'POS, 'VAL, 'SUCC, PRED, 'LEFTOF, 'RIGHTOF (the function already knows the return type so it can get at these things by referencing basically its own function declaration. One does not need to get it from the target and it is just as easy for the end user to get it from the function). 'VALUE just brings nothing of value to the function.

KJ: Version 12 will also have some minor changes to section 12. Patrick noticed that one of Ernst's objections had not been met. The changes to section 12 have to do with defining scope and visibility of 'return identifier'. The changes are minor in intent (i.e. scope and visibility of return identifier needs to be the same as scope and visibility of parameters), the precise wording of course being the thing that gets picked over if not quite the way it should be.

-- Kevin Jennings - 2017-03-15

JL: : How can the "return identifier" be an "alias for a subtype"?

MZ: This is a simple definition. The intention is to have a valid prefix to access attributes of the subtype T.

-- Martin Zabel - 2017-03-15

Version 12 created, changes are: - Incorporate suggestions #1 and #4 from Jim's comment earlier today. - Add some minor changes to section 12.2 and 12.3 (new to this LCS) to cover the scope and visibility of the return identifier.

-- Kevin Jennings - 2017-03-16

@MZ and KJ, A return identifier is a name, hence, it can be a prefix. As a result, you do not need to designate it as an alias, you simply need to say that the return identifier denotes the subtype of the target.

I think you can replace all of the text in the edit labeled "Page 20 Add after the first paragraph" with the following

The return identifier denotes the subtype of the target. The target shall either have a scalar or a fully constrained composite type or subtype. A function which uses the return identifier as a prefix may be called in one of the following contexts:
a) as the expression following the ":=" in a constant, variable, or signal declaration,
b) as the value expression of an assignment,
c) as the actual in an association,
d) as the operand of a qualified expression

The first sentence of the above edit may be able to be reduced to:
The return identifier denotes the subtype of the target. A function which uses the return identifier as a prefix may be called in one of the following contexts when the target has either a scalar or a fully constrained composite type or subtype.

With this edit, the type can be:

type complex is record 
   n : unsigned ;
   i : unsigned ; 
end type complex ; 

Then using the return identifier one can say:

function FlintStone (A, B : complex) return RtnVal : complex is
   variable result : complex( n(RtnVal.n'range), i(RtnVal.i'range) ) ;
begin 
   . . . 
   return result ; 
end function FlintStone ; 

-- Jim Lewis - 2017-03-16

@Jim: Your definitions do not define what the prefix represents in all of your 4 cases.

-- Martin Zabel - 2017-03-16

@Jim: The term "target" is defined only for signal and variable assignment statements, see clause 10.5 and 10.6 which define and use the EBNF for "target".

-- Martin Zabel - 2017-03-16

@MZ It is late, but here is an attempt at a correction to my suggested edit:

The return identifier denotes the subtype of the return expression. When a function that uses the return identifier to determine the subtype is called, the subtype of return expression may be determined from the context of the call when the return expression is used: a) as the expression following the ":=" in a constant, variable, or signal declaration and the corresponding declaration is a scalar or fully constrained composite type,
b) as the value expression of an assignment and the target of the assignment is a scalar or fully constrained composite type,
c) as an expression representing the actual in an association and the corresponding formal is a scalar or fully constrained composite type,
d) as an expression with a qualifier and the corresponding qualifier is a scalar or fully constrained composite subtype

It is an error to call a function that uses the return identifier to determine the subtype of the return expression and the subtype of the return expression is not determinable from the context of the call.

-- Jim Lewis - 2017-03-16

@Kevin: Regarding Version 12

1) Please remove SUBTYPE from the list of attributes for scalars and arrays, because SUBTYPE is only defined for objects not for subtypes.

2) As identified by Jim, the points a) and b) in the list of allowed contexts (addition for page 20) must be clarified as follows: replace the corresponding subtype T with the subtype T of the declaration.

3) I do not understand the proposed change for clause 12.3. Can you give an example please.

4) Maybe the phrase fulfills the requirements below in the list of allowed contexts could be replaced by is either a scalar type or a fully constrained array type. But, I not sure why we haven't done this simplification earlier.

EDIT Regarding, my point 4. In case of an array, the array needs not to be fully constrained. It is sufficient that the index ranges are defined. That's why I suggested the wording as found in version 10 (and still found in version 12). Thus, I would still keep the phrase fulfills the requirements below.

-- Martin Zabel - 2017-03-16

Martin,

To your listed items:

1. SUBTYPE will be removed for Version 13

2. Text changes that you identified in your #2 above will be made for Version 13

3. In a post from 12/15 in the comment area on this page, Ernst noted "If the target is in fact an identifier, how does it become visible in the subprogram body? There are currently no changes to clause 12 in this LCS". Recently, Patrick noted that item had not been addressed. Correct me if I'm wrong, but I believe that 'return identifier' is a new thing that should then have new scope rules (section 12.2) and visibility rules (section 12.3) defined. If that's the case, then I believe that the scope and the visibility of this new 'return identifier' should be exactly the same as that of a function parameter.

On that basis, it looked to me that for section 12.2, the only edit needed is to bullet c) so I added "or a return identifier" to that bullet.

Similarly, for 12.3, bullet j) is the place where parameter visibility is discussed. For this bullet, it wasn't quite as easy as simply saying "or a return identifier" so I took the wording in bullet j) and modified it to what I think it needs to say when referring to "return identifier" and made this into a new bullet item u). I added it to the end of the list so that if there happened to be a reference elsewhere in the LRM to bullets k) thru t) I wouldn't muck it up by adding my new bullet in where it might fit in better if all you're doing is reading that list of bulleted items. If you have better wording, let me know and I'll incorporate it.

4. Based on your latest comment, it appears that no changes are necessary.

Thanks again for your review and suggestions.

Kevin

-- Kevin Jennings - 2017-03-16

@Kevin: Regarding point 3:

I do not understand why Ernst requested this. For example:

architecture a of e is

  function f(x : integer) return integer; -- function declaration

  function f(x : integer) return integer is  -- function body
  begin
    return x;
  end function;

  constant c : integer := f(x => 1); -- extended scope

begin
end architecture;

The formal parameter "x" is declared immediately in the declarative region of function "f". And this declarative region includes the function declaration and function body of "f" due to clause 12.1.

Thus, the immediate scope of "x" starts with the declaration of "x" and ends with the function body of "f" due to clause 12.2 (2nd paragraph).

But the formal parameter "x" is also required outside the immediate scope, e.g., in the initial expression for constant "c" above. And that's why it is listed in the enumerated list on page 186 (clause 12.2). But the visibility is still limited due to the enumerated list of clause 12.3 (specifically item j).

The return identifier must not be visible outside of the declarative region of function "f". Thus no changes are required for clause 12, please remove them from your LCS.

The LCS Version 12 does not really state that the return identifier is actually an alias declaration. I think you should reword this sentence:

If the above conditions are met, then the return identifier is an alias for the subtype T.

To:

If the above conditions are met, then the return identifier declares an alias for the subtype T._

-- Martin Zabel - 2017-03-16

Version 13 is available: Changes are:

1. Slight rewording of bullets a) and b) in the changes for "Page 20 Add after the first paragraph"

2. Slight rewording of the sentence that begins "If the above conditions are met..." in the section "Page 20 Add after the first paragraph"

3. Removed SUBTYPE as an available attribute. Not needed because 'return identifier' is a subtype.

4. Removed all changes to clause 12 that were recently added per Martin Z's analysis and recommendation in the previous comment.

-- Kevin Jennings - 2017-03-16

This is a technical review of version 13. While I am ok with the concept of 72, I cannot vote yes on the current version until the following issues are addressed.

1) "A function call with a return identifier" A function declaration has a return identifier, a function call does not.

2) "A function call with a return identifier shall appear only in one of the following contexts" Hence, if a function is declared with a return identifier, but does not use it, and it is not called in one of the stated contexts, it is an error.

3) Is the return identifier a subtype or an object? The LCS seems to sometimes say it is a subtype and sometimes an object. It cannot be an object. Functions do not return objects. They return a value. Hence, it can only be a subtype.

4) Is a return identifier an alias? An alias is created with an alias declaration. If you want it to be an alias, you are going to have to provide an implicit transformation of some sort.

5) Since a simple_name denotes a subtype and not an object, one should be able to use any attribute that is appropriate for a subtype. There is no need to enumerate what is and what is not legal for a subtype. When you do this, you are simply duplicating information that is elsewhere and is more appropriately elsewhere.

Going further, when you specify the exact attributes you allow, you leave out things like RetID 'simple_name.

The reason you had people demanding that you list out the attributes is because various revisions of LCS 72 have incorrectly referred to the return identifier as an object.

6) We should not try to identify what types are legal for the return identifier, instead, we identify when it is illegal to use the return identifier. IE. it is an error if the return_identifier is used to access a subtype constraint for a subtype that is unconstrained.

7) Lets assume that we allow RetID 'simple_name, LCS 72 forbids its usage unless the subtype is determinable from context.

-- Jim Lewis - 2017-03-19

Topic attachments
I Attachment Action Size Date Who Comment
Microsoft Word filedocx LCS_2016_072_Ver_10.docx manage 19.7 K 2017-02-24 - 17:06 KevinJennings  
PDFpdf LCS_2016_072_Ver_10.pdf manage 321.6 K 2017-02-24 - 17:07 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_11.docx manage 20.4 K 2017-03-14 - 18:17 KevinJennings  
PDFpdf LCS_2016_072_Ver_11.pdf manage 320.5 K 2017-03-14 - 18:17 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_12.docx manage 21.4 K 2017-03-16 - 03:29 KevinJennings  
PDFpdf LCS_2016_072_Ver_12.pdf manage 427.0 K 2017-03-16 - 03:30 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_13.docx manage 20.4 K 2017-03-16 - 16:40 KevinJennings  
PDFpdf LCS_2016_072_Ver_13.pdf manage 319.9 K 2017-03-16 - 16:40 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_3.docx manage 25.6 K 2016-12-28 - 16:48 KevinJennings Word doc, Version 3 of LCS
PDFpdf LCS_2016_072_Ver_3.pdf manage 446.5 K 2016-12-28 - 16:48 KevinJennings PDF file, Version 3 of LCS
Microsoft Word filertf LCS_2016_072_Ver_3.rtf manage 109.3 K 2016-12-29 - 18:42 KevinJennings RTF file, Version 3 of LCS
Microsoft Word filedocx LCS_2016_072_Ver_4.docx manage 19.2 K 2016-12-30 - 02:21 KevinJennings  
PDFpdf LCS_2016_072_Ver_4.pdf manage 347.7 K 2016-12-30 - 02:22 KevinJennings  
Microsoft Word filertf LCS_2016_072_Ver_4.rtf manage 57.3 K 2016-12-30 - 02:22 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_5.docx manage 21.1 K 2017-01-05 - 03:44 KevinJennings  
PDFpdf LCS_2016_072_Ver_5.pdf manage 355.4 K 2017-01-05 - 03:44 KevinJennings  
Microsoft Word filertf LCS_2016_072_Ver_5.rtf manage 65.7 K 2017-01-05 - 03:45 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_6.docx manage 21.1 K 2017-01-16 - 13:51 KevinJennings  
PDFpdf LCS_2016_072_Ver_6.pdf manage 314.7 K 2017-01-16 - 13:51 KevinJennings  
Microsoft Word filertf LCS_2016_072_Ver_6.rtf manage 67.1 K 2017-01-16 - 13:51 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_7.docx manage 21.2 K 2017-02-08 - 21:22 KevinJennings  
PDFpdf LCS_2016_072_Ver_7.pdf manage 318.3 K 2017-02-08 - 21:22 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_8.docx manage 19.2 K 2017-02-14 - 20:51 KevinJennings  
PDFpdf LCS_2016_072_Ver_8.pdf manage 306.8 K 2017-02-14 - 20:51 KevinJennings  
Microsoft Word filedocx LCS_2016_072_Ver_9.docx manage 20.2 K 2017-02-16 - 04:04 KevinJennings  
PDFpdf LCS_2016_072_Ver_9.pdf manage 405.4 K 2017-02-16 - 04:04 KevinJennings  
Unknown file formatvhdl application_of_lcs072.vhdl manage 4.2 K 2017-02-12 - 18:20 MartinZabel Application of LCS based on "use_of_others.vhdl"
Unknown file formatvhdl use_of_others.vhdl manage 3.4 K 2017-02-12 - 18:19 MartinZabel Demonstrates use of "others"
Topic revision: r92 - 2017-04-02 - 15:43:17 - PatrickLehmann
 
Copyright © 2008-2021 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback