Rust wybór IDE między Intellij lub PyCharm

Rust wybór IDE między Intellij lub PyCharm

Wątek przeniesiony 2021-08-05 08:08 z Inne języki programowania przez Adam Boduch.

SA
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:10
0

W czym na co dzień programujecie pod Rust? Zakochałem się w tym języku programowania, jak dla mnie i wielu innych osób jest to obecnie najlepiej zaprojektowany język programowania.

lion137
A co to za różnica, przecież obydwa są od JetBrains.
SA
Chyba tylko w lekkości, Intellij ma więcej dodatków których nie da się odinstalować.
Wibowit
Zarówno IntelliJ jak i PyCharm bazują na IntelliJ Platform, tzn to jest to samo IDE tylko inaczej skonfigurowane i z innym zestawem domyślnie zainstalowanych wtyczek.
hauleth
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:3 dni
1

Lubię Rusta, ale nie nazwałbym go "najlepiej zaprojektowanym językiem programowania". Bardzo dużo można by w nim poprawić. Co do narzędzi to ja piszę w Vimie.


Zobacz pozostałe 4 komentarze
SA
Ja właśnie nie lubię składni Javy, C# i są podobni do mnie.
hauleth
Rust ma problemy, np. ja osobiście uważam, że operator ? jest wygodny, ale w zamian za wygodę poświęcono czytelność. <> do szablonów też nie jest najlepszym wyborem, i Scalowe [] IMHO jest lepsze. @sanny uwierz mi, siedzę w Ruscie zapewne zdecydowanie dłużej niż Ty i "stara gwardia" by się z Tobą zapewne nie zgodziła. Prawdą jest, że Rust ma fajne rzeczy i ciekawe rozwiązania, ale jest trochę rzeczy, które wg mnie mogłyby zostać rozwiązane zdecydowanie lepiej.
SA
Pamiętaj, że języki programowania dzielą się na imperatywne(proceduralne i obiektowe) i deklaratywne(funkcyjne i logiczne) do tego dochodzi jeszcze inna składnia danego języka. Jeden lubi rybki, a drugi akwarium. Fakt, iż obecnie Rust nie jest jeszcze bardzo popularny, ale za 20 lat kto wie. Być może Google i Microsoft rozwiną nowe systemy właśnie w tym języku programowania.
hauleth
@sanny: nawet nie wiesz o czym mówisz, bo już rozwijają. Współpracowałem też przy Redox OS, więc trochę na ten temat wiem.
SA
Chyba każdy słyszał o FuchsiaOS, ale z tego co wiem Microsoft nic jeszcze nie powiedział na temat nowego systemu. A co do RedoxOS to system zabawka, wielu ludzi narzeka, że nie jest tworzony na poważnie i jest źle zaprojektowany.
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
3

Ja wykorzystuję CLion i nie narzekam - na duży plus jest zintegrowany debugger (gdb-multiarch).

jak dla mnie i wielu innych osób jest to obecnie najlepiej zaprojektowany język programowania.

Ostrożnie z tym r/rustjerk ;-) najlepiej zaprojektowany dla każdego znaczy coś innego - spróbuj przykładowo napisać bardziej skomplikowaną apkę Qt w Ruście.

Do tego jest cała masa tematów na reddit w których Rust też wygrywa

Do tego jest również cała masa tematów na Reddicie, w których Rust przegrywa - przykładem jest programowanie asynchroniczne (przynajmniej jeszcze przez najbliższe miesiące).


edytowany 3x, ostatnio: Patryk27
SA
Ale QT nie zostało stworzone dla Rusta, to tak jak byś napisał spróbuj napisać apkę GTK3 w Javie. Jednak coś się ruszyło pod tym względem, możesz już tworzyć aplikacje webowe i desktopowe. https://rocket.rs/ https://azul.rs/
Patryk27
Btw, Azul jest już martwy niestety - autor się poddał :-P
SA
I już naprawdę nie ma innego zamiennika GUI do Rusta?
Patryk27
Takiego, który byłby aktualnie polecany i nadawałby się na produkcję - nie; wszystko póki co w powijakach. Klasycznie: https://areweguiyet.com/
SA
Na pewno jest więcej GUI tylko nie znamy wszystkich nowych projektów.
hauleth
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:3 dni
5

