변경 불가능한 콜렉션에서 변경 불가능한 "add"메소드의 가장 좋은 이름은 무엇입니까?


229

와플 제목에 대해 죄송합니다. 간결한 제목을 제시 할 수 있다면 질문을 할 필요가 없습니다.

불변 목록 유형이 있다고 가정하십시오. Foo(x)지정된 인수를 가진 새로운 불변 ​​목록을 끝에 추가 요소로 반환 하는 작업 이 있습니다. 따라서 "Hello", "immutable", "world"값으로 문자열 목록을 작성하려면 다음과 같이 작성할 수 있습니다.

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을 반환합니다.

최종 결과를 얻는 또 다른 (관용적) 방법은 다음과 같습니다.

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

내 질문은 : Foo의 가장 좋은 이름은 무엇입니까?

편집 3 : 나중에 공개 할 때 유형의 이름이 실제로는 아닐 수도 ImmutableList<T>있으므로 위치가 명확 해집니다. 대신 TestSuite프레임 워크의 일부가 불변이기 때문에 불변이라고 상상해보십시오 .

(편집 3 끝)

지금까지 내가 생각해 낸 옵션 :

  • Add: .NET에서 일반적이지만 원래 목록의 변형을 의미합니다.
  • Cons: 나는 이것이 기능적 언어에서 일반적인 이름이라고 생각하지만 그러한 언어를 경험하지 않은 사람들에게는 의미가 없다.
  • Plus: 지금까지 내가 가장 좋아하는 것은 나에게 돌연변이 암시하지 않습니다 . 분명히 이것은 Haskell 에서도 사용 되지만 약간 다른 기대치가 있습니다 (Haskell 프로그래머는 다른 목록에 단일 값을 추가하는 대신 두 목록을 함께 추가 할 것으로 기대할 수 있습니다).
  • With: 다른 불변의 규칙과 일치하지만 IMO에 대한 "추가 성"은 동일하지 않습니다.
  • And: 매우 설명 적이 지 않습니다.
  • +에 대한 연산자 과부하 : 나는 정말로 이것을 좋아하지 않습니다. 나는 일반적으로 연산자가 하위 유형에만 적용되어야한다고 생각합니다. 그래도 설득 될 것입니다!

선택에 사용하는 기준은 다음과 같습니다.

  • 메소드 호출 결과에 대한 올바른 인상을줍니다 (예 : 추가 요소가있는 원래 목록 임)
  • 기존 목록을 변경하지 않도록 최대한 명확하게합니다.
  • 위의 두 번째 예와 같이 함께 연결하면 합리적으로 들립니다

충분히 명확하지 않은 경우 자세한 내용을 문의하십시오 ...

편집 1 : 여기 선호에 대한 내 추론의 PlusAdd. 다음 두 줄의 코드를 고려하십시오.

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

(이 내 시야에서 입니다 개인 것), 후자는 분명히 버그 - 그것은 서면 같다 "X + 5;" 그 자체로 진술로. 첫 번째 줄은 불변이라는 것을 기억할 때까지 괜찮습니다. 실제로 더하기 연산자가 피연산자를 변경하지 않는 방식 Plus이 내가 가장 좋아하는 또 다른 이유 입니다. 연산자 오버로드가 약간 심하지 않으면 피연산자 (또는이 경우 메소드 대상)를 변경하지 않는 것을 포함하여 여전히 동일한 의미를 내포합니다.

편집 2 : 좋아하지 않는 이유 추가.

다양한 답변을 효과적으로 있습니다 : "이동 추가로 그 무엇. DateTime수행하고 String있다 Replace명백한 불변성을하지 않는 방법 등." 동의합니다-우선 순위가 있습니다. 사람들이 전화의 그러나, 나는 많이 보았다 DateTime.Add또는 String.Replace돌연변이를 기대합니다 . "당신은 반환 값을 무시하고 있습니다 String.Replace; 문자열은 불변이며, 새로운 문자열이 반환됩니다."

지금, 나는이 질문에 대한 미묘한를 공개한다 - 유형 수 없는 사실은 불변의리스트하지만, 다른 불변의 유형합니다. 특히, 스위트에 테스트를 추가하고 새로운 스위트를 만드는 벤치마킹 프레임 워크를 개발 중입니다. 다음이 분명 할 수 있습니다.

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

아무것도 달성하지 못하지만 다음과 같이 변경하면 훨씬 어두워집니다 .

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

괜찮을 것 같습니다. 나에게 이것은 실수를 더 명확하게 만듭니다.

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

그것은 단지 구걸하고 있습니다 :

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

이상적으로는 사용자에게 테스트 스위트가 변경 불가능하다는 것을 알리지 않기를 바랍니다. 나는 그들이 성공의 구덩이에 빠지기를 원합니다. 이 할 수없는,하지만 난 노력하고 싶습니다.

불변 목록 유형에 대해서만 이야기함으로써 원래 질문을 지나치게 단순화 한 것에 대해 사과드립니다. 모든 컬렉션이 ImmutableList<T>:) 만큼 자기 설명 적이지는 않습니다.


