Coder Social home page Coder Social logo

Comments (4)

tatumizer avatar tatumizer commented on July 22, 2024

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.

tatumizer avatar tatumizer commented on July 22, 2024

(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.

lrhn avatar lrhn commented on July 22, 2024

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.

tatumizer avatar tatumizer commented on July 22, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.