관용구는 무엇입니까?


19

나는 "이디엄"이 특정 언어에서 정수 증가와 같은 핵심 언어 구문에 의해 단순화되지 않는 일반적인 연산이나 패턴이라는 것을 이해합니다.

i = i + 1;

C ++에서이 관용구는 연산자로 단순화됩니다.

++i;

그러나 누군가가 "관념적"이라는 용어를 사용할 때, 그것을 이해하는 방법을 잘 모르겠습니다. 코드를 "아이디 오 매틱"하게 만드는 것은 무엇입니까?


이것은 english.stackexchange.com 과 마찬가지로 여기에 있습니다.
S.Lott

@ perl.j : 통찰력. 당신은 왜 "Idiomatic"의 정의가 english.stackexchange.com에 속하지 않는지를 분명히 알았습니다. 매우 도움이됩니다.
S.Lott

답변:


24

일부 코드를 작성하는 관용적 방법은 다른 언어에는없는 언어 별 관용구 때문에 매우 구체적인 방식으로 코드를 작성할 때입니다.

예를 들어 C ++에서 RAII 관용구를 악용하면 관용적 인 리소스를 관리하는 C ++ 코드를 작성하는 방법이 생깁니다.

또 다른 예는 파이썬에서 목록 이해를 사용하여 목록을 생성하는 것입니다. 관용적 파이썬에서 목록 이해를 사용했기 때문에 관용적이지만 다른 언어 또는 파이썬에서도 생성기 함수를 사용하여 동일하게 수행 할 수 있기 때문에 관용적입니다.

종종이 언어와 관련된 관용구를 사용하지 않고 새로운 언어를 시도하는 사람은 관용적 코드를 쓰지 않을 것입니다.


훌륭한 설명. 따라서 C # TryAdd()에서 Generic Dictionary클래스에서 호출 된 확장 메서드 를 먼저 확인한 !Contains()다음 호출 Add()하면 관용적입니까? C #-확장 방법과 관련된 기능을 사용하고 있습니다.
void.pointer

1
가장 경험이 많은 C ++ 코더가 가능한 경우 멤버를 추가하는 대신 클래스를 확장하기 위해 무료 함수를 작성하라고 말할 것입니다. C # 확장 메서드와 동일하지는 않지만 무료 기능을 허용하는 모든 언어에서 사용할 수 있습니다. 내가 확신하는 것은 속성을 사용하여 C #에서 "set / getters"를 작성하는 것이 관용적이라는 것입니다.
Klaim

그러나 이것은 C ++이 아니므로 "C ++ 방식"을 사용하는 것이 "아이디 오 매틱"하지 않을 수 있습니다. 확장 방법을 사용하는 것은 합리적이고 매우 C #과 비슷합니다. 어쨌든 그것은 예제 였지만 확장 방법은 C #에 관용적입니다.
void.pointer