2
@Adam : 아니요. 후자는 분명히 버그가 있습니다. 그들은 둘 다있어 실제로 (그들은 결과에 아무것도하지 않고있는 것처럼) 버그 -하지만 먼저하지 않습니다 보면 나에게 버그.
Jon Skeet

36
고양이는 개입니까?
Michael Myers

7
Concat / Condog ...은 저에게 효과적입니다! ;)
gnovice

11
Uncat-좀비 고양이 일 것입니다.
Erik Forbes

2
@Trap : API를 유동적으로 만드는 측면에서 짜증납니다.
Jon Skeet 2016 년

답변:


130

그런 상황에서 나는 보통 Concat. 그것은 일반적으로 새로운 객체가 생성되고 있음을 의미합니다.

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

3
이것이 내가 사용하는 것입니다 .System.Linq.Enumerable이 사용하기 때문입니다. 결정은 이미 이루어졌습니다. :) IEnumerable에서 Concat 확장 프로그램의 자체 과부하를 정의하여 단일 값을 추가하도록 정의한 유일한 사람은 아닙니다.
Daniel Earwicker 2016 년

9
+1이다 프레임 워크 내에서 이름의 일관성을 유지하기위한 정답.
Sam Harwell

내가 그것을 놓치지 않으면, System.Linq.Enumerable (및 Linq는 일반적으로) "시퀀스 + 시퀀스"에 대해서만 Concat ()을 사용하고 "아이템 + 시퀀스"는 사용하지 않습니다. 누군가 "다른 목록에 단일 값을 추가하지 않고 두 개의 목록을 함께 추가 할 것으로 예상 할 수있는"문제는 다른 원래 옵션 중 하나를 사용하지 않는 이유로 명시 적으로 제공되었습니다.
Ssswift

119

한 가지 간단한 이유 때문에 단점과 함께 갈 것입니다. 그것은 정확히 당신이 원하는 것을 의미합니다.

  1. 나는 특히 소스 코드에서 내가 의미하는 바를 정확하게 말하는 것에 대한 열렬한 팬입니다. 초보자는 Cons의 정의를 한 번만 찾아야하지만이를 1,000 번 읽고 사용해야합니다. 장기적으로는 선결제 비용이 약간 더 높더라도 일반적인 경우를 더 쉽게 만드는 시스템으로 작업하는 것이 더 좋습니다.

  2. FP 경험이없는 사람들에게 "의미 없음"이라는 사실은 실제로 큰 이점입니다. 당신이 지적했듯이, 당신이 발견 한 다른 모든 단어는 이미 약간의 의미가 있으며, 그 의미는 약간 다르거 나 모호합니다. 새로운 개념 에는 새로운 단어 (또는이 경우 오래된 단어) 있어야합니다. 오히려 누군가 Add의 기능을 잘못 알고 있다고 생각하는 것보다 Cons의 정의를 찾아야합니다.

  3. 기능적 언어에서 빌린 다른 작업은 종종 명백한 재앙없이 원래 이름을 유지합니다. 나는 비 지도자들에게 더 친숙하게 들리는 "지도"와 "감소"의 동의어를 내놓으려는 어떤 추진력도 보지 못했고, 그렇게함으로써 어떤 이점도 얻지 못했다.

(전체 공개 : 저는 Lisp 프로그래머이므로 단점이 무엇인지 이미 알고 있습니다.)


16
"testSuite"를 입력하면 검색 가능성이 중요하다는 것을 잊지 마십시오. 방법 목록을 보면 올바른 것을 제안하는 방법을보고 싶습니다. 나는 아마도 내가 원하는 것 인 오프 런스에서 무의미한 (나에게) 이름을 찾지 않을 것입니다.
Jon Skeet

33
으스스한 느낌이 든다면 Add 메소드를 작성하여 message = "Cons를 사용하여 ImmutableList 앞에 추가하십시오"라는 예외를 던졌습니다. :-)
Ken

2
그 이름이 왜 그런지 설명하고 Abelson & Sussman의 "컴퓨터 프로그램의 구조 및 해석"을 언급하는 몇 줄의 주석을 읽는 사람은 아무도 죽지 않을 것입니다.
John R. Strohm

16
전통적으로 단점은 끝이 아니라 처음에 추가됩니다. 따라서 설명 된 방법의 이름이 오도 될 수 있습니다.
walkytalky

16
다음 비 기능 프로그래머를 클릭 또는 3 ... en.wikipedia.org/wiki/Construct 라는 단어에서 저장하기 위해, "x를 y에 cons"로 표현한다는 것은 ( 죄수 xy)
Myster

59

사실 나는 And특히 관용적 인 방식으로 좋아 합니다. 빈 목록에 대한 정적 읽기 전용 속성이 있고 생성자를 비공개로 만들면 항상 빈 목록에서 작성해야합니다.

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

나는 빈 아이디어를 좋아한다. 그래도 확신하지 못했습니다. 그냥 조금입니다.
Jon Skeet

