Świetna dyskusja dlaczego OOP ssie.

Świetna dyskusja dlaczego OOP ssie.
MS
  • Rejestracja:ponad 10 lat
  • Ostatnio:15 minut
  • Postów:312
1

@Troll anty OOP

Skoro bardziej wydajny program potrafił sobie bez nich poradzić, to znaczy że te operacje nie były konieczne. Im więcej operacji jest wykonywanych, tym bardziej złożony jest program i tym trudniejszy w utrzymaniu, tym więcej miejsc potencjalnego błędu

Wydaje mi się, że wychodzisz z błędnego założenia, że stopień skomplikowania programu musi przekładać się na stopień skomplikowania kodu. @katelx podawała przykład ze swojego doświadczenia. Może Ty podasz coś Z PRAKTYKI, o której tak ciągle wspominałeś?


TA
  • Rejestracja:około 7 lat
  • Ostatnio:dzień
  • Postów:266
3
mstl napisał(a):

Wydaje mi się, że wychodzisz z błędnego założenia, że stopień skomplikowania programu musi przekładać się na stopień skomplikowania kodu. @katelx podawała przykład ze swojego doświadczenia. Może Ty podasz coś Z PRAKTYKI, o której tak ciągle wspominałeś?

Forumowiczka katelx podawała przykład, który jest niesprawdzalny dla innych uczestników forum.
Sprawdzalnym przykładem na moją tezę jest chociażby wspomniany już wcześniej git. Innym sprawdzalnym przykładem jest nginx - serwer HTTP powstały w momencie silnego już hypu na OOP, a napisany w C. W serwerach HTTP dużą wagę przykłada się do ograniczania liczby błędów i gdyby OOP taką cechę oferowało, to na pewno jakiś program napisany obiektowo by się wybił zamiast niego.

MS
  • Rejestracja:ponad 10 lat
  • Ostatnio:15 minut
  • Postów:312
1

Sprawdzalnym przykładem na moją tezę jest chociażby wspomniany już wcześniej git. Innym sprawdzalnym przykładem jest nginx - serwer HTTP powstały w momencie silnego już hypu na OOP, a napisany w C

Nie jest to sprawdzalny przykład, bo nie ma żadnego porównania. Nie było "przepisywania" Gita na OOP, ani odwrotnie.
I nadal podtrzymuję, że:

wychodzisz z błędnego założenia, że stopień skomplikowania programu musi przekładać się na stopień skomplikowania kodu


edytowany 2x, ostatnio: mstl
PM
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:13
2
mstl napisał(a):

I nadal podtrzymuję, że:

wychodzisz z błędnego założenia, że stopień skomplikowania programu musi przekładać się na stopień skomplikowania kodu

Że tak zapytam, gdzie u niego widzisz takie twierdzenie? Wszak wiele już było omawianych przypadków pisania skomplikowanego kodu do tworzenia prostych programów, oraz tworzenia prostego kodu do tworzenia skomplikowanych programów. Oświecisz mnie?

MS
"Proponuję czytać następnym razem ze zrozumieniem. Polecam. Rozumienie czytanego tekstu się przydaje również programistom. Naprawdę." ;)
PM
Cieszę się, że odnalazłeś w tekście tą poradę. Teraz tylko pozostało Ci zastosować ją w praktyce. ;)
katelx
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Hong Kong
2

Forumowiczka katelx podawała przykład, który jest niesprawdzalny dla innych uczestników forum.

to ze wiekszosc softu gieldowego jest pisana w javie to nie jest wiedza tajemna, sporo firm otwiera tez swoje zrodla przynajmniej czesciowo.

W serwerach HTTP dużą wagę przykłada się do ograniczania liczby błędów i gdyby OOP taką cechę oferowało, to na pewno jakiś program napisany obiektowo by się wybił zamiast niego.

za to systemy przetwarzajace setki tysiecy zlecen gieldowych na sekunde moga sobie nagle przestac dzialac :) wez nie zartuj

algorithmic trading to jest glownie java a najbardziej podatne na bledy czesci takich systemow (czyli te podejmujace decyzje) sa wylacznie w oop + fp lub przepisywane na nie. mowie na podstawie kilkunastu takich systemow z ktorymi mialam do czynienia.
firmy takie jak goldman sachs, jp morgan, ubs, nomura, credit suisse, morgan stanley wszystkie uzywaja glownie oop wspomagajac sie fp przy budowie systemow operujacych w realtime setkami miliardow dolarow dziennie majac nad soba dosc wymagajacych klientow i dziesiatki audytow tylko czekajacych zeby dowalic kare za bledy.

a w takich serwerach http to przeciez bledow nie ma, gdzie tam :)

FE
głównie Java, a 2nd most used to C czy C++?
TA
  • Rejestracja:około 7 lat
  • Ostatnio:dzień
  • Postów:266
3
mstl napisał(a):

