[Rejected] PEP 736 - Shorthand syntax for keyword arguments at invocation
원문 링크: PEP 736 - Shorthand syntax for keyword arguments at invocation
상태: Rejected 유형: Standards Track 작성일: 28-Nov-2023
PEP 736 – 함수 호출 시 키워드 인수에 대한 축약 문법 제안 (Shorthand syntax for keyword arguments at invocation)
- 작성자: Joshua Bambrick, Chris Angelico
- 상태: Rejected (거부됨)
- 유형: Standards Track
- 생성일: 2023년 11월 28일
- Python 버전: 3.14
- 해결일: 2025년 3월 13일
개요 (Abstract)
이 PEP는 키워드 인수의 이름이 해당 값으로 사용되는 변수의 이름과 동일한 일반적인 패턴, 즉 f(x=x)
에 대한 구문 설탕(syntactic sugar)인 f(x=)
를 도입할 것을 제안했습니다.
동기 (Motivation)
키워드 인수를 사용할 때 불필요하게 반복적이고 장황해질 수 있습니다. 다음 함수 호출을 고려해 보세요.
my_function(
my_first_variable=my_first_variable,
my_second_variable=my_second_variable,
my_third_variable=my_third_variable,
)
키워드 인수의 이름이 해당 값으로 사용되는 변수 이름과 일치하는 경우는 파이썬 라이브러리에서 흔히 볼 수 있습니다. 이러한 중복은 명명된 인수(named arguments)의 사용을 저해하고 시각적 노이즈(visual noise)를 증가시켜 가독성을 떨어뜨립니다.
근거 (Rationale)
인수를 사용하여 함수를 호출하는 방법은 위치(position)와 키워드(keyword) 두 가지가 있습니다. 키워드 인수는 명시적(explicit)이므로 가독성을 높이고 의도치 않은 전치(transposition) 위험을 최소화합니다. 반대로 위치 인수는 종종 장황함을 줄이고 시각적 노이즈를 최소화하기 위해 선호됩니다.
이 일반적인 패턴을 단순화하는 간단한 구문 설탕이 수많은 이점을 제공할 것이라고 주장합니다.
- 명명된 인수 사용 장려 (Encourages use of named arguments): 기존 키워드 인수 구문이 유발할 수 있는 시각적 노이즈를 줄임으로써, 이 문법은 명명된 인수의 사용을 장려하여 가독성을 높이고 인수 전치로 인한 버그를 줄입니다.
- 장황함 감소 (Reduces verbosity): 시각적 노이즈와 일부 경우 코드 라인 수를 최소화함으로써 가독성을 높일 수 있습니다.
- 일관된 변수 이름 장려 (Encourages consistent variable names): 의미론적으로 동일한 변수가 컨텍스트에 따라 다른 이름을 가지는 것이 일반적인 문제입니다. 이 문법은 함수를 호출할 때 저자가 인수 이름과 동일한 변수 이름을 사용하도록 권장하여 변수 이름의 일관성을 높이고 가독성을 향상시킵니다.
-
이 패턴을 따르지 않는 인수 강조 (Highlights arguments not following this pattern): 현재 문법으로는 많은 인수가 지역 컨텍스트에서 전달되는 함수 호출에서 시각적 노이즈 때문에 다른 인수 값을 놓치기 쉽습니다.
예를 들어:
add_middleware( excluded_urls=excluded_urls, server_request=server_request, client_request=client_request, client_response=client_response, span_details=_get_span_details(), tracer=tracer, meter=meter, )
이 축약 문법을 사용하면 예외적인 인수를 더 쉽게 식별할 수 있습니다.
add_middleware( excluded_urls=, server_request=, client_request=, client_response=, span_details=_get_span_details(), # 예외적인 인수가 눈에 띈다. tracer=, meter=, )
- 딕셔너리 생성에 적용 가능 (Applicability to dictionary construction): 이 문법은 유사한 패턴(딕셔너리 키가 해당 값으로 할당된 변수 이름과 동일한 경우)이 자주 발생하는 딕셔너리 생성에도 적용될 수 있습니다.
{"x": x, "y": y}
또는dict(x=x, y=y)
와 같은 형태를dict(x=, y=)
로 작성할 수 있게 됩니다.
명세 (Specification)
이 PEP는 함수 호출에서 키워드 인수의 값이 생략되면, 해당 인수의 값이 호출 스코프(invocation scope)에서 이름과 일치하는 변수로 추론되는 구문 설탕을 도입할 것을 제안합니다.
예를 들어, 다음 함수 호출:
my_function(my_first_variable=, my_second_variable=, my_third_variable=)
은 기존 문법에서 다음 코드와 정확히 동일하게 해석됩니다.
my_function(
my_first_variable=my_first_variable,
my_second_variable=my_second_variable,
my_third_variable=my_third_variable,
)
호출 스코프에 해당 이름과 일치하는 변수가 없으면, 기존의 확장된 구문과 동일하게 NameError
가 발생합니다.
이 제안은 함수 호출에만 해당하며, 함수 정의는 이 구문 변경의 영향을 받지 않습니다. 기존의 유효한 모든 구문은 변경되지 않습니다.
하위 호환성 (Backwards Compatibility)
이전에는 구문 오류였던 새로운 구문만 추가됩니다. 기존의 유효한 구문은 수정되지 않습니다. 따라서 제안된 변경 사항은 완전히 하위 호환됩니다.
보안 영향 (Security Implications)
이 변경으로 인한 보안 영향은 없습니다.
선행 기술 (Prior Art)
파이썬은 이미 f-string 보간(interpolation)에서 f'{x=}'
가 사실상 f'x={x}'
로 확장되는 매우 유사한 기능을 가지고 있습니다.
여러 현대 언어는 함수 호출 시 유사한 기능을 제공하며, 때로는 ‘punning’이라고도 합니다.
- Ruby:
f(x:, y:)
는f(x: x, y: y)
의 구문 설탕입니다. - ReasonML:
f(~x, ~y)
는f(~x=x, ~y=y)
의 구문 설탕입니다. - SystemVerilog:
(.mult, .mop1, .data);
는(.mult(mult), .mop1(mop1), .data(data));
의 구문 설탕입니다. - Jakt:
f(x, y)
는f(x: x, y: y)
의 구문 설탕입니다.
함수 호출 외에도 더 많은 언어가 유사한 기능을 제공합니다.
- OCaml:
let+ x in …
은let+ x = x in …
의 구문 설탕입니다. - JavaScript:
{ x, y }
는{x: x, y: y}
의 구문 설탕입니다. - Rust:
User { x, y }
는User {x: x, y: y}
의 축약형입니다.
적용 가능성 (Applicability)
최근 몇 년간 인기 있는 파이썬 라이브러리를 분석하여 다음을 계산했습니다.
f(x=x)
형태의 키워드 인수 개수f(x=x)
형태의 키워드 인수 비율- 이 구문 설탕을 사용하여 줄일 수 있는 코드 라인 수
통계 | Polars | FastAPI | Rich | HTTPX |
---|---|---|---|---|
f(x=x) 형태 키워드 인수 개수 |
1,654 | 1,408 | 566 | 759 |
f(x=x) 형태 키워드 인수 비율 |
15.83% | 28.11% | 15.74% | 45.13% |
절약된 라인 수 | 170 | 35 | 62 | 117 |
이를 통해 f(x=x)
키워드 인수 패턴이 널리 퍼져 있으며, 코드베이스에 따라 전체 키워드 인수 사용량의 15%에서 절반 가까이를 차지한다는 점을 알 수 있습니다.
제안된 문법 (Proposed Syntax)
이 기능은 여러 차례 다른 형태로 제안되었지만, f(x=)
형태가 다음과 같은 이유로 가장 선호되었습니다.
- 이 기능은 10년 동안
f(x=)
또는f(=x)
가 가장 일반적으로 제안된 구문으로 자주 제안되었습니다. 이는 가장 명확한 표기법임을 강력히 시사합니다. - 제안된 구문은 f-string 디버그
f'{var=}'
구문(확립된 Pythonic 스타일)과 매우 유사하며 거의 동일한 목적을 제공합니다. - 제안된 구문은 Ruby 키워드 인수 구문 설탕과 정확히 유사합니다.
- 이 구문은 간단한 구문 설탕이므로 구현하기 쉽습니다.
- 접두사 형태(Rejected Ideas 참조)와 비교할 때, 이 구문은 “여기에 매개변수가 있으니, 해당 인수를 찾아라”고 전달하며, 이는 명명된 인수의 의미론에 더 적합합니다.
- 파이썬 개발자 설문조사 결과, 이 구문이 제안된 것 중 가장 인기 있는 구문으로 나타났습니다.
학습 방법 (How to Teach This)
이 기능의 전달과 검색을 용이하게 하기 위해 ‘keyword argument shorthand’와 같은 이름을 부여하는 것도 유용할 수 있습니다.
숙련된 파이썬 개발자들은 뉴스 게시판, 소셜 미디어, 메일링 리스트, 온라인 포럼 또는 입소문과 같은 일반적인 정보 채널을 통해 이 기능에 대해 알게 될 것입니다. 더 많은 개발자들은 코드를 읽다가 함수 호출에서 키워드 인수의 값이 생략된 것을 발견하고 의아해하며 이 기능을 접하게 될 것입니다. 이러한 개발자들이 이 기능의 의미를 설명하는 문서를 쉽게 접하고 검색 시 쉽게 찾을 수 있도록 해야 합니다.
교사는 새로운 파이썬 프로그래머에게 “f(x=)처럼 등호만 뒤따르는 인수를 보면, 이는 인수 이름과 그 값이 동일한 키워드 인수를 나타냅니다. 이것은 확장된 표기법인 f(x=x)
와 동일하게 작성할 수 있습니다.”라고 설명할 수 있습니다.
이것을 이해하기 위해 파이썬 학생은 기존 키워드 인수 구문 외에 함수의 기본 사항에 익숙해야 합니다. 이 기능이 비교적 간단한 구문 설탕이라는 점을 고려할 때, 키워드 인수를 이해하는 학생은 이 개념을 빠르게 습득할 수 있을 것입니다. 이는 f-string 구문의 성공과 다른 언어의 유사한 기능(선행 기술 참조)을 통해 입증됩니다.
거부된 아이디어 (Rejected Ideas)
많은 대안적인 구문이 제안되었지만, f(=x)
또는 f(x=)
외의 다른 형태는 큰 지지를 얻지 못했습니다.
f(a, b, *, x)
: 이 구문은 키워드 전용(keyword-only) 함수 정의에서 친숙하지만, 인수가 위치 인수인지 명명된 인수인지 지역 컨텍스트에서 덜 명확하고,*
의 새로운 의미 부여가 혼란을 야기할 수 있다는 반대 의견이 있었습니다.f(=x)
: 이 접두사 형태는*args
,**kwargs
와 유사하고 시각적으로 더 눈에 띄지만,f(x=)
보다 f-string 구문과 덜 유사하며, 의미론적으로 “여기 값이 있으니 매개변수를 채워라”는 의도와 맞지 않는다는 단점이 지적되었습니다.f(%x)
또는f(:x)
또는f(.x)
:=
대신 다른 문자를 사용하는 여러 변형이 제안되었지만, 어떤 형태도 지지를 얻지 못했으며,=
에 비해 기호 선택이 임의적이라는 평가를 받았습니다.
반대 의견 (Objections)
이 구문 설탕 도입에 대한 강력한 반대 의견은 소수에 불과했습니다. 대부분의 반대자들은 ‘나는 사용하지 않을 것이다’라는 입장이었습니다. 그러나 이 기능에 대한 광범위한 논의를 통해 다음과 같은 반대 의견이 가장 흔하게 제기되었습니다.
- 문법이 보기 흉하다 (The syntax is ugly): 이 반대 의견은 주관적이며 많은 커뮤니티 구성원이 동의하지 않았습니다. 거의 동일한 구문이 이미 f-string에 확립되어 있으며, 프로그래머들은 언제나처럼 시간이 지나면서 적응할 것이라고 반박되었습니다.
- 기능이 혼란스럽다 (The feature is confusing): 새로운 기능 도입은 일시적으로 혼란을 줄 수 있지만, 이 구문은
f'{x=}'
구문과 매우 유사하며 다른 인기 있는 현대 언어에서도 익숙합니다. 또한x=
가x=x
로 확장되는 것은*arg
,**kwarg
확장보다 훨씬 덜 복잡합니다. - 기능이 명시적이지 않다 (The feature is not explicit): 이 제안된 구문에서 인수 값이 ‘암묵적’이라는 점은 인정되지만, 이는 Zen of Python이 의도하는 바와 다르다고 주장합니다.
x += 1
이x = x + 1
보다 암묵적이지 않은 것처럼,f(x=)
도 지역 컨텍스트에서 무엇을 의미하는지 즉시 명확하므로 명시적이라고 볼 수 있습니다. 오히려 시각적 노이즈를 줄여 명명된 인수 사용을 장려함으로써 파이썬 코드베이스를 전반적으로 더 명시적으로 만들 수 있습니다. - 기능이 다른 방식 하나를 더 추가한다 (The feature adds another way of doing things): 이는 모든 구문 변경에 대해 제기될 수 있는 주장입니다.
x += 1
이x = x + 1
의 구문 설탕인 것처럼, 이것은 인수를 전달하는 ‘새로운 방식’이라기보다는 같은 방식에 대한 더 읽기 쉬운 표기법입니다. - 호출 컨텍스트에서 변수 이름을 바꾸면 코드가 깨진다 (Renaming the variable in the calling context will break the code): 대부분의 경우
NameError
가 발생하여 실수를 명확히 할 것입니다. 상위 스코프에 원래 변수와 같은 이름의 변수가 있어NameError
가 발생하지 않을 수 있는 혼란이 있을 수 있지만, 이는 현재 구문을 사용하는 키워드 인수에서도 발생할 수 있는 문제입니다. 또한, 다른 스코프에서 동일한 이름의 변수를 사용하는 것은 일반적으로 좋지 않은 관행으로 간주되며 린터(linter)에 의해 권장되지 않습니다. - 이 문법은 결합도를 높인다 (This syntax increases coupling): 모든 문법은 오용될 가능성이 있으므로 코드베이스를 개선하기 위해 신중하게 적용되어야 합니다. 매개변수와 그 값이 두 컨텍스트에서 동일한 의미를 가질 때 이 문법을 사용하는 것이 적절하며, 의도치 않은 비동기화 위험을 완화하는 데 도움이 될 것이라고 제안되었습니다.
이 문법 사용에 대한 권장 사항 (Recommendations for Using This Syntax)
다른 언어 기능과 마찬가지로, 프로그래머는 특정 상황에서 이 기능을 사용하는 것이 현명한지 스스로 판단해야 합니다. 린트 규칙이나 스타일 가이드 등을 통해 적용 가능한 모든 경우에 이 기능을 사용하도록 강제하는 것은 권장하지 않습니다.
“이 문법은 결합도를 높인다” 섹션에서 설명한 바와 같이, 매개변수와 그 인수가 동일한 의미를 갖는 경우에 이 문법을 사용하여 부적절한 결합을 유발하지 않으면서 의도치 않은 비동기화를 줄이는 것이 합리적인 경험 법칙이 될 수 있습니다.
편집에 미치는 영향 (Impact on Editing)
- 일반 텍스트 편집기 사용 (Using a plain text editor): 일반 텍스트 편집기를 사용하여 편집하는 것은 일반적으로 영향을 받지 않습니다. ‘찾아 바꾸기’ 방법을 사용하여 변수 이름을 변경할 때, 이 문법이 사용된 경우 개발자는 함수 호출 시 인수 부분을 접하게 됩니다. 이 시점에서 개발자는 평소처럼 인수를 업데이트할지, 아니면 전체
f(x=x)
구문으로 확장할지 결정할 수 있습니다. - IDE에 대한 제안 (Proposals for IDEs): IDE는
f(x=)
가f(x=x)
의 구문 설탕이라는 점을 인식하고 현재와 동일하게 처리해야 합니다.- NameError 강조 (Highlighting NameErrors): IDE는
NameError
를 일으킬 수 있는 코드를 강조하는 기능을 제공합니다. 이 축약 구문도f(x=x)
와 유사하게 처리하여 생략된 변수가 존재하지 않을 수 있는 경우를 식별하고 강조 표시해야 합니다. - 정의로 이동 (Jump to definition): 커서 위치에 따라 ‘정의로 이동’ 기능을 구현하는 몇 가지 방법이 있습니다. 한 가지 옵션은 인수에 커서가 있을 때 함수 정의의 인수로 이동하고, 제안된 구문에서
=
뒤의 문자에 커서가 있을 때 생략된 변수의 정의로 이동하는 것입니다. - 다른 참조 강조 (Highlighting other references): IDE는 현재 커서 위치에 있는 값과 일치하는 코드 참조를 자주 강조합니다. 이 축약 구문을 사용할 때, 인수 이름에 커서가 있으면 인수와 그 값에 대한 참조를 모두 강조하거나, 마우스 오버 시 구문을 시각적으로 확장하고 커서에 따라 기존 강조 로직을 적용하는 것이 유용할 수 있습니다.
- 심볼 이름 변경 (Rename symbol): IDE는 이 구문에 대해 ‘심볼 이름 변경’ 기능을 지원하는 몇 가지 방법을 고려할 수 있습니다. 예를 들어, 인수의 이름을 변경할 때 IDE는 이 구문이 사용된 각 호출 컨텍스트에서 값으로 사용되는 변수의 이름도 변경하거나, 변경되지 않은 변수를 이름이 변경된 인수의 값으로 전달하기 위해 전체 구문으로 확장하거나, 개발자에게 두 옵션 중 하나를 선택하도록 프롬프트할 수 있습니다.
- NameError 강조 (Highlighting NameErrors): IDE는
참조 구현 (Reference Implementation)
CPython에 대한 제안된 구현은 @Hels15가 제공했습니다. 이 구현을 확장하여 값이 생략되었는지 여부를 나타내는 AST 노드 속성을 추가할 것입니다. 그렇지 않으면 AST는 변경되지 않습니다.
참고: 이 PEP는 최종적으로 거부(Rejected)되었습니다. 이는 제안된 기능이 파이썬 언어에 추가되지 않는다는 것을 의미합니다.
⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.
Comments