자연어로 물건 목록을 구성하는 방법에 대해 생각하는 것처럼 보입니다. 크게 읽으면 추가 또는 플러스보다 직관적으로 보입니다. "목록"은 빈 목록이며 "Hello"및 "Immutable"및 "Word"입니다. 그러나 격리가 ​​명확하지 않다는 데 동의합니다.
tvanfosson

52

명명법으로 잼에 빠질 때마다 웹간에 충돌합니다.

thesaurus.com 은 "add"에 대해 이것을 반환합니다 :

정의 : 인접, 증가; 더 언급하다

동의어 : 접사, 부록, 앤티, 추가, 확대, 강화, 강화, 강화, 쌓기, 충전, 계속, 큐인, 알아 내기, 육체, 가열, 하이킹, 하이킹, 히치 온, 연결, 연결 포함, 잭업, 재즈, 함께 참여, 패드, 팔레이, 피기 백, 플러그인, 쏟아 부어, 답장, 실행, 더 말하다, 때 리고, 눈덩이, 수프, 속도 향상, 스파이크, 스텝 업, 보충, 달다, 압정, 태그

나는 Adjoin더 좋은 소리를 좋아한다 Join. 그게 네가하는 일이야? 이 방법은 다른 회원 가입에도 적용될 수 있습니다 ImmutableList<>.


1
나는 'Join'과 비슷하지만 대부분의 경우 2 개의 객체를 결합하면 1로 끝납니다.이 경우 2 개의 객체를 결합하면 실제로 새로운 객체를 생성하게됩니다.
무법자 프로그래머

1
조인이 돌연변이를 의미하는 .NET, Perl, PHP 또는 VBScript의 경우는 모르겠습니다. 디자인은 A와 B가 C를 만들기 위해 합류하도록하는데, 여기서 C는 항상 새로운 개체입니다.
spoulson

나는 Join을 좋아하고 thesaurus.com에 전적으로 동의합니다. :) 이름이 의심 될 때는 항상 사용하십시오.
Skurmedel 2016 년

var suite = new TestSuite <string, int> () .Join (x => x.Length);
교활한 그리폰

3
피기 백, imo로 가십시오. 또는 HookUpWith.
Chris Marasti-Georg

48

개인적으로 .With ()를 좋아합니다. 객체를 사용하는 경우 설명서 또는 코드 주석을 읽은 후에는 해당 기능을 명확하게하고 소스 코드에서 ok를 읽습니다.

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

또는 "함께"를 추가합니다. : :)

object.AlongWith("this new item");

+1. "WITH"는 SETL의 동일한 연산자를 수행하는 삽입 연산자입니다. 만약 SETL이 그것을 사용한다면 그것은 옳 아야한다 :-)
finnw

1
바 ... 누가 더 이상 VB를 사용합니까? :) 어 .. 죄송합니다. 크게 들렸습니까? 그러나, 모든 진지하게, 이것이 VB 문제를 제거하는 "AlongWith"를 고려한 이유입니다. 그가이 방법으로 갈 수있는 방법은 약 백만 가지뿐입니다. 그러나 게시 ... heh ..
LarryF

33

결국 BclExtras의 모든 불변 컬렉션에 대해 Add로 이동 했습니다 . 그 이유는 예측하기 쉬운 이름이기 때문입니다. 형식 이름 앞에 Immutable이라는 접두사가 붙기 때문에 Add와 mutate add를 혼동하는 사람들에 대해 크게 걱정하지 않습니다.

잠시 동안 나는 단점과 다른 기능적 스타일 이름을 고려했습니다. 결국 나는 거의 알려지지 않았기 때문에 할인했습니다. 기능 프로그래머는 이해하지만 대부분의 사용자는 아닙니다.

다른 이름 : 당신은 언급했다 :

  • 플러스 : 나는 이것에 대해 소원합니다. 나를 위해 이것은 Add보다 더 non-mutating operation으로 구별하지 않습니다.
  • 포함 : VB에 문제가 발생 함
  • 연산자 오버로딩 : 검색 가능성이 문제입니다

내가 고려한 옵션 :

  • Concat : String은 불변이며 이것을 사용하십시오. 불행히도 그것은 끝에 추가하기에 정말 좋습니다
  • CopyAdd : 무엇을 복사 하시겠습니까? 소스, 목록?
  • AddToNewList : 아마도 List에 좋은 것입니다. 그러나 컬렉션, 스택, 대기열 등은 어떻습니까?

불행히도 실제로 다음과 같은 단어는없는 것 같습니다

  1. 확실히 불변의 조작
  2. 대부분의 사용자가 이해할 수있는
  3. 4 단어 미만으로 표현 가능

List 이외의 컬렉션을 고려하면 훨씬 더 이상해집니다. 스택을 예로 들어 보겠습니다. 첫해 프로그래머조차도 스택에 푸시 / 팝 방식이 있다고 말할 수 있습니다. ImmutableStack을 만들어 완전히 다른 이름을 지정하고 Foo / Fop이라고 부르면 컬렉션을 사용하기 위해 더 많은 작업을 추가했습니다.

편집 : 플러스 편집에 대한 응답

