Skip to main content

웹프론트엔드 개발자의 Rust 돌려까기 🥊

· 20 min read
양희창

안녕하세요! 비브로스 웹프론트엔드팀 양희창입니다. 🙇🏻‍♂️

이번 글에서는 7년째 떠오르는 언어인 Rust 를 학습한 경험을 공유합니다.

rust

글의 작성 배경

비브로스 웹프론트엔드팀은 주력 개발 언어로 Typescript 를 사용하고 있습니다.

https://media.vlpt.us/images/cjh951114/post/dcedbd85-a3ef-4add-8280-136c6a3d35b5/typescript_logo.png

Typescript가 현재 웹프론트엔드 진영에서 가장 성공적인 언어로 자리매김한 이유도 있지만(제일 유명하니까?) 무엇보다도 정적 타입 선언으로 인한 안정성으로 동료와의 협업에 큰 도움이 되는 장점이 있어 사용합니다.

99BE50335A25FBAF2265D7.jpeg

그런데 상당히 오랜기간동안 개발자 선호도 조사에서 Typescript를 압도하는 언어가 있습니다.

바로 Rust 입니다. 그리고 요즘 핫해...

Stack Overflow Developer Survey 2021

2015년 부터 스택오버플로우 설문조사에서 매년 개발자들이 가장 좋아하는 언어로 선정되고 있습니다.

2021 스택오버플로우 개발자 조사

2021 스택오버플로우 개발자 조사

~~Clojure는 왜 2위야... 몰라..뭐야, 그거...~~

Clojure는 왜 2위야... 몰라..뭐야, 그거...

왜 개발자들은 Rust를 좋아할까요?

저렇게 많은 개발자들이 좋아하는 Rust를 우리는 왜 가장 먼저 배우지 않는 걸까요?


Rust의 역사에 Typesciprt 한스푼 🥄

러스트 (프로그래밍 언어) - 위키백과, 우리 모두의 백과사전

Rust는 모질라 리서치에서 개발한 범용 프로그래밍 언어이다. ... 2006년 개발자 그레이든 호아레의 개인 프로젝트로 시작... 2010년 처음으로 일반에 공개... 2012년 1월 첫 번째 알파버전 0.1이 발표되었다.

Rust의 역사는 생각보다 오래됐습니다. 공식 블로그에서 연혁을 확인해 보면 2014년 9월 15일에 1.0 버전이 발표되었죠. 일반에 공개된 시점부터 계산하면 무려 12년이 넘었습니다.

그리고 현재 2022년 Rust는 1.59.0 버전까지 릴리즈 되었죠.

여기서 잠깐, 그럼 Typescript는?

1.4 타입스크립트의 역사

타입스크립트는 Turbo Pascal, Delphi, 그리고 C#의 핵심 개발자인 Microsoft 직원 Anders Hejlsberg의 리드 하에 개발되었고, 2년간의 내부 개발을 거쳐 2012년 10월 1일 공개되었다.

여기서 인상적인 것은 TypescriptRust와 비슷한 시기에 공개된 언어라는 점입니다.

그리고 현재 Typescript는 4.6 버전까지 릴리즈 되었습니다.

Typescript는 Javascript의 Superset 언어입니다.

Typescript는 Javascript의 Superset 언어입니다.

우리에게 Intellij 또는 WebStorm으로 익숙한 JetBrains사의 2020년 개발자 조사에 따르면

JavaScript 프로그래밍 - 2020년도 개발자 에코시스템 현황 인포그래픽

2017년도에는 Typescript 사용자가 약 13%에 불과했으나 무려 3년만에 40%으로 상승한 결과가 발표되었습니다. 수많은 엔터프라이즈급 코드들이 Typescript로 작성되고 있다고 유추해 볼 수 있습니다.

같은 해(2020년) 조사된 Rust는 어떨까요?

스크린샷 2022-03-28 오후 5.47.28.png

야... Rust 좋다며...? 개발자들이 제일 좋아한다며...?

야... Rust 좋다며...? 개발자들이 제일 좋아한다며...?


