디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

업뎃) 동일 안전성 목표 하의 코드 비교 - Rust vs. Ada/..

루비갤로그로 이동합니다. 2025.07.03 20:05:00
조회 46 추천 0 댓글 0

부록 B: 동일 안전성 목표 하의 코드 비교 - Rust vs. Ada/SPARK


이 부록은 본문 5장에서 철학적 차원으로 다룬 ‘의도 중심’과 ‘규칙 중심’의 설계 방식이, 실제 코드에서는 어떻게 구현되는지 구체적으로 비교 분석합니다.


이를 위해, 컴퓨터 과학의 가장 기본적인 자료구조 중 하나를 구현하는 것을 목표로 설정하고, 각 언어가 이 문제를 해결하는 접근 방식과 그 과정에서 개발자가 겪는 경험이 어떻게 다른지 독자 여러분께서 직접 판단하실 수 있도록 구성했습니다.


비교 과제: ‘부모-자식 관계’를 가진 노드(Node) 구조 표현하기


우리의 목표는 간단한 트리(Tree) 구조를 만드는 것입니다. 이 구조에서 각 노드는 여러 자식 노드를 가질 수 있으며, 동시에 각 자식 노드는 자신의 부모 노드를 가리키는 참조를 가질 수 있어야 합니다.


접근법 1: 러스트 (Rust) - ‘규칙’이 ‘의도’를 가로막는 경우


1. 직관적이지만 ‘실패’하는 코드


다른 언어에 익숙한 개발자라면 누구나 떠올릴 법한, 가장 직관적인 코드입니다. 하지만 이 코드는 러스트의 빌림 검사기(Borrow Checker) 규칙 때문에 절대로 컴파일되지 않습니다.


// 이 코드는 컴파일되지 않습니다!

struct Node<'a> {

    parent: Option<&'a Node<'a>>, // 부모를 가리키는 참조

    // ... 다른 필드들

}


fn main() {

    let mut root = Node { parent: None, /* ... */ };


    // 컴파일 에러: `root`의 소유권과 빌림 규칙이 충돌합니다.

    // 빌림 검사기는 이처럼 데이터가 순환 참조 구조를 갖는 것을 허용하지 않습니다.

    let child = Node { parent: Some(&root), /* ... */ };

}

‘자식이 부모를 가리킨다’는 개발자의 단순하고 명확한 의도가, ‘데이터는 단 한 명의 소유자만 가져야 하며, 빌림 규칙은 순환을 만들 수 없다’는 컴파일러의 엄격한 규칙과 정면으로 충돌하는 상황입니다.


2. ‘성공’하지만 복잡한 우회로


이 문제를 ‘안전한(safe)’ 러스트로 해결하려면, 개발자는 자신의 단순한 의도를 포기하고, 컴파일러의 규칙을 통과하기 위해 Rc, RefCell, Weak라는 복잡한 개념들을 동원한 ‘우회로’를 설계해야 합니다.


use std::rc::{Rc, Weak};

use std::cell::RefCell;


// 부모를 가리키는 참조는 '소유권 없는' 약한 참조(Weak)를 사용해야 합니다.

// 내부의 값을 변경하기 위해 RefCell을 사용합니다.

struct Node {

    parent: RefCell<Weak<Node>>,

    children: RefCell<Vec<Rc<Node>>>,

}


fn main() {

    let root = Rc::new(Node {

        parent: RefCell::new(Weak::new()),

        children: RefCell::new(vec![]),

    });


    let child = Rc::new(Node {

        parent: RefCell::new(Rc::downgrade(&root)), // 부모를 '약한 참조'로 저장

        children: RefCell::new(vec![]),

    });


    // 자식 노드를 추가하기 위해 .borrow_mut()를 호출해야 합니다.

    root.children.borrow_mut().push(Rc::clone(&child));


    println!("트리 구조 생성 완료!");

}


러스트 방식 분석