당신이 플러스와 함께가는 곳을 봅니다. 더 강한 경우는 실제로 빼기 빼기라고 생각합니다. 내가 다음을 보았을 때 나는 분명히 세상에서 프로그래머가 무엇을 생각하고 있었는지 궁금해 할 것입니다.

list.Minus(obj);

내가 플러스 / 마이너스 또는 새로운 페어링에서 가장 큰 문제는 과잉 인 것 같은 느낌입니다. 컬렉션 자체에는 이미 고유 한 이름 인 Immutable prefix가 있습니다. 불변 접두사와 같은 구별을 추가하려는 어휘를 추가하여 더 나아가 야하는 이유는 무엇입니까?

콜 사이트 인수를 볼 수 있습니다. 단일 표현의 관점에서 더 명확합니다. 그러나 전체 기능의 맥락에서 그것은 불필요한 것 같습니다.

편집 2

사람들이 String.Concat 및 DateTime.Add에 의해 혼란스러워했다는 데 동의하십시오. 나는 매우 밝은 몇몇 프로그래머들이이 문제에 부딪 치는 것을 보았다.

그러나 ImmutableList는 다른 인수라고 생각합니다. 프로그래머에게 불변으로 설정하는 String 또는 DateTime은 없습니다. 다른 소스를 통해 변경할 없다는 것을 간단히 알아야 합니다. 따라서 혼란은 예상치 못한 것이 아닙니다.

이름이 동작을 정의하기 때문에 ImmutableList에는 문제가 없습니다. 당신은 사람들이 불변이 무엇인지 알지 못한다고 주장 할 수 있으며 그것이 또한 유효하다고 생각합니다. 나는 대학에서 2 학년까지 그것을 확실히 몰랐다. 그러나 추가 대신 선택한 이름과 동일한 문제가 있습니다.

편집 3 : 불변하지만 단어를 포함하지 않는 TestSuite와 같은 유형은 어떻습니까?

나는 이것이 새로운 메소드 이름을 발명해서는 안된다는 생각을 불러 일으킨다 고 생각합니다. 즉, 병렬 작업을 용이하게하기 위해 유형을 변경 불가능하게 만드는 드라이브가 분명히 있기 때문입니다. 컬렉션의 메서드 이름을 변경하는 데 중점을두면 다음 단계는 사용하지 않는 모든 유형의 변경 메서드 이름입니다.

대신 불변으로 식별 가능한 유형을 만드는 데 집중하는 것이 더 귀중한 노력이라고 생각합니다. 이렇게하면 모든 변경 방법 패턴을 다시 생각하지 않고도 문제를 해결할 수 있습니다.

이제 TestSuite를 불변으로 식별하는 방법은 무엇입니까? 오늘날의 환경에는 몇 가지 방법이 있다고 생각합니다

  1. 변경할 수없는 접두사 : ImmutableTestSuite
  2. Immutablitiy 레벨을 설명하는 속성을 추가하십시오. 이것은 확실히 덜 발견 가능하다
  3. 그다지 많지 않습니다.

필자의 추측 / 희망은 개발 도구가 불변의 유형을 시력 (다른 색상, 강한 글꼴 등)으로 쉽게 식별 할 수있게 하여이 문제를 돕기 시작한다는 것입니다. 그러나 나는 그것이 모든 메소드 이름을 바꾸는 것에 대한 대답이라고 생각합니다.


질문에 추가하기에 Plus를 선호하는 이유를 추가했습니다. 그 추론에 대한 의견을 환영합니다. 나는 내가 어리 석다는 생각에 정말 열려 있습니다.
Jon Skeet

@JaredPar : 타입이 TestSuite라면 어떨까요?
Jon Skeet

편집 3에 다른 +1을주고 싶지만 분명히 할 수는 없습니다. 난 아직 아니에요 - (I에 대한 이유를 쉽게 코드에 그 불변성 리드를 생각한다. 내 경우에는 내가 병렬 처리를 얻으려고 노력하고 있지 않다) 매우 추가가 갈 수있는 방법이라고 확신하지만, 여기에 대한 답변에 대한 지원 설득력이 있습니다.
Jon Skeet

직장 에서이 질문을 대화에 빠뜨릴 수 있다면 정말 좋을 것입니다. C # 목록에서 토론을 시작 했으므로 일부 동료가 이미 참여했을 수 있습니다. Google에서 내부적으로 물어볼 수도 있습니다 ...
Jon Skeet

@Jon, 나는이 질문을 직장
JaredPar

27

나는 이것이 +운영자 에게 과부하가 걸리는 드문 상황 중 하나 일 수 있다고 생각합니다 . 수학 용어에서, 우리는 그것이 +다른 것의 끝에 무언가를 추가하지 않는다는 것을 알고 있습니다. 항상 두 값을 결합하여 새로운 결과 값을 반환합니다.

예를 들어, 말할 때 직관적으로 명백합니다

x = 2 + 2;

x의 결과 값은 22가 아니라 4입니다.

비슷하게,

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

각 변수가 무엇을 보유 할 것인지 명확히해야합니다. 이 명확해야 list2되지 않은 변경 마지막 줄에, 대신 그 list3에게 "단어"를 추가 한 결과를 할당됩니다 list2.