Rust가 아직 방구석 언어인 이유 2가지

1. Rust는 어렵다.

요즘 Rust를 밀고있는 Microsoft의 MSDN 페이지에 가보면 이런 문구가 있습니다.

Rust를 사용하여 Windows에서 개발하는 방법에 대한 개요

... 그렇다면 Windows의 최신 언어 프로젝션에 Rust를 사용하기로 선택한 이유는 무엇일까요? 한 가지 이유로, Stack Overflow의 연간 개발자 설문 조사를 보면 현재까지 매년 가장 많은 사랑을 받은 프로그래밍 언어가 바로 Rust입니다. 이 언어는 가파른 형태의 학습 곡선을 보이지만, 첫 고비만 넘기면 이 언어를 좋아하지 않을 수 없습니다.

인용된 문단에서 어쩐지 위화감이 드는 문장을 찾아 볼 수 있습니다. 첫 고비만 넘기면 ...? 😱 대체 이 첫 고비라는 게 뭘까요?

1.1 가비지 콜렉터(Garbage Collector)가 없다

JavaJavascript와 같은 고수준 언어들은 할당된 메모리가 더이상 필요 없을 경우를 판단해 자동으로 회수하는 GC를 가지고 있습니다. 이러한 GC의 존재 때문에 Javascript 또는 Typescript를 사용하는 개발을 하면서 메모리를 할당만 하지 해제는 할 필요가 없는 것이죠.

이런 사람이 되지 않아도 이제 누구나 개발자로 밥벌이를 할 수 있다

이런 사람이 되지 않아도 이제 누구나 개발자로 밥벌이를 할 수 있다

하지만 Rust는 다릅니다. GC(Garbage Collector 녹십자)가 없습니다.

대신 우리를 미치게 만드는 소유권(Ownership) 이 있죠! 😀

The Rust Programming Language

소유권(Ownership)은 러스트의 가장 유니크한 특성이며, 러스트가 가비지 콜렉터 없이 메모리 안정성 보장을 하게 해줍니다.

뭔소리여...

뭔소리여...

1.2 소유권(Ownership) 개념이 매우 생소하다

Rust는 쉽게 말해 쓰레기(Garbage)를 깨끗하게 치우는 방법보다 쓰레기를 만들지 않는 방법을 선택합니다.

아래와 같은 규칙으로 말이죠.

  • 소유권 규칙
    1. Rust 의 각각의 값은 해당값의 오너(Owner)라고 불리우는 변수를 갖고 있다.
    2. 한번에 딱 하나의 오너만 존재할 수 있다.
    3. 오너가 스코프 밖으로 벗어나는 때, 값을 버려진다(dropped).

hello 라는 string을 받아서 hello world! 를 출력하는 코드를 작성해 봅시다.

function main() {
let s1 = 'hello';
let s2 = s1;

console.log(`${s1}, world!`); // hello, world!
}
fn main() {
let s1 = String::from("hello");
let s2 = s1;

println!("{}, world!", s1); // error[E0382]: borrow of moved value: `s1`
}

Typescript에서는 자연스럽고 익숙한 코드 같은데 Rust에서는 왜 s1 변수를 출력 할 수 없을까요?

바로 hello 라는 문자열의 소유권이 s1 에서 s2이동(Move) 됐기 때문입니다.

  • let s2 = s1 의 메모리 할당 동작 방식 차이

위와 같은 코드에서 Typescripts1의 참조값(reference value)이 s2에 복사되어 서로 같은 메모리 주소를 바라보고 있는 상태가 되며 그 상태가 유지됩니다. 그리고 값이 더이상 사용되지 않을 경우 다양한 GC 알고리즘을 통해 할당이 해제되어 메모리 자원이 회수됩니다.

V8 Engine의 Garbage Collection

V8 Engine의 GC 알고리즘에 대한 깊은 내용

하지만 Rusts1의 참조값을 s2에 할당 하는 순간 복사(Copy)가 아닌 이동(Move)으로 사용이 끝난 메모리를 즉시 회수합니다.

