Skip to content

Add default Keyword and New ::default Operator for Using Default Parameters #4096

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

Closed
stan-at-work opened this issue Sep 20, 2024 · 2 comments
Labels
feature Proposed language feature that solves one or more problems state-duplicate This issue or pull request already exists

Comments

@stan-at-work
Copy link

Add default Keyword and New ::default Operator for Using Default Parameters, with Hover Documentation

Summary

Introduce a default keyword and a shorthand ::default operator to Dart for explicitly invoking default parameter values in conditional expressions. Additionally, update the IDE hover documentation for constructors to indicate when a parameter is "defaultable," informing the user that they can use default or ::default.

Motivation

While Dart allows setting default values for optional parameters, there’s no intuitive way to invoke the default parameter value explicitly when using conditional logic. This forces developers to manually handle nullable values or repeat default values, leading to redundancy. Moreover, users are not informed directly in their IDE when parameters are defaultable, causing uncertainty.

Example Use Case:

Consider the following class:

class Article {
  const Article({this.articleCode = '123'});

  final String articleCode;
}

Currently, when creating an instance conditionally, a developer would write:

final String? articleCode = '456';

final article = Article(articleCode: articleCode != null ? articleCode : '123'); // Manually handling default.

The default value ('123') is hardcoded in this logic, which is prone to errors and repetitive.

Proposed Solution:

1. Introduce the default Keyword:

The default keyword would allow developers to explicitly indicate the use of a default parameter value when the condition fails:

articleCode != null ? articleCode : default;

2. Introduce the ::default Operator:

To make the code even more concise, introduce a ::default operator. This operator would allow developers to pass parameters that fall back to the constructor-defined default value:

final article = Article(articleCode::default);
  • Behavior: If articleCode is null, the ::default operator uses the constructor's default value ('123'), otherwise, it uses the passed value.

3. Hover Documentation Indicating "Defaultable" Parameters:

To improve the user experience in IDEs, the constructor's parameter should be marked as defaultable in the hover documentation. This would inform developers when a parameter has a default value and that they can use the default keyword or ::default operator.

Example:

When hovering over the Article constructor in an IDE, the following would appear:

class Article {
  const Article({this.articleCode = '123'}); // Hovering shows: "articleCode: defaultable"
}

The tooltip or hover documentation could indicate:

articleCode: String (defaultable)
Default value: '123'
Use 'default' or '::default' to invoke default value.

This would provide immediate feedback, letting the developer know that the articleCode parameter can accept the default or ::default keyword.

Advantages of the Proposed Solution:

  1. Cleaner Code: The default keyword and ::default operator reduce verbosity and eliminate the need for manually handling defaults.
  2. Better Developer Experience: Hover documentation showing that a parameter is defaultable informs developers of the available options, making the feature discoverable.
  3. Improved Readability: The ::default operator makes it clear when default parameter values are being used, reducing the chances of errors or miscommunication in code.

Example in Use:

Before:

articleCode != null ? articleCode : '123' // Manually handling default.

After:

Using the default keyword:

articleCode != null ? articleCode : default // Automatically apply default value.

Using the ::default operator:

final article = Article(articleCode::default); // Concise syntax for default values.

With hover documentation:

const Article({this.articleCode = '123'}); // Hover tooltip: "articleCode: defaultable"

Current Workaround Without ::default:

In Dart's current state, without the ::default operator, developers would need to manually handle default values with nullable checks:

final String? articleCode = '456';

final article = Article(articleCode: articleCode ?? '123');

In this workaround, the ?? operator is used to fall back to the manually repeated default value ('123'), but it lacks the convenience and clarity of the proposed solution.

Conclusion:

By adding the default keyword, the ::default operator, and hover documentation indicating "defaultable" parameters, Dart will improve its handling of default parameter values. These changes will make code more concise, reduce manual error-prone handling, and offer a better developer experience by providing feedback directly in the IDE.

@stan-at-work stan-at-work added the feature Proposed language feature that solves one or more problems label Sep 20, 2024
@lrhn
Copy link
Member

lrhn commented Sep 20, 2024

This is a variant of #2269 where you just write default, also suggested here #1639 (comment)

The article::default should likely just be articleCode: articleCode ?? '123'. It highlights that this is null-related.
We don't have a shorthand for articleCode: articleCode, so adding one for a more specialized operation seems weird.
If we allowed (: articleCode) to implicitly mean (articleCode: articleCode), then we could maybe allow (:articleCode ?? '123') too.

@lrhn lrhn closed this as completed Sep 20, 2024
@lrhn lrhn added the state-duplicate This issue or pull request already exists label Sep 20, 2024
@github-staff github-staff deleted a comment from SAMBILI Oct 28, 2024
@github-staff github-staff deleted a comment from SAMBILI Oct 28, 2024
@lucaesposto
Copy link

This is a variant of #2269 where you just write default, also suggested here #1639 (comment)

The article::default should likely just be articleCode: articleCode ?? '123'. It highlights that this is null-related. We don't have a shorthand for articleCode: articleCode, so adding one for a more specialized operation seems weird. If we allowed (: articleCode) to implicitly mean (articleCode: articleCode), then we could maybe allow (:articleCode ?? '123') too.

As pointed out in #1639 (comment), the main purpose should be to have syntactic sugar for:

// Given that Article constructor fields have default values
final article = articleCode != null ? Article(articleCode: articleCode) : Article();

Mainly because it becomes even more cumbersome and boilerplate when having multiple fields with defined defaults, such as:

final article = articleCode != null
? articleWidth != null
    ? Article(articleCode: articleCode, articleWidth: articleWidth)
    : Article(articleCode: articleCode)
: articleWidth != null
    ? Article(articleWidth: articleWidth)
    : Article();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems state-duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

3 participants