Reactive Programming - hit czy kit ?

Reactive Programming - hit czy kit ?
0

Czesc, na wstepie przepraszam za brak polskich znakow.

Co sadzicie o idei / manifescie "Reactive Programming" ? Piszmy wszystko asynchronicznie, niech nic nie blokuje niczego bezmyslnie, wykorzystujmy sprzet granic mozliwosci...

Chodzi mi to Scale, Akke, Playa, Spray.io, Reactive Mongo,itp. Czy to ma szanse zawojowac rynek ? A moze dalej bedziemy pisac w Javie na Tomcata ? Zaczalem sie tym jarac troche. Fajnie byloby znac Jave, Springa itp a do tego Scala i asynchronous-oriented-programming. Jednak utrzymac oba stosy wiedzy na wysokim poziomie moze byc ciezkie.

niezdecydowany
niezdecydowany
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 9 lat
  • Lokalizacja:Bieszczady
1

czekaj czekaj, możesz mieć appke w "javie na tomcata" i obok mieć osobno coś na czym stoi Akka (ktoś tu nie przeglądał materiałów) :D przecież w Springu jest deferredResult(które pod spodem tak naprawdę wykorzystuje async z servlet 3.0), jest @Async, a co to jest jak nie asynchroniczne programowanie ? W ogóle skąd to podejście że jedna "szkoła" musi od razu wyprzeć inną.

Są zastosowania dla microservisów ale są miejsca gdzie sprawdzają się klasyczne monolityczne aplikacje. Tak samo jest z programowaniem asynchronicznym, Ty masz szukać rozwiązań pod use-case a nie szukać miejsc żeby na chama wsadzać tam Akke czy rxJave.

Zresztą, żeby mieć jakiś "stos" na wysokim poziomie, to potrzebujesz z 5lat w codziennym użytku - w tedy Ci "noga wyrośnie" ( )


"Perhaps surprisingly, concurrent programming isn’t so much about threads or
locks, any more than civil engineering is about rivets and I-beams."
edytowany 2x, ostatnio: niezdecydowany
wiciu
  • Rejestracja:ponad 11 lat
  • Ostatnio:około 23 godziny
  • Postów:1205
1

Źle się zabierasz za temat. Chcesz ogarniać Scalę, Akkę, Rx i coś tam jeszcze. Wszystkiego na raz nie da się ogarnąć. IMO powinieneś zacząć or RxJavy i na spokojnie dużo o tym poczytać, napisać kilka prostych programów i potem brać się za resztę. Sama RxJava ma wysoki próg wejścia i trzeba spędzić trochę czasu, żeby to dobrze zrozumieć i umieć się tym posługiwać. Korzystam z RxJavy jakiś czas i nie mogę powiedzieć, że w pełni poznałem tę bibliotekę, ponieważ API jest potężne. Nie można popadać w skrajności pisać wszystko w sposób reaktywny, ale w bardzo wielu miejscach takie podejście się sprawdza. Upraszcza kod i daje więcej możliwości. W przypadku aplikacji mobilnych na Androida staje się to powoli standardem, bo do tej pory nie wymyślono lepszego rozwiązania do obsługi asynchronicznych operacji dla tej platformy. W wielu innych miejscach też się to sprawdzi, ponieważ mamy API podobne do strumieni z Javy 8, ale ze wsparciem dla wielowątkowości.

Polecam m.in krótką prezentację n.t. Retrofita i RxJavy:

