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

Rust wybór IDE między Intellij lub PyCharm

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.

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.

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).

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.
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ę.

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 :-)

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.

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.

0

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

$ 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).

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

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:

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:

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

    #[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:

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ą.

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ą.

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?

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 :-)

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

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.

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?

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ę.

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?

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.

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.

0

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1