Sprawdzalnym przykładem na moją tezę jest chociażby wspomniany już wcześniej git. Innym sprawdzalnym przykładem jest nginx - serwer HTTP powstały w momencie silnego już hypu na OOP, a napisany w C

Nie jest to sprawdzalny przykład, bo nie ma żadnego porównania. Nie było "przepisywania" Gita na OOP, ani odwrotnie.

Na prawdę w to wierzysz, że nie było? Choćby już w tym wątku był podawany JGit. Nie znalazłem aktualnych porównań, a te wzmianki które znalazłem mówiły o dwukrotnie słabszej wydajności od oryginału, pomimo skrupulatnych optymalizacji wersji Javowej, a nie wiem o ile więcej RAM-u marnotrwawił.
Nie słyszymy o próbach przepisania gita na OOP, bo jak sobie wyobrażasz, że autor zrobi furorę takim np. ogłoszeniem:
"Zrobiłem fork git-a, używajcie, co prawda na pewno ma mnóstwo błędów wieku dziecięcego, ale jest rewelacyjny, bo udało mi się uzyskać tylko 5-krotnie gorszą wydajność od oryginału"?

Myślisz, że na prawdę nie było chętnych by sprawdzić się w OOP z problemem rozwiązywanym przez nginx?

I nadal podtrzymuję, że:

wychodzisz z błędnego założenia, że stopień skomplikowania programu musi przekładać się na stopień skomplikowania kodu

Nie wiem co dokładnie masz tu na myśli.

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:dzień
3

Programowanie obiektowe W PRAKTYCE prowadzi do tworzenia bardziej złożonych rozwiązań do problemów, które proceduralnie W PRAKTYCE rozwiązuje się prościej.

No to podaj złożone rozwiązania w OOP, których proceduralne odpowiedniki są prostsze i mają taką samą funkcjonalność.

Nginx nie zajmuje się generowaniem HTMLa, więc trzeba dołożyć do niego framework by mieć pełny zestaw. Microbenchmarki dla generowania prostych odpowiedzi HTTP są tutaj: https://www.techempower.com/benchmarks/#section=data-r15 Jakoś nie widzę, by serwery napisane w C rządziły w tym zestawieniu, oprócz serwera h2o

Porównywalną z h2o wydajność (w tym microbenchmarku) ma Javowy serwer undertow. Można sobie porównać kody źródłowe rozwiązań:
https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/C/h2o/src
https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Java/undertow/src/main/java/hello

Ten kod w C jakoś nie wygląda mi na prosty i przyjemny, a przecież chodzi tutaj zaledwie o generowanie prostych popierdółek. Stworzenie skomplikowanej webowej aplikacji biznesowej w czystym C byłoby drogą przez mękę.

Oprócz h2o w C napisany jest też onion, ale ten jednak zamula i przegrywa z serwerami napisanymi w Javie, C# czy nawet z Pythonem.

Na prawdę w to wierzysz, że nie było? Choćby już w tym wątku był podawany JGit. Nie znalazłem aktualnych porównań, a te wzmianki które znalazłem mówiły o dwukrotnie słabszej wydajności od oryginału, pomimo skrupulatnych optymalizacji wersji Javowej, a nie wiem o ile więcej RAM-u marnotrwawił.
Nie słyszymy o próbach przepisania gita na OOP, bo jak sobie wyobrażasz, że autor zrobi furorę takim np. ogłoszeniem:
"Zrobiłem fork git-a, używajcie, co prawda na pewno ma mnóstwo błędów wieku dziecięcego, ale jest rewelacyjny, bo udało mi się uzyskać tylko 5-krotnie gorszą wydajność od oryginału"?

A to w gicie nie ma skrupulatnych optymalizacji? Polecam sprawdzić ile poprawek optymalizacyjnych do gita wprowadził Microsoft, bo git zamulał na ich gigantycznych repozytoriach: https://blogs.msdn.microsoft.com/devops/2018/01/11/microsofts-performance-contributions-to-git-in-2017/ Wątpię, by MS portował swoje zmiany do JGita.

Mimo optymalizacji w oryginalnym gicie ten i tak dalej zamulał na repozytoriach MS, więc MS zrobił własną implementację gita w C# i C++, która już radzi sobie z ich repozytoriami: https://github.com/Microsoft/GVFS

A co do Linusa Torvalda to przypomnę kawałek swojego poprzedniego postu:

Linus Torvalds - skrytykował C++ i słusznie - C++ to bardzo kiepska implementacja OOPa, napisał też: you can write object-oriented code (useful for filesystems etc) in C, _without_ the crap that is C++


"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 6x, ostatnio: Wibowit
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
0
Troll anty OOP napisał(a):
vpiotr napisał(a):
Troll anty OOP napisał(a):

Swoją drogą, przyglądałem się dyskusjom krótko po tej wypowiedzi Linusa, bo wiadomo że była popularna. Było mnóstwo OOP-entuzjastów przypisujących mu brak umiejętności. Kompletny absurd.

Dlaczego absurd?

