On 14 Oct 2021, at 12:21 PM, Steven D'Aprano <steve@pearwood.info> wrote:


Why abbreviate list and tuple but not string?

Empty strings would be confusing as a type unless you mean a Literal empty string.     We just limit the picture of the type to lists, tuples, dicts, and sets. Builtin most often used collections. Imagine you have a default parameter like this... name: “” = “”. This adds unnecessary confusion.

Not really. Your first example is explicit and I can get the meaning by 
just reading it out loud:

   tuple[list[list[str]], list[list[str]]]

   "tuple (of) list (of) list (of) str, list (of) list (of) str

Your abbreviated version:

   ([[str]], [[str]])

is too terse. I have to stop and think about what it means, not just 
read it out loud. Without the hint of named types (tuple and list), my 
first reaction to seeing [str] is "is this an optional string?".

I am a visual guy. ([[str]], [[str]]) is much easier to my eyes than reading tuple (of) list (of) list (of) str, list (of) list (of) str. 

don't look like "optional" to me

Optional would be Optional[str] or str | None, not [str]. 

No, because the # indicates that the rest of the line is a comment. This 
is already legal:

   def func(d: {str  # this is an actual comment
                : int}) -> Any: ...

so this would be ambiguous between a real comment and an annotation.

Even if we agreed to change the behaviour of comments, you suggested:

   func(d: {str # product label: [float] # prices from 2000 to 2015})

How is the interpreter to know that the first annotation is just

   "product label"

rather than this?

   "product label: [float] # prices from 2000 to 2015"

So I don't think this works.


# is not a good idea I agree. How about the following for Annotated:

func(d: {str & "product label": [float]  & "prices from 2000 to 2015"})? 

The “&” is similar to “& co.” (and company). They come together but the first one is the group leader and represents all of them. It works in an opposite way to “|” (or), which gives importance equally to the members. 

def func(
time: float & “hours” & datetime.timedelta.total_seconds()/3600,
verbose: bool & “option for long text” = False,
) -> str: … 

Abdulla