edytowany 1x, ostatnio: wiciu
Zobacz pozostały 1 komentarz
wiciu
Oczywiście, że są. Przecież to jest tylko poetyka kodu. W takim razie spróbuj napisać kod, który rozwiązuje problem omówiony w podlinkowanej prezentacji za pomocą samych natywnych mechanizmów Javy 7. Ciekawe, ile Ci to zajmie i ile będzie tam kodu. Spróbuj sobie też obsłużyć cały error handling, filtry, throttling i inne tym podobne sprawy bez RxJavy. Powodzenia. Da się, ale po co sobie życie utrudniać. ;-)
niezdecydowany
niezdecydowany
dobra spoko, zgoda, w takich systemach i takich przypadkach, ale nie oszukujmy się, a androidowych appkach nie robisz drugiego netfixa :D
wiciu
Netflix rozwiązuje u siebie inne problemy. Głównie na poziomie serwerów (np. Hystrix). W przypadku aplikacji mobilnych zwraca się uwagę przede wszystkim na ograniczenia i zawodność urządzeń oraz połączeń sieciowych, a nie serwerów. W każdym razie sama RxJava daje dużo możliwości bez względu na to, co piszemy.
niezdecydowany
niezdecydowany
nie znam się na aplikacjach mobilnych, czyli dla mnie "inne problemy" to mobilne problemy.
niezdecydowany
niezdecydowany
Aczkolwiek, jeżeli ktoś chce się brać za rxJave i Akke, to MUSI poznać niższy poziom (wait, notify,join,synchronized,JMM,api z JSE 5) bo inaczej używa się tego bezmyślnie
KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:dzień
  • Postów:2964
0

W tej chwili robię coś mocno rozproszonego na bazie Netty. Nie bardzo widzę, jak uzyskać taką wydajność i skalowalność pisząc w sposób klasyczny, tj. blokujący. Przede wsystkim jestem w stanie obsłużyć tysiące połączeń na kilku wątkach i praktycznie jednym wspólnym executorze, przez który przechodzi wszystko:

  • połączenia od klientów
  • połączenia do bazy danych
  • we/wy dyskowe
  • komunikacja między węzłami systemu

Mała liczba wątków to:

  • małe straty na przełączaniu kontekstu i ciągłym blokowaniu wątków
  • małe użycie pamięci stosu

Poza samym reactive dochodzi jeszcze fakt, że Netty począwszy od wersji 4.0 ma bardzo wydajne mechanizmy ręcznego zarządzania pamięcią (tak! w Javie :P), co powoduje, że GC Javowe pod pełnym obciążeniem nam się nudzi i ziewnie (w sensie - minor GC) może raz na kilka minut.

Wady:

  • trochę trzeba się mentalnie przyzwyczaić do innego modelu, np. czasem korci żeby na jakimś future zrobić get
  • czasem można natrafić jeszcze gdzieniegdzie na blokujące API i wtedy trzeba obchodzić stosując osobną pulę wątków aby "udawać" asynchroniczne
  • pewne rzeczy się potrafią skomplikować i trzeba uważać na nowe typy problemów -
    • np. utknięcie w jakimś stanie na zawsze, bo zapomnieliśmy obsłużyć prawidłowo jakieś zdarzenie (albo wysłaliśmy nie tam gdzie trzeba),
    • albo nieograniczony wzrost liczby skolejkowanych komunikatów (tj. system szybciej generuje niż konsumuje).
edytowany 1x, ostatnio: Krolik
0

Czyli co? Czas sie zaczac uczyc, zeby Janusze IT nas nie wygryzli?

T2
  • Rejestracja:ponad 10 lat
  • Ostatnio:7 miesięcy
  • Postów:194
0

Zdecydowanie tak. Utworzysz kilka bardziej rozbudowanych aplikacji w RX i od razu pomyślisz jak bez tego mogłem żyć. Z swojej strony mogę sugerować abyś wybrał się na jakiś wykład o Rx.

edytowany 1x, ostatnio: teo215
KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:dzień
  • Postów:2964
2

Patrząc na to z drugiej strony - zabawne jest, jak stare koncepcje z wczesnych lat 70-tych (albo i jeszcze wcześniej), dostają nową nazwę i już B-playerzy podniecają się "nową technologią".

Jeśli jesteś Januszem IT, to używanie RxJava nie sprawi, że będziesz nim mniej. :P