Bo jego doświadczenie jest powszechnie znane i wielokrotnie udowodnił, że jego teorie mają bardzo dobre przełożenie na praktykę.

Które teorie?

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:dzień
0
Troll anty OOP napisał(a):

Bo jego doświadczenie jest powszechnie znane i wielokrotnie udowodnił, że jego teorie mają bardzo dobre przełożenie na praktykę.

O'RLY? No to ja podam przykład: Is The Linux Kernel Scheduler Worse Than People Realize?
Analiza schedulera: The Linux Scheduler: a Decade of Wasted Cores
Oraz cytat Linusa Torvaldsa z 2001 roku pokazujący w jak dużym był błędzie:

And you have to realize that there are not very many things that have aged as well as the scheduler. Which is just another proof that scheduling is easy.

Podobnych mocno nieoptymalnych uproszczeń w Linuksie jest więcej. ZTCP to stos TCP/IP jest (był?) zaimplementowany bardzo naiwnie (ale z wyżyłowaną stałą, co trolle C bardzo lubią) co powodowało duże obciążenie CPU podczas transferów danych w pewnych warunkach.

A i jeszcze odnośnie tego, że Java jest 2x wolniejsza od C, bo jest obiektowa to proponuję porównać wydajność języków strukturalnych nieobiektowych. Czyli np:


"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 5x, ostatnio: Wibowit
PM
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:13
2
Wibowit napisał(a):
Troll anty OOP napisał(a):

Bo jego doświadczenie jest powszechnie znane i wielokrotnie udowodnił, że jego teorie mają bardzo dobre przełożenie na praktykę.

O'RLY? No to ja podam przykład: Is The Linux Kernel Scheduler Worse Than People Realize?
Analiza schedulera: The Linux Scheduler: a Decade of Wasted Cores
Oraz cytat Linusa Torvaldsa z 2001 roku pokazujący w jak dużym był błędzie:

And you have to realize that there are not very many things that have aged as well as the scheduler. Which is just another proof that scheduling is easy.

Podobnych mocno nieoptymalnych uproszczeń w Linuksie jest więcej. ZTCP to stos TCP/IP jest (był?) zaimplementowany bardzo naiwnie (ale z wyżyłowaną stałą, co trolle C bardzo lubią) co powodowało duże obciążenie CPU podczas transferów danych w pewnych warunkach.

Zzzzzz.... Zzzzz.....
No i co to wnosi do tematu?

PM
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:13
2

Perełki wypowiedzi użytkownika @Wibowit z komentarzy pod postem https://4programmers.net/Forum/1457019

zaglądałeś w kod gita, że twierdzisz iz nie jest pisany obiektowo? To że pisany jest w jakims języku o niczym nie przesądza.... - kaczus dziś, 16:16

Ba, nie tylko zaglądałem, ale i debugowałem. - ProceduralMasterRace dziś, 16:44

po co debugować kod w C? przecież wszyscy programiści C mają dyscyplinę. - Wibowit dziś, 16:46

A co ma dyscyplina do niepopełniania błędów? Nigdy nie twierdziłem, że nie popełnia się błędów w którymś z paradygmatów. Wręcz wskazywałem jak paradygmaty sprzyjają im. Czytałeś moje posty z zamkniętymi oczami? - ProceduralMasterRace dziś, 17:13

Jak nie ogarniasz paradygmatu X to wiadomo, że będziesz popełniał w nim mnóstwo błędów. - Wibowit 11 minut temu

Ameryki nie odkryłeś. Proponuję czytać następnym razem ze zrozumieniem. Polecam. Rozumienie czytanego tekstu się przydaje również programistom. Naprawdę. - ProceduralMasterRace 9 minut temu

Nie będę na wiarę przyjmował twoich bredni. Nie masz argumentów ani autorytetu. - Wibowit 7 minut temu

A ty ani grama talentu w erystyce. Rozumienie czytanego tekstu też u ciebie szwankuje. - ProceduralMasterRace 4 minuty temu

Czytam twoje brednie i już zrozumiałem, że jesteś debilem. - Wibowit 1 minuta temu

Tyle na temat trollingu w tym wątku. Niewątpliwie @Wibowit dał jego koncertowy popis. Połączony z popisem prostactwa i czystej wody chamstwa.

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:dzień
0

Wet za wet :)

Przekleję jeszcze koment którego zapomniałeś wkleić:

Poza tym: jakiej retoryki należy się spodziewać po wątku który ma w tytule określenia typu "ssie", a potem ktoś jedzie z "bullshit"? - Wibowit 12 minut temu


"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
PM
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:13
2
Wibowit napisał(a):

Wet za wet :)

Gdzie? Byłeś inicjatorem.

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:2 minuty
  • Postów:2368
1
Troll anty OOP napisał(a):

..

Programowanie obiektowe W PRAKTYCE prowadzi do tworzenia bardziej złożonych rozwiązań do problemów, które proceduralnie W PRAKTYCE rozwiązuje się prościej.
...

