,

손의 동작으로 읽는 라틴어 어근 7개 — mit·ject·pos·ten·struct·fac·script 한 페이지 (어근 2편)

이 글의 위치: 영어(English) → 어원(Etymology) → 개발 영어(Developer English)
시리즈 hub: 라틴어 어근 6개 한 페이지(port·duct·vis·spect·man·per)의 2편. 원래 어근마다 카드 한 장씩 일곱 편으로 쓰려던 것을 한 페이지로 묶었다.
어원은 Online Etymology Dictionary · Cambridge Dictionary 로 교차 확인한 것만 실었다. 개발 맥락 해석은 내 판단이라 그렇게 표시했다. 기준은 Editorial Policy 참조.


왜 일곱 개를 한 번에 묶는가

1편에서 어근 여섯 개를 다루고 나서, 다음 일곱 개를 카드로 나눠 쓰다가 멈췄다. 쓰다 보니 카드마다 마지막에 "헷갈리는 이웃 어근" 절을 붙이고 있었는데, 그 절이 매번 나머지 여섯 개를 가리키고 있었기 때문이다. ject 카드는 "pos는 놓는 것, ten은 쥐는 것"이라 적고, ten 카드는 "ject는 던지는 것, struct는 쌓는 것"이라 적는 식이었다.

일곱 개가 서로를 설명해야만 각자가 선명해진다면, 애초에 한 페이지에 있어야 한다.

그리고 묶고 나니 보이는 게 있었다. 일곱 개 전부 손으로 하는 동작이다.

잡는다 → 쥐고 있다 → 보낸다 / 던진다 → 놓는다 → 쌓는다 → 만든다 → 새긴다
 (cap)   ten/tain    mit/miss  ject     pos/pon   struct    fac      script

물건을 손에 쥐고(ten/tain), 손에서 떠나보내거나(mit/miss) 힘껏 던지고(ject), 어딘가에 내려놓고(pos/pon), 그걸 층층이 쌓아 올리고(struct), 그렇게 무언가를 만들어 내고(fac), 마지막으로 표면을 긁어 기록을 남긴다(script).

개발 어휘가 이 일곱 개로 뒤덮여 있는 건 우연이 아니라고 생각한다. 소프트웨어가 하는 일이 결국 무언가를 받아서, 옮기고, 놓고, 쌓고, 만들어, 적어 두는 것이기 때문이다.


한 장 요약

어근 손동작 라틴어 개발에서 만나는 단어
mit / miss 손에서 떠나보낸다 mittere (보내다) commit, submit, transmit, message
ject 힘껏 던진다 jacere (던지다) inject, object, project, reject
pos / pon 가만히 놓는다 ponere (놓다) repository, component, expose, compose
ten / tain 쥐고 놓지 않는다 tenēre (붙잡다) container, retention, maintain, tenant
struct 층층이 쌓는다 struere (쌓다) structure, infrastructure, construct
fac / fect / fic 만들어 낸다 facere (만들다) factory, interface, artifact, refactor
script / scrib 긁어 새긴다 scribere (새기다) script, subscribe, describe

1. mit / miss — 손에서 떠나보내다

mit- / miss-
└── 라틴어 mittere (보내다)
    ├── 현재 어간 mitt-  → mit-  (transmit, submit, permit …)
    └── 과거분사 missus  → miss- (mission, transmission, dismiss …)
= "손에서 놓아 저쪽으로 떠나보내다"

이 어근을 처음 보면 mit-miss-가 왜 같은 뿌리인지 헷갈린다. 답은 라틴어 동사의 활용에 있다. mittere(보내다)는 현재형에서 mit- 꼴을, 과거분사 missus(보내진)에서 miss- 꼴을 남겼다. 그래서 보내는 행위 쪽은 transmit·submit처럼 mit-으로, 보내진 결과·명사 쪽은 mission·transmission처럼 miss-로 갈라진 경우가 많다.

단어 분해
commit com(함께) + mit 함께 보내 → 맡기다·확정하다
submit sub(아래로) + mit 아래로 보내 → 제출
transmit trans(가로질러) + mit 가로질러 보내 → 전송
permit per(통과시켜) + mit 통과시켜 보내 → 허가
admit ad(~로) + mit ~로 보내 들이다 → 인정·입장
emit e(밖으로) + mit 밖으로 보내 → 방출
omit ob(지나쳐) + mit 지나쳐 보내 → 생략
mission miss + ion 보내진 것 → 임무
message miss + age 보내진 것 → 메시지
dismiss dis(흩어) + miss 흩어 보내 → 해산·기각