edytowany 2x, ostatnio: Krolik
Zobacz pozostałe 5 komentarzy
KR
Napisałem, że projekty robione dla zabawy / nauki, to insza inszość. Raczej chodzi mi o ludzi, którzy w projektach produkcyjnych porywają się na jakąś technologię, dlatego, że teraz teraz jest modna, a nie dlatego, że faktycznie rozwiązuje ich problemy. Jedna z pierwszych firm, w której pracowałem w taki sposób porwała się na JEE i o mało co nie zakończyło się to spektakularną katastrofą.
JasnyPatryk
"Napisałem, że projekty robione dla zabawy / nauki, to insza inszość" - ale czy w pracy - co prawda nie na produkcyjnym środowisku - w ramach "eksperymentu" czy "nauki" ktoś tworzy mikroserwis w teoretycznie nowej technologii(w której jeszcze nic produkcyjnie nie stawiał) to ... jest b playerem bo jara się jak cymbał ? przecież sam pisałeś że robisz coś na np: netty, przecież musiałeś zacząć to robić pierwszy raz, pierwszy projekt stawiany na tym to musiał być eksperyment.
KR
Eksperymenty są ok, a nawet właśnie bardzo wskazane. Ślepe podążanie za modą / reklamą lub, bo ktoś coś na blogu napisał - nie. A moją wypowiedź o Januszach IT czy B-playerach potraktuj z przymrużeniem oka. ;) Serio nie spotkałeś nigdy gościa, który Ci próbował wmówić, że np. robisz coś źle, bo Twój kod nie jest OOP albo bo nie masz mikroserwisów / SOA czy czegoś tam innego? Raz spotkałem we wczesnych latach 2000 takiego, który twierdził, że niedługo wszystko będziemy programować graficznie i że programiści nie będą potrzebni, bo analityk strzałkami bloczki połączy.
JasnyPatryk
jakoś na swojej drodze nie spotkałem żadnego takiego świra - ale to raczej nic dziwnego w javie programuje może rok, a tak naprawdę ze 3 miesiące (przygody z rozszerzaniem systemów ERP nie nazwałbym programowaniem). Wracając do hejtu :D:D:D "wszystko będziemy programować graficznie i że programiści nie będą potrzebni, bo analityk strzałkami bloczki połączy" - https://youtu.be/zvVkD7huKAE?t=7m47s
02
podniecanie sie jezykami funkcyjnymi tez jest lamerskie bo przeciez to juz bylo dawno temu w lispie
0

Od czego warto zacząć się uczyć w stronę "reactive" gdy ktos jest programistą java, ale z dosć podstawową wiedzą o wielowątkowości?

Trochę jestem sceptyczny ale wydaje się warte przynajmniej pobawienia się.

Wizzie
java concurrency in practice, a potem może jakaś RxJava? ;)
0

Może ktoś zarzucić przykładowymi use casami dla web development?

0

java concurrency in practice, a potem może jakaś RxJava? ;)

chyba tak zrobie... chociaz podjaralem sie scala ostatnio.

a ma ktos jakas opinie o spring reactorze? albo reactive jersey? :p

0

Czy to cale reactive to bardziej frontend stuff?

jakies zastosowania na backend, server side?

0

Same zastosowania do backendu. Przeczytaj manifest...

0

Macie moze jakiegos linka z porownaniem futurow i callable vs threading w rxjava?

H1
  • Rejestracja:około 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:185
0

hmm... niedawno natrafiłem na RxJave i zastanawiam się do czego by można jej użyć.
Zrobiłem nieco bezmyslny przykład. Wątpię, że jest poprawny.
Czy w ten sposób albo podobny mógłbym robić async rest calls?
To Schedulers.io spawnuje RxCachedThreadSchedulers.

Kopiuj
import java.util.List;

import rx.Observable;
import rx.functions.Func2;
import rx.schedulers.Schedulers;

public class App {

	public static void main(String[] args) {
		Observable<List<Person>> ziped = Observable
				.zip(getObservableName(), getObservableAge(), new Func2<String, Integer, Person>() {

					@Override
					public Person call(String name, Integer age) {
						Person person = new Person();
						person.setName(name);
						person.setAge(age);
						return person;
					}
				}).toList();

		List<Person> personList = ziped.toBlocking().single();
		personList.stream().forEach(person -> System.out
				.println("[Name : " + person.getName() + ", Age : " + person.getAge() + "]"));
		// [Name : Maciek, Age : 18]
		// [Name : Rysiek, Age : 20]
		// [Name : Zdzichu, Age : 45]
		ziped.subscribe();
	}

        // emits Observables of Lists.newArrayList("Maciek", "Rysiek", "Zdzichu");
	private static Observable<String> getObservableName() {
		return Observable.from(RestService.getNames()).subscribeOn(Schedulers.io());
	}
        
        // emits Observables of Lists.newArrayList(18, 20, 45);
	private static Observable<Integer> getObservableAge() {
		return Observable.from(RestService.getAges()).subscribeOn(Schedulers.io());
	}
}

edit: z tego co widzę to moglbym tez wywalic subscribe w ogole, albo przeciwnie zrobic jakis cache() i zebrac wynik w subscription. Zreszta nie wiem ;]

edytowany 1x, ostatnio: H1ghlander
H1
  • Rejestracja:około 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:185
0

jakas podpowiedz? ;)

0

Ba, nawet bardzo dobrze się w tym sprawdza. Poszukaj wykładu z Confitury 2015 o RxJavie i Hystrixie ;)

H1
  • Rejestracja:około 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:185
0

Ok, obadam. Ale czy powyzszy przyklad to prawidlowe uzycie? Mniej wiecej. Glownie chodzi mi o kawalek toBlocking() gdzie nawet dokumentacja mowi, ze raczej sie tego nie robi. ;)

Chociaz mysle, ze chodzi o to by ten stream wystawic w swiat i publikowac wyniki kolejnych zipow, zamiast go przyblokowac i zwrocic wynik.

0

A ja mam pytanie. Jak na warstwie sieciowej są zrealizowane takie streamy. Niereaktywne mogę wystawić sobie RESTa, który pobiera stronę danych / cokolwiek, a Reactive przewiduje traktowanie danych jako streamu. Czyli mogę odwołać się najpierw po 10 elementów a potem po 20.

Chciałbym się dowiedzieć jak serwer wystawia "taką usługę" i jak klient z niej korzysta. Ktoś coś ?

Wibowit
  • Rejestracja:prawie 20 lat
  • Ostatnio:15 minut
0

Expertem nie jestem, ale wydaje mi się, że też możesz użyć RESTa - robisz tylko połączenie HTTP keep-alive i urywasz po tych 20-tu czy iluś tam żądaniach. Nie wiem czy to jest zalecana metoda.


"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.
Wizzie
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 7 lat
0

Websockety są chyba w sam raz do tego. Są już dobrze wspierane przez przeglądarki: http://caniuse.com/#feat=websockets

H1
  • Rejestracja:około 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:185
0

websockets i server sent events

http://en.lichess.org/ to cos to chyba websockets, scala, play, akka streams

0

Ile plus / minus może zająć nauka Scali, Akki i Play'a mając 1,5 roku doświadczenia zawodowego w Javie ?

Wizzie
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 7 lat
0

Jak chcesz używać Scali jako "lepszej Javy" to niedługo i ponoć sporo projektów jest w ten sposób pisanych w Scali. Natomiast jeśli chcesz się nauczyć programowania funkcyjnego, to trochę więcej.

Wątpię, czy ktoś ci dokładnie odpowie ile ci to zajmie, bo tak to nie działa ;)

edytowany 1x, ostatnio: Wizzie
KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:dzień
  • Postów:2964
0

Tak, żeby zacząć kodować coś i poczuć się w miarę swobodnie (składnia, podstawowy biblioteki standardowej itp.) to zajęło mi jakieś 2 tygodnie. Później to już zależy od tego co robisz, jak szybko się uczysz i jak bardzo chcesz być zaawansowany.

edytowany 1x, ostatnio: Krolik
02
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 8 lat
  • Postów:1176
