Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

Fw: Motion 31 Suggestions



Thanks for your reply and the updates.

When I have time I'll reread all the text about functions, constants and variables and give it more thought. Treating constants as functions and unlike variables seems unnatural to me, but actually has some similarities to something I designed.

The latest 2011 C++ standard has a new feature I initiated. When you define a class (a type with a data representation and operations on it) you will now be able to specify "user defined literals". A special conversion operator (ie, a special function) can be defined along with a pattern the compiler can use to match literals it should handle. Then it will be executed at compile time (hence has some constraints on how it's written) to turn those literals from characters in the source code into an object of the class.

Examples of literals that could be recognized if the class author defined appropriate conversion operators include 123.45dd (the proposed C/C++ syntax for an IEEE 754-2008 decimal64 floating point), 10100101b (a bit string), 123456789_123456789_123456789_int128 (a 128 bit integer), "Abcdef"unicode (a Unicode string), 123.45_grams and 987.6_oz (units of weight), or 123.45_USD and 123.45_Euros (units of currency), 2_pi (2 times pi), or 5.6_i (imaginary 5.6). Each would be converted into a constant of the result type of the conversion operator that handles the suffix pattern and whether it takes quoted or nonquoted sequences of characters. A class can recognize multiple suffixes. If the literal syntax or value is wrong, the programmer would get an error at compile time not execution time.

I designed that (and others improved my design) before 1788, so it wasn't designed for intervals, but there are several ways it could be used for them. The brackets are an problem. One solution would be to require quoting, eg, "[1, 2.5]"interval. If the Interval class conversion operator allowed it, you could write syntax like "[0, oo)"interval. The class author or any user could of course define the name Entire to be the constant "[-oo, +oo]"interval. The interval for a floating point value could potentially be written 12_interval or 12.345_interval, which would be converted into the singleton [12, 12] and the non-singleton [12.345 rounded down, 12.345 rounded up].

This may someday make interval programming in C++ easier. The approach may also influence how we think of intervals as we write the standard.

User defined literals define a function (or functions) to convert some sequence of characters in a program that meet some defined syntax representing a literal into the corresponding internal constant of the specified type. The constant is not a function, but the conversion from its external form to its internal form is defined by a function. It is internally represented the same way a variable is and generally treated the same way a variable is, except that it is not allowed to be changed. Maybe 1788 could use that approach, instead of defining constants as functions?


The case expressions issue is complicated and I doubt there is any ideal answer. I prefer boolean because it makes the programmer specify the condition, whether it's < 0 versus >= 0, /= 0 versus = 0, odd versus even, or something else. That makes it more flexible, but more importantly having to be explicit about something that has no one universally right answer should make the programmer think just enough to prevent some bugs. I believe the C / C++ approach of treating nonzero as true and zero as false is dangerous. I worry that having true be /= 0 for some types and < 0 for other types will be even more error prone. Of course language designers don't always ask my opinion and wouldn't always follow it if they did. 8<)

- Ian McIntosh IBM Canada Lab Compiler Back End Support and Development


Inactive hide details for John Pryce ---01/24/2012 08:59:32 AM---Dear Ian I had forgotten where I had stored your comments of 2John Pryce ---01/24/2012 08:59:32 AM---Dear Ian I had forgotten where I had stored your comments of 29 Dec. Apologies for the delay. Respon


From:

John Pryce <j.d.pryce@xxxxxxxxxxxx>

To:

Ian McIntosh/Toronto/IBM@IBMCA

Cc:

stds-1788 <stds-1788@xxxxxxxxxxxxxxxxx>

Date:

01/24/2012 08:59 AM

Subject:

Re: Motion 31 Suggestions

Sent by:

prycejd1@xxxxxxxxxxxxx





Dear Ian

I had forgotten where I had stored your comments of 29 Dec. Apologies for the delay. Responses below.

John

On 29 Dec 2011, at 23:07, Ian McIntosh wrote:
> 3.2.1 arithmetic operation:
> "Constants such as 3 and TT are regarded as arithmetic operations whose number of arguments is zero."
> I disagree with treating constants as arithmetic operations instead of as constant values (interval datums). It adds too many complications in too many places (5.4.1, 5.4.2, 5.4.3, ...).
> If we treat constants as arithmetic operations, shouldn't we treat variables as arithmetic operations too? And if constants are arithmetic operations defined in the implementation library, should all constants be included in either section 5.6 or 5.7? And maybe all variables? Of course then we'd have to decide which constants (and maybe which variables?) are required and which are recommended. 8<) It's better to treat constants as what they are - constants. That of course means rewriting section 5.4.4 Constants, keeping some of the wording relating to how the value of a constant is determined.