Dziedziny gdzie Rust ma sens:

  • FFI
  • Crypto
  • IoT/Embedded (w przyszłości, bo na razie wsparcie architektur jest nie za bogate)
  • Przetwarzanie wielowątkowe
  • "Tight loops"
  • OS-dev
  • Niskopoziomowe network-stuff
  • Game Dev

Dziedziny gdzie Rust może mieć jakieś szanse, ale są lepsze alternatywy:

  • CLI - Go/Python/JS/Ruby/Bash jednak mają tutaj przewagę w zdecydowanie łatwiejszym pakowaniu na różne platformy (cross-compiling w Ruscie jeszcze nie jest idealny)
  • GUI - na razie Rust nie ma żadnej biblioteki z prawdziwego zdarzenia do GUI, ale kto wie jak będzie w przyszłości, jak na razie to Python/C++/C#/Java

Dziedziny gdzie Rust IMHO nie ma sensu, chyba, że jesteśmy ograniczeni jakimiś zasobami (jak np. IoT):

  • Backend - zwyczajnie IMHO nie ma sensu wydatek czasowy, skoro to samo można uzyskać Erlangiem/Elixirem zdecydowanie łatwiej i nie tracić tak dużo na wydajności, a jak coś to zawsze mamy Rustler (patrz FFI wyżej) i można "tight loop" (patrz wyżej) napisać w Ruscie.
  • Obliczenia naukowe - tutaj Python/Julia/R będą jednak wiodły prym, Rust może jako FFI (patrz wyżej), ale większość "zasadniczej pracy" będzie we wcześniej wymienionych językach.
  • Przetwarzanie rozproszone (aka wiele maszyn) - tutaj dalej Java/Scala, Erlang/Elixir, Pony i im podobne będą miały zdecydowanie więcej zalet.

Zobacz pozostałe 2 komentarze
SA
Nie zauważyłem, żeby Rust był przesadnie trudny, język jak język. Raczej C++ jest gorszy pod tym względem.
hauleth
Nie jest trudny, jest inny, więc wymaga przyswojenia dużej ilości konceptów na raz w porównaniu do Pythona, a to może być przytłaczające.
Cr0w
@hauleth co przejścia python -> rust twórca Flaska tak zrobił. Teraz chyba w obu.
hauleth
@Cr0w: nie nazwałbym go "początkującym". Jak ktoś już pisze dużo, to nie jest dla niego problem by przejść z jednego do drugiego, dla nowych osób w programowaniu może to być jednak trochę problemem.
siloam
Znaczniej łatwiej z Pythona przejść na https://nim-lang.org/ Tym bardziej, że już wyszedł RC2 i niedługo wyjdzie 1.0.
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
1
hauleth napisał(a):

Dziedziny gdzie Rust ma sens:

  • Przetwarzanie wielowątkowe

Moim zdaniem nie. Tracing GC zdecydowanie ułatwia pisanie wydajnego kodu wielowątkowego. Przeciętny programista prędzej napisze wielowątkowe przetwarzanie w języku z tracing GC jak Java, C# czy Go gdzie można sobie przesyłać jakiekolwiek referencje między wątkami ot tak bez martwienia się o dealokację niż w języku typu C, C++ czy Rust, gdzie zarządzanie zasobami, referencjami atomowymi, etc zjada czas programisty i/ lub procesora. Języków skryptowych nie wziąłem pod uwagę, gdyż są z reguły jednowątkowe (np JavaScript ze swoim event loopem czy Python z GILem) - przynajmniej te które kojarzę.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 4x, ostatnio: Wibowit
Cr0w
w pythonie jest jakis ruch z obejsciem GIL'a, wiec moze niedlugo... ale skladnia okropna :(
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Przeciętny programista prędzej napisze wielowątkowe przetwarzanie (...)

Pytanie tylko jak długo taki program podziała i czy będzie zwracał prawidłowe wyniki :-)


Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
0