그렇기 때문에 "확실하지 않다"고 말하면서 관용구를 느끼지만 다른 언어의 다른 기본 기능과 너무 가까워서 확실하지 않습니다 (C # 개발자가 아니기 때문에). 또 다른 예가 있습니다. 루핑은 모든 기능적 언어에서 재귀에 의해 수행됩니다. 다른 언어로도 할 수 있지만 분명히 기능적 언어에 관용적입니다. 그것이 도움이되는지 확실하지 않습니다.
클라 임

1
물론 파이썬은 관용적 코드, 즉 pythonic을 참조하는 관용적 방법을 가짐으로써 한 단계 더 나아갑니다. * 8 ')
Mark Booth

12

일반 정의

원어민에게 자연스러운 표현 사용, 포함 또는 표시

프로그래밍 정의

[Insert Language] 프로그래머 에게 자연스러운 표현식 사용, 포함 또는 표시


1
이 용어에 대한 "google"정의가 도움이되었다고 생각되면 여기에 게시하지 않았을 것입니다. 예제로 더 나은 설명 (자습서처럼)을 원했습니다.
void.pointer

3
@Robert-이해가 안되는 이유를 이해하지 못하는 것 같습니다.
ChaosPandion

2
나는 당신의 대답을 먼저 읽었습니다. 정확하지 않았습니다. 이제 내 답변으로 표시된 응답을 읽은 후 "아이디 오 매틱"의 의미가 매우 명확 해졌으며 이제는 이해합니다. 이제 당신의 대답을 읽었으니 말이됩니다. 그러나 당신은 나에게 예제와 다른 시나리오를 안내하지 않았으므로 귀하의 답변이 도움이되지 않았다고 생각합니다. 기술적으로 정확하지만 이해하는 데 도움이되지 않는 "웹스터"응답을 제공했습니다. 그래도 당신의 도움에 감사드립니다.
void.pointer

7

프로그래밍의 맥락에서 관용어는 일반적으로 "언어로 무언가를 표현하는 가장 자연스러운 방법"으로 정의 될 수 있습니다

관용구라는 단어가 루비에서 특히 많이 나옵니다. Ruby에는 대규모 메타 프로그래밍 기능이 있으며 관용적 인 Ruby 코드를 작성하려면 일반적으로 이러한 기능을 사용해야합니다.

코드 조각이 관용적이라고해서 그것이 깨끗하거나 간결하다는 것을 의미하지는 않습니다. 여러 번 타협해야합니다.

따라서 기본적으로 관용구는 가장 일반적으로 "속어"(이디엄)를 포함하여 언어로 무언가를 쓰는 가장 일반적인 방법을 말합니다. 코드 조각이 관용적이지 않으면 완벽하게 읽을 수 있고 간결하고 깨끗하며 정확할 수 있지만 사용 된 언어에 따라 어색해 보일 수 있습니다. 그러한 코드를 관용적으로 재 작성하는 것이 실제로 좋은지, 사례별로 판단해야하는지에 대한 취향의 선호

예를 들어 관용 영어는 지역에 따라 다를 수 있습니다. bum관용구 영국 영어 에는이 단어 를 사용해야하지만 butt미국 영어에는 더 적합합니다. (나는 슬프게 영국 영어를 많이 모른다 : /)


감사합니다.
Ashaman Kingpin

3

관용적 인 것을 위해 머리 꼭대기에서 고안 할 수있는 가장 좋은 예는 Ruby에서 온 것입니다.

다양한 언어로 다음을 반복 할 수 있습니다.

for( start; end; increment){
    code;
}

또는 매우 유사한 것. 많은 언어들에도 foreach(x in SetOfXes)구문이 있습니다. 그러나 Ruby에 관용적 인 반복에는 다음과 같은 것들이 포함됩니다.

collection.each do |current|
  current.do_stuff
end

심지어

10.times do |x|
  puts x
end

나는 그것들이 덜 보편적 인 것을하는 방법을 나타내며, 그것의 영역 철학의 핵심에있는 것을 나타내는 것이 관용적이라고 생각합니다. 루비에는 고유하지는 않지만 보편적이지 않은 객체와의 상호 작용에 대한 철학이 있습니다.

시맨틱 한 노트에서, 관용어라는 단어를들을 때마다, 나의 두뇌는 자동적으로 생각을 "아이디 오마 틱에서 ..."로 완성합니다-나는 단지 특정 주제와 관련된 것으로 그것을 반사적으로 분석합니다.


collection.each do |current|와는 어떻게 다른 foreach(current in collection)가요? 둘 다의 current각 요소로 설정된 루프 구조 입니다 collection.
MSalters

2

관용구는 일반적으로 비교적 복잡한 상황을 언어로 표현하는 가장 좋은 방법입니다. 증가는 관용구 나 그런 종류의 것이 아닙니다. postfix 대신 prefix 증가를 사용하면 C ++ 관용구가 될 수 있습니다.

숙어는 전문가 사용자에 의해 결정된 언어를 사용하는 가장 좋은 방법입니다. 실제 C ++ 관용구는 함수 객체입니다. 또 다른 관용구는 RAII입니다. 이 언어에는 소멸자에서 리소스를 비워야한다고 말하는 것이 없습니다. 그러나 그렇게하는 것은 관용적입니다. 또 다른 예는 템플릿입니다. 템플릿을 사용하는 것은 관용적입니다. 그러나 상속을 과도하게 사용하는 것을 막을 수있는 것은 없습니다.


Wikipedia는 증분을 예로 사용했기 때문에 내 질문에서 언급했습니다. 관용구가 복잡한 이유는 무엇입니까? 이것은 다른 답변을 기반으로 한 정의의 일부처럼 보이지 않습니다.
void.pointer

4
@Robert Dailey : 어떻게 관용구가 관용구가 될 수 있습니까? 언어의 일부입니다 . 숙어는 언어 사용자에 의해 만들어지며 시간이 지남에 따라 변경됩니다. 증가는 관용구가 아니며 언어의 기본 기능입니다. 그 논리를 취하면 다른 기본 언어 기능은 관용구이므로 모든 프로그램은 관용적이지 않습니다.
DeadMG

2

당신의 정의는 나에게 맞지 않습니다. 관용구는 다른 언어로는 가능할 수도 있고 불가능할 수도 있지만이 언어에서는 일반적입니다. 일반적으로 대안보다 짧지 만 실제로 요구 사항은 아닙니다.

비 아이디 오닉에 대해 이야기하면 설명하기가 더 쉬울 수 있습니다. C ++에서 쓰는 것은 관용적입니다.

Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y);
if(p)
{
 // whatever
}

