Post

구문과 표현식

구문과 표현식

도입

코드를 작성하다보면 구문(Statement)과 표현식(Expression)이라는 용어를 종종 접하게 된다. 이 두 용어는 비슷한 것을 지칭하는 것으로 보인다.

이전에는 낯선 프로그래밍 언어의 문법을 확인하기 위해 “Ruby for loop statement”와 “Ruby for loop expression”을 혼용해서 검색했다.

하지만 엄밀히 말해 두 단어는 확실히 구분되어야 한다. “Ruby for loop expression”는 틀린 표현이다.


다음 코드는 구문이다:

1
2
for i in range(5):
  continue

다음 코드는 표현식이다:

1
len(input())

구문은 어떤 처리가 어떻게 작동되어야 하는지 코드 흐름을 정의할 수 있다. 구문은 코드의 실행 흐름을 제어하기 위해 존재하므로 처리 결과의 반환값이 존재할 수 없다. 표현식보다 더 문법적이라고 이야기할 수 있다. 상황에 따라서는 문법 자체를 지칭할지도 모른다.

1
2
>>> len(for i in range)
SyntaxError: invalid syntax

당연히 말도 안되는 코드이지만, for문이 표현식이라면 이 코드는 코드를 해석하는 컴파일 단계를 통과해야 한다. 즉, 표현식은 말 그대로 결과값이 존재하여 그 결과를 표현할 수 있는 식이다.

식의 결과값을 도출하는 과정에서 분명 어떠한 제어 흐름이 관여하거나, 단순히 값 계산으로는 생각하기 어려운 행위가 발생할 수도 있다. 하지만 그것들은 결과를 얻어내기 위한 부수적인 단계일 뿐이다.

1
2
1 + 3 == 4
# True

1 + 3은 런타임에서 4로 계산되지만, 결과적으로는 저 1 + 34로 대체할 수 있다. 표현식은 상황에 따라서 처리 과정이나 처리 결과의 값으로 수식을 대체할 수 있다. 단일한 반환값으로 대체할 수 있다.

다른 값으로 바꿔 생각할 수 있다.

사람이 직접 코드를 읽고 해석하는 과정에서, 표현식의 각 부분에 임의의 값을 가정함으로써 코드를 정리하고 대체하면서 이해할 수 있다.

1
print('/'.join(sys.stdin.readline().split()))

위는 print를 포함하여 일련의 표현식이다. print는 단지 None을 반환할 뿐, 표현식이 아닌 것은 아니다.

1
2
3
4
5
6
7
>>> a = print(1)

>>> b = 0
>>> a + b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

위와 같이 시도했을 때, 컴파일 오류에 해당하는 문법 오류가 발생하지 않는다. 대신 런타임 오류로 볼 수 있는 타입 오류가 발생했다. 위 코드는 문법 검사를 통과했다.

다음은 위에서의 표현식 중 print 내부의 부분이다:

1
'/'.join(sys.stdin.readline().split())

print가 없어도 여전히 위 식은 표현식이고, 결과값을 반환한다.

이어서 코드의 실행 시나리오를 다소 제한하고 상황 조건을 다소 가정하여 더 대담하게 정리할 수 있다.

  • 많은 횟수의 입력이 필요하지 않다.
  • 입력은 공백으로 구분되어 주어진다.

예시 입력

박종현 정준희 김광재 안주현
  1. '/'.join(sys.stdin.readline().split())
  2. '/'.join(input().split())
  3. '/'.join('박종현 정준희 김광재 안주현'.split())
  4. '/'.join(['박종현', '정준희', '김광재', '안주현'])
  5. '박종현/정준희/김광재/안주현'

마무리

프로그래밍 언어를 처음 배우기 시작하면, 특히 문법 부분에서의 숙련도가 부족하여 규칙에 근거하기보다는 직관과 감각에 의존한다. 그리고 대부분 처음 학습자의 직관은 기대와 다른 결과를 낸다.

아래는 지난 1학기 중에 새내기들을 가르치며 접한 코드였다.

1
input() = '무엇을 원하시나요?'

위 코드는 변수의 정의와 표현식을 이해한다면 해결할 수 있을 것으로 생각한다.