단순한 부모-자식 관계를 표현하기 위해, 개발자는 Rc(참조 카운팅 포인터), RefCell(내부 가변성), Weak(약한 참조), borrow_mut()(가변 빌림), downgrade()(약한 참조로 변환) 등 수많은 난해한 개념과 마주해야 합니다. 개발자의 초점은 ‘트리 구조’라는 원래 문제에서 벗어나, ‘어떻게 하면 빌림 검사기를 통과할까’라는 러스트의 규칙 자체를 해결하는 문제로 변질됩니다. 안전성은 컴파일러가 강제하지만, 그 대가로 개발자는 비직관적인 코드와 씨름해야 합니다.


접근법 2: Ada/SPARK - ‘의도’를 코드로 직접 표현하는 경우


Ada/SPARK 생태계는 개발자의 의도를 존중하고, 안전성을 다층적으로 확보하는 길을 제시합니다.


1. Ada: 직관적인 구조 표현과 런타임 안전성


먼저, Ada 언어 자체는 access라는 ‘포인터’ 타입을 사용하여 개발자의 의도를 직접적으로 표현하도록 돕습니다.


-- `Node` 타입을 미리 선언하여 자기 참조 구조가 가능하게 합니다.

type Node;

-- `Node` 타입을 가리킬 수 있는 '포인터' 타입을 정의합니다.

type Node_Access is access all Node;


-- 실제 `Node` 타입을 정의합니다.

type Node is record

   -- 부모를 가리키는 포인터를 필드로 가집니다. (자연스러운 표현)

   Parent   : Node_Access;

   -- 자식들을 담는 자료구조...

end record;


-- 사용 예시

procedure Create_Tree is

   Root  : Node_Access := new Node;

   Child : Node_Access := new Node;

begin

   Root.Parent := null; -- 루트 노드의 부모는 없음


   -- 자식 노드의 Parent 필드가 부모 노드(Root)를 직접 가리킵니다.

   Child.Parent := Root;


   -- ... 자식 노드를 Root의 Children 리스트에 추가하는 로직 ...

end Create_Tree;

이처럼 개발자의 의도(“노드는 다른 노드를 가리킬 수 있다”)가 매우 간결하게 표현됩니다. 이때 Ada는 러스트와 다른 방식으로 안전성을 확보합니다. 만약 개발자가 Parent가 null인 상태에서 Parent.all과 같이 역참조를 시도하면, 컴파일러는 이 코드를 막는 대신 런타임에 Constraint_Error라는 예외를 발생시키는 코드를 기본적으로 삽입합니다. 즉, 런타임에서 안전장치가 작동하는 것입니다.


이처럼 Ada의 런타임 안전망은 훌륭하지만, 일부 고신뢰성 시스템에서는 이마저도 부족할 수 있습니다. 바로 이 지점에서 SPARK가 등장하여 안전성을 한 차원 더 끌어올립니다.


2. SPARK: 명시적 계약을 통한 ‘증명된’ 컴파일 타임 안전성


SPARK는 개발자가 자신의 ‘의도’를 ‘계약(Contract)’으로 명시하면, 정적 분석 도구(Prover)가 “이 코드는 런타임 에러가 절대 발생하지 않는다”는 것을 수학적으로 증명합니다.


-- 부모의 정보를 사용하는 프로시저

procedure Process_Parent (Item : in Node_Access)

  with

    -- 사전 조건(Pre-condition)으로 "Item의 부모는 null이 아니다"라고 명시합니다.

    -- 이것이 개발자의 '의도'이자, Prover에게 증명을 요청하는 '계약'입니다.

    Pre => Item.Parent /= null

is

begin

   -- 이 계약 덕분에, SPARK Prover는 아래 코드가 런타임 에러 없이

   -- 안전함을 100% 증명할 수 있습니다.

   Put_Line ("My Parent is: " & Image (Item.Parent.all));

end Process_Parent;


이처럼 SPARK는 개발자에게 자신의 코드가 안전하다는 것을 ‘스스로 증명’하도록 요구합니다. 도구는 개발자의 이 선언이 타당한지를 수학적으로 검증해 줄 뿐입니다.


결론: 두 방식의 비교