작성하는 것이 더 관용적입니다.

Foo* p; 
if(p = SomeThingThatReturnsAFooPointer(arg, param, x, y))
{
 // whatever
}

이 코드는 정확히 같은 기능을 수행합니다. C ++를 처음 접하는 일부 사람들은 p가 함수가 반환하는 값과 같은지 테스트하는 것으로 읽을 수 있지만 그 기능은 아닙니다.

다른 언어에서 온 관용적이지 않은 사람이 쓴 것과 비교해보십시오.

Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y);
if(p !=NULL)
{
 // whatever
}

당신은 또한이 물건들이 비 아이디 오닉으로 쓰러지는 것을 볼 것입니다

if (x>0)
  return true;
else
 return false;

관용적 접근 방식은

return (x>0);

비 관용적 인 방법은 잘못이 아니지만 관용구를 아는 사람들에게는 일반적으로 입력하는 데 시간이 오래 걸리고 읽는 데 더 오래 걸립니다. 내가 당신을 "늑대를 울었던 소년"이라고 부르고 당신이 그 이야기를 알고 있다면, 잘못된 경보로 인해 사람들이 당신을 무시하게 만드는 방법에 대해 설명하는 것보다 빠릅니다. 물론 문제는 이야기를 모르고 우리가 말하는 것과 늑대가 무엇을해야하는지 모른다는 것입니다. 마찬가지로, return x<y;전에 본 적이없고 실제로 무엇을 모르는 경우 문제가 될 수 있습니다 .


1
관용적 접근법은 반드시 if 조건 에서 포인터를 선언하여 NULL이 아닌 경우 포인터 액세스 할 수 없도록해야합니다. if(Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y))
DeadMG

아마도. 또는이 블록 전체에서 사용되기 때문에 1000 줄 이전입니다. 또는 멤버 변수이기 때문에 헤더 파일에서. 나는 독자들이 그것이 Foo *라는 것을 알 수 있도록 선언했을뿐입니다. 실제 생활에서는 그것이 선언되지 않았을 것입니다.
케이트 그레고리

1

무언가를 표현하는 여러 방법이있을 때 가장 일반적이거나 일반적으로 받아 들여지는 방법입니다. 예를 들어, goto 문을 사용하는 것과 동등한 C 대신 구조적 문을 사용하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.