W sensie sugerujesz, że poleganie na GC sprawi, że program będzie miał więcej błędów niż przy ręcznym zarządzaniu pamięcią? Jest raczej odwrotnie.

Atomowe referencje (pomijając już to, że są kosztowne obliczeniowo) też wymagają dyscypliny, bo nie dealokują automatycznie cyklów. Musisz sam zadbać o ich dealokowanie, a jak nie to zostaniesz z wyciekiem pamięci.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

sensie sugerujesz, że poleganie na GC sprawi, że program będzie miał więcej błędów niż przy ręcznym zarządzaniu pamięcią?

Wielowątkowy - jak najbardziej.
Zwłaszcza biorąc pod uwagę, że Rust zwyczajnie nie pozwala np. na. niesynchronizowany dostęp do pamięci (w porównaniu do Javy, C# oraz Go).

Atomowe referencje (...) nie dealokują automatycznie cyklów

Są biblioteki do Rusta, które obchodzą ten problem, choć - jak przypuszczam - pewnym kosztem obliczeniowym.


edytowany 7x, ostatnio: Patryk27
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
0

Niby Rust na wiele rzeczy nie pozwala, ale od czego jest unsafe? Mnóstwo kodu jest usiane słówkiem unsafe. Np:

Kopiuj
$ git clone https://github.com/servo/webrender.git
Cloning into 'webrender'...
$ cd webrender/
$ find . -name *.rs | wc -l
121
$ grep --include=\*.rs -rnw '.' -e 'unsafe' | wc -l
244

Średnio ponad dwa słówka unsafe na plik. Tutaj niby unsafe jest wykorzystywane do różnych rzeczy, ale już się spotkałem z podejściem typu - kod w Ruście działa za wolno - użyję unsafe i arytmetyki wskaźników. Obstawiam, że w momentach gdy zabawa w referencje i borrow checking stawałaby się upierdliwa to unsafe ścieliłoby się gęsto.

W komercyjnym kodzie Scalowym w firmie mamy mnóstwo aktorów, future'ów, asynchronicznych strumieni, etc a problemów z data races prawie żadnych (oprócz pewnych kulawych testów opartych o globalny mutowalny stan, ale to inna historia, bo ktoś wymyślił genialny inaczej framework do testów, a synchronizacja nic by tu nie pomogła). To dlatego, że korzystamy w dużej części z niemutowalnych struktur danych do przesyłania danych między wątkami. Wygodnie i bezpiecznie. Nie trzeba ekstra bibliotek żeby coś obchodzić. Nie trzeba się zastanawiać, czy przesyłanie referencji między wątkami jest kosztowne (bo nie jest).


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 8x, ostatnio: Wibowit
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Niby Rust na wiele rzeczy nie pozwala, ale od czego jest unsafe?

unsafe służy do budowania abstrakcji, których nie da się wyrazić w systemie typów Rusta (https://matklad.github.io/2019/07/25/unsafe-as-a-type-system.html) oraz do komunikacji z zewnętrznymi API (które z założenia mogą robić wszystko, stąd ich niebezpieczeństwo).

Mnóstwo kodu jest usiane słówkiem unsafe

Zależy jak na to spojrzysz: technicznie każdy program napisany w C#, Go czy Javie składa się wyłącznie z bloków unsafe - przy czymś takim średnio dwa na plik to miód na oczy :-)

Obstawiam, że w momentach gdy zabawa w referencje i borrow checking stawałaby się upierdliwa to unsafe ścieliłoby się gęsto.

Ano zdarza się (np. w projekcie actix będącym implementacją aktorów oraz serwera HTTP w Ruście) - przy czym nie jest to w żaden sposób wina języka.

Język oraz społeczność starają się wręcz wyjść na przeciw wykorzystywaniu unsafe, stąd m.in. powstała dyrektywa #![forbid(unsafe_code)] oraz projekty typu cargo-geiger.

korzystamy w dużej części z niemutowalnych struktur danych do przesyłania danych między wątkami (...) Nie trzeba się zastanawiać, czy przesyłanie referencji między wątkami jest kosztowne (bo nie jest).

Jeśli masz niemutowalną strukturę, w Ruście owijasz ją w Arc i bez problemu wysyłasz do wszystkich wątków, jakie potrzebujesz - w cenie wtedy masz wtedy zarówno zliczanie referencji, jak i brak problemów z borrow checkerem.

Fakt, wysłanie takiej referencji nie jest darmowe (trzeba wszak odpalić calutkie fetch_add()! /s), lecz w dalszym ciągu jest to lżejsze od garbage collectora z C# czy Javy.

Edit: z ciekawości sprawdziłem te przypadki unsafe w WebRender i zdaje się, że ok. połowa z nich związana jest z odwoływaniem się do zewnętrznego API (OpenGL oraz FreeType). FFI całkiem słusznie jest unsafe-by-default, można się rozejść :-P


edytowany 9x, ostatnio: Patryk27
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
2

Zależy jak na to spojrzysz: technicznie każdy program napisany w C#, Go czy Javie składa się wyłącznie z bloków unsafe - przy czymś takim średnio dwa na plik to miód na oczy :-)

Natomiast kod typu x = x + 1 jest impure i unsafe w Haskellu, więc z punktu widzenia Haskella cały kod w Ruście jest unsafe. Idąc dalej - kod w Haskellu jest unsafe dla programistów Coq czy Idrisa, bo nie ma dowodów poprawności.

Trzeba się zastanowić co te obostrzenia w Ruście dają. Memory corruption w czystej Javie (bez sun.misc.Unsafe) nie dostaniesz, dereferencja nulla zawsze skutkuje NPE, a nie jest UB jak w C++ czy Ruście z unsafe. To co Rust wymusza to widoczność zmian w zmiennych współdzielonych między wątkami. W Javie można zapomnieć volatile i wtedy nie wiadomo kiedy zmiany się rozpropagują. Rustowy borrow checker nie zapobiega np niepoprawnemu kodowi typu:

Kopiuj
while (arc.get() != 5) {}
// tutaj osobny wątek może ustawić arc na wartość != 5
arc.set(8);

podczas, gdy poprawny kod wygląda mniej więcej tak:

Kopiuj
while (!arc.compareAndSet(5, 8)) {} // zmiana jeśli zajdzie to zawsze z 5 na 8

Ogólnie to Rustowe safety jest niewiele wyższe niż Javowe, ale borrow checker w Ruście jest upierdliwy.

Ano zdarza się (np. w projekcie actix będącym implementacją aktorów oraz serwera HTTP w Ruście) - przy czym nie jest to w żaden sposób wina języka.

Jak nie jest? Borrow checker jest głupi. Przykład - Vec::split_off

Kopiuj
    #[inline]
    #[stable(feature = "split_off", since = "1.4.0")]
    pub fn split_off(&mut self, at: usize) -> Self {
        assert!(at <= self.len(), "`at` out of bounds");

        let other_len = self.len - at;
        let mut other = Vec::with_capacity(other_len);

        // Unsafely `set_len` and copy items to `other`.
        unsafe {
            self.set_len(at);
            other.set_len(other_len);

            ptr::copy_nonoverlapping(self.as_ptr().add(at),
                                     other.as_mut_ptr(),
                                     other.len());
        }
        other
    }

unsafe trzeba tutaj wrzucić gdyż borrow checker nie jest w stanie zorientować się, że podzielenie mutowalnego wektora na dwa jest bezpieczne.

W Javce wszystkie kolekcje są w 100% oparte na bezpiecznym kodzie (no chyba, że jest tam jakiś natywny w ramach optymalizacji, ale jeśli już to bardzo mało).

Fakt, wysłanie takiej referencji nie jest darmowe (trzeba wszak odpalić calutkie fetch_add()! /s), lecz w dalszym ciągu jest to lżejsze od garbage collectora z C# czy Javy.

malloc + free jest bardziej kosztowne obliczeniowo niż tracing GC, ale za to mniej kosztowne pamięciowo. Dowód jest tutaj:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/binarytrees.html
Najszybsze rozwiązanie w C#, F#, Erlangu i Javie korzystają ze standardowego tracing GC (zwykły new oraz automatyczne odśmiecanie). Rozwiązania oparte o malloc/ free bądź new/ delete są wolniejsze od tych z tracing GC. Dopiero użycie pul (szukaj nazw pool lub arena w importowanych modułach) w C++, Ruście, C, etc sprawia, że takie coś jest szybsze niż tracing GC, ale pule to rozwiązanie o bardzo wąskim spektrum zastosowań.

Jeśli masz niemutowalną strukturę, w Ruście owijasz ją w Arc i bez problemu wysyłasz do wszystkich wątków, jakie potrzebujesz - w cenie wtedy masz wtedy zarówno zliczanie referencji, jak i brak problemów z borrow checkerem.

Jak dostanę Arca to już jestem z nim uwięziony albo muszę skopiować obiekt na który wskazuje. Co jeśli chcę by 5 wątków miało referencję do tego samego obiektu? Wszystkie 5 muszą mieć Arce. Słabe rozwiązanie.

W programowaniu funkcyjnym używa się standardowo niemutowalnych kolekcji z structural sharing. Weźmy dla przykładu drzewa: https://en.wikipedia.org/wiki/Persistent_data_structure#Trees Stworzenie nowego drzewa na podstawie poprzedniego z jedną nową zmianą wymaga tylko O(lg n) dodatkowej pamięci, a nie O(n) jak w przypadku kopiowania całego drzewa. Dlaczego tylko O(lg n)? Dlatego, że nowe drzewo zawiera referencje do starych poddrzew. Wyobraź sobie teraz że wyprodukowałem trzy drzewa:

Kopiuj
val drzewo1 = (0 to 1000 * 1000).map(i => i -> i * i) // drzewo z milionem elementów
val drzewo2 = drzewo1 + (8 -> 3) // drzewo z milionem elementów
val drzewo3 = drzewo2 + (-1 -> 8) // drzewo z milonem i jednym elementem

Sumarycznie te 3 drzewa zajmują praktycznie tylko tyle co samo pierwsze dzięki structural sharing. Co jeśli chcę teraz przesłać te drzewa do 3 różnych wątków w np Scali? Po prostu je przesyłam bez żadnego opakowywania. Co musiałbym zrobić w Ruście? Skopiować dane tak by drzewa były niezależne? To marnotrawstwo pamięci. Użyć Arc do wszystkich referencji wewnątrz drzewa? To nie tylko narzut pamięciowy, ale przede wszystkim obliczeniowy. Zamiast miliona zwykłych referencji byłoby milion Arców.

Wszystkie języki funkcyjne są oparte o tracing GC głównie dlatego, że umożliwia to tanie współdzielenie skomplikowanych struktur danych między równocześnie wykonującymi się wątkami. No chyba, że jednak pokażesz mi że można mieć wydajne wielowątkowe structural sharing w Ruście bez bloków unsafe i jakiegoś ręcznego zarządzania pamięcią.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Memory corruption w czystej Javie (bez sun.misc.Unsafe) nie dostaniesz

Możesz mieć np. dwa wątki próbujące uzyskać niesynchronizowany dostęp do zasobu (np. próbujące zmodyfikować to samo pole) - jeśli podpada to pod definicję memory corruption.

Porównujmy jednak jeżyny do jeżyn - Rust celuje w nisze C++-o-podobne, gdzie 70% wszystkich bugów związanych jest z dostępem do pamięci; większości z tych błędów (jeśli nie wszystkich) nie da się odtworzyć w tzw. safe Rust.

Rustowy borrow checker nie zapobiega np niepoprawnemu kodowi typu:

Nie zapobiega i nie może zapobiegać - mimo XXI wieku kompilatorom ciężko idzie czytanie w myślach, a przytoczony przez Ciebie kod równie dobrze może mieć jak najbardziej oczekiwane zachowanie.

Nie zmienia to faktu, że borrow checker zapobiega pewnej znaczącej klasie błędów (patrz wyżej: 70%), czyli jest good enough.

W Javce wszystkie kolekcje są w 100% oparte na bezpiecznym kodzie

Przytoczony przez Ciebie kod jest całkowicie bezpieczny - ułomność borrow checkera tego nie zmienia.

Należy mieć na uwadze, że celem Rusta nie jest bycie 100%-unsafe-free, a kompromisy - w porównaniu do C++, gdzie wszystko jest legalne, w Ruście podejrzany kod owijasz w blok unsafe i wtedy wiesz, którym fragmentom należy zwrócić szczególną uwagę w trakcie PR oraz ich wykorzystywania, jakie inwarianty muszą zostać spełnione itd.

Co jeśli chcę by 5 wątków miało referencję do tego samego obiektu? Wszystkie 5 muszą mieć Arce. Słabe rozwiązanie.

Dla mnie jest to dobry kompromis - spróbuj zrobić podobną akcję ze structural sharing w C++ :-)

chyba, że jednak pokażesz mi że można mieć wydajne wielowątkowe structural sharing w Ruście bez bloków unsafe i jakiegoś ręcznego zarządzania pamięcią.

Istnieje biblioteka im-rs, która zawiera raptem kilka bloków unsafe - dla porównania do C++ znalazłem immer, które zawiera potencjalnie unsafe w każdej linijce kodu.

Ogólnie rzecz biorąc porównywanie Rust ze Scalą uważam za tani chwyt marketingowy - gdyby Rust działał na maszynie wirtualnej, cały ten "niebezpieczny" kod można by przenieść do środka VMki i chwalić się patrzcie, nasz Rust 2.0 nie ma ani jednego unsafe!. Nie ma, bo cały jest wewnątrz VMki - dokładnie tak, jak ma to miejsce z Javą.


edytowany 2x, ostatnio: Patryk27
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
1

Możesz mieć np. dwa wątki próbujące uzyskać niesynchronizowany dostęp do zasobu (np. próbujące zmodyfikować to samo pole) - jeśli podpada to pod definicję memory corruption.

Wydaje mi się, że nie podpada.

Porównujmy jednak jeżyny do jeżyn - Rust celuje w nisze C++-o-podobne, gdzie 70% wszystkich bugów związanych jest z dostępem do pamięci; większości z tych błędów (jeśli nie wszystkich) nie da się odtworzyć w tzw. safe Rust.
Należy mieć na uwadze, że celem Rusta nie jest bycie 100%-unsafe-free, a kompromisy - w porównaniu do C++, gdzie wszystko jest legalne, w Ruście podejrzany kod owijasz w blok unsafe i wtedy wiesz, którym fragmentom należy zwrócić szczególną uwagę w trakcie PR oraz ich wykorzystywania, jakie inwarianty muszą zostać spełnione itd.

No w porównaniu do C/ C++ Rust wygląda OK, ale dalej cudów nie ma, bo języków programowania jest dużo więcej.

Istnieje biblioteka im-rs, która zawiera raptem kilka bloków unsafe - dla porównania do C++ znalazłem immer, które zawiera potencjalnie unsafe w każdej linijce kodu.

No i jak przeczuwałem są osobne wersje oparte o Rc i Arc. Ciekawe byłyby wyniki benchmarków przy przetwarzaniu wielowątkowym.

Ogólnie rzecz biorąc porównywanie Rust ze Scalą uważam za tani chwyt marketingowy - gdyby Rust działał na maszynie wirtualnej, cały ten "niebezpieczny" kod można by przenieść do środka VMki i chwalić się patrzcie, nasz Rust 2.0 nie ma ani jednego unsafe!. Nie ma, bo cały jest wewnątrz VMki - dokładnie tak, jak ma to miejsce z Javą.

No niespecjalnie. Taki Vec::split_off to typowa funkcja biblioteczna, a nie jakaś niskopoziomowa operacja, która nadaje się do wbudowania w VMkę. Zauważ, że całe kolekcje w Javie są napisane w Javie, a nie np w C jak w CPythonie. W Javie unsafe kod jest w zasadzie potrzebny tylko do FFI albo optymalizacji wydajnościowej. Memory safety w Javie jest osiągnięte bez upierdliwego borrow checkera, więc skoro borrow checker w Javie nie istnieje to nie trzeba używać unsafe by go obejść. Oczywiście da się kombinować w Ruście jak koń pod górę by unikać unsafe, tylko czy efekt jest warty zachodu? Może w pewnych przypadkach warto zmienić język?


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

No i jak przeczuwałem są osobne wersje oparte o Rc i Arc.

I całkiem słusznie, ponieważ są to dwa odmienne typy o różnych zastosowaniach.

Zauważ, że całe kolekcje w Javie są napisane w Javie

Vec::split_off() można by bez problemu napisać w Safe Rust z wykorzystaniem najklasyczniejszej pętli - kod wygląda jak wygląda w ramach optymalizacji; copy_nonoverlapping jest unsafe, ponieważ stanowi ono odpowiednik C-owego memcpy, gdzie pewne inwarianty należy zapewnić z zewnątrz (m.in. bloki pamięci muszą być odpowiednio duże oraz nie mogą na siebie nachodzić - kompilator potrafiący rozumieć tak niskopoziomowe abstrakcje byłby krok od rozwiązania problemu stopu).

W Javie unsafe kod jest w zasadzie potrzebny tylko do FFI albo optymalizacji wydajnościowej

Ponieważ reszta niebezpiecznego kodu znajduje się w VMce, która gwarantuje zachowanie pewnych inwariantów w runtime'ie - stąd nie ma w Javie potrzeby wykorzystywania unsafe poza FFI.

skoro borrow checker w Javie nie istnieje to nie trzeba używać unsafe by go obejść

Raz jeszcze: jeżyny z jeżynami; Rust nie powstał jako alternatywa dla Javy czy innych języków z zarządzaną pamięcią, których charakterystyka i wykorzystanie znacznie odbiegają od takiego C++.

Patrząc z drugiej strony mógłbym wysunąć argument, że Java jest gupia, bo nie nadaje się do oprogramowania ATtiny.

A, no i najważniejsze: unsafe nie powstało wyłącznie jako narzędzie do "unikania" borrow checkera - dowolną własną funkcję mogę również oznaczyć jako unsafe i dorzucić komentarz z informacją co np. musi zajść, aby funkcja działała prawidłowo, a na co należy uważać.

Oczywiście da się kombinować w Ruście jak koń pod górę by unikać unsafe, tylko czy efekt jest warty zachodu?

Trochę aplikacji w Ruście już napisałem i nie zdarzyło się, abym - rozumiejąc zasadę działania borrow checkera - musiał kombinować jak koń pod górę; to raczej bolączka początkujących programistów.

Może w pewnych przypadkach warto zmienić język?

Język to tylko narzędzie - ja przykładowo profesjonalnie piszę w PHPie, czyli jeszcze inna bajka ;-)

Rust nie jest żadnym świętym Graalem, podobnie jak nie jest nim Java czy Go - każde ma / stara się znaleźć swoją niszę i uważam, że przede wszystkim należy dostosowywać narzędzia do zadań. Nie od tego jednak wywiązała się dyskusja :-)


edytowany 3x, ostatnio: Patryk27
Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
1

Nie od tego jednak wywiązała się dyskusja :-)

Wywiązała się od wielowątkowości w Ruście. No cóż, pożyjemy i zobaczymy jak ta wielowątkowość w Ruście będzie się sprawować. Błędów związanych z brakiem volatile'a (czyli widocznością zmian między wątkami) mam śladowe ilości, więc ich redukcja nie zrekompensowałaby mi utraty wygody znanej chociażby z Javy.

Rust (a konkretnie actix) ostatnio zaszalał konkretnie w benchmarkach TechEmpower: https://www.techempower.com/blog/2019/07/09/framework-benchmarks-round-18/
Przepis na suckes to jednak unikanie komunikacji między wątkami (bye bye Arc) oraz zastąpienie zwykłej alokacji przez pule obiektów: https://github.com/TechEmpower/FrameworkBenchmarks/issues/4834#issuecomment-499429995


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 2x, ostatnio: Wibowit
SA
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:10
0