구분러스트 (Rust)Ada/SPARK
핵심 철학‘규칙’이 ‘의도’를 제약‘도구’가 ‘의도’를 지원하고 검증
안전성 확보컴파일러가 암묵적 규칙을 자동으로 강제개발자가 명시적 계약을 작성하고 도구가 증명
개발자 경험컴파일러의 규칙을 통과하기 위한 싸움자신의 의도를 코드로 표현하고, 그 안전성을 계약으로 증명
주요 어려움언어의 고유한 패러다임(소유권)에 대한 적응문제에 대한 형식적이고 논리적인 사전 분석 및 ‘계약’ 작성
안전성의 기본값성능 우선 (안전은 Opt-in)안전 우선 (런타임 체크가 기본, 증명은 Opt-in)



이 ‘그래프/트리’ 예시는 ‘개발자의 단순한 의도’(자식이 부모를 가리킨다)와 ‘컴파일러의 엄격한 규칙’(데이터는 단 한 명의 소유자만 가져야 한다)이 정면으로 충돌하는 상황을 극명하게 보여줍니다. 러스트의 방식이 왜 어떤 이들에게는 ‘불필요한 장벽’이자 ‘비정석적인 설계’로 평가받는지, 이 예시만큼 명확하게 보여주는 것은 없습니다.