form을 submit하고, 데이터를 transmit하고, 권한을 permit하고, 변경을 commit한다. 개발이 이토록 mittere 가족으로 가득한 건 우연이 아니라고 본다. 소프트웨어가 하는 일의 상당수가 결국 무언가를 어디론가 보내는 일이기 때문이다. commit이 유독 "맡겨 확정한다"는 무게를 갖는 건 com-(함께)이 "하나로 맞붙여 되돌릴 수 없게"라는 뉘앙스를 얹기 때문이다.


2. ject — 힘껏 던지다

-ject
└── 라틴어 jacere (던지다)
    └── 과거분사 jactus → -ject (던져진)
[ 접두사 = 방향 ] + [ ject = 던짐 ]

ject는 언제나 "던진다"로 고정되어 있고, 바뀌는 건 어느 쪽으로뿐이다. 안으로 던지면 inject(주입), 밖으로 던지면 eject(배출), 앞으로 던지면 project(투사), 되받아 던지면 reject(거부).

단어 분해
inject in(안으로) + ject 던져 넣다 → 주입
object ob(맞은편에) + ject 앞에 던져진 것 → 대상·객체
project pro(앞으로) + ject 앞으로 던지다 → 투사·기획
reject re(되-) + ject 되던지다 → 거부
eject e(밖으로) + ject 밖으로 던지다 → 배출
subject sub(아래로) + ject 아래로 던져진 → 주제·주체
trajectory tra(가로질러) + ject 가로질러 던진 길 → 궤적
conjecture con(함께) + ject 함께 던져 → 추측
interject inter(사이에) + ject 사이에 던지다 → 끼어듦

이 가족에서 내가 가장 좋아하는 짝은 object와 subject다. object는 "내 맞은편(ob)에 던져진 것", 곧 내가 바라보고 다루는 대상이고, subject는 "아래로(sub) 던져진", 곧 어떤 힘 아래 놓인 주체다. 문법에서 주어와 목적어가 왜 그렇게 불리는지가 던지는 방향 하나로 설명된다.

개발에서. 의존성 주입(dependency injection)은 어원을 알면 문장 그대로 그림이 그려진다. 객체가 자기 손으로 협력자를 만들지 않고, 밖에서 던져 넣어 주는 것 — in(안으로) + ject(던지다)가 정확히 그 동작이다. "pass"나 "give"가 아니라 inject를 쓰는 이유는 대상이 요청하기 전에 바깥에서 능동적으로 밀어 던져 넣는다는 뉘앙스 때문이다. 이 패턴을 제어의 역전(IoC)이라 부르는 것과도 결이 맞는다. 던지는 주체가 객체 자신이 아니라 바깥이라는 뜻이니까.

반대로 SQL injection은 내가 원치 않는 문장을 남이 내 쿼리 안으로 던져 넣는 것이다. 같은 어근의 밝은 면과 어두운 면인 셈이다.


3. pos / pon — 가만히 놓다

pos / pon
└── 라틴어 ponere (놓다, 두다)
    └── 과거분사 positus (놓인)
        ├── pon- (현재 어간) : component, opponent, postpone
        └── pos- (과거분사)   : position, deposit, expose
= "제자리에 갖다 놓다"

ponere 자체는 그냥 "놓다"라서, 뜻을 가르는 건 앞에 붙는 접두사다. com-(함께)이면 여러 조각을 한자리에 놓아 compose, ex-(밖)면 밖에 내놓아 expose, de-(아래)면 아래에 놓아 deposit, re-(되-)면 되-놓아 두는 곳 repository가 된다.

단어 분해
repository re(되-) + pos 되놓아 두는 곳 → 저장소
component com(함께) + pon 함께 놓인 것 → 부품
expose ex(밖) + pos 밖에 놓다 → 드러내다
compose com(함께) + pos 함께 놓다 → 구성
deposit de(아래) + pos 아래 놓다 → 예치
propose pro(앞에) + pos 앞에 놓다 → 제안
dispose dis(흩어) + pos 흩어 놓다 → 처분
position pos + ition 놓인 자리 → 위치
opponent op(맞은편) + pon 맞은편에 놓인 → 상대

