Numpilot
손안의 수치해석/2부 언어의 문제 — DSL

설계 ③: 단위와 좌표계라는 함정

11 / 30
2026-08-03 · 읽는 데 9분

가장 흔하고 가장 조용한 실패

앞 편에서 애매함을 다뤘다. 이 편의 주제는 애매함이 아니라 오해다.

둘은 다르다. 애매함은 값이 정해지지 않은 상태다. 오해는 양쪽 다 명확한데 서로 다른 상태다.

사용자가 “두께 3”이라고 쓴다. 시스템은 3밀리미터로 읽는다. 사용자는 3센티미터를 뜻했다.

애매한 것이 없다. 사용자도 명확하고 시스템도 명확하다. 다만 다르다. 그리고 결과는 열 배 틀린다.

더 나쁜 것은 이 실패가 에러를 내지 않는다는 점이다. 3밀리미터 판의 온도 분포는 완벽하게 계산된다. 답이 나온다. 그럴듯하다. 그리고 틀렸다.

왜 사람은 단위를 흘리나

6편에서 봤듯 사람은 단위를 자주 생략한다. 게으름이 아니라 맥락이 단위를 결정하기 때문이다.

프라이팬 이야기 중이라면 “10”은 센티미터다. 반도체 소자 이야기라면 마이크로미터다. 건물 이야기라면 미터다. 사람끼리는 무슨 이야기를 하는지 아니까 단위를 말할 필요가 없다.

그런데 여기 함정이 있다. 분야마다 관습 단위가 다르고, 그 관습은 명시되지 않는다.

  • 기계 설계 도면 — 밀리미터
  • 건축 도면 — 미터 또는 밀리미터
  • 반도체 — 마이크로미터, 나노미터
  • 미국 제조 — 인치
  • 열전도율 — W/m·K (미터 기준)

마지막 줄이 특히 위험하다. 치수는 밀리미터로 말하면서 물성값은 미터 기준인 상황. 여기서 1000배 오차가 조용히 들어온다. 실제 공학 계산에서 가장 흔한 실수 유형이다.

대응 1 — 내부는 하나로 통일한다

첫 번째 원칙은 단순하다. DSL 내부에서는 단위를 하나로 고정한다.

우리는 SI 기본 단위(미터, 켈빈, 초, 와트)로 정했다. 사용자가 무엇을 입력하든, DSL에 기록되는 값은 SI로 변환된 것이다.

이게 왜 중요한가. 여러 단위를 그대로 들고 다니면, 계산 코드의 모든 지점에서 단위를 확인해야 한다. 한 곳에서 빠뜨리면 조용히 틀린다.

변환은 입구에서 한 번만. 안쪽은 단위가 하나뿐이므로 실수할 여지가 없다.

대응 2 — 화면에는 사람의 단위로 보여준다

내부가 SI라도 사용자에게 미터로 보여주면 불편하다. 프라이팬 두께가 0.003미터라고 나오면 읽기 어렵다.

그래서 표시 단위는 따로 둔다. 문제의 크기 규모를 보고 적절한 단위를 골라 보여준다. 수 센티미터 규모의 문제라면 밀리미터로, 수 미터 규모라면 미터로.

즉 값은 하나인데 두 얼굴이 있다. 계산은 SI로, 표시는 사람 단위로.

대응 3 — 단위를 명시적으로 되돌려 보여준다

여기가 핵심이다.

사용자가 “두께 3”이라고 쓰면, DSL 화면에 이렇게 나타난다.

두께: 3 mm     ← 단위 추정 (mm)

추정했다는 사실이 표시된다. 사용자가 3cm를 뜻했다면 이 줄을 보고 알아챈다.

이건 10편의 원칙 — 정하고 드러낸다 — 를 단위에 적용한 것이다. 다만 단위에는 한 가지가 더 붙는다. 틀렸을 때의 피해가 크기 때문에 더 눈에 띄게 표시한다.

대응 4 — 물리적으로 말이 되는지 검사한다

마지막 방어선이 있다. 단위를 잘못 짚으면 대개 값이 이상해진다.

프라이팬 두께가 3미터일 수는 없다. 손잡이 길이가 0.02밀리미터일 수도 없다. 사람 손으로 쓰는 물건이라는 맥락에서 크기의 범위가 정해진다.

그래서 각 항목에 물리적으로 타당한 범위를 정해뒀다. 그 범위를 크게 벗어나면 경고한다.

두께: 3 m      ⚠ 조리기구 두께로는 이례적입니다. mm를 뜻하셨나요?

이 검사가 완벽하지는 않다. 범위 안에서 틀린 경우 — 3mm를 3cm로 오해한 경우 — 는 잡지 못한다. 그래도 자릿수가 크게 어긋난 실수는 걸러낸다. 그리고 실제 사고는 대개 자릿수 실수에서 온다.

좌표계라는 조용한 문제

단위보다 덜 알려졌지만 비슷하게 위험한 것이 좌표계다.

“왼쪽 변”이 어디인가. 화면을 보고 있으면 명확하다. 그런데 시스템 내부에서는 좌표축의 방향과 원점 위치로 정의된다. 사용자가 생각하는 “왼쪽”과 시스템의 x축 음의 방향이 일치하지 않으면, 경계조건이 엉뚱한 면에 붙는다.

그리고 이것도 조용히 틀린다. 계산은 되고 결과는 나온다. 다만 열이 반대쪽에서 들어온다.

우리 대응은 좌표를 노출하지 않는 것이었다.

사용자는 좌표를 쓰지 않는다. 대신 의미 있는 이름으로 면을 가리킨다. “바닥”, “손잡이 끝”, “측면”, “가열면”. 시스템이 형상을 만들 때 각 면에 이름을 붙여두고, 사용자는 그 이름으로만 조건을 지정한다.

그리고 그림으로 확인시킨다. 어느 면에 어떤 조건이 붙었는지 색으로 표시한다. 사용자가 좌표를 이해할 필요 없이, 그림을 보고 “아 여기가 아닌데”를 알아챌 수 있다.

세 편을 정리하면

9·10·11편에서 세 가지 설계 결정을 다뤘다. 공통된 원칙이 하나 있다.

문제 원칙
9 무엇을 표현할까 기본값이 정해지는 것만 다룬다
10 애매함 정하고, 드러내고, 중요한 것만 강조한다
11 오해 변환은 한 번만, 추정은 반드시 표시

세 줄 모두 같은 것을 말한다. 시스템이 많이 결정하되, 결정한 것을 전부 사람에게 보여준다.

이 조합이 우리가 찾던 균형이었다. 결정을 사용자에게 미루면 도구가 어려워진다. 결정을 숨기면 도구가 위험해진다. 결정하고 보여주면 편하면서 안전하다.

그런데 이 설계가 실제로 작동하려면 한 가지가 더 필요했다. 사용자의 애매한 문장을 이 DSL로 옮기는 번역층이다. 그것이 어떻게 생겼는지 다음 편에서 다룬다.


다음 편 예고 — 자연어에서 DSL로 — 번역층의 구조. 문장이 어떤 경로를 거쳐 실행 가능한 조건이 되는지, 그 사이에서 무엇이 검사되는지 따라간다.