Generics 模板/通用语法字符

Generics 模板/通用语法字符,generics,syntax,language-design,Generics,Syntax,Language Design,我正在为模板/泛型设计语法。C++语言使用角度括号进行此操作,但我正在使用分隔符来代替。例如,您可以在Java中编写: Map<String, Foo> foos = new HashMap<String, Foo>(); 我试图决定分隔符字符是什么;它不能字面上是*,因为它已经被用于乘法(不是说我不能重载它,而是优先级是错误的)。查看可用字符,以下是一些选项: .foos = hmap!string!foo .foos = hmap$string$foo .foos

我正在为模板/泛型设计语法。C++语言使用角度括号进行此操作,但我正在使用分隔符来代替。例如,您可以在Java中编写:

Map<String, Foo> foos = new HashMap<String, Foo>();
我试图决定分隔符字符是什么;它不能字面上是*,因为它已经被用于乘法(不是说我不能重载它,而是优先级是错误的)。查看可用字符,以下是一些选项:

.foos = hmap!string!foo
.foos = hmap$string$foo
.foos = hmap?string?foo
.foos = hmap^string^foo
.foos = hmap`string`foo
.foos = hmap|string|foo
.foos = hmap~string~foo
由于这在某种程度上是一个美学问题,我想我应该做一个调查:你最喜欢哪种选择?还有其他更可取的选择吗?(像往常一样,如果您的答案已经发布,请向上投票,而不是重复。)

此外,在标准的美国键盘上,“是非移位的,其他键盘都需要shift键。国际键盘有区别吗?是否有任何键盘布局,上面的任何候选人都特别容易或难以键入


(因为这是一个没有单一正确答案的问题,它是否应该是一个社区wiki?

尖括号比您的选项更适合我,因为它们将元素与其他代码进行了视觉分离


我会尝试类似的
{}
()
,如果它们还没有被使用的话。

我认为这些符号中的任何一个都不能清楚地表明您将类型参数列表应用于泛型类型

为什么不像在大多数常见语言中那样使用括号语法呢

Map<String, Foo>
(或分别为
{}
/
()

请注意,与OCaml或Haskell中一样,空白也可以非常全面地使用

foos : int list


一些更广泛的理论:简单泛型类型是带有
*->*
的类型,因此它必须被视为从一个类型到另一个类型的函数

List
泛型类型构造函数
List
应用于具体类型
Int
,从而生成另一种具体类型-专用列表

因此,我喜欢泛型专门化以某种方式类似于函数应用程序

*
的使用在键入时是有意义的!因此,如果您想依赖运算符语法,那么
Map String*Foo实际上是一个不错的选择,因为它区分了类型构造函数和(元组)类型参数。

.foos = hmap(string, foo)

这是一种很好的语法:允许将类型用作返回新类型的“函数”。

出于其他人提到的原因,我对其中任何一种都不太感兴趣。括号只是用来表示这类事情,不管它是否是<{[(等等)。这里有4个选项

您列出的选项中的一些具体要点:

    .foos = hmap!string!foo - could be confused with negation.
    .foos = hmap$string$foo 
    .foos = hmap?string?foo - just doesn't look very definitive, the question mark makes me think you are saying it may be a string
    .foos = hmap^string^foo 
    .foos = hmap`string`foo - tricky to find the key!
    .foos = hmap|string|foo - could be confused with an 'or' operation
    .foos = hmap~string~foo 

一般来说,我不喜欢中缀运算符,因为它会引起关于关联性的问题

例如是
hmap*string*foo
一个
hmap
hmap
或可能是
foo

也许你应该使用“of”关键字:

在Boo中,它将如下所示:

map = HashMap[of string, Foo]()

确实如此。也许我应该使用!然后遵循这个先例?(我必须使用显式标记字符来消除对象创建的歧义,并且我不能使用尖括号,因为它们对于比较运算符来说是不明确的。)@卢瓦莱斯:你想创建什么样的语法?当然你可以在不同的上下文中使用相同的符号。达里奥-没错,但我正在尝试创建一种最小化冗余的语法,这意味着我必须小心潜在的歧义;我正在尝试确保最常见的操作具有最简洁的语法。在语法还是实际语言?想想F#。在算术方面,我们有
1*2
(*)
作为一个部分应用的函数,以及类型上下文中的
int*string
。这是大量的符号重用,但非常清楚。好吧,让我们假设我写list*float 100是指创建一个浮点数列表,最初为100个元素分配足够的空间。函数调用(我的语法是并置的)绑定比乘法更紧密,因此将解析为list*(float 100),不是期望的结果;这就是为什么我认为我需要使用与*不同的字符,除非我遗漏了什么。我还认为泛型专门化类似于函数应用程序。在一些函数语言中,我对函数参数使用并置,所以f(a,b)如果我使用类似于hmap!string!foo的东西来进行泛型专门化,我喜欢将其视为函数应用程序的一种变体,其中空格被替换为不同的字符以消除歧义。@rwallace:那么,
$
可能有点合适;)但这种语法必然意味着类型转换,这在非函数语言中可能有点像couterintuitive。因此,元组方法或简单括号可能更好(只是我的观点)。请注意,这些符号中的任何一个都很难从简单的光学角度区分单个类型。必须使用空格或至少使用大小不同的符号,如“或”*。这是一个很好的观点,但我想我确实需要使用类型转换。在我看来,数组最一致地表示为泛型,因此,例如array!float是一个浮点数数组(任意长度)数组!float!100是一个由100个浮点数组成的数组。你是说$^或~~会比!更好,因为视觉上更清晰?括号都是经过充分讨论的,唉。但是你提出了一些好的观点。好吧,“,”出局了;`可能是不明智的,尽管未移位的符号很诱人。至少我用了一个关键字不,所以!是明确的。在你的语言中可能是明确的。是的,但是你必须记住,阅读代码的人必须能够对代码的含义有一个模糊的概念
.foos = hmap(string, foo)
    .foos = hmap!string!foo - could be confused with negation.
    .foos = hmap$string$foo 
    .foos = hmap?string?foo - just doesn't look very definitive, the question mark makes me think you are saying it may be a string
    .foos = hmap^string^foo 
    .foos = hmap`string`foo - tricky to find the key!
    .foos = hmap|string|foo - could be confused with an 'or' operation
    .foos = hmap~string~foo 
map = HashMap of String, Foo()
map = HashMap[of string, Foo]()