A ja nadal nie wiem które IDE lepiej podpowiada składnie Rust, PyCharm czy Intellij? Widziałem, że powstało kilka webowych frameworków do Rusta. Więc śmiało można w nim pisać szybki backend? Obecnie poszukuję najlepszych i najpopularniejszych bibliotek do pisania programów graficznych(GUI) i silników gier w tym języku. Oby jak najszybciej wybili się jacyś liderzy, konkretne frameworki.

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 5 godzin
2

A ja nadal nie wiem które IDE lepiej podpowiada składnie Rust, PyCharm czy Intellij?

Przecież to to samo IDE i ta sama wtyczka, więc co za różnica?


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
SA
No raczej nie jest to samo, skoro tu w intellij muszę pobrać około 600MB, a w przypadku PyCharm tylko 350MB. Jeżeli to samo, to ja wybieram to drugie.
Wibowit
No straszne. 300 MB to mi się w niecałą minutę ściąga jak leci z pełną prędkością. Różnica w funkcjonalności byłaby jakbyś wybrał CLiona - ten ma chyba dodatkowo debuggera dla Rusta i może też inne dodatki. CLion nie ma jednak wersji community.
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:4 dni
  • Lokalizacja:Stacktrace
  • Postów:6821
2

PyCham i IntelliJ to jest to samo IDE z różnym zestawem wtyczek. Dlatego IntelliJ jest „trochę” cięższe. Nie ma znaczenia, które wybierzesz, bo i tak musisz dociągnąć wtyczkę do Rusta. Kluczem do odpowiedzi na twoje pytanie jest to, jakich innych języków używasz? Wiedząc, co jeszcze będziesz potrzebować można podjąć decyzję.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
stivens
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 godziny
0