Jak w praktyce nie-OOP projektuje się rozwiązanie dotyczące jakiejś nietrywialnej domeny? W przypadku OOP jest ot po prostu przejście od OOA. Jak to wygląda w przypadku tej prostszej praktyki proceduralnej?

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:dzień
3

Ja mogę zgadywać: architektura to kolejna rzecz w której można popełnić błędy, więc najlepiej stworzyć program bez architektury. Profit! Zaraz zobaczymy czy mam rację.


"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.
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:mniej niż minuta
  • Postów:8406
0
Troll anty OOP napisał(a):
tamtamtu napisał(a):

@ProceduralMasterRace oraz @Troll anty OOP no i anonim czy mozecie podac powody dla ktorych OOP ssie?

Wielbiciele OOP mają wiele argumentów teoretycznych, ale te argumenty teoretyczne zakładają nierealistyczną, perfekcyjną, wręcz nieludzką naturę idealnego programisty.

Nie, po prostu zdyscyplinowanie i przestrzeganie pewnych reguł, które i tak są mniej ścisłe i mniej ograniczające niż reguły pisania choćby programowania funkcyjnego.

Czysto teoretycznie, jeśli jakieś narzędzie jest na widoku człowieka i wywołuje w nim złudzenie że jest pomocne,
ale w 99% przypadków okazuje się gorsze, a w tym 1% jest trochę lepsze,
to czysto teoretycznie posiadanie tego narzędzia jest czymś dobrym.
Czysto praktycznie - należałoby się takiego narzędzia pozbyć.

Gorsze się okazuje dlatego, że 99% programistów to idioci, którzy klepią bezmyślnie, a tylko 1% coś ogarnia, więc idąc tym tropem, należałoby się w ogóle pozbyć programowania jako takiego. Nie jest problemem OOP, tylko to, że ludzie, którzy nie maja pojęcia o niczym (i powinni siedzieć w piwnicach i się douczać, ew. robić coś na stażu pod okiem ludzi bardziej doświadczonych) programują prawdziwe komercyjne duże rzeczy.

Walczysz z wiatrakami, bo problemem jest niekompetencja ludzka, a nie paradygmat. W każdym paradygmatu będziesz mieć spaghetti.

Te dodatkowe warstwy abstrakcji, których robienie tak ułatwiają języki OOP są taką pułapką,
która na pierwszy rzut oka wydaje się właściwym rozwiązaniem, natomiast w ogromnej ilości przypadków,
po pewnym czasie, okazuje się błędem, z którego ciężko się wycofać,

Jeśli ludzie łamią wszystkie dobre praktyki i zasady, o których piszą w książkach i klepią obiektówkę "na pałę", to zawsze tak się kończy. Spaghetti kodem. Praktyka powinna mieć oparcie w teorii, a teorii o obiektówce nie brakuje, tylko nikt nie chce się słuchać tych zasad.

Ale z drugiej strony teoria powinna mieć pokrycie w praktyce. Ludzie, którzy próbują naśladować bezmyślnie to, co jest w książkach i uczą się na pamięć wzorców projektowych z książki też osiągną porażkę.

Jeśli ktoś jest przeładowany teorią, a brak mu doświadczenia własnego (i własnego rozeznania, co się sprawdza, a co nie), to też stworzy shit.

Rozwiązanie jest proste - programowania należy się po prostu uczyć - częściowo poprzez praktykę, częściowo poprzez teorię, równoważąc jedno z drugim. Taka nauka może zająć kilka, kilkanaście, czy więcej lat, ale w końcu człowiek się nauczy na tyle, żeby było w miarę ładnie. Nikt nie rodzi się programistą i wiadomo, że na początku każdy będzie pisał słaby kod w każdym paradygmacie.

bo programy obiektowe W PRAKTYCE, nie w teorii, mają silniejsze powiązania pomiędzy poszczególnymi swoimi modułami.

No dobra, ale pokazujesz sytuację, w której ktoś nie umie dobrze programować w OOP, wtedy faktycznie wychodzi szambo (przecież obiektówka wymyśliła już recepty na problem powiązań między modułami - Single Responsibility Principle, Separation of concerns, decoupling, dependency inversion...) Poza tym OOP zaczyna się jeszcze przed włączeniem komputera, trzeba pomyśleć nad tym, w jaki sposób moduły/obiekty się między sobą komunikują, w jaki sposób są od siebie zależne i co zrobić, żeby nie były zależne; trzeba też pomyśleć i przewidzieć "co może pierdyknąć za pół roku, rok". Na tym polega OOP, na patrzeniu na projekt zarówno z lotu ptaka jak i na poziomie bardzo mikro (aż do poziomu pojedynczej metody).

To co krytykujesz, to spaghetti kod ludzi, którym wydaje się, że znają OOP, bo przeczytali jedną książkę o tym albo przerobili tutorial, i tworzą śmieciowy kod bez większego przemyślenia, bez rozważenia "za i przeciw" każdej kluczowych decyzji w kodzie. Mają to, co mają potem.

Czyli masz złego nicka, bo w dalszym ciągu nie widzę tu żadnego ataku na OOP, tylko raczej krytykę tego, że w teorii w programowaniu są jakieś zasady, a w praktyce programowaniem zajmują się ludzie niekompetentni, którzy piszą jak chcą. Gdzie tu OOP?


edytowany 5x, ostatnio: LukeJL
Maciej Cąderek
Maciej Cąderek
Gorsze się okazuje dlatego, że 99% programistów to idioci - a do której grupy Ty się zaliczasz?
LukeJL
do obu XD zależy czy napiszę coś ładnego, czy naklepię spaghetti kod.
PM
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:13
2
Wibowit napisał(a):

Ja mogę zgadywać: architektura to kolejna rzecz w której można popełnić błędy, więc najlepiej stworzyć program bez architektury. Profit! Zaraz zobaczymy czy mam rację.

Myślenie, to też coś w czym można popełniać błędy, jak nam to świetnie zilustrowałeś tym postem. Jednak profitem bym tego nie nazwał. Mam nadzieję, że trollując w tym wątku, bawisz się co najmniej tak dobrze jak ja czytając twoje posty. Jakoś @LukeJL jest w stanie pisać normalnie w tym wątku. Co tobie przeszkadza?

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:2 minuty
  • Postów:2368
4

Po weekendzie i zetknięciu z miażdżącymi argumentami o słabości OOP spróbuję jakoś ulepszyć stosowanie tego paradygmatu, rozszerzyć o tę praktyczną część proceduralną. Procedural OOP, w skrócie POOP, ewentualnie rozszerzyć OOP o rozpoczynanie od części struktrualnej (OOP-Strucutral).

"Naszym klientom proponujemy rozwiązania klasy POOP albo OOPS". Brzmi nieźle.

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:dzień
2

Dorzucę jeszcze historię o Gicie, bo dla niektórych git jest objawieniem geniuszu Linusa Torvaldsa. Okazuje się, że git jest mocno wzorowany na BitKeeperze. Ponadto mało brakowało, a zamiast gita Linus używałby Mercuriala, także pisanego po tym jak BitMover odebrał licencję na BitKeepera dla Linuksa (z powodu inżynierii wstecznej).

https://softwareengineering.stackexchange.com/a/96992 :

I see a lot of answers to this that rely on the feelings the author had when hearing about one or the other SCM. Others say it all was sheer luck. I believe luck can be traced back in history.

I will talk about history.

Git and Mercurial were created simultaneously in order to solve the same issue. Back in those days, the Linux kernel was forced out of a period during which it had been using BitKeeper, a proprietary distributed SCM which had served them well for many years.

Indeed, Larry McVoy, CEO of BitMover, the company behind BitKeeper, stopped giving his software away for free to Linux developers, because someone inside the Linux community had reverse-engineered it.

Linus Torvalds, dissatisfied with what already existed, subsequently started to work on a brand-new SCM that he would soon call Git. Quickly thereafter, Matt Mackall started the Mercurial project for similar reasons.

After some time developing these projects separately, Matt Mackall presented an advanced version of his SCM and benchmarked it a certain way, comparing it to Git (which was itself only a couple weeks old). Linus considered using it instead of Git for Kernel development, but dropped the idea when he realized that Mercurial was using Changesets to log revision modifications. He feared that was too close to the way BitKeeper worked, and he certainly didn't want anything that could make someone say, "They built a BitKeeper clone".

Git was therefore used for Kernel development instead of Mercurial, but both were technically relevant. The end-result is, Git started out by being actually used where it was designed to be used, while Mercurial was not as fast to find its first big FOSS use. Because it was endowed with a very good design, and thanks to Matt Mackall's perseverance, it eventually became famous and got used for big, real-world projects.

Today, they are both famous. Which one is most famous is impossible to say. Google Code only integrated Git recently, while it had Mercurial for a long time. Many really big and famous projects use either.

I guess what I mean is, when the very reason why you have started a project vanishes, it is harder to gain popularity, but still feasible.

Bazaar is another SCM which is very famous in the GNU world, but not so much outside that, because it was built with the intent of satisfying the GNU community. Software often go where their creators want to go, and no further.

On the other hand, distributed SCMs are clear winners. I don't see many widely-used non-distributed SCMs out there.

(nie wiem czy takie długie cytowanie mieści się w ramach fair use, ale w taki sposób jest lepsza widoczność)


"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.
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Wrocław
2
yarel napisał(a):

Po weekendzie i zetknięciu z miażdżącymi argumentami o słabości OOP spróbuję jakoś ulepszyć stosowanie tego paradygmatu, rozszerzyć o tę praktyczną część proceduralną. Procedural OOP, w skrócie POOP, ewentualnie rozszerzyć OOP o rozpoczynanie od części struktrualnej (OOP-Strucutral).