그렇지 않으면 함수 이름을 Plus ()로 지정합니다.


정수 (예 :) 또는 다른 정수 목록을 합법적으로 추가 할 수있는 일반 목록이 있으면 어떻게 됩니까? 그런 다음 +를 사용하면 연결과 충돌합니다.
finnw 2016 년

@finnw : 당신의 요점이 보이지 않습니다. 목록을 사용하면 하나 이상의 요소를 추가하든 항상 +가 추가를 의미합니다.
Bill the Lizard

4
재사용 가능한 API의 경우 누군가가 연산자 오버로드없이 언어에서 클래스를 사용하는 경우 명명 된 메소드를 사용하는 것이 좋습니다.
Neil

"하나의 요소를 추가하든 여러 요소를 추가하든"-목록을 단일 요소로 추가하려면 어떻게해야합니까? 즉, [1] + 2 = [1,2]그러나 [1] + [2] = [1,[2]]. 당신이 제안하는 것은 일관되지 않은 행동입니다. 이것은 아마도 파이썬 이이 방식으로 하나의 요소 를 추가 할 수없는 이유 일 것입니다 .
mpen

C #과 같이 정적으로 형식이 지정된 언어에서는 목록 목록 또는 요소 목록인지 여부에 따라 목록 요소 유형이 무엇인지 알 수 있으므로 유형을 사용하여 목록에있는 하나의 요소를 추가할지 또는 연결할 요소를 결정할 수 있습니다 두 목록.
Dobes Vandermeer

22

최대한 명확하게하기 위해 wordier CopyAndAdd또는 이와 유사한 것을 사용하는 것이 좋습니다.


모든 불변 컬렉션에 추가를 위해 사본이 필요한 것은 아닙니다. 불변의 나무를 생각하면 새로운 노드가 필요하며 기존의 나무를 잎으로 사용할 수 있습니다.
JaredPar

BTW, 나는 당신의 프로필을 읽은 다음 순서대로 나이를 먹었고 당신이 몇 살인지 간략하게 놀랐습니다. 그 후 곧 정신이 차 버렸다.
JaredPar

Re first comment : 나는 나무가 너무 드물기 때문에 그 생각이 결코 일어나지 않았다. 좋은 지적입니다.
Michael Myers

두 번째 논평 : 나는 고백한다. 나는 배지를 위해 그것을했다! 나는 단지 내 나이를 포기하고 싶지 않습니다. (실제로 당신보다 젊지 만, 필요하다면 나는 오래 된 양조업자를 잘 부를 수 있습니다. 나이가 89 세인 유일한 사람은 아닙니다.)
Michael Myers

불변의 나무 주장은 강력하고 좋은 지적입니다. 따라서 EquivalentReferenceWithAdded (x)는 그 주장과 싸우지 만 어리석게 들리고 추론하기는 어렵습니다.
TheBlastOne

21

나는 부를 것이다 확장 () 또는 어쩌면 ExtendWith을 () 당신이 정말로 자세한 기분합니다.

확장이란 다른 것을 변경하지 않고 다른 것을 추가하는 것을 의미합니다. 나는 이것이 확장 메서드의 개념과 유사하기 때문에 C #에서 매우 관련성이 높은 용어라고 생각합니다. 클래스 자체를 "손질"하지 않고 클래스에 새 메서드를 "추가"합니다.

그렇지 않으면 원래 객체를 전혀 수정하지 않는다는 것을 강조하고 싶다면 Get-와 같은 접두사를 사용하면 피할 수없는 것처럼 보입니다.


1
여전히 다소 기본 객체에 무언가를하는 것을 의미합니다.
혼돈

18

추가됨 (), 추가됨 ​​()

불변 개체에 대한 작업에 과거 시제를 사용하고 싶습니다. 원본 객체를 변경하지 않는다는 생각을 전달하며, 볼 때 쉽게 알아볼 수 있습니다.

또한, 변이 분석법 이름은 종종 현재 시제 동사이기 때문에, 불변의 분석법 이름이 필요한 대부분의 경우에 적용됩니다. 예를 들어, 불변 스택에는 "pushed"및 "popped"메소드가 있습니다.


1
파이썬도이 규칙을 사용합니다. 예를 들어 내장 함수 reverse () 및 sorted ().
Joe

18

CopyAndAdd의 mmyers 제안을 좋아 합니다. "돌연변이 (mutation)"테마를 유지하면서 Bud (무성 생식), Grow , Replicate 또는 Evolve ? =)

편집 : 내 유전 적 주제를 계속하려면 Procreate는 어떻 습니까? 이전 객체를 기반으로하지만 새로운 것이 추가 된 새로운 객체가 생성되었음을 암시합니다.


14

이것은 아마도 스트레치 일 수도 있지만, 루비에는 그 구별에 일반적으로 사용되는 표기법이 있습니다 add. add!돌연변이. 이것이 프로젝트에서 널리 퍼져있는 문제라면, 알파벳이 아닌 문자 일 필요는 없지만 일관된 표기법을 사용하여 돌연변이 / 비 돌연변이 방법을 표시 할 수도 있습니다.


