-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Constant parameters #1684
Comments
It's probably possible, but not something I think is going to be easy, or necessarily worth it. As a language feature, it would need to be linked into the type system. A static requirement when calling a function comes from the static type of the function. Effectively, some arguments would be annotated That also means that If it touches the type system, that makes it a feature with a major impact. On the other hand, it's breaking to make any existing parameter be It's only for parameters. I guess that's reasonable, we can already make variables Can Can you abstract over All in all, I don't think the scale of the feature matches the benefits. That said, I don't really understand why you'd require |
Those are all good questions, and I tend to agree with your assessment. It would indeed need to be part of the type system.
This might be the wrong way to approach the problem, but the original goal was to be able to define APIs that would otherwise be vulnerable to attack in such a way that user data couldn't be provided to them. For example, an API that uses arguments to compose a database query could be written such that the arguments are required to be compile-time constants, thus preventing the possibility that some user-entered value could accidentally be passed in. |
You can do awful things with constants, interface implementation and either expandos or class SupposedlySafe implements Safe {
const SupposedlySafe();
static _state = Expando<String>();
String get someProperty => _state[this];
void set someProperty(String value) { _state[this] = value; }
} That'll let you create a You can't trust malicious code, or protect yourself from it, if it runs in the same isolate. The type system is not a security system. |
True, but I probably wasn't clear enough. They aren't executing user-written code. This is helping to protect against things like user-entered text from a text widget accidentally being passes to a trusted method. There's no delusion that this will prevent every kind of bug, just that it will reduce the probability of one kind of bug. |
Would this solve the issue of not being able to create a constant like this: const spacings = Spacings(xs: 2, s: 4, m: 8);
const padding = EdgeInsets.all(spacings.m); When writing a package there is no way of requiring a set of spacings and create const paddings from those spacing ? |
I may be wrong, but that feels like a separate problem: const Spacings spacings = Spacings(xs: 2, s: 4, m: 8);
const int number = spacings.m; // error: invalid constant value
const EdgeInsets padding = EdgeInsets.all(number); The issue isn't that class Spacings2 {
final int _m;
const Spacings({required int xs, required int s, required int m}) :
this._m = m;
int get m => myLogic(_m); // not constant
} This would require the notion of a field-only getter (so we can assign a value and be sure it is never touched), which doesn't exist yet in Dart. |
Chiming in with this code snippet from #1774 (multiple generics). This feature requires both built-in tuples (#207 or #68 are similar) and constant parameters. I added some comments for context. /// `T[]` denotes a list or tuple of type arguments.
///
/// I'll use `<int, String, bool>` in my examples
class Tuple<T[]> {
/// [T] is a tuple or list of types. In this case: `<int, String, bool>`
final T items;
/// Using the example from earlier, this can be `Tuple([1, "Hello", true])`.
///
/// Maybe the spread operator (`...`) can be used to unpack these, so you can simply
/// do: `Tuple(1, "Hello", true)`. See https://github.com/dart-lang/language/issues/1014.
Tuple(T this.items);
/// This returns `<dynamic>[1, "Hello", true]`.
List<dynamic> toList() => items;
/// `getStaticItem(0)` returns the first element, statically known to be an int.
T[comptimeIndex] getStaticItem(const int comptimeIndex) => item[comptimeIndex];
/// `getDynamicItem(index)` returns the value at the corresponding index.
///
/// Since the index is only known at runtime, the type is unknown ahead of time, and
/// this is subject to an [IndexError].
dynamic getDynamicItem(int runtimeIndex) => item[runtimeIndex];
/// Returns a [Tuple] with one element replaced, but with the same type.
///
/// `tuple.withItem(1, "World")` returns `Tuple([1, "World", true])`.
Tuple<T> withItem(const int i, T[i] item) => Tuple(...item.sublist(0, i), item, ...item.sublist(i+1));
} |
For future reference if we ever revisit this. Propagate consts can lead to a space explosion as detailed in (#2776 (comment)). Also, when doing propagation, we quickly get into the question whether control flow should be supported and whether string concatination or any other const-able operation should be supported as discussed above. These can lead to more space explosion. (For now, the use cases in dart-lang/native#153 don't seem to need it. And dart-lang/sdk#29381 is going for an annotation instead of a language feature for now.) |
constant. As const-only parameters are not planned, see dart-lang/language#1684, an annotation with analyzer support could help a bit at least, see #29381. The motivation is to enforce const arguments for methods annotated with `@ResourceIdentifier`, to be able to record the argument values at build time, see https://dart-review.googlesource.com/c/sdk/+/329961. Tested: pkg/analyzer/test/src/diagnostics/const_argument_test.dart Change-Id: I2b8d2dce0c899fc0caa4985d892a5d031c747521 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/357701 Reviewed-by: Phil Quitslund <[email protected]> Reviewed-by: Lasse Nielsen <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Moritz Sümmermann <[email protected]> Reviewed-by: Marya Belanger <[email protected]>
There is a request to add an annotation for parameters whose semantics ensures that the argument corresponding to the annotated parameter is a constant expression.
It occurred to me that this might be an interesting language feature. The proposal would be to allow the modifier
const
on parameter declarations and for the semantics to match those requested for the annotation. For example,It might additionally provide some possibilities for compiler optimizations if it's known that the value of the parameter can't be modified.
I suspect that we'd want to introduce the annotation first and see how/whether it's used in practice, but I thought I'd mention it in case you'd want to track the work on the annotation.
The text was updated successfully, but these errors were encountered: