Rust

W ramach podcastu “Porozmawiajmy o IT” miałem okazję porozmawiać z Pawłem Dulębą i Michałem Krasnoborskim o tym jak z głową zmienić pracę i branżę na IT.

Posłuchaj naszej rozmowy w wersji audio 🎧 👇

Cześć! Dzisiaj moimi gośćmi są Paweł Dulęba, Senior Software Engineer w CodiLime, programista Embedded od ponad dekady, pracował w technologiach obecnych w urządzeniach codziennego użytku po wielkie serwery. Jest zdania, że najlepszy język programowania to ten, który daje największe możliwości w rozwiązywaniu aktualnego problemu.

Oraz Michał Krasnoborski, Senior Software Engineer w CodiLime, programista odnajdujący się wszędzie tam, gdzie wydajność ma znaczenie. Od programowania GPU po przetwarzanie ruchu sieciowego na żywo. Lubi łączyć wysokopoziomowe abstrakcje z analizą kodu na poziomie Asemblera. W sukces Rusta wierzył już przed wydaniem wersji 1.0.

Panowie, bardzo miło mi gościć Was w podcaście.

P.D.: Nam jest miło, że tu jesteśmy z Tobą.

M.K.: I mnie również.

Cieszę się bardzo, a dzisiaj będziemy rozmawiać właśnie o Rust jako o języku. Co jakiś czas w ramach mojego podcastu staram się omawiać języki programowania, żeby nieco przybliżyć ich historię, ale również to, gdzie najlepiej się odnajdują. Dzisiaj mam dwóch gości, więc myślę, że temat Rusta rozwałkujemy i pokażemy jego możliwości.

Ale zanim do tego przejdziemy, to chciałbym Was zapytać o to, o co pytam standardowo na wejściu do mojego podcastu, czyli: czy słuchacie podcastów? Jeśli tak, to może macie jakieś swoje ulubione audycje, o których chcecie powiedzieć?

M.K.: Ja słucham, ale niestety żadnych polskojęzycznych. Słucham podcastu Lexa Freedmana i w zasadzie w moim życiu mam czas na słuchanie pół podcastu i jest to ten podcast. Wchodzi na ciekawe tematy filozoficzne, tak że malutka odskocznia od programowania.

P.D.: Szczerze powiedziawszy, ja nie mam czasu na nic i naprawdę zastanawiałem się, jaki tytuł tutaj wybrać i czy kojarzę jakikolwiek, natomiast niestety nie. Tak że bardzo mi przykro.

Jasne, nie ma problemu. To tym bardziej cieszę się, Paweł, że znalazłeś czas na nagrywanie podcastu, skoro z tym czasem faktycznie jest tak trudno.

Na początku chciałbym Was zapytać, jaka jest historia powstania Rusta, kto go stworzył i skąd ta rdzawa nazwa.

M.K. To zacznę od końca, bo rdzawa nazwa wynika z tego, że jest to język, który jakby odgrzebuje rzeczy, które zostały już dawno wymyślone, gdzieś w obszarze researchowych takich języków programowania, ale nigdy nie zostały mainstreamowo użyte, więc tak naprawdę to jest nowe połączenie starych rzeczy, chociaż dla przeciętnego programisty mogą to być nowe rzeczy. I ten język powstał jako prywatny projekt niejakiego pana Graydona, który później został przyjęty pod skrzydła Mozilli i w 2015 roku została wypuszczona w świat wersja 1.0.

Jasne. Ja rozgraniczam języki programowania, pod względem historycznym przynajmniej, na takie, które powstają z powodów hobbistycznych — po prostu ktoś chciał stworzyć nowy język programowania — ale pewnie większość adresuje jakieś problemy, albo powstają, ponieważ brakowało czegoś takiego na rynku. Jak to jest z Rustem? Czy to jest projekt hobbistyczny, czy może powstał dlatego, że miał być panaceum na jakieś problemy? Jeśli tak, to jakie bolączki właśnie adresuje?

M.K. W Mozilli Rust był używany na początku jako takie eksperymentalne pole, jak wyglądałby język, w którym przyjemnie pisałoby się przeglądarkę na miarę obecnej czy poprzedniej dekady, gdyż Firefox jako dosyć stary codebase napisany w C++, były próby „zrównaleglania” go, ale często kończyły się porażką. Więc Rust miał być tym językiem, w którym przyjemnie i bezpiecznie rozwiązuje się problemy concurrency i „zrównoleglania” przy oczywiście zachowaniu wydajności, bo to jest kod w przeglądarce. Ale to były tylko początki i w zasadzie zaraz, jak zostało to wypuszczone, community zaczęło ciągnąć temat i Rust stał się językiem, w którym bezpiecznie można rozwiązywać trudne problemy, z naciskiem na wielowątkowość.

Okej, czyli powiedziałeś tutaj o takich dwóch rzeczach, przynajmniej ja usłyszałem dwie rzeczy: wielowątkowość wykonana lepiej, niż to miało miejsce do tej pory oraz bezpieczeństwo. Zastanawiam się tylko, czy to są takie cechy tego języka, które zostały niejako dorobione, albo stały się marketingowym przekazem już później, czy też faktycznie były powodem, dla którego sam język powstał. Czy twórca miał od samego początku zamiar stworzenia języka, w którym tworzenie systemów, programów „zrównoleglonych” będzie przynosiło jakąś tam frajdę, a nie tylko problemy, jak to występowało wcześniej? Czy też raczej sam rozwój języka pokazał, że to jest właśnie ten kierunek? Czy wiecie coś na ten temat?

M.K. Ja myślę, że to dwie rzeczy. W sensie obie te rzeczy są prawdziwe, bo zarówno Rust powstawał z taką myślą, ale też w czasie rozwoju Rusta za każdym razem, jak padała jakaś decyzja zmian w języku, to tych założeń nie chciano zepsuć. W sensie, że w tym języku zawsze miało się łatwo pisać aplikacje wielowątkowe i zawsze ten język miał być językiem bezpiecznym i przyjemnym w użyciu. Więc rozwój tego języka jakby tylko zakorzeniał te wartości.

Jedyna rzecz, która zmieniła się od momentu powstania tego języka i gdzieś jako takiego projektu na boku do mniej więcej wydania wersji 1.0 było to, że Rust się stawał coraz bardziej niskopoziomowy w taki sposób, żeby nadawał się do programowania kerneli czy Embedded i żeby był jak najbliżej systemu. Bo jednak na początku on był troszeczkę bardziej wysokopoziomowy i dużo bardziej podobny do Golanga tak naprawdę. I troszeczkę jakby rozszerzył tutaj swoją niszę, że jest nie tylko bezpieczny i przyjemny, ale także niskopoziomowy.

Jasne, rozumiem. Te cechy, o których tutaj powiedziałeś, czyli właśnie tworzenie „zrównoleglonych” programów czy też bezpieczeństwo, to jest coś, o co zabiega pewnie wiele innych języków również, prawda? Bo mogą być one ważne dla innych języków. Czy musiał powstać nowy język, żeby poradzić sobie z tymi problemami, czy też może dałoby się wykorzystać już istniejące rozwiązania, żeby nieco poprawić ten model współbieżności, bezpieczeństwo? Jakie macie opinie na ten temat?

P.D.: Wiesz co, to jest tak, że tak naprawdę każdą funkcjonalność jesteś w stanie napisać w każdym języku. Ja jestem ze świata Embedded i miałem kiedyś takie podejście do życia, że po co mi C++ na małym klocuszku, jeżeli wszystko jestem w stanie napisać w E-Samplerze i będzie znakomicie działać. I oczywiście, że będzie działać, natomiast trzeba wziąć pod uwagę to, że aktualnie oprogramowanie rozwija się tak szybko i dynamicznie oraz w takich różnych i nieprzewidywanych kierunkach, że dobrze jest mieć standard. I to, co w wielu językach jesteś w stanie osiągnąć, czy to pisząc odpowiednie moduły, czy „poprawiając język przez różne biblioteki” oraz design patterny, wreszcie dostajesz jako standard. Po prostu tak się tutaj pisze.

Dopytam może jeszcze: czy to jest taki standard, który jest pilnowany przez język, przez ekosystem? Czy też raczej jest pewnym standardem wypracowanym po prostu przez programistów?

P.D.: No właśnie to pierwsze. To jest bardzo problematyczne na początku, przy początkowych fazach współpracy z językiem, ponieważ kompilator przekreślił wszystko. Tak naprawdę cokolwiek nie zrobisz z rzeczy, do których jesteś przyzwyczajony w innych językach, Rust powie, że mogłoby być lepiej, i on Ci tego nie weźmie. On tego nie skompiluje i koniec. To nie jest tak, że rzuci warningiem. Nie.

Domyślam się, że to wpływa właśnie na bezpieczeństwo. Albo również może wpływać na bezpieczeństwo tych rozwiązań, jeśli nie mamy różnych możliwości osiągnięcia tego samego, tylko jest pewien standard, pewnie dopracowany, który jest wręcz wymuszany przez kompilator, prawda?

P.D.: Jak najbardziej. To, co powiedziałeś wcześniej, że programiści mogą sobie wypracować pewien sposób działania i rozwijania oprogramowania w danym języku. Tylko że mimo wszystko tak, jesteśmy dorośli i dążymy do tego samego celu, tzn. do znakomitego oprogramowania, które będzie bez błędów, ale zawsze jest zmęczenie, zawsze są pomyłki, zawsze jest coś, co powstrzyma nas od tego idealnego oprogramowania. A tutaj nie ma wyjścia, tutaj na pewno będzie bezpiecznie, ponieważ jest grupa ludzi, która czuwa nad tym, żeby dodawać różne checkery do kompilatora, które w tym pomogą.

Bo tak, oczywiście, w C++ jest dużo linterów, jest dużo tooli do statycznej analizy i oczywiście są ludzie, którzy tego używają, są projekty, które bez tego by się nieobeszły, ale to wszystko jest wbudowane w Rusta i to jest takie wielkie WOW, przynajmniej dla mnie to był taki olbrzymi przeskok jakościowy.

M.K.: Ja bym pociągnął ten temat też, bo w innych językach jest tak, że te lintery jakby powstały później i one są na boku i po pierwsze, ludzie nie zawsze z tego korzystają, a po drugie, nawet jak się z tego korzysta, to są jakieś false positive, są jakieś false negative. Natomiast w Rust lintery i compilarry to jest to samo. Więc to, że te wszystkie checki się rozwijają jednocześnie z językiem, a wręcz są tym językiem, sprawia, że to jest niby coś, co było kiedyś, ale jest to jednak swego rodzaju nowa jakość.

No tak, nie jest to takie oczywiste podejście i nie jest spotykane zbyt często, bo okej, możemy faktycznie, tak jak powiedzieliście, stosować różnego rodzaju lintery czy też zbiory dobrych praktyk, ale tak naprawdę bardzo szybko okazuje się, że i tak powstają obozy, które preferują takie podejście, takie rozwiązania itd. i nie ma takiego jednego standardu. Tymczasem jeśli kompilator nam po prostu nie przepuszcza przypadku Rusta pewnych rozwiązań, to nie mamy wyjścia i jesteśmy jakby trochę przymuszeni do tego, żeby stosować takie, a nie inne rozwiązania.

Czy to była jedna z rzeczy, która Was przyciągnęła, zainteresowała, jeśli chodzi o Rusta? Co Was skłoniło do tego, żeby się nad tym językiem pochylić?

M.K.: Myślę, że tak, że to dla mnie ta jedna rzecz to było jak bardzo spójny był ten język i jak wszystko się tak ładnie składało do kupy. Ja w czasie, kiedy odkrywałem Rusta, eksperymentowałem z wieloma językami programowania, akurat wtedy miałem fazę na Haskella, ale byłem też programistą C++ i po prostu pewnego razu zobaczyłem, że ten Rust jest linkowany, więc postanowiłem przejść sobie przez tutorial i moje wrażenie było takie, że WOW, tu jest dużo rzeczy, które właśnie w C++ są dobrymi praktykami, w Rust są po prostu wbudowane i wymagają wpisania dosłownie jednego znaku i wszystko działa. I to wydało mi się taką elegancką ewolucją lub wręcz ewolucją z C++.

P.D.: A u mnie było troszkę inaczej, znaczy tak, to też były eksperymenty, bo staram się być cały czas na czasie i wiedzieć, co w trawie piszczy, natomiast po tym, jak poznałem Golanga i w przeciągu jednego popołudnia byłem w stanie napisać coś konkretnego, co działało i miało ręce i nogi, stwierdziłem, że drugie popołudnie Rust to jest kolejny język, na którego jest taki hype, więc jest kolejnym wspaniałym kandydatem do zrobienia tego samego: siądnięcia na jedno popołudnie i zrobienia czegoś fajnego i wtedy to wszystko, co powiedzieliśmy przed chwilą, tak strasznie mnie uderzyło w tył głowy. Bo tego się nie dało zrobić. To jest dosyć skomplikowany na początku język, który daje wspaniałe możliwości, ale trzeba chwilę poświęcić.

Czyli ten taki challenge tutaj w Twoim przypadku, mam wrażenie, Paweł, tak? Takie zainteresowanie jakieś tym językiem wynikające być może nie z prostoty, tylko właśnie z zaawansowania. Ciekawe.

P.D.: Tak, z zaawansowania, przy czym szukałem czegoś, co zastąpi mi C i Asemblera na Embedded. Ponieważ ja mam background głównie Embedded i nigdy to C++ na małych mikrokontrolerach i troszkę większych mi nie pasowało, a Rust w swojej dokumentacji obiecuje, że on tyle rzeczy zrobi za mnie, za darmo i w ogóle ja tego nie będę widział w kodzie maszynowym, że musiałem spróbować. Troszkę się odbiłem, ale jestem bardzo zadowolony z tego, że mnie to nie odstraszyło aż tak bardzo.

Jasne.

M.K.: À propos nieodstraszenia, to chciałem dodać, że Rust był pierwszym językiem, w którym w zasadzie nie widziałem żadnej jakiejś takiej większej luki, i to był w zasadzie taki pierwszy język, w którym powiedziałem, że WOW, to faktycznie może być język taki uniwersalny.

Brzmi całkiem dobrze. To spróbujmy może osadzić ten język na firmamencie innych języków programowania, jakoś go porównać. Gdybyście mogli powiedzieć, czym on się wyróżnia, już trochę padło tutaj na ten temat, co może być taką specyfiką tego języka, ale gdybyście mogli tutaj właśnie podsumować, co go odróżnia od innych języków, a jakie też może z kolei inspiracje z innych języków tutaj widzicie przeniesione do Rusta?

M.K.: Wydaje mi się, że na pewno go wyróżnia to, jakie ma połączenie ficzerów niekoniecznie konkretne ficzery, lecz połączenie. Bo osobiście nie znam żadnego języka, który jest tak wydajny, tak niskopoziomowy, a jednocześnie bez użycia słowa kluczowego unsave. Kompilator nam gwarantuje, że ten kod będzie wolny od wszystkich brzydkich rzeczy, typu jakieś losowe mazanie po pamięci. Rust jest świadomy tego, że to jest coś trudnego do osiągnięcia, więc w ogóle autorzy mówią o czymś takim, jak weirdness budget, czyli że Rust ma określony budżet na wszelkie swoje dziwactwa i żeby osiągnąć ten cel, że mamy ten język bezpieczny, który jednocześnie jest szybki i niskopoziomowy, Rust ma w zasadzie takie dwie unikalne cechy, bo ma concept of ownership, czyli w zasadzie każdy obiekt ma dokładnie jednego posiadacza, i cały concept pożyczania i concept referencji.

To są takie dwie unikalne rzeczy. Natomiast autorzy starają się, żeby wszystkie rzeczy, które nie są kluczowe do osiągnięcia tego celu, czyli oprócz tego ownership i borrowing raczej ficzery są pożyczone z innych języków, np. Pattern Matching jest, powiedzmy, pożyczony z OCamla i innych języków tego typu, trejty są wzięte z Haskella i składnia generalnie jest C++, mimo że nie musiała być taka itd.

P.D.: Ja może odpowiem tak bardzo przyziemnie. Całe cargo i ten cały tooling, który wokół Rusta tak naprawdę jest, bo on jest dodawany w komplecie. Instalujesz Rusta, który ma po prostu skrypt rust.app, uruchamiamy na platformie, którą Rust wspiera i nagle masz Rusta. To nie jest paczka, którą ścągasz chociażby ze strony Golanga, ropakowujesz, uruchamiasz instalator i on coś tam ściąga. Tutaj uruchamiasz jeden mały skrypt, który ściągasz ze strony i cały tooling jest już u Ciebie. I jak jest już u Ciebie, to odkrywasz, że z tym toolczeniem przyszło bardzo dużo standardowych dla Rusta narzędzi i to wszystko jest takie skondensowane. Ty nie musisz szukać w paczkach swojej dystrybucji czy exe-ków na inne systemy, to wszystko jest. No i jest takie cargo, które jest menedżerem paczek w Rust i oczywiście, to menedżery paczek w innych językach programowania są, od pewnego momentu zaczęły się pojawiać, jest sobie w Pythonie MPM dla Java Scriptu, natomiast cargo jest, po pierwsze, od samego początku w Rust, no prawie od samego początku, ale dla zwykłych śmiertelników, którzy nie są Michałem: od samego początku. I po prostu działa, robi wszystko, czego potrzebujesz. „Menedżuje” paczkami, rozwiązuje zależności.

A właśnie, Rust ma taką wspaniałą rzecz, której inne języki nie mają, tzn. jedno centralne repozytorium paczek. Jeżeli jest jakaś paczka, która nie jest Twoją prywatną paczką, którą chcesz sobie gdzieś tam trzymać na boku, ponieważ jest firmowa i tajna, to te wszystkie paczki lądują w jednym miejscu, w jednym repozytorium stamtąd są ściągane.

Więc to jest taki kolejny sposób Rusta na to, żeby wszystko było ładnie skondensowane, opakowane i dostarczone Ci prosto pod nos. I cargo jest w stanie również wysyłać te paczki na ten serwer, tzn. jesteś sobie w stanie wyleopować swoją paczuszkę, swojego crate’a, bo tak to się w Rust nazywa, który będzie coś robił, nie wiem, wrapował jakąś bibliotekę albo dostarczał jakąś funkcjonalność i przy pomocy tego samego cargo, które zainicjował Ci projekt, wysłać go do repozytorium. I to wszystko dzieje się w jednym miejscu. Rusta można debugować w GDB, tak jak wiele programów w C i w C++. I również z dystrybucją przychodzą skrypty pythonowe, które w tym GDB pozwalają ładnie wyświetlać te wszystkie dodatki Rusta, takie dodatki programistyczne, żeby się łatwiej debugowało. I tak, to jest takie wielkie WOW dla mnie, który jest niby bardzo podobne do innych języków, ale jest bardzo unikalny w swoich rozwiązaniach.

Okej. Muszę powiedzieć, że bardzo ładną laurkę tutaj wystawiacie temu językowi. I teraz właśnie chciałbym Was zapytać o Wasze wrażenia z drugiej strony. Bo na koniec dnia, jak by nie było, Rust, jak każdy inny język programowania jest językiem, w którym wyrażają się programiści, którzy mają różne opinie na temat języka. Pewne elementy się im podobają, na pewne narzekają.

Sporo już powiedzieliście o tym, co Wam się podoba w tym języku, jeśli jeszcze o czymś nie wspomnieliście, to też poproszę Was, żeby jeszcze dopowiedzieć ewentualnie, co zdecydowanie jest na plus tego języka, a może też, żeby powiedzieć, co Was razi, czego Wam brakuje może w tym języku w takiej codziennej pracy.