I don't agree with this. Maybe I need to say more about how constants are defined: there is a language-defined syntax that says what kind of string is a (point) literal constant and what its value is. There may also be language-, library- or user-defined constants.

The syntax and semantics of expressions in §5.5 makes clear that variables are completely different from constants. It has the advantage that "interval extension of a point constant" has an immediate definition, being a particular case of "interval extension of a point function".

This notion of constants was good enough for Ada, as I recall, so it should be good enough for 1788.  Defining a language is different from defining a language-neutral standard, but the necessary adjustments should not be beyond us.

However, I see that §5.6 "Required operations" needs a paragraph on constants. Its statement
>   an implementation shall provide interval versions
>   appropriate to its supported interval types
must apply to literal and named constants. Are there syntactic/semantic obstacles to doing this in a way consistent with "treating constants ... as constant values (interval datums)" (your words)?

E.g., what's the interval version of the literal "1.234" appropriate to the (inf-sup) binary64 type? This is where the work by Arnold and others on ways of ensuring containment comes in. It's not enough to write something like
    num2interval<binary64>(1.234)
because that won't enclose the true value 1.234, only its binary64 approximation. So we need
    text2interval<binary64>("1.234") & similarly text2interval<binary64>("Pi"), etc.
Arnold has had interesting ideas on this since the Vienna proposal; I need to search for them in the emails.

Your advice will be valuable here. 1788 should not make requirements that are properly the concern of languages, but it must make its definitions implementable in a language.

BTW, I guess a literal is a symbolic object, but in many languages (e.g. Maple) symbols and text strings are different kinds of thing, and denoted differently. So we should aim to use wording that doesn't force literals to be text strings.

> "Details in S5.4."
> This shouldn't be part of the paragraph about constants, since section 5.4 says nothing about them.

Changed 5.4 to 5.4.4.

> 3.2.3 domain:
> "the domain comprises those points in the set..."
> Comprises is am awkward word for a standard to use, since it has two definitions that are almost opposites and that are both in current use. In the first, the parts comprise the whole. In the second, the whole comprises its parts. The first was I think the first definition, and there is no good synonym for it. The second can be replaced by "consists of". Maybe this doesn't matter here, since the sentence makes the meaning clear, but I prefer to avoid ambiguous words. See also sections 3.2.5, 4.1 Level 2, 5.2, ...

A good point. My usage is
 "Set S comprises those x in set X such that P(x)" means S = {x in X | P(x)}.
whereas
 "Set S consists of x in set X such that P(x)" means S \subseteq {x in X | P(x)}.
and "comprises" is usually replaceable by "consists of exactly". I've added a note about that to 1.5 "Word usage".

> 4.1 Specification Levels Overview - Level 2
> "In addition to an ordinary (bare) interval, this level de nes a decorated interval..."
> Should that be deleted in this motion?

I've marked it as such.

> "The arrows in the table..."
> Perhaps "The arrows in Table 1..."?

Done

> 5.4.4 Constants:
> "an interval extension of a real constant is any zero-argument interval function that returns an interval containing c."
> Should this return the hull, instead of any interval containing the constant?

It says the *natural* extension is [c,c], i.e. the hull. Am I missing your point?

> 5.5.2 Generic functions
> "An arithmetic operation or _expression_ may also denote a floating point function; this is not relevant to this standard."
> At level 1, should "floating-point" be "Real"?

No, it means "floating-point". "Real functions" are "point functions", which this subclause _is_ about.  

> And would it be more precise to say such functions are not defined by this standard?
Yes, done.

> 5.6 Required operations
> "as well as those normally written in binary operator notation x  y"
> ... should include "or written in unary operator notation  x".
Done
>
> 5.6.2 Case expressions and case function
> There are probably good reasons for defining the case condition as true if it's <0, but most programming languages consider any nonzero value as true so this may cause some confusion. An alternative would be to define c as a boolean, with c<0 giving the current semantics.
> The hull (g U h) aspect may also cause confusion. Confusion leads to bugs.

I struggled with this for some time. An earlier version had c as a boolean, but reconciling that with the concept of interval hull is horribly unnatural IMO. As is "taking any nonzero value as true".

> Table 2 Required forward elementary functions.
> "Rev" shouldn't be capitalized.
> Why not call it recip, short for reciprocal?
Done. Meant to be recip. Probably the result of a careless "replace all"?

> Table 5 Recommended elementary functions
> In the final standard we should try to avoid having any section split by any table.
I agree. Getting good page layout with so many tables is hard, so I'll leave it till near the final cut.