dart-lang / language

Design of the Dart language
Other
2.61k stars 200 forks source link

Provide canonical way to reference a specific class #3959

Open gaaclarke opened 5 days ago

gaaclarke commented 5 days ago

The problem

The Dart language doesn't have a way to specify exactly what class one is talking about canonically. This is a minor nuisance when communicating between humans or to an LLM where one must say something like "an instance of Color from 'dart:ui'". However, a lack of consistency when communicating about Dart classes is also an impediment when building semantic understanding in an LLM.

Here is an example of something I've had to request to an LLM:

okay, now switch the color preview so it isn't drawing a Color object from 'dart:ui', but instead is drawing an Image object from 'dart:ui' that is just a solid color

Proposal

I propose we make an additional form for import to codify a format for communicating about specific classes. I don't think the form has much value to users programmatically, but meta-language-wise it is valuable.

import 'dart:ui/Color';
import 'package:foo/foo.dart/Foo'

These would behave similarly to:

import 'dart:ui' show Color;
import 'package:foo/foo.dart' show Foo;

After this is established I could request to the LLM:

okay, now switch the color preview so it isn't drawing a 'dart:ui/Color', but instead is drawing a 'dart:ui/Image' that is just a solid color

Wdestroier commented 5 days ago

We already have import 'dart:ui' as ui show Color;. However, the IDE won't suggest imports from 'dart:ui' if we have a show clause. Or the IDE won't add imports to the show clause, I don't remember well. Which is very inconvenient, unless it works now.

gaaclarke commented 5 days ago

Ah right, thanks. I'll update the example.

lrhn commented 4 days ago

One problem is that the library URIs are not globally unique. Almost in practice, but it's not guranteed. They definitely doesn't account for the version of the package, and different versions can have different APIs.

The suggested syntax is a problem. The .dart is just a convention, so import 'package:foo/foo.dart/Foo'; is already defined to mean import the file Foo in directory /foo.dart/ of package:foo. The syntax is already taken.

A more realistic syntax could be package:foo/foo.dart#Foo, which identifies thie file package:foo/foo.dart and the fragment of that file with name Foo, which is exactly what a declaration named Foo is.

It could be useful to have a global (semi-)unique way to identify a declaration. The "libraryURI#name" is sufficient so far, but with agumentations, one migth want to denote the individual syntactic declarations that combine to a liibrary member. Might need fileUri#Name#number for the numberth declaration named Name in in the file identified by fileUri.

It's non-trivial. Code is not static, it evolves over time, and references have to be either very high-level, or they should expect to become stale. Even high-level references can get stale accross major package versions.