이 비교를 통해, 우리는 두 언어가 ‘안전성’에 도달하는 길이 근본적으로 다름을 알 수 있습니다. 러스트는 개발자의 실수를 원천적으로 막는 엄격한 ‘자동화된 규칙’을 선택했고, Ada/SPARK는 개발자의 ‘명시적인 의도와 증명’을 통해 안전성을 확보하는 길을 선택했습니다. 어느 쪽이 더 합리적인지는, 결국 개발자의 철학에 달려있을 것입니다.

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 현역으로 군대 안 간게 의아한 스타는? 운영자 25/06/30 - -
AD 휴대폰 바꿀까? 특가 구매 찬스! 운영자 25/07/02 - -
공지 프로그래밍 갤러리 이용 안내 [88] 운영자 20.09.28 45153 65
2869619 금요일에 일 추가로 시키진 않겠지 아스카영원히사랑해갤로그로 이동합니다. 09:30 10 0
2869617 [업뎃] 러스트 가스라이팅의 3단계 루비갤로그로 이동합니다. 09:12 16 1
2869616 프로그래밍 얘기는 계속 패배하니까 [3] ㅇㅇ(211.235) 09:11 46 3
2869615 나 노래 잘부르는거임? ㅇㅇ(222.104) 09:03 11 0
2869614 ❤✨☀⭐나님 시작합니당⭐☀✨❤ ♥냥덩이♥갤로그로 이동합니다. 09:01 12 0
2869613 러스트의 현실 프갤러(218.50) 08:43 25 0
2869612 컴공 나왔는데 임베디드 개발자는 힘드냐 [1] 프갤러(112.171) 08:28 36 0
2869611 여자아이 출산이랑 태반이 최고 ㅇㅅㅇ 류류(118.235) 08:27 19 0
2869610 어린 여자아이 알몸이 최고 잠지가 최고 류류(118.235) 08:26 21 0
2869609 러스팅 소울, 5장: 바이너리의 그림자, 현실의 무게 루비갤로그로 이동합니다. 08:22 13 0
2869608 골목길 접어들때에~ 내가슴은 뛰고 있었지~ ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 08:17 11 0
2869607 태연 ㅇㅅㅇ 헤르 미온느갤로그로 이동합니다. 08:12 12 0
2869606 자바 음... 참으로 안타까운 문제지. 음... 진짜 쓰레기 같은건데 프갤러(42.26) 08:06 18 0
2869605 하루 한 번 헤르미온느 찬양 헤르 미온느갤로그로 이동합니다. 08:05 13 0
2869603 학점딸리는 개발자 부캠가려는데 자바 부캠하는거 미친짓이냐? [1] 프갤러(112.171) 07:59 23 0
2869602 저능아들의 발작 포인트. 러스트의 존재 자체. 프갤러(223.54) 07:58 15 0
2869601 러스트 극성 지지자들의 '발작' 포인트: 짧고 강하게 짚어보기 루비갤로그로 이동합니다. 07:57 17 0
2869600 난 군대있을때 배구공(119.202) 07:55 20 0
2869599 나훈아 씨가 말한 슈퍼스타의 조건. 팬들만 미치게 해서는 부족하다. 프갤러(223.54) 07:54 16 0
2869598 나는 러스트를 욕한적 없고 커널이 동적링킹한다는 말도 한 적이 없다. [17] 루비갤로그로 이동합니다. 07:53 41 1
2869597 러스트 까들은 자신의 열등한 지능을 숨기려 llm 츠쿠요미로 도망쳤지만 프갤러(223.33) 07:52 13 1
2869596 러스트 1. 베어메탈 임베에서도 문제, 2. 리눅스 임베에서도 문제 루비갤로그로 이동합니다. 07:51 11 0
2869595 러스트하면 눈을 뒤집고 욕하는 놈들의 심리 프갤러(223.33) 07:49 14 0
2869594 이게 이전 버전 임베디드 관련 문서다. 루비갤로그로 이동합니다. 07:48 26 0
2869593 선생님들 조언좀 부탁드립니다 ㅇㅇ갤로그로 이동합니다. 07:43 22 0
2869592 러빠와 ㅆㅇㅆ이 허위사실 유포하는 거지 루비갤로그로 이동합니다. 07:42 16 1
2869591 서울에 가보니까 배구공(119.202) 07:42 24 0
2869590 임베디드 관련 내가 초기에 주장했던 글에 오류 없음 루비갤로그로 이동합니다. 07:38 20 1
2869589 소름돋는 홍콩과 같은 길을 가는 공산한국 ♥냥덩이♥갤로그로 이동합니다. 07:28 17 0
2869588 짱깨,북괴 핵 발사시 서울 상황 ♥냥덩이♥갤로그로 이동합니다. 07:24 17 0
2869586 중요) 모두 봐라. 그리고 이걸 모두에게 말하라. 나라의 중대사다. 근구수왕갤로그로 이동합니다. 07:17 21 0
2869585 나라가 어쩌고 저쩌고 하기 전에 먼저 해야할 것 프갤러(110.8) 07:17 15 0
2869583 나라가 나한테 잘못한 것 넥도리아(175.196) 07:03 17 0
2869581 한번시작한 프로젝트는 하기싫어져도 끝까지 하는게 좋냐? [1] 프갤러(106.102) 06:59 18 0
2869580 커널모듈이 동적링크로 로딩되서 커널 바이너리 크기가 줄어드나요? 프갤러(110.8) 06:58 16 0
2869574 나님 기분 ㄱㅆㅅㅌㅊ !!! ♥냥덩이♥갤로그로 이동합니다. 06:44 13 0
2869570 청년기본소득 줄까? [1] 넥도리아(175.196) 05:19 23 0
2869566 루비가 훌륭한건 알겠음 프갤러(118.37) 04:59 34 1
2869562 디시를 어떻게해야 닉만으로 부대를 알지? [9] ㅇㅇ(211.227) 04:33 45 0
2869560 Bob Dylan on The Fugs – CIA Man 발명도둑잡기(118.216) 04:29 10 0
2869558 저사람은 아침에도 점심에도 저녁에도 새벽에도있네 [1] ㅇㅇ(211.227) 04:17 39 1
2869556 군대 이야기 참 생각하면 좆같은게 동생 죽는거 군대때문에 못봄 [3] ㅆㅇㅆ(124.216) 04:13 69 0
2869554 이게 루비가 초기에 주장했던 임베디드를 다들 루비글을 안읽으니 ㅆㅇㅆ(124.216) 04:09 33 0
2869552 ㅆㅇㅆ아 군대에서처럼 살지 마라 [6] 프갤러(156.146) 04:05 77 2
2869550 펌쟁이가 임베떡밥있길래 글 써봄 [3] 프갤러(39.120) 03:50 44 0
2869549 20분 전쯤 내 갤럭시 S20 유튜브가 재생이 시작 안되서 발명도둑잡기(118.216) 03:50 26 0
2869548 3차원 시간 가설 사실이면 노벨상이고 혁명 발명도둑잡기(118.216) 03:47 15 0
2869547 제 방 책들 정리중입니다. 넥도리아(175.196) 03:36 33 0
2869545 민생지원금이 25만원인데 오른 집값은 2억5천 정도 발명도둑잡기(118.216) 03:01 18 0
뉴스 페이블 재현, 백혈병 투병 중 사망…향년 23세 디시트렌드 07.03
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2