"Naszym klientom proponujemy rozwiązania klasy POOP albo OOPS". Brzmi nieźle.

Genialny akronim! I jakby nie patrzeć, to POOP od zawsze był bardzo powszechny, przy czym twórcy takiego kodu zawsze twierdzili, że piszą w OOP.

KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:około 2 godziny
  • Postów:2964
6

Wielbiciele OOP mają wiele argumentów teoretycznych, ale te argumenty teoretyczne zakładają nierealistyczną, perfekcyjną, wręcz nieludzką naturę idealnego programisty.

Akurat jest odwrotnie. To w programowaniu proceduralnym wymagane jest więcej dyscypliny. Programowanie proceduralne nie dostarcza narzędzi kontroli dostępu do struktur danych. Dane są globalne, więc każdy fragment kodu może w nich dowolnie grzebać. Jeśli programista A napisał kod do operowania na strukturach jakiegoś typu, to programista B, bez żadnych przeszkód i tak może napisać kod, który weźmie taką strukturę i ją "zepsuje", a programista A nigdy się o tym nie dowie. Gorzej, taką zepsutą strukturę może przekazać do kodu, który się jej nie spodziewa. W efekcie programowanie proceduralne dużo częściej jest programowaniem defensywnym. Wiele funkcji jest najeżonych warunkami wejściowymi sprawdzającymi poprawność danych. Dyscyplina jest bardzo wskazana.

Natomiast w programowaniu obiektowym, jeśli napisałem kod obiektu i poprawnie chronię spójność danych prywatnych, to żaden osioł nie jest w stanie tego zepsuć tak, abym się nie dowiedział. Albo będzie musiał zmienić mój kod (i np. jakieś private na public) albo użyć jakiś brzydkich sztuczek z refleksją, które będą wyłapane przez linter i też się dowiem.

Oczywiście w programowaniu proceduralnym można narzucić pewien zbiór reguł, np. że tylko kod modułu X może dotykać struktur definiowanych przez moduł X. Do tego odpowiednia konwencja nazewnicza i można utrzymać porządek. I wtedy de-facto dostajemy programowanie obiektowe w języku proceduralnym. Praktycznie wszystkie duże projekty, jakie się udały, są pisane w taki sposób (np. kernel Linuksa).

OOP to właśnie próba sformalizowania takich reguł. Nikt nie wymyślił OOP. OOP zostało odkryte jako pewien wzorzec, na podstawie istniejących projektów.

Natomiast wszystkie pozostałe rzeczy takie jak dziedziczenie, polimorfizm czasu wykonania, garbage collection nie mają silnego związku z OOP. Np. polimorfizm czasu wykonania był wszechobecny w systemach Unix jeszcze zanim ktokolwiek wymyślił termin OOP.

edytowany 3x, ostatnio: Krolik
PT
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:17
0
Krolik napisał(a):

Wielbiciele OOP mają wiele argumentów teoretycznych, ale te argumenty teoretyczne zakładają nierealistyczną, perfekcyjną, wręcz nieludzką naturę idealnego programisty.

Akurat jest odwrotnie. To w programowaniu proceduralnym wymagane jest więcej dyscypliny. Programowanie proceduralne nie dostarcza narzędzi kontroli dostępu do struktur danych.

  1. Jaki to ma związek z cytowanym tekstem? Nie widzę, by cytat zaprzeczał. Atakujesz więc coś, czego @Troll anty OOP nie napisał. To czytsej wody metoda erystyczna.

  2. Jest to prawda i o tym pisaliśmy. Więc nie rozumiem sensu pisania tego jeszcze raz.

Dane są globalne, więc każdy fragment kodu może w nich dowolnie grzebać.

Może, tylko po co?

Jeśli programista A napisał kod do operowania na strukturach jakiegoś typu, to programista B, bez żadnych przeszkód i tak może napisać kod, który weźmie taką strukturę i ją "zepsuje",

No i? Programowanie to proces, który wymaga myślenia. Żaden kompilator nie zastąpi mózgu.

a programista A nigdy się o tym nie dowie.

Nie musi. To problem programisty B. A przede wszystkim kiepskiego zaplanowania organizacji kodu. A jak już będzie mu to potrzebne, to sobie dość łatwo może to zdebugować jak wyglądają wartości w strukturze. To nie jest jakieś rocket science i można to spokojnie robić już na pierwszym roku informatyki. Osobiście pracowałem przy tego typu "zabawach" na poziomie bardzo niskim (jądra), jak i wysokim (użytkownika). Nie stwierdziłem, aby wymagało to jakoś szczególnie wiele potu. Chyba, że ktoś się poci przy wpisywaniu komend debbugera, albo dopisując print w kodzie.

Gorzej, taką zepsutą strukturę może przekazać do kodu, który się jej nie spodziewa.

To mankament każdego paradygmatu.

W efekcie programowanie proceduralne dużo częściej jest programowaniem defensywnym.

To wada, czy zaleta?

Wiele funkcji jest najeżonych warunkami wejściowymi sprawdzającymi poprawność danych.

j.w.

Dyscyplina jest bardzo wskazana.

Jak w każdym paradygmacie.

Natomiast w programowaniu obiektowym, jeśli napisałem kod obiektu i poprawnie chronię spójność danych prywatnych, to żaden osioł nie jest w stanie tego zepsuć tak, abym się nie dowiedział.

W C to też jest wykonywalne. Oraz Google Go. W kilku innych językach też. Tak, wszystkie są proceduralne. Służą do tego inne mechanizmy.

Albo będzie musiał zmienić mój kod (i np. jakieś private na public) albo użyć jakiś brzydkich sztuczek z refleksją, które będą wyłapane przez linter i też się dowiem.

Ale czego to dowodzi? Że OOP ma inne narzędzia do debugowania.

Oczywiście w programowaniu proceduralnym można narzucić pewien zbiór reguł, np. że tylko kod modułu X może dotykać struktur definiowanych przez moduł X.

Tak, a nawet da się to wymusić przez odpowiednią strukturę kodu, modułów i pakietów.

Do tego odpowiednia konwencja nazewnicza i można utrzymać porządek.

W OOPie też są potrzebne dyscypliny, innego rodzaju, ale są.

I wtedy de-facto dostajemy programowanie obiektowe w języku proceduralnym.

Nie.

Praktycznie wszystkie duże projekty, jakie się udały, są pisane w taki sposób (np. kernel Linuksa).

Czyli forsujesz tezę, że "jak coś jest modularne to jest obiektowe". To absurd.

OOP to właśnie próba sformalizowania takich reguł.

Poprawka, OOP to jedna z prób. Istnieją inne.

Nikt nie wymyślił OOP. OOP zostało odkryte jako pewien wzorzec, na podstawie istniejących projektów.

Może i nie "wymyślił", ale "zebrał razem i nazwał" już tak. Co niewiele w tej rozmowie zmienia.

Natomiast wszystkie pozostałe rzeczy takie jak dziedziczenie, polimorfizm czasu wykonania, garbage collection nie mają silnego związku z OOP.

I nikt z nas, przeciwników OOP w tej dyskusji tego nie sugerował.

Np. polimorfizm czasu wykonania był wszechobecny w systemach Unix jeszcze zanim ktokolwiek wymyślił termin OOP.

Bardzo dydkusyjne, bowiem zależne od przyjętej deinicji, ale nie widzę potrzeby zaprzeczania temu.

Podsumowując: zaczęliście w tej dyskusji atakowac chochoła.

edytowany 3x, ostatnio: ProceduryToJestTo
KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:około 2 godziny
  • Postów:2964
1

Czyli forsujesz tezę, że "jak coś jest modularne to jest obiektowe". To absurd.

Jeśli:

  • kod jest podzielony na moduły
  • każdy moduł mają swoje prywatne dane
  • każdy moduł może grzebać tylo w swoich danych (wymuszone jakimkolwiek sposobem, czy dyscypliną, czy mechanizmami języka)
  • moduły komunikują się poprzez przesyłanie sobie komunikatów (np. wywołania procedur z jednego modułu do drugiego)

to tak - jest to esencja programowania obiektowego.

Jednak w programowaniu modularnym chodzi jedynie o to, że kod jest podzielony na moduły. Paradygmat modularny nie postuluje takiego ścisłego rozdziału danych / ochrony danych przez właściciela jak programowanie obiektowe. Programowanie obiektowe jest w zasadzie rozwinięciem progamowania modularnego, gdzie rozdział dotyczy również danych, a nie tylko organizacji kodu.

// edycja: przeredagowanie w punktach dla czytelności

edytowany 2x, ostatnio: Krolik
PT
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:17
0
Krolik napisał(a):

Czyli forsujesz tezę, że "jak coś jest modularne to jest obiektowe". To absurd.

Jeśli coś jest modularne a do tego moduły mają swoje prywatne dane i wymusisz (jakimkolwiek sposobem, czy dyscypliną, czy mechanizmami języka) aby dane prywatne były ruszane tylko przez moduł, który za nie odpowiada, a moduły komunikują się przesyłając sobie komunikaty (które mogą być reprezentowane po prostu przez wywołania procedur), to tak - jest to esencja programowania obiektowego.

Czyli język C, jest językiem obiektowym. Linux jest napisany obiektowo, git jest napisany obiektowo, Apache jest napisane obiektowo, w ogóle wszystko w C co ma więcej niż 10k linii jest napisane obiektowo. Trolololo. Wspaniale. @Troll anty OOP jesteśmy obaj programistami obiektowymi, co ty na tą nowinę? :D

KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:około 2 godziny
  • Postów:2964
0

A jak myślisz, dlaczego kompilator po skompilowaniu kodu w c robi pliki *.o?
Skąd się wzięło "o"?

Linux jest napisany obiektowo, git jest napisany obiektowo, Apache jest napisane obiektowo

W kod gita i apache nie zaglądałem, ale Linux - oczywiście.

Czyli język C, jest językiem obiektowym.

Język C jest językiem, w którym można programować obiektowo. Niektórzy nawet oficjalnie to tak nazywają. Np. Gnome Gobject.

edytowany 2x, ostatnio: Krolik
PT
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:17
0
Krolik napisał(a):

A jak myślisz, dlaczego kompilator po skompilowaniu kodu w c robi pliki *.o?
Skąd się wzięło "o"?

O widzisz, nawet sport jest zorientowany obiektowo, bo odbywa się w "obiektach sportowych"! Obiekty są wszędzie! Nawet, jak ich nie ma (jak w całej masie kodu C, Limbo, Go i wielu innych proceduralnych). Dlaczego zatem krytykujecie programowanie proceduralne, skoro ono jest tak naprawdę obiektowe?

PT
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:17
0
Krolik napisał(a):

A jak myślisz, dlaczego kompilator po skompilowaniu kodu w c robi pliki *.o?
Skąd się wzięło "o"?

Linux jest napisany obiektowo, git jest napisany obiektowo, Apache jest napisane obiektowo

W kod gita i apache nie zaglądałem, ale Linux - oczywiście.

A po co zaglądać? Przecież wystarczy że jest podzielony na moduły. Każdy większy projekt w C jest. Sam przecież piszesz, że moduły komunikujące się między sobą = OOP.

KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:około 2 godziny
  • Postów:2964
0

Przecież programowanie obiektowe spełnia definicję programowania proceduralnego.
Metoda niby czym jest jak nie procedurą operującą na obiekcie?

Paradygmat proceduralny zakłada, że masz kod podzielony na procedury, które modyfikują jakieś dane. Koniec definicji.
Gdzie programowanie obiektowe się z tym kłóci?

Programowanie obiektowe narzuca dodatkowe wymagania poza podziałem na procedury. Mówi o tym, że dane mają też być odpowiednio podzielone.

Sam przecież piszesz, że moduły komunikujące się między sobą = OOP.

Przeczytaj jeszcze raz całą definicję OOP, którą przytoczyłem kilka postów wyżej, bo nie czytasz uważnie.
Niezupełnie. Moduły komunikujące się między sobą nie są warunkiem wystarczającym. Dane muszą być prywatne dla tych modułów. Nie jest dopuszczalne, że moduł A grzebie w danych modułu B z pominięciem kodu B. Dlatego nie każdy kod napisany proceduralnie będzie można uznać za obiektowy.

edytowany 1x, ostatnio: Krolik
PT
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:17
0

Okej, skoro piszę modularny kod, o takich cechach, to jestem programistą obiektowym, a więc zarzuty, że nie rozumiem OOPu są wzięte z sufitu i nieprawdziwe. Więc proszę się odstosunkować od pisanie orzeze mnie wszystkiego w C lub Go. Okej a zatem, na mocy bycia programistą obiektowym stwierdzam - OOP ssie, kiedy są w nim klasy, nie ssie kiedy w nim klas nie ma. Wszyscy zadowoleni?

PT
  • Rejestracja:około 7 lat
  • Ostatnio:około 7 lat
  • Postów:17
0
Krolik napisał(a):

Przecież programowanie obiektowe spełnia definicję programowania proceduralnego.
Metoda niby czym jest jak nie procedurą operującą na obiekcie?

Paradygmat proceduralny zakłada, że masz kod podzielony na procedury, które modyfikują jakieś dane. Koniec definicji.
Gdzie programowanie obiektowe się z tym kłóci?

Łał, czyli nawet programowanie funkcyjne jest proceduralnym.

Zobacz pozostałe 7 komentarzy
KR
Dlatego nie uznaje się języka C za obiektowy a Pascala za funkcyjny. Choć w tym pierwszym na siłę można pisać obiektowo. I skoro ludzie to robią, mimo oczywistej ułomności języka w tym zakresie, to znaczy że zalety OOP muszą być większe niż ból z robienia OOP w C.
PT
Pascal nie jest kompletny w sensie Turinga? Których to algorytmów nie da się w nim implementować?
PT
Jaki ból? Pisanie modularnego kodu w C boli tyle co używanie mózgu do myślenia.
KR
Znowu nie czytasz uważnie. Podzbiór funkcyjny Pascala prawdopodobnie nie jest, bo nie ma wyrażenia warunkowego. Ale dawno nie pisałem w Pascalu - może jest takowa konstrukcja a ja tylko o niej nie wiem. Ale nawet jeśli jest, to byłby to bardzo ułomny język funkcyjny.
PT
Teraz zebrałeś te dwie rzeczy w jednym zdaniu i jest to jasne. Wystarczy jaśniej pisać zdania. Wszak rozmawiasz z kimś komu @Wibowit postawił diagnoze bycia debilem.
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)