关于语言不可知:对于不可变集合上的非变异“添加”方法的最佳名称是什么?

What's the best name for a non-mutating “add” method on an immutable collection?

抱歉,我的华夫飞标题-如果我能想出一个简洁的标题,我就不必问这个问题。

假设我有一个不变的列表类型。它有一个操作Foo(x),它返回一个新的不可变列表,并在末尾将指定的参数作为一个额外元素。因此,要用值"hello"、"immutable"、"world"构建字符串列表,您可以编写:

1
2
3
4
var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");

(这是C代码,如果你觉得语言很重要,我对C建议最感兴趣。这从根本上说不是语言问题,但语言的成语可能很重要。)

重要的是,现有列表没有被Foo更改,所以empty.Count仍然返回0。

达到最终结果的另一种(更惯用的)方法是:

1
2
3
var list = new ImmutableList<string>().Foo("Hello")
                                      .Foo("immutable")
                                      .Foo("word");

我的问题是:foo最好叫什么名字?

编辑3:正如我稍后所揭示的,类型的名称实际上可能不是ImmutableList,这使得位置清晰。假设它是TestSuite,它是不变的,因为它所包含的整个框架是不变的……

(编辑3结束)

到目前为止,我提出的选择是:

  • Add:在.NET中很常见,但意味着原始列表的突变。
  • Cons:我认为这是功能语言中的正常名称,但对于那些没有这种语言经验的人来说毫无意义。
  • Plus:到目前为止我最喜欢的,这并不意味着我会有突变。显然,这在haskell中也被使用,但是期望值略有不同(haskell程序员可能希望它将两个列表一起添加,而不是将单个值添加到另一个列表中)。
  • With:与其他一些不变的约定相一致,但在imo中没有完全相同的"附加性"。
  • And:不太具描述性。
  • +的运算符重载:我真的不太喜欢这样;我通常认为运算符只应应用于较低级别的类型。但我愿意被说服!

我选择的标准是:

  • 给出方法调用结果的正确印象(即它是带有额外元素的原始列表)
  • 尽可能清楚地表明它不会改变现有列表
  • 像上面的第二个例子一样,当链接在一起时听起来很合理

如果我不够清楚的话,请询问更多细节…

编辑1:这是我选择Plus而不是Add的理由。考虑这两行代码:

1
2
list.Add(foo);
list.Plus(foo);

在我看来(这是一件私人的事情),后者显然是错误的——就像写"x+5";作为一个声明。第一行看起来没问题,直到你记住它是不变的。事实上,加号运算符本身不改变其操作数的方式是我最喜欢Plus的另一个原因。不需要稍微讨厌操作符重载,它仍然提供相同的含义,包括(对我来说)不改变操作数(在本例中是方法目标)。

编辑2:不喜欢添加的原因。

各种答案都是有效的:"继续添加。这就是DateTime所做的,StringReplace方法等,这些方法不会使不可变性变得明显。"我同意,这里有优先权。然而,我见过很多人称之为DateTime.AddString.Replace,并期待突变。有大量的新闻组问题(如果我仔细研究的话,可能也是这样)的答案是"你忽略了EDOCX1的返回值(17);字符串是不可变的,会返回一个新的字符串。"

现在,我应该向您展示这个问题的一个微妙之处——类型可能不是一个不变的列表,而是另一个不变的类型。特别是,我正在研究一个基准框架,在这个框架中,您向一个套件添加测试,并创建一个新的套件。很明显:

1
2
var list = new ImmutableList<string>();
list.Add("foo");

不会完成任何事情,但是当你把它改为:

1
2
var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);

看起来应该没事的。然而,对我来说,这使错误更加明显:

1
2
var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);

那只是乞求:

1
var suite = new TestSuite<string, int>().Plus(x => x.Length);

理想情况下,我希望我的用户不必被告知测试套件是不可变的。我希望他们陷入成功的深渊。这可能不可能,但我想试试。

我为只讨论不可变的列表类型而过度简化原始问题而道歉。并不是所有的收藏品都像ImmutableList那样自我描述。


在这种情况下,我通常和Concat一起去。这通常意味着一个新的对象正在被创建。

1
2
var p = listA.Concat(listB);
var k = listA.Concat(item);