P.D.: Mnie najbardziej razi składnia oraz learning curve, ponieważ wejście w ten język nie jest takie proste. To nie jest tak, że posadzisz pierwszą osobę z brzegu, która nigdy nie miała nic wspólnego z programowaniem, i powiesz „programuj w Rust”. Ja jestem w stanie to zrobić przykładowo z Pythonem, ponieważ to jest język prosty. Jestem w stanie zrobić to z Java Scriptem przy odpowiednim przygotowaniu, nie jestem w stanie zrobić z Rustem. Hello Word jest proste. Po Hello Word zaczynają się schody. I mimo wszystko, nawet jeżeli jesteś doświadczonym programistą, przynajmniej tak mi się wydaje, może po prostu ja nie jestem wystarczająco doświadczony, ale chwilę czasu musisz spędzić nad poznaniem języka, a nie po prostu rzucić się na głęboką wodę i stwierdzić: projekt w jedno popołudnie to jest to, co zrobię.

Jest jeszcze kwestia bibliotek, jak w każdym języku. To jest tak, że aktualnie w Rust są biblioteki tak naprawdę „do wszystkiego”, ale po pierwsze, rzeczy, które są rzadziej wykonywane, bardzo specyficzne, są oczywiście w o wiele mniejszej części reprezentowane w tym ekosystemie, i oczywiście, jest taki tool, który się nazywa bindgen — on pozwala „tłumaczyć” pliki nagłówkowe z bibliotek C do Rusta tak, żeby stworzyć crate’y, które korzystają z bibliotek z C. I on działa fajnie dla C. Przy C++ już zaczyna się problem. Więc jeżeli mamy bibliotekę w C++, czasami trzeba więcej czasu na zintegrowanie jej z takim projektem, a napisanie jej od nowa w Rust czasami może być po prostu niemożliwe.

M.K.: To ja może bardziej z pozytywami tutaj wejdę, bo oczywiście, niestety learning curve jest, jaki jest, ale jakby dzięki temu, że ten kompilar, powiedzmy, sprawdza więcej rzeczy niż przeciętny język, to co prawda, tak jak Paweł mówił, nie można oczekiwać, że interna, który nie zna Rusta, rzuci się do projektu i żeby napisał jakiś ficzer w Rust, ale z drugiej strony, jeśli taki intern w końcu napisze ten ficzer, wystawi full requesta, to ja się nie będę bał, że on zepsuje produkcję. Bo jak by miał zepsuć, to kompilator by go wyłapał bądź, powiedzmy, jakieś bardziej high-levelowe rzeczy by w review wylazły.

Natomiast jeśli chodzi o takiego np. C++, albo też Golang, który też niby jest językiem, który więcej gwarantuje, ale wydaje mi się, że te języki mają tak dużo tzw. footgun’ów, że poziom wiedzy, który jest wystarczający do tego, żeby napisać coś działającego, nie jest tym samym poziomem, co poziom potrzebny do kontrybuowania do jakiegoś większego projektu, który ma się nie wywalać na produkcji. I też dodam tutaj, że ja już tak naprawdę nie pamiętam, jak to było, kiedy się uczyłem Rusta, bo to było jeszcze przed wydaniem wersji 1.0, ale w tym momencie, jak już piszę w Rust, to ja czuję taką jakby świeżość, że nie muszę z tyłu głowy trzymać jakichś takich drobnostek, typu czy to może być nilem, czy to nie może być nilem, a co jeśli ktoś mój obiekt zacznie wołać z wielu wątków, czy powinienem na coś zrobić asserta, czy nie powinienem. I wszystkie takie rzeczy, które w innych językach są jakby tylko i wyłącznie w dokumentacji, w Rust ja w ogóle nie muszę o tym myśleć. Mogę się skupić na logice.

👉 Czytaj dalej na: https://porozmawiajmyoit.pl/poit-156-rust/

--

--

Dev and life blog. Thoughts about programming, design patterns, Ruby and life.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Krzysztof Kempiński

Krzysztof Kempiński

IT expert. Ruby on Rails/iOS/Elixir programmer. Blogger. Podcaster.