Replies: 72 comments
-
And for actual ranges: dotnet/roslyn#23205 |
Beta Was this translation helpful? Give feedback.
-
I don't ask for numeric range array . I want a limited value range variable. that can have a single value granteed to be in the range. This is a sort of value validation, that can be aplied to Properties and will affect binding them to data entry controls. |
Beta Was this translation helpful? Give feedback.
-
I dont think its needed. You can already achieve it using struct and implicit operator.
|
Beta Was this translation helpful? Give feedback.
-
In case default value should not be 0 use constant offset.
|
Beta Was this translation helpful? Give feedback.
-
@MkazemAkhgary That gives you no compile-time safety, it only automates a handful of exceptions. |
Beta Was this translation helpful? Give feedback.
-
Yes, but that is constraining a value to be within a range. Completely different from the range itself. |
Beta Was this translation helpful? Give feedback.
-
@MkazemAkhgary |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h |
Beta Was this translation helpful? Give feedback.
-
@Joe4evr |
Beta Was this translation helpful? Give feedback.
-
ah, I didn't see @alrz had posted it already. @MohammadHamdyGhanem If you click through from that proposal to the original Roslyn issue, you should see how it's relevant. |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h |
Beta Was this translation helpful? Give feedback.
-
I fear you've fallen out of the book completely. 😄 You appear to asking for a way to constrain a variable or property to have maximum and minimum values. This sounds like part of method contracts, which is a proposal based upon the old Microsoft Research project, Code Contracts. The idea here is more general than your specific case, but would allow you do something like: class RiskyDriver
{
public int Age ensures return >= 18 && return < 25 { get; }
} |
Beta Was this translation helpful? Give feedback.
-
Yes. I read that and it is very clear that my syntax is easear:
than
If you constrained the data type, then you've already constrained all other language elements built with it. |
Beta Was this translation helpful? Give feedback.
-
@Pzixel No, you made the claim that 99% of arrays have sizes that cannot be determined until runtime. The burden is yours to prove your claim. Regardless, you are focusing on a single case of several I described. Who said this was for locals only? You are the first to mention it. |
Beta Was this translation helpful? Give feedback.
-
Ok, I will after you prove yours :)
You don't know array length when you passed it into the method
|
Beta Was this translation helpful? Give feedback.
-
That isn't how burden of proof works. You made the claim. I made the counterclaim. You must prove the claim before expecting me to prove the counterclaim. You do know the array length when it is a constant. Obviously if it isn't a constant, then this feature doesn't apply. |
Beta Was this translation helpful? Give feedback.
-
There's another reason why Range data types are a bad idea - and it's something that I haven't seen mentioned yet in this thread. Consider this class and imagine you have a non-trivial system (>250kloc) that makes extensive use of it:
What happens when the local government changes the law and now the legal age for drinking alcohol is going to change to 21 years of age? Worse, the type declaration If you think this is a contrived example, I challenge you to check out some of the so-called constants in your local jurisdiction. Things like age thresholds (e.g. for voting, drinking age, or for military service), sales tax rates (e.g. NZ GST), and food standards (e.g. how much meat is needed a sausage) are inevitably political decisions - and those can change, sometimes with very short notice. Simply using Instead, we can define We can already define If the language did support range types, we'd only need to use them in one place … so the benefit to the codebase would be very low. A last couple of comments … … with Method Contracts, we could appropriately annotate the … if memory serves (it's been a long while since comparing programming languages in my university days), the experience of Ada developers using ranged type reflects this problem as well. They have nice characteristics when first writing code, but at the cost of making future feature development significantly harder. |
Beta Was this translation helpful? Give feedback.
-
If such changes occur regularly, or if you need to deal with multiple jurisdictions that have different definitions, then keep it as an Nobody is getting rid of
This is a design decision. In a previous job we made the decision to hard-code the list of US states into an Could the states change? Sure, there has been talk about adding Puerto Rico for a while now. Did we feel it was worth the cost instead of simply releasing an update to the app? No, since the lead time for this change would be longer than our typical update schedule. |
Beta Was this translation helpful? Give feedback.
-
As I mentioned before, type aliases can be handy here: type DrinkingAge = int<18,99>; Now just change that once and push out an update. sorry, I really don't like putting the brackets and numbers first |
Beta Was this translation helpful? Give feedback.
-
Another possible implementation:
Usage:
which can have a short syntax:
The importance of this synatax appeares when declaring properties and method parameters and return values. |
Beta Was this translation helpful? Give feedback.
-
Anyway it has type |
Beta Was this translation helpful? Give feedback.
-
Why? checks exists already in the Value property. Whenever T is passed to a range, the compiler sets Range.Value = T and it will accept the value or throw an exception. |
Beta Was this translation helpful? Give feedback.
-
@MohammadHamdyGhanem void Foo(<20, 40>int range) => Console.WriteLine(range);
<18, 60>int range = 59;
Foo(range); Compiles to: void Foo(new Range<int> range) => Console.WriteLine(range.Value);
var range = new Range<int>(18, 60) { Value = 59 };
Foo(range); And fails at runtime. Where is the profit from having this type? The problem here is that we are not in C++ world and we cannot write |
Beta Was this translation helpful? Give feedback.
-
Look at this:
The compiler translates it to:
The the profit:
You miss the point of code validation. Most methods and properties throw exceptions even those of the coreFX. We do this not to make the code fail at rune-time, put to foce our logic on any programmer that uses our code, so he had to provide valid values, and if he is not sure, he uses the try catch structure. This is how you design a reusable code for yourself and your team. In all cases the Foo method will reais an exception if it gets invalid values. The deference is that we don't have to write long validating code over and over. |
Beta Was this translation helpful? Give feedback.
-
If I don't have compile time check I don't want to have it in the language. Ranges are rare enough. I'd rather prefer correct datetime interop (see NodaTime) than this one. Just write your own Range type then, you don't need language support for it.
It's beside the point. I show you that this feature gives nothing to me. It doesn't help to pass invalid range somewhere. It just save me some typing when I can write |
Beta Was this translation helpful? Give feedback.
-
You can't use "new Range(1,10) { Value = 5 }" as a parameter type, or as a retrun value type, or as a property type. This is what the example shows. |
Beta Was this translation helpful? Give feedback.
-
Sure it does. I expect that the compiler will give you a design time error at:
and will give you a runtime error when a wrong value can't be calculated at design time. This is the standerd behavior with basic numeric types:
|
Beta Was this translation helpful? Give feedback.
-
Frankly, the proposed If the language were to go down the path of exploring constrained types I'd much rather they be defined as proper type aliases with constraints, something akin to: public type CustomerName : string;
public type CustomerId : Guid;
public type AgeRange : int where (AgeRange > 0 && AgeRange < 150); The implementation could be a simple struct wrapper around the "extended" type: public struct CustomerName {
private readonly string value;
private CustomerName(string value) => this.value = value;
public static implicit operator string(CustomerName rhs) => rhs.value;
public static explicit operator CustomerName(string rhs) => new CustomerName(rhs);
} Then you'd be able to use the type alias like a normal type and the compiler would require explicit casting to that type which would/should at least cause the developer enough pause to think about whether the type is valid. When constraints are included those constraints could be embedded in the constructor to throw if violated at runtime. They could also be encoded into attributes which would allow for compile time validation, although that could be tricky if the syntax for defining constraints is fairly open-ended. |
Beta Was this translation helpful? Give feedback.
-
I suggest to improve current numeric types by adding a way to set a value range. I don't ask for numeric range array . I want a limited value range variable that can have a single value within the range. This is a sort of value validation, that can be applied to Properties and will affect binding them to data entry controls.
This can be done by adding two readonly properties to each data type: Min, Max. The compiler should check them before assigning any value to the object.
Max and Min Values can also be set via the constructor.
The can be done also by some attributes, but it will be easier to give it a syntax like this
[5,10]int i = 7;
or
<5,10>int i = 7;
The compiler must not allow i to have any value < 5 or >10.
It should validate values before any assignment and raise overflow exceptions.
One can omit one limit:
or
This will make it easy to write auto-properties like this:
[18,30]int Age {get; set;};
Or
<18,30>int Age {get; set;};
In-Range Data Types give an easier way to achieve Method Contracts. It is very clear that this syntax
is easear than:
If you constrained the data type, then you've already constrained all other language elements built with it.
Note:
If you want to complicate things, I suggest to use regular expression syntax such as:
[reg exp]int x;
This can allow writting constrains on string data types as well.
Another possible implementation:
Usage:
which can have a short syntax:
The importance of this synatax appeares when declaring properties and method parameters and return values
For example:
The compiler translates it to:
Beta Was this translation helpful? Give feedback.
All reactions