Pages

Sunday, January 16, 2022

Flutter/DART: First Impression

All of sudden, I had a chance to briefly review Flutter. Covering all desktop, mobile, web in single programming language, and for web, compiled to Javascript instead of WebAssembly which takes a forever-log real time compilation time - isn't it lovely and beautiful? (Oh, Qt has WebAssembly port, but it takes forever to compile the code, which may be because of that big fat core library).

Someone said that the biggest weakness of Flutter is DART, but I don't agree. The structure of DART is quite interesting, and considering the accessibility from other programming languages it is both understandable(I'm looking at you, Rust). The only thing I dislike is that darn garbage collector, but I think I should admit if DART doesn't want to manually control pointers in any way. Or, if they force RAII in whatever way everyone will be angry. :P

I think, the biggest drawback of Flutter is state management. For other frameworks you don't have to distinguish stateful against stateless widgets, but in Flutter you must do it verbosely. What's more, if build() is called it automatically finds only changes and applies only found changes. For someone the word "automatic" will say "yeah so it's Google!". But as a C++ developer myself, I throw a question like "why do you compare everything when you can recognize changed area?" For me, it looks like that the Flutter developers designed to change everything, yet distinguishing stateful widgets against stateless ones to minimize overhead to GC(the garbage collector). I think, for me, the property binding of Qt is better than this.

I'm afraid the approach of Google in this way would drop the readability of the code. If you read Introduction to widgets, one of the official documentation for Flutter, you see "the separation of responsibility allows greater complexity to be encapsulated in the individual widgets, while maintaining simplicity in the parent". For me, it sounds like a warning to prepare for the hellish burning(......) hell, when you have to change the stateless widget. What if you have to separate some part of stateless to stateful side? And there's no absolute way to prevent you from doing it. Most of the people select Python or Javascript because they provide very flexible development environment for requirements changed in real time, but I think, for Flutter that kind of flexibility would be a bit hard.

I'm not sure about others' opinions, but for me DART is okay but I'm a bit against Flutter. It's like...... it forces specific development process and design concepts. Do I really have to do it this way? I'm not sure.

Flutter/DART를 훑어보다

어쩌다 보니 요즘 뜨고 있는 개발환경인 Flutter를 살펴보게 되었습니다. 단일 프로그래밍 언어에 단일 환경으로 desktop과 mobile과 web을 모두 커버할 수 있는데다가, 심지어 web의 경우 컴파일하다가 날 샐지도 모르는(......) WebAssembly 대신 Javascript로 직접 컴파일된다 하니, 이 어찌 신박하다 하지 않을 수 있겠습니까(Qt도 WebAssembly 포트가 있습니다만, Qt 자체가 덩치가 크기 때문인지 프로그램을 로딩하다가 날밤을 샐 정도로 답답합니다. -_-).

혹자는 Flutter의 최대 단점은 DART다(......)라는 희대의 명언(?)을 내놓기도 했습니다만, 전 이 부분에 대해서는 그다지 동의하지 않습니다. DART의 구조는 매우 흥미로우며, 타 언어 사용자들로부터의 접근성이나 생산성 향상이라는 측면에서 보면 DART의 구조는 최소한 납득할만하다고 생각합니다(Rust 개발자 여러분, 보고 계십니까). 단, 딱 한 가지 제가 싫어하는 부분이라면 역시 그놈의 쓰레기 수집기(garbage collector)인데, 이 부분은 DART가 메모리 수동 제어를 수행하지 않는다는 것을 고려한다면 어쩔 수 없는 한계라고 봅니다. 그렇다고 RAII라던가 하는걸 문법상으로 강제했다간 다들 들고 일어날거고...... -_-

제가 생각하기에 Flutter의 최대 단점은 상태 관리라고 봅니다. 다른 프레임워크들의 경우 stateful과 stateless widget을 따로 구분할 필요가 없는 반면, Flutter는 이를 명시적으로 구분하도록 되어 있습니다. 그리고 build()를 호출할 경우 현재 상태와 이전 상태를 비교해서 변경된 부분을 자동 인식하여 화면을 빠르게 재구성한다고 되어 있습니다. 변경된 부분을 자동으로 인식한다는 이러한 접근 방법은 한편으로는 '오오 구글'이라는 탄성을 가져오게 할 수도 있지만, 지나가던 C++ 개발자의 눈에는 '그냥 변경된 것만 고치지 왜 쓸데없이 모든 부분을 다 비교하지?'라는 생각이 들게 만들더군요. 무조건 전체를 다 고치도록 해놓고, 그 와중에 GC의 오버헤드를 최대한 줄이기 위해 수동으로 stateful과 stateless widget을 나눈게 전부가 아닌가 싶은 생각이 듭니다. 이 부분은 오히려 Qt의 property binding 구조가 훨씬 더 나은 것 같아요.

특히나 구글의 이러한 접근방식은 프로그램이 복잡해질 경우의 가독성을 크게 떨어뜨릴 것 같습니다. Flutter의 공식 문서 중 하나인 Introduction to widgets를 보면 "the separation of responsibility allows greater complexity to be encapsulated in the individual widgets, while maintaining simplicity in the parent"라는 문장이 나오는데, 제게는 저 문장이 나중에 저 stateless widget을 고쳐야 할 경우가 생긴다면 불지옥이 펼쳐질 수도 있다는 소리처럼 들립니다. 이를테면, stateless widget의 일부는 stateless로 남겨두는 대신 일부는 stateful로 가야 하는 상황이 발생한다면 어떻게 될까요? - 그리고 솔직히 그러지 말라는 법도 없습니다. 사람들이 Python이나 Javascript로 가는 이유 중 하나가 실시간으로 발생하는 요구사항에 대한 유연한 대처가 가능하기 때문인데, Flutter는 구조상 이러한 유연성을 가지기가 어렵지 않을까 하는 생각이 듭니다.

다른 분들은 어떻게 생각하실지 모르겠습니다만, 전 DART는 괜찮은데 Flutter는 조금 거부감이 드는군요. 뭐랄까...... 특정한 개발 프로세스와 디자인 컨셉을 무조건적으로 강제하는 듯한 느낌입니다. 굳이 이렇게까지 해야 할까 하는 생각이 드네요.