我同意反对,有一个简单的原因:这正是你想要的。

  • 我非常喜欢准确地说出我的意思,尤其是在源代码中。一个新手只需要查找一次cons的定义,然后阅读和使用一千次。我发现,从长远来看,与使常见情况更容易发生的系统合作会更好,即使前期成本有点高。

  • 事实上,这对于没有FP经验的人来说是"毫无意义的",这实际上是一个很大的优势。正如您所指出的,您发现的所有其他单词都已经有了一些含义,而这个含义要么略有不同,要么模棱两可。一个新的概念应该有一个新词(或者在本例中是一个旧词)。我宁愿有人去查缺点的定义,而不是错误地假设他知道加法的作用。

  • 从函数语言中借用的其他操作通常保留其原始名称,没有明显的灾难。我还没有看到有人推动提出"map"和"reduce"的同义词,这听起来更为非FPER所熟悉,我也没有看到这样做的任何好处。

  • (完全公开:我是一个Lisp程序员,所以我已经知道了cons的含义。)


    实际上,我喜欢And,特别是在惯用的方式。如果空列表有一个静态只读属性,并且可能将构造函数设为私有的,那么我特别希望它能够从空列表中构建。

    1
    2
    3
    var list = ImmutableList<string>.Empty.And("Hello")
                                          .And("Immutable")
                                          .And("Word");


    每当我遇到术语上的麻烦时,我就会打开InterWebs。

    thesaurus.com将此返回"添加":

    Definition: adjoin, increase; make
    further comment

    Synonyms: affix,
    annex, ante, append, augment, beef
    up, boost, build up, charge up,
    continue, cue in, figure in, flesh
    out, heat up, hike, hike up, hitch on,
    hook on, hook up with, include, jack
    up, jazz up, join together, pad,
    parlay, piggyback, plug into, pour it
    on, reply, run up, say further, slap
    on, snowball, soup up, speed up,
    spike, step up, supplement, sweeten,
    tack on, tag

    我喜欢Adjoin的声音,或者更简单地说,Join的声音。这就是你要做的,对吧?该方法也可用于其它ImmutableList<>的连接。


    就我个人而言,我喜欢.with()。如果我在使用这个对象,在阅读文档或代码注释之后,它将很清楚它做了什么,并且在源代码中读取OK。

    1
    object.With("My new item as well");

    或者,你加上"随同"。:)

    1
    object.AlongWith("this new item");


    最后我在bclextras中使用了所有不可变集合的add。原因是它是一个容易预测的名字。我不太担心人们混淆添加和可变添加,因为类型的名称前缀是不可变的。好的。

    有一段时间,我考虑了cons和其他功能风格名称。最后,我打了折扣,因为他们不太出名。当然,功能程序员会理解,但他们不是大多数用户。好的。

    其他名称:您提到:好的。

    • 另外:我很想洗这个。对我来说,这并不像add那样将它区分为一个非变异操作。
    • 与:将导致问题与vb(双关语意图)
    • 运算符重载:可发现性将是一个问题

    我考虑的选择:好的。

    • concat:字符串是不可变的,使用它。不幸的是,这只对增加结尾有好处
    • 复制:复制什么?来源,名单?
    • addtonewlist:也许是一个很好的列表。但是集合、堆栈、队列等呢…

    不幸的是,似乎没有一个词是好的。

  • 绝对是不可变的操作
  • 大多数用户都能理解
  • 少于4个字可表示
  • 当您考虑除列表之外的集合时,它会变得更加奇怪。以堆栈为例。即使是第一年的程序员也可以告诉您堆栈有一对推/弹出的方法。如果你创建了一个不变的图钉并给它一个完全不同的名字,我们称之为foo/foop,你只是为他们添加了更多的工作来使用你的集合。好的。

    编辑:对加编辑的响应好的。

    我知道你要和plus一起去哪里。我认为一个更强大的案例实际上是减去删除。如果我看到下面的内容,我肯定会想知道程序员到底在想什么。好的。

    1
    list.Minus(obj);

    我遇到的最大的问题是正负或是新的配对让我觉得有点过头了。集合本身已经有一个可区分的名称,即不可变的前缀。为什么还要添加词汇表呢?词汇表的目的是添加与不可变前缀相同的区别。好的。

    我可以看到调用站点的参数。从一个表达的角度来看,它更清晰。但在整个函数的上下文中,这似乎是不必要的。好的。

    编辑2好的。

    同意人们肯定被string.concat和datetime.add混淆了。我见过几个非常聪明的程序员遇到这个问题。好的。

    然而,我认为不变列表是另一种观点。对于程序员来说,没有任何关于字符串或日期时间的东西可以将其建立为不可变的。你必须简单地知道,通过其他来源它是不变的。因此,这种混乱并非出乎意料。好的。

    不可变列表没有这个问题,因为名称定义了它的行为。你可以说人们不知道什么是不变的,我认为这也是正确的。直到大学二年级我才知道。但无论你选择什么名字,而不是添加什么名字,你都有同样的问题。好的。

    编辑3:像testsuite这样不可变但不包含单词的类型怎么办?好的。

    我认为这让你明白了不应该发明新方法名的想法。也就是说,为了方便并行操作,显然有一个驱动器可以使类型不可变。如果您将重点放在更改集合方法的名称上,那么下一步将是对您使用的不可变的每种类型使用可变的方法名称。好的。

    我认为这将是一个更有价值的工作,而不是专注于使类型可识别为不可变的。这样,您就可以解决问题,而无需重新考虑现有的每个变化方法模式。好的。

    现在,如何将测试套件标识为不可变?在今天的环境中,我认为有几种方法好的。

  • 前缀不可变:不可变测试套件
  • 添加描述不可变级别的属性。这肯定不太容易被发现。
  • 没有别的了。
  • 我的猜测/希望是开发工具将开始帮助解决这个问题,使通过视觉(不同的颜色、更强的字体等)很容易识别不可变的类型。但我认为这是一个解决方案,尽管改变了所有的方法名。好的。好啊。


    我认为这可能是少数情况之一,在这种情况下,可以接受超载的+运营商。在数学术语中,我们知道+不会在其他内容的末尾附加内容。它总是将两个值组合在一起,并返回一个新的结果值。

    例如,当你说

    1
    x = 2 + 2;

    x的结果值是4,而不是22。

    同样地,

    1
    2
    3
    4
    var empty = new ImmutableList<string>();
    var list1 = empty +"Hello";
    var list2 = list1 +"immutable";
    var list3 = list2 +"word";

    应该明确每个变量将保存什么。应该清楚的是,list2在最后一行没有改变,而是把"word"附加到list2的结果分配给list3

    否则,我只需将函数命名为plus()。


    尽可能清楚地说,你可能会想用更多话的CopyAndAdd,或者类似的东西。


    如果你觉得很冗长,我可以叫它extend()或者extendwith()。

    扩展意味着在不更改的情况下向其他内容添加内容。我认为这是C中非常相关的术语,因为这类似于扩展方法的概念——它们"添加"了一个新方法到类中,而不"接触"类本身。

    否则,如果你真的想强调你根本不修改原始对象,使用一些前缀,比如get-对我来说是不可避免的。


    我喜欢mmyers关于复制和添加的建议。为了符合"突变"的主题,也许你可以选择芽(无性生殖)、生长、复制或进化?=)

    编辑:继续我的基因主题,生育如何,暗示一个新的对象是基于前一个,但添加了一些新的东西。


    added(),added())

    我喜欢用过去时来处理不可变的对象。它传达了这样一个观点:你不会改变原始物体,当你看到它时很容易辨认出来。

    另外,由于方法名的变化通常是现在时态动词,所以它适用于您遇到的大多数不可变的方法名所需的情况。例如,不可变堆栈具有方法"pushed"和"popped"。


    这可能是一个延伸,但在Ruby中,有一个常用的区别符号:Add不变异;add!变异。如果这是项目中普遍存在的问题,您也可以这样做(不一定是使用非字母字符,但始终使用表示法来指示变异/非变异方法)。


    Join似乎合适。


    stems from the…the听到事实,你想在一个操作。他们为什么不分开?风格:DSLP></

    1
    2
    var list = new ImmutableList<string>("Hello");
    var list2 = list.Copy().With("World!");

    西安市中级Copy会返回对象,这是在mutable copy of the original列表。在immutable With会返回列表。P></

    更新:P></

    但是,也有在中间,mutable is not a collection的好方法。茶叶中含茶Copyshould be对象操作:P></

    1
    2
    var list1 = new ImmutableList<string>("Hello");
    var list2 = list1.Copy(list => list.Add("World!"));

    现在,Copythe operation which receives需要委派,在mutable list,so that the copy它可以调控的结果。它可以做很多超过appending安除尘元素或元素,sorting like the list。used in the can also be en to the initial assemble ImmutableList构造函数没有中介immutable lists列表。P></

    1
    2
    3
    4
    5
    6
    public ImmutableList<T> Copy(Action<IList<T>> mutate) {
      if (mutate == null) return this;
      var list = new List<T>(this);
      mutate(list);
      return new ImmutableList<T>(list);
    }

    现在没有可能性,misinterpretation by the of users into the Fall,they will of坑自然成功。P></

    更新:yet anotherP></

    如果你不喜欢我,甚至现在mutable拉提列表,它包含对象的名称,你可以设计,这将specify或脚本,how the copy操作变换,将其名单。will be the same the usage:P></

    1
    2
    3
    var list1 = new ImmutableList<string>("Hello");
    // rules is a specification object, that takes commands to run in the copied collection
    var list2 = list1.Copy(rules => rules.Append("World!"));

    现在你can be with the rules创意的名称,你可以,你只想Copyexpose to the功能性支持能力,not the of an IList全部。P></

    chaining for the reasonable usage,你可以创建构造函数(which will not of使用chaining,道):P></

    1
    2
    3
    4
    5
    public ImmutableList(params T[] elements) ...

    ...

    var list = new ImmutableList<string>("Hello","immutable","World");

    在另一个使用or the same委托构造函数:P></

    1
    2
    3
    4
    5
    6
    var list = new ImmutableList<string>(rules =>
      rules
        .Append("Hello")
        .Append("immutable")
        .Append("World")
    );

    这assumes that the method thisrules.Append归来。P></

    这是什么样的面貌,你会用新的实例:P></

    1
    2
    3
    4
    5
    6
    var suite = new TestSuite<string, int>(x => x.Length);
    var otherSuite = suite.Copy(rules =>
      rules
        .Append(x => Int32.Parse(x))
        .Append(x => x.GetHashCode())
    );


    一些随机的想法:

    • 不可变的()
    • 附件()
    • 不可变列表(immutablelistoriginallist,t newitem)构造函数


    C中的日期时间使用加法。那么为什么不使用相同的名字呢?只要你的类的用户知道类是不可变的。


    首先,一个有趣的起点:http://en.wikipedia.org/wiki/naming_conventions_uu(programming)…特别是,检查底部的"see also"链接。

    我赞成加或加,实际上是一样的。

    加和和都是基于词源学的数学。因此,两者都意味着数学运算;两者都会生成一个表达式,自然地将其作为表达式读取,该表达式可以解析为一个值,这与具有返回值的方法相匹配。And具有附加的逻辑内涵,但这两个词都直观地适用于列表。Add表示对对象执行的操作,与方法的不变语义冲突。

    两者都很短,考虑到操作的原始性,这一点尤为重要。简单、经常执行的操作应该使用较短的名称。

    我更喜欢通过上下文来表达不变的语义。也就是说,我宁愿简单地暗示这整个代码块都有一种功能上的感觉;假设所有东西都是不可变的。不过,那可能只是我。我更喜欢不可变的规则;如果它被做了,它在同一个地方被做了很多;易变性是例外。


    我不认为英语会让你在使用一个动词时以一种明确无误的方式暗示不可变,而这个动词的意思和"添加"相同。加上"几乎可以做到,但人们仍然可以犯错误。

    要防止用户误认为对象是可变的,唯一的方法就是通过对象本身的名称或方法的名称(如"getcopywith"或"copyandadd"等详细选项)将其显式地表示出来。

    所以你只需选择你最喜欢的"加"。


    我认为你想表达的关键是非术语,所以可能是一些有生词的词,比如copyWith()或instancePlus()。


    chain()或attach()怎么样?


    我第一apparently对象C to this question/可可人答案。P></

    1
    2
    3
    4
    NNString *empty = [[NSString alloc] init];
    NSString *list1 = [empty stringByAppendingString:@"Hello"];
    NSString *list2 = [list1 stringByAppendingString:@"immutable"];
    NSString *list3 = [list2 stringByAppendingString:@"word"];

    不想赢任何高尔夫游戏with this队列。P></


    我喜欢加(和减)。它们很容易理解,并直接映射到涉及已知不可变类型(数字)的操作。2+2不改变2的值,它返回一个新的,同样不变的值。

    其他一些可能性:

    拼接()

    格拉夫()

    增生()


    对于那些生活在一起的人来说,伴侣、伴侣或性交如何?就繁殖而言,哺乳动物通常被认为是不可变的。

    也要把工会扔出去。从SQL中借用。


    也许有些单词更能让我记住复制和添加内容,而不是改变实例(比如"concatenate")。但我认为,对于其他行为来说,这些词也有一些对称性是很好的。我不知道"remove"这个词和"concatenate"这个词有什么相似之处。加上"听起来有点奇怪。我不希望它在非数字环境中使用。但那也可能来自我的非英语背景。

    也许我会用这个方案

    1
    2
    3
    AddToCopy
    RemoveFromCopy
    InsertIntoCopy

    不过,当我想到这些的时候,它们也有自己的问题。人们可能认为他们删除了一些东西,或者在给出的论点中添加了一些东西。一点也不确定。我想,这些话也不适合用链子锁起来。文字太多,无法键入。

    也许我也会使用简单的"添加"和朋友。我喜欢它在数学中的用法

    1
    Add 1 to 2 and you get 3

    当然,2仍然是2,你会得到一个新的数字。这是关于两个数字,不是关于一个列表和一个元素,但我认为它有一些类似之处。在我看来,add并不一定意味着你会发生变异。我当然明白你的观点,如果一个单独的语句只包含一个add,并且不使用返回的新对象,那么它看起来就没有问题。但是我现在也考虑过使用另一个名字而不是"添加"的想法,但是我只是想不出另一个名字,如果不让我想到"嗯,我需要查看文档来了解它是关于什么的",因为它的名字不同于我所期望的"添加"。只是有点奇怪的想法,从Litb,不确定是否有意义:)


    在http://thesaurus.reference.com/browse/add和http://thesaurus.reference.com/browse/plus上,我发现了增益和词缀,但我不确定它们有多意味着非突变。


    我认为,Plus()Minus()或者,或者,Including()Excluding()在暗示不可变行为方面是合理的。

    然而,没有任何命名选择能让每个人都清楚地知道,所以我个人认为一个好的XML文档注释在这里会有很长的路要走。当您在IDE中编写代码时,VS会直接将这些代码抛到您的脸上——它们很难被忽略。


    我觉得"加"或"加"听起来不错。列表本身的名称应该足以表达列表的不可变性。


    list.CopyWith(element)

    和Smalltalk一样:)

    以及删除一个元素的所有出现的list.copyWithout(element),当用作list.copyWithout(null)删除未设置的元素时最有用。


    Append—因为,请注意,System.String方法的名称表明它们改变了实例,但它们没有。

    或者我很喜欢AfterAppending

    1
    2
    3
    4
    5
    void test()
    {
      Bar bar = new Bar();
      List list = bar.AfterAppending("foo");
    }


    也许在静态方法或安社(which is静电)会是最好的。它会把责任的情况下,和外卖from the users will,就知道that the operation of the to不属于任何情况下。重要的是specially not to their方法使用扩展的方法,因为resemblance to the usage defeats河畔审的目的。P></

    静态方法是Joincalled the:P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static class ListOperations {
      public static ImmutableList<T> Join<T>(ImmutableList<T> list, T tail) {
        // ...
      }
      public static ImmutableList<T> Join<T>(T head, ImmutableList<T> list) {
        // ...
      }
      public static ImmutableList<T> Join<T>(ImmutableList<T> list1, ImmutableList<T> list2) {
        // ...
      }
      // substitutes chaining:
      public static ImmutableList<T> Join<T>(ImmutableList<T> list, params T[] tail) {
        // ...
      }
    }

    // ....

    var list = new ImmutableList<string>("Hello");
    var list2 = ListOperations.Join(list,"immutable"); // inferred type parameter
    var list3 = ListOperations.Join(list2,"world!");

    但我喜欢# HIFI级,C函数在自由。or something like java' least静电设备的进出口。P></

    经营者:是+theP></

    1
    2
    3
    var list = new ImmutableList<string>("Hello");
    var list2 = list +"immutable";
    var list3 = list2 +"world!";

    但我宁愿用something else like to be可以<<::or which are not possible .,# C。P></

    静态成员函数也期待更多,我认为这immutable themselves更好的借景。P></


    我个人喜欢unite(),因为当你联合对象的时候,你仍然保持着它们的个性,但是它们的结合是一个独立的新实体。Union与建议的相似,但在集合论中已经有了很好的定义,unite更直言不讳,对我说,按照这种方法,我有了一个新的先验。我知道很晚了,但他们在名单上找不到建议。加上这个词让我想起了老人们团结起来参战的日子。和合


    我会选择"添加",因为我可以看到更好的名称的好处,但问题是为每个其他不变的操作找到不同的名称,如果这有意义的话,可能会使类变得非常陌生。


    加上去的名字读起来很好,比加上去的名字好,可以作为形容词来读。

    1
    var list2 = list1.WithAdded("immutable");

    或者对于更详细的版本:

    1
    var list2 = list1.WithAddedElement("immutable");


    我会选择list.NewList("word"),因为它描述了你在做什么(创建一个新的列表)。

    我必须同意,这并不意味着争论被添加到列表的末尾,但我个人属于简洁的阵营(如果可能的话),所以我赞成list.NewList("word")而不是list.NewListAfterAppend("word")


    2点建议:

    "自由"功能:

    1
    2
    Foo f = new Foo(whatever);
    Foo fPlusSomething = Foo.Concat(f, something);

    构造函数重载(在某种程度上,它是"自由函数"主题的变体):

    1
    2
    Foo f = new Foo(whatever);
    Foo fPlusSomething = new Foo(f, something);

    埃多克斯1〔12〕怎么样?

    原因:1。对于建议使用的单字名,在检查文档之前,我不确定它们的作用。2。对于迄今为止提出的化合物名称,我更喜欢cloneWith。我很清楚这个方法的名称是什么,它相对简洁,很容易记住,而且它只是"感觉"对:)三。随着现代代码在大多数编程工具中的完成,更长的名称比以前更容易使用。

    虽然许多时候简洁增加了清晰度,但如果你必须选择,就要用简洁取代简洁。

    行动中:

    1
    2
    3
    4
    var empty = new ImmutableList<string>();
    var list1 = empty.cloneWith("Hello");
    var list2 = list1.cloneWith("immutable");
    var list3 = list2.cloneWith("word");


    我参加聚会有点晚了,但我没有看到一个简单的建议根本不去做的答案!让它保持不变。你所用的任何方法,当他们把它放进循环中时,都会受到滥用,这最终会发生。相反,我建议用建筑工人代替。

    1
    2
    MyImmutableBuilder builder = new MyImmutableBuilder(someImmutable);
    MyImmutable modifiedImmultable = builder.add(element1).add(element2).build();

    在不可变列表的情况下,您的构建器很可能只是一个列表。

    我想一切都归结为…你真的想要一种简单的方法,只向不变的集合中添加一个元素?如果这是常见的情况,您可能不想使用不可变的对象(您可以随时调用build(),在当前状态下发送对象的快照…)如果这不是常见的情况,那么将构建器作为一个要求来执行它不会是一个明显的障碍,特别是如果它被记录在案这就是你想要建立它们的方式。

    @超级卫星-考虑您描述的以下场景:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Stack a = someImmutableStackOfSize(10);
    Stack b = a.popAndCopy(); // size 9
    Stack c = a.popAndCopy(); // also size 9
    // a b and c have the same backing list
    Stack d = b.pushAndCopy("node1");
    Stack e = c.pushAndCopy("node2");
    // because d and e had the same backing list, how will it
    // know that d's last element is node1, but e's last
    // element is node2?


    copyWithSuffix:是一个自定义方法名,与objective-c不可变字符串复制方法stringByAppendingString:类似。

    1
    2
    3
    4
    var suite = new TestSuite<string>();
    suite = suite.CopyWithSuffix("Str1")
                 .CopyWithSuffix("Str2")
                 .CopyWithSuffix("Str3");

    Suffix表示它的加法性,Copy表示不可变性。可以用更符合逻辑的测试套件替换Suffix(也许你没有把它们后缀到一个大的内部字符串上,你可以为我所知道的所有内容提供测试用例名称/参数)。


    虽然正确命名方法可以减少误用的可能性,但是如果有语言结构告诉编译器:"这个方法除了返回一个新对象之外什么也不做,它应该被使用,或者方法调用没有意义",那么每当有人在错误的设置中使用该方法时,编译器可能会抱怨错误/警告。

    我已经填写了一个功能请求,如果您同意,请随意投票。


    作为C++ STL的程序员和爱好者of the add_copy放出来。(这也会和我replace_copyremove_copy蓝晶石,在线)P></


    我个人会和AddVoid或是VoidAdd的另一条路走。


    任何暗示将返回相同类型的对象的名称都可以使用。plus是一个很好的名称,就好像您加上两个期望返回结果的对象一样。

    不过,在这个实例中,plus听起来不像是正确的名称,因为您正在将一个测试"加"到一个测试套件中。

    getWith()听起来像是一个选项。或者gettypewith(),其中类型显然是您使用的类型。例如:

    1
    2
    3
    4
    5
    6
    7
    var list = new ImmutableList<String>();
    var list2 = list.GetWith("First");
    var list3 = list2.GetWith("Second");

    // OR

    var list2 = list.GetListWith("First");

    get意味着您正在获取已经包含的列表,with意味着您需要另一个对象。copyWith()也将满足此条件。

    我看到GetWith的直接问题是它不容易猜测。开发人员希望添加套件,而不是获取当前套件。我会立即输入。添加并希望intellisence显示的内容非常接近我的预期。


    1)问题分析问题摘要可以是:
    从不变的…获得一个新的不变的,但不同于原来的。
    在当前问题上下文中:
    从一个不可变列表中,得到一个新的不可变列表,该列表的结尾除了新元素之外,还具有新元素的差异。

    能否给出一个有效的"动词"(编程语言中的"方法"),不使用简单的"添加"动词,而以简洁的方式表示动作。

    2)提案分析
    第一个概念:不可变给出类似的不可变,
    >>"copy"verb express conservation in"content"but less for it defined constraints(immutable)
    >>"clone"verb express conservative in"content",but also for its defined constraints.
    >>"twin"动词类似于clone,但在软件中不常见,但它很短且声音很好。

    第二个概念:结果给出了与原来不同的东西>>"Add"Express an action to make the difference between original and the new object but by definition we do not act(mutate)an immutable.
    >>"plus"表示动词结果将在不干扰原始对象的情况下得到增强的事实…副词"approach is more"immutable"friendly
    >>"with"和前面一样,它表达了这样一个事实,"动词"可以做更多的事情,但可能与它将做更多的事情有矛盾。也可以表示"动词参数"是"动词"的"更多"这一事实

    3)回答< BR>带动词"clone"
    >>增强克隆
    >>growclone
    >>extendclone
    带"with"
    >>clonewith
    >>增强克隆With
    >>growclonewith
    >>extendclonewith

    带动词"twin"
    >>AugmentTwin
    >>GrowTwin
    >>extendtwin
    带"with"
    >>TwinWith
    >>AugmentTwinWith
    >>GrowTwinWith
    >>extendWinWith


    如果你是一个功能性程序员,这有几个名字:

    1
    (++)

    发音为"append"。或者可能是Concat,这取决于您的类型:

    1
    2
    3
    4
    5
    -- join two things into one thing:
    append :: a -> a -> a    

    -- join many things into one thing
    concat :: [a] -> a

    或者你可能是指(:),也就是说cons

    1
    (:) :: a -> [a] -> [a]

    如果你要把事情放在清单的最前面,那么如果它排在最后,你就要把它排在第1位(17位)。

    至少这就是我们过去20年来一直在说的"把东西添加到哈斯克尔土地的清单上"。

    注意,这不是算术(+),因为它是单正弦的,不是环。


    这似乎可以归结为找到一个表示对象未被修改的单词。另外,它被克隆,作为参数传递的元素被添加到克隆列表的末尾。像addclone这样的标准名称永远不会覆盖它。可能clone_and_append也相当模糊,因为append部分可能意味着参数被附加到原始列表中。因此,它可能类似于clone_and_append_to_clone或更好的append_to_clone,虽然这并不意味着将通过这种方法返回克隆,而是克隆已经作为origina列表的一部分存在。

    因此,在查找不意味着对原始列表进行修改并且建议创建新列表的名称时,请考虑以下内容:

  • 分支——var list1 = list.Offshoot("tail")——在最严格的意义上,分支指的是新元素,而不是整个新列表。另一个明显的缺点是它不是一个动作,更正确的名称是list.CreateOffshoot。但是,我发现它清楚地表明了这样一个事实:新列表将包含原始列表,并且新元素将出现在列表的末尾。
  • 产卵——var list1 = list.Spawn("tail")——与前一种相似。其优点是它是一个操作,但这意味着新列表将包含原始列表的可能性较小。
  • branchoff——var list1 = list.BranchOff("tail")——一个建议将克隆原始列表的操作。一个潜在的模糊性是,参数元素的使用方式并不十分清楚。

  • 由于类型名是不可变列表,因此指定它是不可变的,所以我认为.add()是可以的。但是,如果你真的坚持其他的东西,我可能会选择像.addex()这样的东西,其中ex意味着扩展,并暗示用户应该在使用前(通过阅读文档)确定该ex是什么。我也喜欢plus()和getcopywith()的建议


    "替换"?它不会添加到列表中,而是将列表替换为新列表。


    .trail意味着对列表的理解非常强烈,这个对象在列表后面,它没有被添加到列表中。

    1
    2
    3
    var list = new ImmutableList<string>().Trail("Hello");
                                          .Trail("immutable");
                                          .Trail("word");

    我将使用简单的add()。如果您想表示这实际上是一个集合操作,则另一个选择是append()。

    除了显式方法之外,我仍然建议实现obverloaded+operator。这是一个众所周知的手术。每个人都知道字符串是不可变的,但是每个人都使用"+"来构建它的新实例。


    我喜欢(和)。我认为它最不可能产生歧义。我能想到的唯一冲突是与逻辑和,我不认为这是一个C开发人员的问题,甚至对于VB,我认为上下文不太可能造成问题,任何问题都会在编译时迅速解决。它在英语中也很有效,"对这些和那个做点什么"或者"把这些和那个放在盒子里"。

    我想用()可以。我担心的是它可能看起来有点像linq where<>方法,特别是如果有一个lambda作为参数。我脑子里的英语也不太清楚,尤其是"用它来做些什么"。

    我不喜欢.plus()。我不能把它当作add:plus=plus sign=+=add的同义词。


    "增强"怎么样?

    这是一个不同于"添加"的词,但它是一个相近的同义词。


    "Ad"()

    它返回新列表的事实并不重要,这是由签名显示的实现细节。该方法完成的主要操作是"向列表中添加"一个新元素。它定义或返回的方式或内容不应是方法名的一部分。如果同步了一个方法,会影响方法名-"SynchronizedAdd()"????-当然不是。

    像字符串这样的类仍然有非常简单的方法名,其中没有一个是复合词。


    我去overloading +与经营者。the reason is that‘s的方式工作在.append()EN Python列表mutates on a while the list with another,做+创源列表,在列表中。当然+also does not imply突变。我想这就是为什么我知道你喜欢.Plus()多了,如果你不想,那么你可以去经营者超载,与.Plus()。P></


    一个很晚的答案,但我想加上我的两分:我认为这里的重点可能是动词时态,而不是动词本身:

    1
    var output= myList.joinedWith("Element"); //or AddedTo, ConcatenatedTo...

    在我看来,分词改变了它的含义:我们不会在mylist中添加任何内容,而是返回操作的结果。


    我知道这是在打败一匹看起来死了的马,但我认为你可能会用一种奇怪的方式接近它(因此命名困难)。当我有一个不可变的对象时,我不经常期望该对象具有暗示可变的函数(如add或addall)。我知道string&datetime可以做到这一点,但即使我已经成为忘记使用datetime/string函数结果的牺牲品,因此如果可能的话,我可以避免这些陷阱。

    如果我是你,我会遵循类似于番石榴使用的建设者模式。请参见Guava中的不可变集合。基本上,概念是用它将要包含的所有内容构造不变的对象。如果要生成新的不可变对象,则需要使用新的生成器。

    1
    var suite = new TestSuite.Builder<string, int>().add(newTest).build();

    您可以在构建器上进行扩展,以允许在用户调用构建之前对测试套件进行各种修改(如果愿意,可以使用标准的列表命名约定,如添加/删除)。


    就个人而言,如果你追求一种流畅的风格,我会选择pad(..),或者使用an d with(..)的扩展方法。

    1
    2
    3
    var list = new ImmutableList<string>().Pad("Hello")
                                          .AndWith("immutable")
                                          .AndWith("word");

    String.Replace这样的方法的问题在于,用户可能错误地认为发生了突变,因为他可以忽略返回值。因此,使用out参数作为"返回"值。用户不能忽略:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class ImmutableList<T> {
      public ImmutableList(params T[] items) {
        // ...
      }
      /// <summary>
      /// Creates a new list with the items in this list plus the supplied items.
      /// </summary>
      /// <param name="newList">
      /// The new list created for the operation.
      /// This is also the return value of this method.
      /// </param>
      /// <param name="items">Items to add to the new list.</param>
      /// <returns>The new list.</returns>
      public ImmutableList<T> Add(out ImmutableList<T> newList, params T[] items) {
        // ...
      }
    }

    用途:

    1
    2
    3
    var list = new ImmutableList<string>("Hello","Immutable");
    ImmutableList<string> newList;
    list.Add(out newList,"World");


    向C借钱,你看1〔7〕怎么样?


    我会选择"CreateNewListWithAdditionalItems"

    我不介意长的名字,但这一个告诉你它实际上会做什么。另外,如果您使用add或任何其他更改方法,我也会抛出一个异常。


    对于这种函数,我通常在第二种形式中使用动词,在本例中使用Added

    qt使用此约定,例如,QVector2D::normalized返回标准化向量,而QVector2D::normalize规范化向量。

    以同样的方式,Added将返回带有新添加项的对象。


    personally会呼叫和呼叫Clonethe method that is as the parameter AdditionalValueappears to be做什么本质的摇篮和easily understandable例如P></

    1
    2
    3
    4
    var empty = new ImmutableList<string>();
    var list1 = empty.Clone("Hello");
    var list2 = list1.Clone("immutable");
    var list3 = list2.Clone("word");


    我将使用构造函数。

    1
    2
    3
    Foo f1 = new Foo("one");
    Foo f2 = new Foo(f1,"two");
    Foo f3 = new Foo(f2,"three");

    F1包含"一"。F2包含"一"、"二"。F3包含"一"、"二"、"三"。


    list.copyandappend(英语教学)P></

    how does that sound?)P></


    所以我猜名为"immutabledd()"的方法完全过于简单化了?


    既然这个问题现在基本上是一个同义词库:那么.Bring()呢?如中所示,给我这个列表并把这个元素带来?

    1
    2
    3
    Foo = List.Bring('short');
              .Bring('longer');
              .Bring('woah');

    它不会从舌头上脱落,但对我来说,它意味着它。

    实际上,AndBring()可能更好。


    AugmentAugmentWith方法创建包装类怎么样?


    C-ISH伪代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    interface Foo
    {
        // Constructors
        Foo();
        Foo(params Foo[] foos);

        // Instance method
        Foo Join(params Foo[] foos);

        // Class method
        static Foo Join(params Foo[] foos);
    }

    所以你可以这样称呼:

    1
    2
    3
    4
    5
    var f0 = new Foo();
    var f1 = new Foo(new Foo(), new Foo(), new Foo());
    var f2 = Foo.Join(new Foo(), new Foo(), new Foo());
    var f3 = f0.Join(new Foo(), new Foo(), new Foo());
    var f4 = new Foo(new Foo(new Foo()), new Foo(), new Foo(new Foo()));

    等。。。。


    扩展方法怎么样?在这种情况下,你可以称之为Join。作为一种扩展方法,用户应该知道它是一种静态方法,因此可能会给他们一点停顿,并鼓励他们查看返回值。同时,您拥有"实例"方法的可用性。

    1
    2
    3
    4
    5
    public static ImmutableList<T> Join(this ImmutableList<T> body, T tail)
    {
        // add robust error checking in case either is null...
        return new ImmutableList<T>(body, tail);
    }

    后来…

    1
    2
    3
    var list = new ImmutableList<string>().Join("Hello")
                                          .Join("Extensible")
                                          .Join("World");

    我不太清楚在发布多个答案时可以接受的行为,但这是一个有趣的问题,因为我认为命名法是设计中的一个关键步骤,我的大脑一直在思考这个问题。


    比赛进行得很晚,但是Freeze怎么样?在wpf中,优先使用FreezeIsFrozen来测试对象是否可变。当然,这有点扭曲了通常情况下Freeze()的含义,因为它是一种使当前对象不可变的方法,但是如果它有一个参数,您可以看到您得到的是不可变的东西。

    1
    2
    3
    var list = new ImmutableList<string>().Freeze("Hello")
                                          .Freeze("Fridgid")
                                          .Freeze("World");

    基本上:

  • 这是一个词
  • 其内涵围绕着不变性展开。
  • wpf中"相似"语法的进位。

  • 我称之为包括

    1
    2
    3
    4
    var empty = new ImmutableList<string>();
    var list1 = empty.ToInclude("Hello");
    var list2 = list1.ToInclude("immutable");
    var list3 = list2.ToInclude("word");

    习惯用法(?)

    1
    2
    3
    var list = new ImmutableList<string>().ToInclude("Hello");
                                          .ToInclude("immutable");
                                          .ToInclude("word");

    也适用于你提到的案例。

    1
    2
    3
    var list = new ImmutableList<string>();list.ToInclude("foo");

    var suite = new TestSuite<string, int>();suite.ToInclude(x => x.Length);

    另一个有利于Plus的观点是最新不变的Java时间API,其中EDCOX1 OR 4是用来添加到EDCOX1×5秒的API。


    我来晚了一点,纽威怎么样?


    "Stick"或"Stickto"怎么样,它在末端粘贴一个元素。

    或"附加"或"附加"。


    我previously作为上述,你想给你的东西和AT 2盎司for that只是微优化的目的。如果离开原来的Copying occurs collection类定义,"文件名称"、"append"只会混淆。P></

    "cloneappend"就是在这情况会使用。我的不好的东西tells T在这情况。我相信,很快你会find yourself need of other of similar中奇特的"或"操作clonefirstn cloneremovelast"类"。和你很快明白那是多好的克隆复制链/法/无论You need,append remove the collection back to then convert,甚至如果它需要额外的immutable of an在线队列。P></