개발에서. docker pushEXPOSE를 나란히 두면 대비가 선명하다. push는 이미지를 저장소 안쪽에 되-놓아 두는 일이고, EXPOSE는 컨테이너 안의 포트를 바깥으로 내놓는 일이다. 방향은 정반대지만 동사는 똑같이 "놓다"다.

"Only expose the port you actually need, and push the image to a private repository."
실제로 필요한 포트만 노출하고, 이미지는 비공개 저장소에 올려라.

한 문장에 pos/pon이 두 번 들어 있는데 방향이 반대다. exposeex-(밖)이라 안의 것을 바깥에 놓아 열어 주는 일이고 — 그래서 필요 이상으로 노출하면 공격 표면이 된다. repositoryre-(되-)라 나중에 다시 꺼내 쓰려고 안쪽에 놓아 두는 자리다. 무엇을 밖에 놓고 무엇을 안에 둘지를 가르는 문장으로 읽힌다.


4. ten / tain — 쥐고 놓지 않다

ten- / -tain
└── 라틴어 tenēre (붙잡다, 쥐다, 유지하다)
    ├── ten-  라틴어 그대로의 꼴 (retain, content, tenant)
    └── -tain 고대 프랑스어를 거쳐 거칠어진 꼴 (contain, maintain, obtain)
= "한 번 쥔 것을 놓지 않고 계속 붙잡아 둔다"

핵심은 단순한 "잡기"가 아니라 계속 붙잡아 둠이다. 순간적으로 낚아채는 건 옆 동네 어근 cap/cept(capture, seize)의 몫이고, tenēre는 잡은 뒤에 손을 펴지 않는 지속의 감각을 맡는다. 그래서 이 뿌리에서 나온 단어들은 하나같이 시간을 품는다. 담아 두고(contain), 유지하고(maintain), 보유하고(retain), 이어간다(continue).

단어 분해
contain con(함께) + tain 함께 붙잡아 담다
maintain manū(손) + tain 손으로 붙잡아 유지
retain re(계속) + tain 계속 붙잡아 보유
detain de(붙들어) + tain 붙잡아 억류
obtain ob(향해) + tain 향해 붙잡아 얻다
sustain sus(밑에서) + tain 받쳐 붙잡아 지탱
continue con + tin 계속 붙잡아 잇다
content con + tent 안에 담긴 것 → 내용
tenant ten + ant 붙잡고 있는 자 → 세입자

표를 세로로 읽으면 라이프사이클이 된다. obtain(얻다)은 손에 들어오는 순간, retain(보유)은 그 뒤에 놓지 않는 상태, maintain(유지)은 그 상태가 망가지지 않게 계속 돌보는 일이다. 자원을 obtain하고, 세션을 retain하고, 서비스를 maintain한다.

개발에서. container라는 이름이 왜 그렇게 잘 맞는지도 어원으로 설명된다. 컨테이너의 본질은 격리 그 자체라기보다, 앱과 라이브러리와 런타임을 한데 붙잡아 두어 어디로 옮겨도 그 묶음이 흩어지지 않게 하는 데 있다. con(함께) + tain(붙잡다) — 이름이 곧 정의다. 로그를 얼마나 오래 붙잡아 둘지 정하는 retention, 한 시스템 안에 여러 입주자를 담는 multi-tenancy도 같은 뿌리다.

"We retain the session for 24 hours, but we no longer maintain this service."
세션은 24시간 보유하지만, 이 서비스는 더 이상 유지보수하지 않는다.

둘 다 뿌리는 "붙잡다"인데 온도가 다르다. retain은 가만히 쥐고만 있는 수동적 보유이고, maintain은 manū(손) + tain, 곧 손으로 계속 붙들고 돌보는 능동적 유지다. 그래서 "더는 maintain하지 않는다"는 말은 서버를 끈다는 뜻이 아니라 손을 뗀다는 뜻이다.


5. struct — 층층이 쌓다

struct-
└── 라틴어 struere (쌓다, 얹다, 세우다)
    └── 과거분사 structus (쌓아 세워진)
= "벽돌을 한 장씩 얹어 구조물을 올리다"

이 어근을 만날 때마다 나는 벽돌을 쌓는 손을 떠올린다. 구조(structure)는 쌓아 세운 것, 건설(construct)은 함께 쌓는 것, 파괴(destruct)는 쌓은 걸 도로 허무는 것. 방향만 다를 뿐 모두 "쌓기"라는 한 동작의 변주다.