그리고 이러한 메모리 관리 동작 방식을 위해 Rust 컴파일러는 사사건건 에러를 던지고 지나치게 개발자를 괴롭히고 구속합니다.

1.3 고인물 컴파일러의 지나친 친절함

개발 뉴비가 Rust 컴파일러를 만났을 때

개발 뉴비가 Rust 컴파일러를 만났을 때

Rust 컴파일러는 정말 친절합니다.

어느 line 에서 어떤 문제가 발생했는지도 알려주고 그 문제에 대한 해결 방법까지 추천해 줍니다.

warning: unused variable: `s2`
--> main.rs:3:6
|
3 | let s2 = s1;
| ^^ help: if this is intentional, prefix it with an underscore: `_s2`
|
= note: `#[warn(unused_variables)]` on by default

error[E0382]: borrow of moved value: `s1`
--> main.rs:5:25
|
2 | let s1 = String::from("hello");
| -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
3 | let s2 = s1;
| -- value moved here
4 |
5 | println!("{}, world!", s1); // error[E0382]: borrow of moved value: `hello`
| ^^ value borrowed here after move
|
= note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0382`.

스크린샷 2022-03-28 오후 9.55.40.png

네 맞습니다. 컴파일러가 시키는대로 하면 됩니다. 그걸 이해할 수 없어도 말이죠 🥲

다만 Rust로 개발을 배워보고 싶은 뉴비가 위와 같은 에러 로그를 일주일동안 만났을 때...

아래와 같은 블로그 포스팅은 절대 할 수 없을 거라고 확신할 수 있습니다.

일주일만에 Rust에 매료되다

심지어 프론트엔드 뉴비 개발자라면 더더욱 불가능한 이야기, 이분의 github repo에도 rust로 된 public repo는 없었다

여기서 Rust가 여전히 방구석 개발언어, 취미용 언어로 취급되는 이유를 알 수 있습니다.

그동안 여러 언어를 학습하면서 한가지 확신하게 된 점은 어떠한 언어가 폭넓게 선택되고 쓰여지기 위해서는 신입 개발자의 유입이 꾸준히 있어야 한다는 점입니다.

하지만 개발자 꿈나무가 유입되기에 Rust는 학습하기 위해 익혀야 하는 사전지식의 깊이(러닝커브)가 지나치게 깊고 높습니다.

Rust를 배우기 위해 C++과 Java 둘 다 배워야 한다면...?

Rust를 배우기 위해 C++과 Java 둘 다 배워야 한다면...?

특히 Rust의 컴파일러는 이러한 문제를 심화시킵니다.

지나치게 엄격한 문법복잡한 타입의 존재(정수형 10가지 타입, 문자열 6가지...등등)는 뭔가를 만들어 보기도 전에 개발자 꿈나무들을 지치게 만들며 크고 앞으로 Rust 생테계의 미래를 어둡게 하는데 일조할 가능성이 큽니다.

다들 대학에서 C++ 수업 들어봤잖아여....?

Golang 를 개발한 구글의 개발자들이 Safety와 Performance를 몰라서 GC를 남겨뒀다고 생각하지 않는다.

Golang 를 개발한 구글의 개발자들이 Safety와 Performance를 몰라서 GC를 남겨뒀다고 생각하지 않는다.

Rust와 자주 비교되는 Golang의 경우 여전히 GC를 가지고 있는 점이 이러한 측면을 고려한 부분이 아닐까 싶고

Go 언어의 GC에 대해 - LINE ENGINEERING

마찬가지로 탈 지구급 개발 인력을 가진 Microsoft가 새로운 언어를 개발하지 않고 고작(?) Javascript의 Superset 언어인 Typescript를 개발한 이유와도 일맥상통하는 지점이 아닐까 생각됩니다.

2. Rust로 뭐 해야해?

2.1 WebAssembly

Rust가 프론트엔드 개발자에게도 조금씩 주목받는 이유는 아마도 WebAssembly 때문일 겁니다.

Rust를 WebAssembly로 컴파일하기 - 웹어셈블리 | MDN

Rust 또는 저레벨 수준의 언어(C, C++)로 작성된 코드를 wasm으로 변환하면 네이티브에 가까운 성능으로 웹브라우저 상에서 코드를 실행할 수 있습니다.

그러나 wasm을 사용하기 위해 꼭 Rust를 사용해야 하는 것은 아닙니다.

https://docs.microsoft.com/ko-kr/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-6.0

Microsoft의 경우 자사가 개발한 언어가 아님에도 이례적으로 Rust를 MSDN에서 소개하며 가이드 문서를 제공하고 있지만 Microsoft 의 다양한 제품 포트폴리오에서 blazor 와 같은 .NET 계열 프레임워크를 사용하면 얼마든지 wasm 으로 코드를 변환 할 수 있습니다.

Rust를 활요한 웹프레임워크 또는 라이브러리도 활발하게 개발되고 있는 것으로 보이나 아직 시장을 선도하는 (React 와 같은) 제품은 찾아보기 어렵습니다.

Rocket - Simple, Fast, Type-Safe Web Framework for Rust

What is Yew? | Yew

이는 현재의 SPA(Single Page Application) 시장에서는 React가 확실한 우위를 보이며 시장을 선도하고 신입 개발자들을 끌어들이는 것과는 크게 비교됩니다.

Angular vs React 😎 오랜 SPA 대결은 React의 승리가 화...확실하다

Angular vs React 😎 오랜 SPA 대결은 React의 승리가 화...확실하다

React, Angular, Vue 와 같은 삼대장(?)급 물건들이 나오지 않는다면 앞으로도 수많은 웹프론트엔드 개발자들이 Rust 학습에 동기부여 하기는 어려울 것입니다.


그래도 우리가 Rust를 학습 해야 하는 이유 🙆🏻‍♂️

야 너두 Rust 할 수 있어...?

야 너두 Rust 할 수 있어...?

Getting Started - SWC

Rust로 Javascript/Typescript 컴파일러를 만들어버리는 초능력자가 되자는 얘기가 아니다

Rust는, Javascript는 GC 있으니까 괜찮겠지(심지어 이런 생각조차 안해 본)~ 컴퓨터 성능이 좋아져서 괜찮겠지~ 라고 생각하는 개발자들의 습관으로 인해 생기는 수많은 버그와 오류들을 사전에 걸러내고 경고해주는 점에서 배울 가치가 있는 언어입니다. 🤦🏻

사실 웹 시장에서 SPA 형태의 웹앱이 개발되기 시작한 뒤로 웹앱 개발의 러닝커브가 많이 낮아짐에 따라 개발자를 꿈꾸는 사람이 많아졌습니다. 물론 시장의 수요도 폭발해서 대우도 많이 좋아졌죠

하지만 그에 대한 반작용으로 빠른 개발 속도로 인한 코드 품질의 저하, JIT 컴파일로 인한 에러 핸들링의 소홀 등과 같은 문제점들도 많이 발생 됐다고 생각합니다.

스크린샷 2022-03-28 오후 5.47.28.png

추측컨데 Rust를 사용하는 사람들 중 다수를 차지하는 취미 또는 개인적/부차적 프로젝트 사용자들은 본인이 밥벌이로 사용중인 개발 언어가 따로 있을 가능성이 큽니다.

이러한 배경을 가진 사람들이 Rust를 통해 얻고자 하는 건 아마도 안정성과 성능을 확보하는 아이디어를 자신이 다루는 언어에 녹여내고자 함이 아닐까 생각합니다.


회고 👨‍💻

오랜만에 새로운 언어를 공부하니 뇌에 과부하가 걸린 것 같은 느낌이었지만! 나름 잘 소화해 낸 것 같아 뿌듯하네요. 다만 코로나로 인해서 세미나 준비에 온전히 집중하지 못했고 목표로 했던 Rust 학습 단계를 전부 마치지 못했던 점이 아쉬움으로 남았습니다.


💡 🚀 우리팀이 일하는 방법! 👉🏻 비브로스 웹프론트엔드팀 👈🏻

비브로스