+1. 이것은 언어에 의해 시행되지는 않지만 협약으로 합의되었습니다. 나는 그것을 좋아한다.
oma


13

어쩌면 혼란은 하나의 작업으로 두 가지 작업을 원한다는 사실에서 비롯된 것일 수 있습니다. 왜 분리하지 않습니까? DSL 스타일 :

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

Copy원래 목록의 변경 가능한 사본 인 중간 객체를 반환합니다. With새로운 불변 ​​목록을 반환합니다.

최신 정보:

그러나 중간에 변경 가능한 컬렉션을 갖는 것은 좋은 접근 방법이 아닙니다. 작업에 중간 오브젝트가 포함되어야합니다 Copy.

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

이제 Copy작업이 변경 가능한 목록을 수신하는 델리게이트를 가져 와서 복사 결과를 제어 할 수 있습니다. 요소를 제거하거나 목록을 정렬하는 것과 같이 요소를 추가하는 것보다 훨씬 많은 작업을 수행 할 수 있습니다. 또한 ImmutableList생성자에서 중간 불변 목록없이 초기 목록을 어셈블하는 데 사용할 수 있습니다 .

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);
}

이제는 사용자가 잘못 해석 할 가능성이 없으며, 성공의 구덩이에 빠질 것 입니다.

또 다른 업데이트 :

당신은 여전히 오늘날에도이 포함되어 있다고는 변경 가능한리스트 언급 마음에 들지 않으면, 당신은 사양합니다 개체를 디자인 할 수 있습니다 지정 하거나 스크립트를 복사 작업이 목록을 변환하는 방법. 사용법은 동일합니다.

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!"));

이제 규칙 이름으로 창의력을 발휘할 수 있으며 Copy의 전체 기능이 아니라 지원 하려는 기능 만 노출 할 수 있습니다 IList.

체인 사용의 경우 합리적인 생성자를 만들 수 있습니다 (물론 체인을 사용하지 않음).

public ImmutableList(params T[] elements) ...

...

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

또는 다른 생성자에서 동일한 대리자를 사용하십시오.

var list = new ImmutableList<string>(rules => 
  rules
    .Append("Hello")
    .Append("immutable")
    .Append("World")
);

rules.Append메소드는를 리턴 한다고 가정 합니다 this.

최신 예제에서 다음과 같이 보입니다.

var suite = new TestSuite<string, int>(x => x.Length);
var otherSuite = suite.Copy(rules => 
  rules
    .Append(x => Int32.Parse(x))
    .Append(x => x.GetHashCode())
);

@Jordao : 이런 종류의 구성은 훨씬 간단한 초기화 형식으로 이어지기 때문입니다. 하나만 원할 때 왜 두 개의 개별 변수가 있습니까? 마찬가지로 변경 가능한 사본을 만들고 싶지 않습니다. IMO에 대해 추론하기 쉬운 코드로 이어지기 때문에 모든 것이 변경 불가능합니다.
Jon Skeet

이 모든 것들은 여전히 ​​"Plus"보다 다루기 힘들다. 돌연변이와 관련된 아이디어에 감사하지만, 나는 "불변의 유지"접근법을 선호한다.
Jon Skeet

어쩌면 작업의 실제 의미가 무엇인지에 대한 오해가 항상있을 수 있습니다. 사양 객체 경로를 따르면, 최소한 외부에서는 진행되지 않는 돌연변이가 없으며, 객체는 새로운 불변 ​​객체가 어떻게 보일지를 지정합니다. 당신이 가진 것은 불변의 한 객체에서 다른 객체로 이동하는 작업이며, 복사라고하기 때문에 오해의 여지가 없습니다.
Jordão

당신에게 맞는 유일한 이름은 CopyAndAppend, CopyAndAdd 등과 같은 복합적인 이름 인 것 같습니다.
Jordão

1
나는 실제로 불변의 컬렉션에 대한 API로서 (모든 편집과 함께)이 접근법을 더 잘 발전시키고 있습니다. 그러나 Concat과 같은 기본 사양에 대한 도우미 메서드 와이 방법을 결합하면 두 가지 이점 중 최고를 제공 한다고 주장합니다 .
hep

11

몇 가지 임의의 생각 :

  • ImmutableAdd ()
  • 추가 ()
  • ImmutableList <T> (ImmutableList <T> originalList, T newItem) 생성자

1
ImmutableAdd의 경우 +1; Append (열악한 StringBuilder.Append와 너무 비슷)에 치열하지 않으며 생성자 버전은 연결 측면에서 고통 스럽습니다.
Jon Skeet

10

C #의 DateTime은 추가를 사용합니다. 왜 같은 이름을 사용하지 않습니까? 클래스 사용자가 클래스를 변경할 수 없다는 것을 이해하는 한.


DateTime.Add가 사람들을 혼란스럽게하는 것으로 알려져 있다고 주장하지만 우선 순위를 보여줍니다.
Jon Skeet

1
문자열을 변경하는 방법은 새로운 개발자에게 혼란을주는 것과 같습니다. 그러나 곧 모든 사람들이 "현은
변할 수 없다