단어 분해
structure struct + ure 쌓아 세운 것 → 구조
construct con(함께) + struct 함께 쌓다 → 건설
instruct in(안에) + struct 안에 쌓아 넣다 → 지시·가르침
destruct de(허물어) + struct 허물다 → 파괴
obstruct ob(앞을) + struct 앞을 막아 쌓다 → 방해
infrastructure infra(아래) + structure 아래에 세운 → 기반
reconstruct re(다시) + construct 다시 세우다 → 재건

내가 이 표에서 가장 좋아하는 짝은 construct와 instruct다. 겉보기엔 "건설"과 "가르침"이라 남남 같지만 어근으로는 둘 다 쌓기다. instruct는 배우는 사람 안에 지식을 한 층씩 쌓아 넣는 것이라, instruction이 "명령어"도 되고 "가르침"도 된다. CPU에 한 줄씩 쌓아 넣는 명령이나 사람에게 한 단계씩 쌓아 주는 설명이나, 어근의 눈으로는 같은 동작이다.

개발에서. 개발이라는 일을 어근 하나로 압축하면 나는 struct를 고르겠다. 서버가 올라설 infrastructure를 세우고, 데이터를 담을 data structure를 세우고, 객체를 constructor로 세웠다가 destructor로 허문다. C나 Go에서는 자료형 자체를 아예 struct라 부른다. 필드를 차곡차곡 쌓아 만든 "쌓은 것" 그 자체니까.

infrastructure를 풀면 infra(아래) + structure(쌓아 세운 것), 곧 아래에 깔아 세운 것이다. IaC(Infrastructure as Code)가 왜 전환점이었는지도 어원으로 보면 선명하다. 예전엔 이 아래층을 사람이 콘솔에서 한 장씩 쌓았지만, 이제는 쌓는 순서를 코드로 적어 두고 기계가 매번 똑같이 다시 세운다. reconstruct(재건)가 한 번의 명령이 된 셈이다.


6. fac / fect / fic — 만들어 내다

fac / fect / fic
└── 라틴어 facere (만들다, 하다 — make, do)
    ├── fac-  현재 어간 그대로   → factory, manufacture, facility
    ├── fect- 과거분사 factus에서 → effect, defect, perfect
    └── fic-  모음 약화형        → efficient, artifact, fiction
= "없던 것을 손으로 만들어 실제로 이뤄내다"

겉모습은 셋으로 갈라졌지만 흐르는 뜻은 하나다. fac이 보이면 만드는 것(factory, facility), fect이 보이면 만들어 낸 결과(effect, defect), fic이 보이면 역시 만들어 냄(efficient, fiction)이다. 나는 이 어근을 알고 나서야 effect(밖으로 만들어 낸 것 = 결과)와 defect(어긋나게 만들어진 것 = 결함)가 왜 그런 뜻인지 납득했다.

단어 분해
factory fac + ory 만드는 곳 → 공장
interface inter(사이) + face 사이에 만든 면 → 접점
artifact arti(기술로) + fact 만든 것 → 산출물
effect ex(밖으로) + fect 만들어 냄 → 결과
defect de(어긋나게) + fect 잘못 만듦 → 결함
perfect per(끝까지) + fect 끝까지 만듦 → 완벽
manufacture manū(손으로) + fact 손으로 만듦 → 제조
efficient ex + fic + ient 잘 만들어 내는 → 효율적인

perfect와 defect가 한 쌍이라는 게 이 어근의 백미다. perfect는 per(끝까지) 다 만들어 흠이 없는 것이고, defect는 de(어긋나게) 만들어져 흠이 생긴 것이다. 완벽과 결함이 "만드는 방식" 하나의 차이로 갈린다.

개발에서. 객체를 대신 만들어 주는 factory, 모듈 사이에 만든 계약면 interface, 빌드가 만들어 낸 산출물 artifact, 겉은 그대로 두고 안을 다시 만드는 refactor — 하나같이 fac 가족이다.

"Let’s refactor this — factor out the duplicated creation logic into a factory."
이거 리팩터링하자 — 중복된 생성 로직을 팩토리로 빼내자.

짧은 한 문장에 같은 뿌리 단어가 셋(refactor, factor, factory)이나 들어 있다. fac = 만들다를 알고 나면 문장 전체가 하나의 그림이 된다. 만드는 방식을 다시 짜서(refactor), 흩어진 만드는 요소(factor)를 하나로 모아, 만드는 전담 자리(factory)로 옮기자. 리팩터링이 "결과물을 새로 뽑는 게 아니라 만드는 방식 자체를 다시 짜는 일"이라는 정의가, 어원과 놀랄 만큼 정확히 맞는다.