1

Te manifesty w IT sa zalosne :D
Tylko ten jest dobry: http://programming-motherfucker.com/

edytowany 1x, ostatnio: 0x200x20
0

Ktoś może podać praktyczne przykłady tego?

Chat? Google Spreadsheets? real time?

1
Złoty Szczur napisał(a):

Ktoś może podać praktyczne przykłady tego?

Chat? Google Spreadsheets? real time?

Reactive programming może być (prawie) wszędzie.
Scala + Akka + Slick (baza danych) wszystko wewnątrz frameworka Play!

Prosty z życia wzięty przykład:

rest api w wykonaniu Play!

controller przyjmuje request, daje znać do aktora (ask -> zwraca future) do np pobrania danych z bazy -> aktor przekazuje zapytanie do bazy danych (slick), który zwraca future (albo stream, jeśli ktoś chce/potrzebuje), wszystko asynchronicznie wraca do controllera jako future, który na przyjście future zwraca dane do klienta, a jak future będzie failed to wykona jakąś tam inną akcję.

Piszę reactive od około 2lat i od czasu jak zacząłem tak pisać razem ze scalą, to
-nie ma pętli for (za wyjątkiem for comprehension w scala:) )

  • if'ów prawie nie ma
  • zapomniałem co to jest nullpointerexception
  • kod jest bardziej zwarty, prostszy do refactorowania.

Jeden duży minus - próg wejścia w reactive (o scali nie wspomnę) dla ludzi, którzy od dawna piszą "normalnie" jest dość duży. Trzeba przestawić myślenie na zupełnie inne tory. Ale bardzo warto.... I na pewno nie jest łatwo używać tego w już istniejących systemach.

R3
Ale w pytaniu chodziło o use case a nie, że można bo można... w javie też mogę robić async, ale to chyba nie wszystko za czym kryje się reactive? ...
Pipes
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 3 lata
  • Postów:459
0

Zważywszy na kryteria takiego rodzaju programowania to pasuje do tego kod w Erlangu/Elixirze. Aktorowy model komunikacji, zero mutowalnych danych, funkcje mają wiele sygnatur wspierających różne scenariusze (poprzez pattern matching), funkcje rekurencyjne w przypadku przeglądania/modyfikowania list i map.
Próg wejścia: Wyrzucasz całe OO i wchodzisz w programowanie funkcyjne. Później ogarniasz dobrze model komunikacji "gołych" procesów, sprawdzasz GenServer/GenEvent/GenStage i Taski - rozwiązanie pośrednie.

KR
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Lokalizacja:Gdynia
  • Postów:3
0
Pipes napisał(a):

Zważywszy na kryteria takiego rodzaju programowania to pasuje do tego kod w Erlangu/Elixirze. Aktorowy model komunikacji, zero mutowalnych danych, funkcje mają wiele sygnatur wspierających różne scenariusze (poprzez pattern matching), funkcje rekurencyjne w przypadku przeglądania/modyfikowania list i map.
Próg wejścia: Wyrzucasz całe OO i wchodzisz w programowanie funkcyjne. Później ogarniasz dobrze model komunikacji "gołych" procesów, sprawdzasz GenServer/GenEvent/GenStage i Taski - rozwiązanie pośrednie.

Programowanie funkcyjne to jest magia, w kierunku którym idą (powoli niestety) języki programowania. Java 8 pooowoli zaczyna, Scala wg purystów nie jest w pełni funkcyjna, ale chyba już wyszła poza akademicki język. Haskel to samo. Jest też F#, cały LinQ, który jest "monadic" i wiele innych.
Póki co mam wrażenie, że niewielu jest programistów, którzy rozumieją functional programming.
Wielu nie widzi sensu w nauce nowego, skoro można po staremu :)
A to, że kod jest blokujący, a to, że trzeba się nawalić w klawiaturę, żeby coś dobrze napisać, a to, że refactor prostego mechanizmu potrwa 2dni... who cares?

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)