9

나는 당신이 표현하려고하기 어려운 핵심은 순열이 아니라고 생각합니다. 따라서 CopyWith () 또는 InstancePlus ()와 같은 생성 단어가있는 것입니다.


9

나는 영어가 "추가"와 같은 것을 의미하는 동사를 사용하면서 틀림없이 불변성을 암시 할 수 있다고 생각하지 않습니다. "플러스"는 거의 가능하지만 사람들은 여전히 ​​실수를 저지를 수 있습니다.

사용자가 변경 가능한 것으로 객체를 잘못 이해하지 못하게하는 유일한 방법은 객체 이름이나 메서드 이름을 통해 명시 적으로 만드는 것입니다 ( "GetCopyWith"와 같은 자세한 옵션 사용) "CopyAndAdd").

좋아하는 "플러스"로 가십시오.


9

먼저 흥미로운 출발점 : http://en.wikipedia.org/wiki/Naming_conventions_(programming) ... 특히 하단의 "참조"링크를 확인하십시오.

나는 Plus 또는 And를 똑같이 선호합니다.

플러스와 앤은 어원학에서 수학을 기반으로합니다. 따라서 두 가지 모두 수학 연산을 의미합니다. 둘 다 값으로 해석 될 수있는 표현식으로 자연스럽게 읽는 표현식을 생성하며, 이는 리턴 값을 갖는 메소드에 적합합니다. And추가 논리 의미를 갖지만 두 단어 모두 목록에 직관적으로 적용됩니다. Add객체의 수행 된 동작을 의미하며, 이는 메소드의 불변의 의미와 충돌합니다.

둘 다 짧으며, 작업의 기본 성을 고려할 때 특히 중요합니다. 단순하고 자주 수행되는 작업은 이름이 짧아야합니다.

불변의 의미론을 표현하는 것은 컨텍스트를 통해 선호하는 것입니다. 즉,이 전체 코드 블록이 기능적으로 느껴진다는 것을 의미합니다. 모든 것이 불변이라고 가정하십시오. 그러나 그것은 단지 나일 수 있습니다. 나는 불변성을 규칙으로 선호한다. 완료되면 같은 장소에서 많이 수행됩니다. 가변성 은 예외입니다.


8

Chain () 또는 Attach ()는 어떻습니까?


1
변이와 같은 소리를냅니다. 아마도 WithAttached는 더 현명 할 것이지만 위에서 논의한 WithAdded와 매우 가깝습니다.
TheBlastOne

이것으로 무엇을하려고하는지 설명 할 때 "체인"이 몇 번이나 언급되는지는 재미 있습니다. (5 회), 제안으로 제공되지 않았습니다! visualthesaurus.com내가 검색 할 때 가장 먼저 나타났습니다 (가맹 없음) concatenate.
cod3monk3y

7

나는 플러스와 마이너스를 선호합니다. 그것들은 쉽게 이해할 수 있으며 잘 알려진 불변 유형 (숫자)과 관련된 작업에 직접 매핑됩니다. 2 + 2는 2의 값을 변경하지 않고 동일하고 불변의 새로운 값을 반환합니다.

다른 가능성 :

접착()

부정 이득()

늘리다()


6

방법에 대한 동료 , mateWith , 또는 성교 준수 사람들을 위해. 재생산의 관점에서 포유류는 일반적으로 불변으로 간주됩니다.

던져가는 연합 (EU)을 너무 거기에서. SQL에서 차용했습니다.


2
유니언 +1 그러나 나는 그것을 이론에서 직접 빌려왔다. :-)
Christoffer Lette

SQL이 정해진 이론으로부터 많은 용어를 얻지 못합니까?
Jason D

1
또한 Union은 구별을 의미합니다. 중복을 포함 시키려면 (적어도 TSQL에서는) Union All을 명시 적으로 사용해야합니다.
hep

6

분명히 나는이 질문에 대답 한 최초의 Obj-C / Cocoa 사람입니다.

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

이 코드 골프 게임에서 이길 수 없습니다.


[object]By[Verb]ing[Object]:이 메소드 의 접두어 +1은 단순히 [verb][Object]:객체가 변경되지 않고 단순히 새로운 문자열이 반환되는 것을 의미합니다 .
Dave DeLong

3
+1. 나는 사람들의 자세한 언어 혐오 (일명 자기 문서화)를 이해하지 못한다.
hatfinch

5

"추가"또는 "플러스"가 잘 들립니다. 리스트 자체의 이름은리스트의 불변성을 전달하기에 충분해야합니다.


그것은 목록이 아니며 테스트 스위트입니다.
tstenner

5

어쩌면 "Concatenate"와 같이 인스턴스를 변경하는 대신 사본을 만들고 그 내용을 추가하는 것을 기억하는 단어가있을 수 있습니다. 그러나 다른 행동에 대해 그 단어에 대해 대칭을 갖는 것이 좋을 것이라고 생각합니다. 나는 "연결"과 같은 종류의 생각 "제거"에 대한 비슷한 단어를 모른다. "플러스"는 조금 이상하게 들립니다. 숫자가 아닌 컨텍스트에서 사용되는 것으로 기대하지 않습니다. 그러나 그것은 내 영어가 아닌 배경에서 나올 수도 있습니다.