7. script / scrib — 긁어 새기다

script / scrib
└── 라틴어 scribere (긁어 새기다 → 적다·기록하다)
    ├── scrib-  (현재 어간)     → describe, subscribe, scribble
    └── script- (과거분사 scriptus) → script, description, manuscript
= "표면을 긁어 자국을 남기다"

나는 script를 오래 "대본"이나 "스크립트 언어"로만 알았다. 그런데 뿌리인 scribere의 감각은 훨씬 물리적이다. 뾰족한 도구로 밀랍판이나 돌, 파피루스를 긁어 자국을 내는 동작에서 나왔다. 그러니까 "쓴다"는 건 원래 "새긴다"에 가깝다.

단어 분해
subscribe sub(아래에) + scribe 아래에 적다 → 구독
describe de(따라) + scribe 따라 적다 → 서술
transcribe trans(옮겨) + scribe 옮겨 적다 → 필사
prescribe pre(미리) + scribe 미리 적다 → 처방
inscribe in(안에) + scribe 안에 새기다 → 새김
manuscript manū(손으로) + script 손으로 쓴 → 원고
scripture script + ure 쓰인 것 → 경전
postscript post(뒤에) + script 뒤에 덧쓴 → 추신

가장 반가웠던 건 subscribe다. "구독"이라는 뜻만 외우던 단어인데, 어원으로는 "문서 아래(sub)에 이름을 적어(scribe) 넣는" 서명 행위다. 신문 구독을 신청하며 서류 하단에 서명하던 그림이 그대로 남은 셈이다. 이걸 알고 나면 pub/sub의 subscribe도 "이 이벤트 명단에 내 이름을 적어 둔다"로 자연스럽게 읽힌다.

개발에서. 매일 쓰는 언어 이름(JavaScript·TypeScript)이 이 뿌리고, 리액티브 코드의 subscribe, 테스트를 묶는 describe, package.jsonscripts가 모두 "적다" 한 뿌리에서 나왔다. 컴파일된 실행 파일과 달리 스크립트는 사람이 적은 그대로를 해석기가 한 줄씩 읽어 실행한다. 배우가 대본(script)에 적힌 대로 말하듯이.

"Each describe block groups related tests."
각 describe 블록은 관련 테스트를 묶는다.

de(따라) + scribe(적다)로 풀면 describe는 대상을 따라가며 적어 내려가는 것이다. 그림 그리듯 "묘사"하는 게 아니라 윤곽을 짚어 "서술"하는 쪽이다. 그러니 describe("cart", …)는 장바구니가 어떻게 동작해야 하는지를 따라 적어 두는 블록이고, 테스트가 곧 명세라는 말이 왜 자연스러운지가 어근 하나로 설명된다. 나는 이 감각을 잡은 뒤로 테스트를 "검증 코드"가 아니라 "동작을 적어 둔 문서"로 대하게 됐다.


일곱 개를 한 손동작으로 이어 보면

손동작 어근 대표 개발 단어 무엇이 일어나나
낚아챈다 (cap/cept) capture, catch 순간적으로 붙든다
쥐고 있다 ten/tain container, retention 놓지 않고 계속 붙든다
떠나보낸다 mit/miss commit, transmit 손을 떠나 확정된다
던진다 ject inject, object 힘을 실어 밀어 넣는다
놓는다 pos/pon repository, expose 어느 자리에 둘지 정한다
쌓는다 struct infrastructure, struct 층으로 구조를 세운다
만든다 fac factory, artifact 없던 것을 이뤄낸다
새긴다 script script, describe 사라지지 않게 적어 둔다

이 순서로 읽으면 CI 파이프라인 한 줄이 통째로 어근 문장이 된다. 소스를 저장소에 놓고(repository), 변경을 떠나보내고(commit), 컨테이너로 붙들어(container), 이미지를 레지스트리에 놓고(push/expose), 인프라를 쌓고(infrastructure), 산출물을 만들어(artifact), 무슨 일이 있었는지 로그로 새긴다(script).

이건 어원이 증명해주는 사실이 아니라 내 정리 방식이다. 다만 처음 보는 개발 용어를 만났을 때 "이건 손으로 치면 어떤 동작이지?" 하고 묻는 습관은 꽤 오래 쓸모가 있었다.


함께 읽으면 좋은 글

참고

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다