Comments (4)
Finding good names for positional parameters is not always possible - especially for callbacks. E.g. the parameter of Iterable map
declared in Iterable<T> map<T>( T toElement( E e ) )
is named "e", which is no better than $1
; no matter what other name you choose as a replacement for e
in this declaration, it cannot be specific enough to capture the meaning - so will become a version of $1
, just with a less predictable identifier.
When we use the current syntax, we can assign a more semantic name like listOfRabbits.map((rabbit)->rabbit.age))
, or maybe
something shorter like listOfRabbits.map((r)->r.age))
, but listOfRabbits.map((e)->e.age))
is hardly the best candidate.
In any case, using $1
won't cause more problems than e
.
The same problem of finding a good name can be encountered across dart APIs. The parameter of sqrt
is called x
; you can try to rename it into arg
or anything - and it won't be better than $1
. (Interesting, but trivial, observation: when we pass parameters into direct calls, the semantic name in the program translates to a meaningless name inside a function:
in pow(rabbitPopulation, 10)
: "rabbitPopulation" becomes "x" inside "pow"; in callbacks, we see the reverse: meaningless name can acquire meaning).
I find a bit strange that after introducing records, dart hasn't allowed the names like $n
also to refer to positional parameters. This would be rarely needed, but would still solve the problem of passing parameters conditionally:
foo(
$1: if (cond) 42,
$2: "hello"
);
from language.
(Cont-d)
A much bigger problem IMO is that the proposed syntax, no matter if we write => a + b
or => $1 + $2
, does not scale. If we want to insert a print, we need to fully refactor - because the syntax is designed for a single-expression body.
foo(=>a + b);
// becomes
foo((a, b) { print(a); return a+b; }
These expressions have nothing in common, thus breaking the principle of syntax similarity/dissimilarity between similar/dissimilar "things". The current syntax doesn't scale well either, but
foo((a, b)=> a+b);
foo((a, b) { return a + b; });
at least have a common (a, b)
part. With the new syntax, any similarity is gone - the two expressions look like they came from two different worlds.
As an alternative, consider the syntax :{ $1 + $2 }
(I mentioned it in the parallel thread). It unifies both forms and can be back-ported to the existing syntax:
mylist.map(:{ print($1); $1*$1 });
rabbits.map((rabbit) { print(rabbit); rabbit.age }; // no semicolon after the last expression, no explicit "return"
// plus evaluation syntax
foo(${ print("in anonymous function"); 2+2 });
// as a replacement for IIFE
foo((){ print("in anonymous function"); return 2+2; }());
Nitpick: I browsed the dart core API trying to discern the naming conventions for positional parameters in current libraries.
One thing that baffled me a bit was this declaration:
double sin(num radians)
.
Today, no one cares, but if you make the names "official", it's better to avoid this word "radians". sin(x)
and its friends are defined for real numbers, otherwise we get cos(radians: sin( radians: pi/2))
, which is absurd. I checked other languages (java, C#, python) - they call the parameter x
or a
, and mention radians only in the description. (the parameter names in math functions are not very consistent in respective libraries: sometimes it's "a", sometimes "x", or "d", but always a single-letter identifier).
It's not that easy to come up with good names after all!
from language.
My main worry about making names of positional parameters significant, is that existing code wasn't written for it, and after the feature has launched, changing those names is a breaking change.
The toElement(e)
is a good example, it should probably have been convert(element)
, to be consistent with other declarations. But it had never mattered, so it was never fixed.
If function literal shorthand uses the names of the context type, like a callback parameter, that's a position where people have so far been even less inclined to consider the names than they would in directly callable APIs, after all they're the only one who'll call the function. If they have a name at all. Falling back on $1…$n if the parameters have no name is probably fine.
(Not going to discuss the precise syntax for function literal shorthands here, that has its own issue.)
IMO: The arguments to sin
and cos
are radians, so if the code looks weird if you write that out, maybe it's the code that's weird - why it's someone passing the output of sin
, a number in the range -1..1, into cos
which expects a number in the range -pi..pi? Single argument functions aren't the target audience for named positional arguments, but this one actually doesn't worry me. It's not like cos(x: sin (x: pi/2))
is easier to read, it's just shorter, but omitting the x:
is even shorter.
from language.
I have to disagree on radians, but this is beside the point here (it can be a subject for a philosophical discussion).
A bigger issue is that the feature will necessitate a fair amount of change across dart APIs without clear justification.
For normal functions (not callbacks) it's all about conditional parameters, which are rarely needed, and even then, $n
syntax achieves the same with no modifications to the existing code.
For callbacks, you will have variable names falling from the sky. When we denote the parameters as $n
, it's at least clear that they are the parameters. If $1
becomes an element
- the name comes from nowhere, may conflict with something in your code, too long for the occasion, etc. If you estimate cost/benefit ratio, it won't work in favor of the feature :-)
(As for =>expr
notation, you will probably have to admit that it goes against your own syntax/semantics principles:-)
from language.
Related Issues (20)
- Is future returned immediatelly from async call? Inconsistency in docs HOT 3
- Allow augmenting member declarations immediately in the same body? HOT 7
- [parts-with-imports] Consider dropping the library name from the library directive HOT 1
- Infer the type of an optional parameter from the default value
- Should digit separators be supported in int.fromEnvironment? HOT 1
- Support for Rust like #[cfg()] attributes HOT 10
- [parts-with-imports] Conditional part directives and the analyzer HOT 20
- Allow all variable augmentations to omit the initializing expression HOT 4
- `Error: Method not found` when running Flutter app with macro class HOT 2
- Allow a variable initializer to be unresolved, following the treatment of abstract members HOT 3
- Allow Iterators To Use The for-in Syntax HOT 5
- Macros: Emit diagnostics inside macro arguments HOT 2
- URI shorthands without internal whitespace.
- URI shorthands, allow reserved words.
- URI shorthands, more permissive HOT 1
- [analyzer] Switch cases for destructured records do not promote types HOT 5
- Inheriting a type parameter bound?
- Ordering of augmenting initializers and getters on late variables
- Generalize mixin inference to other superinterfaces? HOT 1
- False negative `unreachable_switch_case` diagnostic when using `switch` statements
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from language.