어쩌면 나는이 계획을 사용할 것입니다

AddToCopy
RemoveFromCopy
InsertIntoCopy

내가 생각할 때 이것들은 그들 자신의 문제가 있습니다. 그들이 무언가를 제거하거나 주어진 논쟁에 무언가를 추가한다고 생각할 수 있습니다. 전혀 확실하지 않습니다. 그 말도 연쇄 적으로 잘 재생되지 않는다고 생각합니다. 입력하기에 너무 장황합니다.

어쩌면 나는 평범한 "Add"와 친구들도 사용할 것입니다. 나는 그것이 수학에서 사용되는 방법을 좋아한다

Add 1 to 2 and you get 3

확실히, 2는 2로 남아 있고 새로운 숫자를 얻습니다. 이것은 목록과 요소가 아니라 두 개의 숫자에 관한 것이지만, 나는 그것이 비슷한 것으로 생각합니다. 내 의견으로 add는 반드시 무언가를 변경한다는 의미는 아닙니다. 확실히 add반환 된 새로운 객체를 사용하지 않고 포함 된 외로운 문장 이 버그가없는 것으로 보입니다. 그러나 나는 또한 "add"가 아닌 다른 이름을 사용한다는 아이디어에 대해 어느 정도 시간을 생각했지만 "hmm, 나는 무엇을 알기 위해 문서를 볼 필요가 없습니다. "add"라고 부르는 것과 이름이 다르기 때문입니다. litb에서 이것에 대한 이상한 생각, 전혀 이해가되지 않습니다 :)


그러나 불변 컬렉션에는 항상 사본이 필요한 것은 아닙니다. 바이너리 트리를 예로 들어 보자. 새로운 루트를 추가하려면 복사 할 필요가 없습니다. 잎 중 하나가 오래된 나무 인 새로운 값
JaredPar

KISS-이름이 구현 세부 사항을 포함하기 시작하면 모든 메소드 이름이 너무 길어질 것입니다. "추가"는 간단하고 작업을 수행합니다.
mP.

1
@ mP : 다시 말하지만 "구현 세부 사항"이라는 문구를 부적절하다고 생각하는 방식으로 사용하십시오. 링크 된 목록이든 후드 아래의 배열이든 구현 세부 사항입니다. API를 변경하지 않고 구현 을 변경할 수 있습니다 . 불변의 양상은 구현 세부 사항 이 아닙니다 .
Jon Skeet

1
권리. JaredPar, 그러나 실제로 트리를 복사하거나 기존 트리를 사용하여 반환 된 새 트리의 리프로 사용 하는지 여부도 중요하지 않다고 생각합니다 . 즉, 그것은 단지 구현 세부 사항입니다. Java의 문자열 클래스에 대한 하위 문자열 작업과 동일합니다 (믿습니다).
Johannes Schaub-litb


5

나는 그렇게 생각 Plus()하고 Minus()또는, 대안 Including(), Excluding()에서 합리적인 의미 불변의 행동을.

그러나 명명 선택이 모든 사람에게 완벽하게 명확하지는 않으므로 개인적으로 좋은 XML 문서 주석은 여기에 매우 먼 길을 갈 것이라고 믿습니다. VS는 IDE에서 코드를 작성할 때 이러한 것들을 당신의 얼굴에 던져 넣습니다. 무시하기 어렵습니다.


4

Append- System.String메소드의 이름은 인스턴스를 변경한다고 제안하지만 그렇지는 않습니다.

또는 나는 아주 좋아한다 AfterAppending:

void test()
{
  Bar bar = new Bar();
  List list = bar.AfterAppending("foo");
}

이전의 DateTime 인수와 마찬가지로 많은 프로그래머 문자열 메소드가 작업을 수행 한다고 기대 하지 않는다면 우선 순위에 동의합니다 . 문자열은 불변이라는 것을 (때로는 반복해서) 알려줘야합니다. 나는 성공의 구덩이에 내 고객 개발자를 유혹하고 싶습니다 :)
Jon Skeet

나는 Append가 점점 더 좋아집니다. 컬렉션을 변경하지 않고 참여하고 있다는 것을 구별합니다.

4

list.CopyWith(element)

스몰 토크와 마찬가지로 :)

또한 list.copyWithout(element)요소의 모든 항목 list.copyWithout(null)을 제거 하므로 설정되지 않은 요소를 제거 할 때 가장 유용 합니다.


3

더 나은 이름의 이점을 볼 수 있기 때문에 Add로 이동하지만 문제는 클래스가 매우 익숙하지 않은 다른 불변의 모든 작업에 대해 다른 이름을 찾는 것입니다.


네, 요점을 봅니다. 나는 여전히 Plus를 선호한다고 생각하지만 고려할만한 가치가 있습니다.
Jon Skeet

고마워 존. 프레임 워크를 사용하기를 기대합니다. 나는 그것에 대해 읽었고 아주 좋아 보인다. 다시 감사합니다.
Joan Venge
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.