Swoja droga jezeli mam pelna wersje IntelliJ to samymi wtyczkami moge go zrownac mozliwosciami z np PyCharmem albo CLionem? Czy to bedzie tylko imitacja?


λλλ
edytowany 1x, ostatnio: stivens
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:4 dni
  • Lokalizacja:Stacktrace
  • Postów:6821
3

Tak, możesz spokojnie go zrównać. Rozróżnienie na wiele produktów jest trochę zaszłością, ale przede wszystkim wynika z chęci „odchudzenia” IDE i przygotowania wersji pod konkretne grupy użytkowników. Obecnie używam IntelliJ z pluginami webowymi jak w WebStormie plus python z PyChama i nie ma najmniejszego problemu. Co prawda taki kombajn czasami potrafi zjeść ramu, ale to akurat nie jest problem.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
stivens
Co prawda taki kombajn czasami potrafi zjeść ramu Fajnie by bylo jakby wtyczki sie aktywowaly na podstawie projektu/glownego jezyka/
Koziołek
Jak masz w projekcie Javę na Springu, Pythona, Reacta, SASS, Dockera i dwie różne bazy danych, to może trochę wtyczek potrzebować.
lamerski
No to klikam na 20k...
FE
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 3 lata
1
Koziołek napisał(a):

Tak, możesz spokojnie go zrównać. Rozróżnienie na wiele produktów jest trochę zaszłością, ale przede wszystkim wynika z chęci „odchudzenia” IDE i przygotowania wersji pod konkretne grupy użytkowników. Obecnie używam IntelliJ z pluginami webowymi jak w WebStormie plus python z PyChama i nie ma najmniejszego problemu. Co prawda taki kombajn czasami potrafi zjeść ramu, ale to akurat nie jest problem.

To chyba nie jest do końca prawda, obecnie CLion nie jest osiągalny na IntelliJ.
Pytanie z wątku miałoby sens gdyby porównywać IntelliJ vs CLion a tak to nie ma znaczenia.


Koziołek
A tu mnie zaskoczyłeś. Co z CLion jest nie tak, że nie można go osiągnąć na IntelliJ?
Patryk27
CLion ma zaimplementowaną natywnie obsługę GDB, której - zdaje się - nie można przemycić we wtyczkach.
Koziołek
@Patryk27: w sensie w IntellliJ trzeba go dociągnąć. Przy czym doczytałem i wychodzi mi, że CLion jest w części zamkniętym softem, ale są pluginy od innych dostawców.
SA
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 5 lat
  • Postów:10
0

Testował ktoś ten edytor KDevelop pod Rust?
https://www.kdevelop.org/
https://github.com/KDE/kdev-rust

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)