Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Scala — pierwsze kroki cz.3

W poprzednich częściach kursu poznaliśmy kilka podstawowych konstrukcji w Scali. Aby można było operować na jakiś realnych danych i pisać użyteczne skrypty musimy zapoznać się z podstawowymi typami tablicowymi (nazywanymi też kolekcjami). W Scali są one wszystkie typami generycznymi. Oznacza to, że zostały napisane z wykorzystaniem metaprogamowania (generics). Parametryzujemy je podając typ obiektu jaki będą przechowywać. Niektóre z kolekcji jak mapy itp. mogą wymagać określenia większej ilości typów.

Krok siódmy - podstawowe kolekcje

Wszystkie typy kolekcji można podzielić na mutowalne (mutable) czyli takie, których elementy można zmieniać, oraz niemutowalne (immutable). W tych ostatnich nie zmienimy (podmienimy) elementu tablicy na inny, tylko musimy stworzyć nowy obiekt kolekcji sklejając ze starych i nowych elementów. W programowaniu funkcyjnym należy używać te drugie i dlatego pakiet, w których się one znajdują jest domyślnie importowany. Jednak ze względu na to, że Scala ma umożliwiać wykorzystanie kodu Javy , oraz nie narzucać pisania w stylu funkcyjnym dodano również tablice mutowalne, które importujemy z pakietu scala.collection.mutable

Array - tablica stałej długości

Jest to odpowiednik prostej tablicy w Javie. Musimy z góry ustalić jej rozmiar i typ.

val powitanieNapisy = new Array[String](3) powitanieNapisy(0) = "Witaj" powitanieNapisy(1) = "w świecie" powitanieNapisy(2) = "programowania!" println(powitanieNapisy.mkString(" "))

W pierwszej linii przykładu tworzymy tablicę napisów o 3 elementach. O ilości elementów mówi liczba typu Int podana w nawiasach okrągłych. Powstała tablica jest typu Array[String]. Programującym w C++ i Javie od razu rzuci się w oczy sposób zapisu typu tablicy, w którym zamiast nawiasów kątowych < > użyto nawiasów kwadratowych. Wszędzie w metaprogramowaniu oraz kodzie wykorzystującym go, używa się właśnie nawiasów kwadratowych zamiast kątowych. Natomiast gdy chcemy się odwołać do konkretnego elementu tablicy, to zamiast nawiasów kwadratowych, użyjemy nawiasów okrągłych, co widać w 2, 3 i 4 linii.
Typy będące kolekcjami mają wbudowane szereg wspólnych wygodnych funkcji, służących do manipulacji nimi, takich jak przedstawiona w ostatniej linii metoda mkString. Metoda ta zamieni całą tablicę w napis i zadba o rozdzielenie go napisem podanym jako parametr tej funkcji, dbając równocześnie, aby nie dodać go na jego końcu.

Przypisanie do kolejnych elementów tablicy może się odbyć za pomocą metody update:powitanieNapisy.update(0, "Witaj")Jest to równoważne drugiej linii z pierwszego przykładu. Co więcej linia ta jest w trakcie kompilacji podmieniana właśnie na metodę update. Jest to część mechanizmu, który omówimy w następnym kroku.

Tablicę, której wszystkie elementy są znane na samym początku możemy zadeklarować w następujący sposób: val tablica = Array("zero", "jeden", "dwa")Charakterystyczny jest tutaj brak słowa kluczowego new, ponieważ używamy tutaj metody apply napisanej w obiekcie Array (będącej czymś w rodzaju singletonu zespolonego z klasą Array - wyjaśnienie tego pojawi się przy omawianiu klas)

Listy

Jedną z najczęściej używanych kolekcji przy typowym programowaniu w Scali jest typ List. Jest to lista jednokierunkowa. Należy ona do typów niemutowalnych w przeciwieństwie do Array. Polega to na tym, że każdą wartość w tablicy Array można zmienić na inną. Natomiast w List nie. Zamiast podmieniać wartość, tworzymy nową listę łącząc dowolnie różne jej elementy z nowymi, porzucając zbędne. Przypomina to sposób przetwarzania napisów w Javie w klasie String.
Aby zadeklarować listę piszemy:val lista = List(1, 2, 3)Powstała lista jest typu List[Int] i składa się z 3 elementów.

Łączenie dwóch list i dodawanie elementu do listy:val lista1 = List(1, 2) val lista2 = List(3, 4) val lista3 = lista1 ::: lista2 val toSamoCoLista3 = lista1 ++ lista2 val lista4 = 5 :: lista3 val lista5 = 1 :: 2 :: 3 :: 4 :: 5 :: Nil Za każdym razem powstaje nowa lista, a stara pozostaje bez zmiany. W trzeciej i czwartej linii pokazane są dwa alternatywne sposoby tworzenia nowej listy z dwóch innych. Dodawanie elementu z przodu listy realizuje podwójny dwukropek. W ostatniej linii widać jak można w inny sposób stworzyć listę. Ostatni element Nil to pusta lista. List nie posiada metody dodawania elementu na jej końcu. Jest to spowodowane faktem, że w liście jednokierunkowej czas realizacji tej operacji byłby długi i proporcjonalny do ilości elementów. Jeśli potrzebujemy takiej możliwości to musimy użyć innej kolekcji. Jednak w dobrze stosowanym stylu funkcyjnym jest to zazwyczaj zbędne i List jest optymalnym rozwiązaniem. Co najwyżej czasem potrzebujemy użyć metody reverse, której wyniku łatwo się można domyśleć.

Tworzenie List i jej metody

  • List() lub Nil - pusta lista
  • List(435454L, 34546534L, 24345448548495L) - tworzenie listy z elementami (tutaj typu Long)
  • List(1, 2) ::: List(3, 4) - łączenie list i tworzenie nowej (lub ++)
  • lista(2) - zwraca 3 element listy (liczone od zera)
  • lista.drop(2) - porzuca wszystkie elementy z przodu włącznie z 2 (NIE liczone od zera)
  • lista.take(2) - bierze dwie pierwsze elementy listy
  • lista.dropRight(2) - podobna do drop tylko porzuca elementy z tyłu
  • lista.last - ostatni element listy
  • lista.head - pierwszy element listy
  • lista.init - wszystkie elementy oprócz ostatniego
  • lista.tail - zwraca wszystkie elementy oprócz pierwszego
  • val pierwszy :: lista2 = lista - przypisuje pierwszy element listy do zmiennej pierwszy, a resztę do lista2
  • lista.reverse - odwraca kolejność elementów w liście
  • lista.isEmpty - zwraca prawdę lub fałsz w zależności czy lista jest pusta
  • lista.length - zwraca ilość elementów listy
  • lista.map(elem => s * 2) - używa funkcji anonimowej do przetworzenia elementów, w tym przypadku zwiększa każdy element 2 krotnie
  • lista.mkString(", ") - łączy elementy tworząc napis oddzielony podanym parametrem
  • lista.forall(x => x > 3) - zwraca prawdę jeśli wszystkie elementy są większe od 3
  • lista.exists(x => x > 3) - zwraca prawdę jeśli chociaż jeden element jest większy od 3
  • lista.filter(x => x > 3) - zwraca listę wszystkich elementów większych od 3
  • lista.filterNot(x => x > 3) - przeciwny do filter
  • lista.foreach(x => printnln(x.toString + " wartość")) - iteruje po wszystkich elementach (niczego nie zwraca)
  • lista.sort((x, y) => x > y) - zwraca listę posortowaną w porządku malejącym

Dla przypomnienia: wszystkie te metody nie zmieniają pierwotnej listy i musimy przypisać wynik do nowej listy.

Krotki - tuples

Ten typ danych jest podobny do znanych krotek w Pythonie. Każdy element krotki może być innego typu. Może to być przydatne przy zwracaniu rezultatów przez funkcje i metody, jednak nie należy nadużywać tego mechanizmu, ponieważ kod może stawać się mało czytelny. val krotka = (3, "trzy", 'a') println(krotka._1) println(krotka._2) println(krotka._3) Krotka powstaje przez wpisanie danych w nawias, a odwołujemy się do elementu podając jego numer po znaku podkreślenia (_) ale licząc od 1.

Może się wydawać, że ciężko się połapać kiedy liczyć elementy od zera, a kiedy od 1. Jest na to reguła, którą będziemy potrafili stosować kiedy zrozumiemy kiedy dany kod napisany jest w stylu funkcyjnym. Tradycyjnie w językach pochodzących od C używa się numerowania tablic od zera. Natomiast w językach funkcyjnych jak Heskell numeruje się od jeden. Zatem w Scali tam gdzie mamy tradycyjne odwołanie podobne do tablicy liczymy elementy od zera, a tam gdzie użycie jest funkcyjne (jak w metodzie listy drop, take itp.) liczy się od jeden.

Mapy i sekwencje

Jak już wspomniałem, Scala wspiera zarówno programowanie imperatywne jak też funkcjonalne, dlatego posiada wersje kolekcji mutowalnych i niemutowalnych. Jeśli jednak dla pozostałych kolekcji zazwyczaj różnią się one nazwą, to dla sekwecji i map nazywają się tak samo.

Sekwencja zachowuje się podobnie do list jednak jej wewnętrzna implementacja jest inna. var pojazdy = Seq("samochód", "rower") pojazdy ++ "samolot" println(pojazdy.contains("samolot") W drugiej linii do kolekcji dodajemy nowy element, jednak sprawdzenie jego obecności da fałsz, ponieważ obiekt pojazdy jest niemutowalny. Musielibyśmy przypisać go z powrotem do pojazdy, co można zrobić jako, że zadeklarowaliśmy go ze słowem kluczowym var.pojazdy = pojazdy ++ "samolot" W rzeczywistości obiekty zadeklarowane jako sekwencje są typami pochodnymi od Seq i lepiej mieć kontrolę nad nimi, wybierając samodzielnie ten typ z pominięciem Seq.

Map składa się klucza i wartości, których typ może być dowolny:import scala.collection.mutable.Map var kurs = Map("USD" -> 3.14, "GBP" -> 5.34) kurs += ("EURO" -> 4.23) kurs("JEN") = 2.34 println(kurs("EURO")*123.34) Do mutowalnej mapy możemy dodawać pary klucz i wartość (3 i 4 linia), a potem pobierać według klucza. Mapa, tak jak i inne klasy z kolekcji, zawiera też wiele metod wspólnych dla większości kolekcji takich jak map, foreach itd. Można więc operować na niej podobnie do List, a także dzięki wbudowanym metodom, zmienić ją w listę par (krotek).

Był to dość długi krok, ale ważny na drodze do poznania Scali ;)
 

programowanie

Komentarze

0 nowych
Frankfurterium   9 #1 06.09.2014 00:09

I tutaj Scala zaczyna się robić "dziwna". Niby wszystko ma swoje wytłumaczenie, ale i tak wygląda dramatycznie niespójnie. Konieczność wykuwania na blachę zupełnie odmiennych sposobów tworzenia i odwoływania się do zawartości różnych struktur przyjemna nie jest. Przez takie patenty Scala zawsze będzie uważana za język fajny i ciekawy, ale bardziej w tonie studni pomysłów do wchłonięcia przez inne języki niż czegoś do realnego użytku.

  #2 06.09.2014 02:51

Wydaje mi się, że List nie jest listą jednokierunkową, bo to jest nieoptymalne od czasów 486. To raczej ubogi krewny Vector z C++. ;-)

mikolaj_s   13 #3 06.09.2014 09:06

@Frankfurterium: To nie kwestia wykuwania, tylko praktyki. Zawsze język dający duże możliwości wymaga nieco więcej praktyki. Samo korzystanie z bibliotek w Scali ze wsparciem IDE jest proste. Natomiast ich pisanie tak, aby były czytelne i łatwe w użyciu to już wyższa szkoła jazdy.

"ale bardziej w tonie studni pomysłów do wchłonięcia przez inne języki niż czegoś do realnego użytku."

Zapewniam Cię, że jak język jak najbardziej nadaje się do realnego użytku. Co więcej z mojego doświadczenia wynika, że co prawda próg wejścia i osiągnięcie umiejętności pozwalającej pisać jakieś większe programy wymaga więcej nauki niż w niektórych innych (choćby w Javie), ale ten większy nakład pracy zwraca się szybko dzięki temu, że pisanie i utrzymywanie w nim kodu jest dużo łatwiejsze. Za to dodawanie nowych paradygmatów do istniejących już języków często skutkuje spadkiem czytelności, rozwlekłością, brakiem spójności i podwyższa trudność nauki danego języka. Patrząc na Jave 8 nie jestem przekonany, że nauczenie się jej od podstaw, aż do poziomu jaki obecnie prezentuje z jej dodatkami funkcyjnymi jest łatwiejsze.

Autor edytował komentarz.
mikolaj_s   13 #4 06.09.2014 10:39

@sprae (niezalogowany): A jednak jest. W przypadku obiektów niemutowalnych vector nie jest lepszy. Zauważ, że w liście łatwo podmienić każdy element, łączyć i scalać części. Jest to szybsze niż kopiowanie fragmentów tablic. Ale listę stosuje się tylko tam gdzie nie chcemy mieć dostępu do konkretnych elementów tylko przetwarzamy je wszystkie sekwencyjnie. Jak potrzebujesz faktycznie Vector to jest dostępny w mutable i wiele innych podobnych kolekcji. Ale sam rzadko z nich korzystam, zazwyczaj sprawdza się lista.

Frankfurterium   9 #5 06.09.2014 10:50

O tym, czy język nadaje się do komercyjnego użytku, decyduje między innymi (a może i głównie) ilość i jakość frameworków i bibliotek z nim stowarzyszonym. Poza Liftem (którego parę lat temu, nie wiem jak dzisiaj, odradzano na początek, bo ma sporo osobliwych naleciałości) Scala nie ma niczego głośnego i natywnego. Tymi kilkoma spektakularnymi wdrożeniami strona Scali chwali się od kilku ładnych lat. Ale po nich nastała posucha. A gdybym ja podszedł do szefa i zaproponował wykonanie następnego projektu w Scali, wyśmiałby mnie albo odesłał do domu.

Parę lat temu też byłem zachłyśnięty Scalą. Nadal czuję do niej sympatię i uważam, że to całkiem fajny instrument do zabawy i poszerzania horyzontów. Więcej - można w niej napisać skrypt albo użyć jako DSL-a w czymś większym. Ale jej najważniejsze ficzery właśnie są wchłaniane, a na horyzoncie wiszą inne języki wieszczone jako następcy Javy.

grapeli23   5 #6 06.09.2014 13:46

Golang rozwija się w imponującym tempie. Jego przyszłość wygląda bardzo ciekawie w wielu aspektach. Szybkością nigdy nie przegoni C lub C++, ale ma jeszcze duże rezerwy, które pozwolą mu się znacząco zbliżyć do nich. W świecie jest o nim bardzo głośno i znajduje swoje miejsce w co raz większej ilości poważnych pojektów. W Polsce cisza jak makiem zasiał.

  #7 06.09.2014 14:13

@mikolaj_s: To co mówisz to akademickie fantazje. Już dawno udowodniono, że Vector jest wydajniejszy w wielu przypadkach mimo teoretyzowania. Wszystko za sprawą tego, że lepiej współpracuje z Cache procesora. Oczywiście o ile trzymasz w nim rzeczywiste dane jednego typu a nie wskaźniki. Bo one zabijają każde rozwiązanie.

Co do bebechów List, to sam napisałeś, że jest niemutowalne. Jakby było pod spodem listą jednokierunkową, to by było jak najbardziej.

mikolaj_s   13 #8 06.09.2014 15:28

@sprae (niezalogowany): W wielu nie znaczy wszystkich. Akurat w sposobie w jaki korzysta się w kolekcji lista sprawdza się bardzo często dobrze.

"Jakby było pod spodem listą jednokierunkową, to by było jak najbardziej."
Nie bardzo rozumiem co ma kierunkowość listy do mutowalności?

@@grapeli23 Go jest raczej takim C na sterydach. Do dzisiaj nie dorobiło się generics. Osobiście mi się nie podoba. Lepiej już wygląda Dart.

grapeli23   5 #9 06.09.2014 15:51

Mało prawdopodobne jest wprowadzenie w Go generyków. To język ukierunkowany na programistów bardziej zaawansowanych, a nie na...

http://research.swtch.com/generic
"The generic dilemma is this: do you want slow programmers, slow compilers and bloated binaries, or slow execution times?"

kostek135   8 #10 06.09.2014 16:30

grapeli23: To co tam piszą to teoretyzowanie na zasadzie znalazłem jednego kulawego na 1000, więc zakładam, że wszyscy są kulawi.

Generics są wymazywane przy kompilacji. Jedyny use-case spowalniający to box/unbox wrapperów typów prymitywnych. Tylko po pierwsze 99% przypadków wygląda tak, że kolekcja nie zawiera Integer, tylko jakiś CustomObject i boxing tego nie dotyczy. Po drugie ich przykład z wektorem bajtów jest tak bardzo z dupy, że nie da się tego opisać. Do takich operacji służy klasa ByteArrayOutputStream. Pod spodem trzymana jest tablica bajtów, która się rozszerza jak zajdzie potrzeba.

To jest takie szukanie dziury, tam gdzie jej nie ma. Gdyby była sytuacja odwrotna (Java nie miała generics, a Go miało), to dorobiłoby się inną teorię, np. Oracle jest leniwy i nie umie zaimplementować.

Autor edytował komentarz.
  #11 06.09.2014 19:20

Bardzo dużo niespójności w tym języku. W takim stanie raczej długo nie pociągnie. No, chyba, że chce podbić serca starych programistów C++.
Na chwilę obecną nie wygląda na to by Scala miała jakąkolwiek przyszłość. Już nie wspomnę o częstym zrywaniu kompatybilności, przez co w jednym projekcie potrafią znaleźć się trzy czy cztery kompilatory Scali dla kilku bibliotek, których poprzednia ekipa nie zdążyła przeportować, a dla nowej nie ma czasu i pieniędzy.

Jeżeli ktoś szuka stabilnego języka niech wybierze Java 8 lub Clojure. Ten pierwszy jest wspierany przez Oracle, a drugi rozszerza ficzery przez biblioteki (bo to Lisp), a nie kolejne niekompatybilne wstecz wersje. Wiele projektów aktualizowanych z Clojure 1.3 (staroć) do 1.6 po prostu działa - co jest nie do pomyślenia w przypadku Scala. Biznesowo Scala wypada bardzo blado.

mikolaj_s   13 #12 07.09.2014 09:15

@Frankfurterium: Bibliotek w Scali jest sporo, a zawsze można jeszcze korzystać z Javowych. Sama Akka i przejrzystość jej składni może być wystarczającym powodem do użycia Scali. Co do Lifta to sam go używam i jest rewelacyjny, chociaż wiele osób używa innych frameworków ze względu na fakt że jest mocno rozbudowany i ma spory próg wejścia. To taki Rails Scali. Ale tych innych frameworków jest masa.

Co do używania Scali to jest bardzo dużo firm które piszą części swoich projektów w Scali. Dobierają odpowiednie narzędzie do zadania. Również w Polsce jest sporo takich firm. Ze znanych mi przypadków w Gdańsku scalac.io pisze tylko w Scali, Kainos ma projekt. IBM w Krakowie też coś pisze w Lifcie, w Warszawie GMoney Bank używa Scali. A niedawno jakaś pani chciała mnie zatrudnić do firmy w Łodzi liczącej 900 osób chcącej rozpocząć projekt w Scali.

" . A gdybym ja podszedł do szefa i zaproponował wykonanie następnego projektu w Scali, wyśmiałby mnie albo odesłał do domu.”

Każdy by tak zrobił gdybyś nie uzasadnił wystarczająco że w danym projekcie się to opłaci i nie miał ludzi którzy to zrobią. Mało który pracodawca będzie czekać na nauczenie się nowego języka. Czas to pieniądz. A jednak czasami ma to sens.


Nie uważam, że jakikolwiek język zastąpi Javę. Programowanie funkcyjne nie przebiło się do mainstreamu tyle lat, że widocznie dla większości nie jest wygodne. Za to jak już ma się odpowiednią kadrę to w niektórych zastosowaniach jest to świetne narzędzie.

mikolaj_s   13 #13 07.09.2014 09:45

@grapeli23: Tak wiem prawdziwi programiści piszą wszystko sami od podstaw. Ale oni używają assemblera ;)

@Anonim "Bardzo dużo niespójności w tym języku. W takim stanie raczej długo nie pociągnie."


Ale gdzie te niespójności? To o czym wspomniałem w kursie po krótkim czasie używania staje oczywiste i sensowne. Sama metoda take(2) jest intuicyjna. Weź dwa elementy resztę porzuć. Dlaczego mianoby liczyć od zera?

”Jeżeli ktoś szuka stabilnego języka niech wybierze Java 8 lub Clojure."

Java pewnie zawsze będzie głównym językiem, chociaż jak tak dalej będą dokładać nowe elementy nie zrywając z przeszłością to postanie drugie C++.
Clojure to zupełnie inna klasa Lisp na JVM. Nie sądzę tak odmienna skladnia zachęciła więcej. osób. Poza tym daleko mu do tego aby mieć tyle bibliotek i dojrzałości co Scala. Gdybym miał wybrać inny język niż Java i Scala szybciej wybrałbym Groovie.

aeroflyluby   14 #14 07.09.2014 11:11

Scala - potrzeba aż trzech części poradnika 'pierwsze kroki'.

cyryllo   16 #15 07.09.2014 11:36

Nie no ale sami maruderzy. Każdy programuje w tym co lubi i co jest dobre do jego projektu. Fajnie napisane trzy kursy! Nie ma to jak wojenki typu ten język jest lepszy od tego bo.... normalnie fanatycy :P Ja wolę pisać alfabetem morsa a scala ssie :P

Frankfurterium   9 #16 07.09.2014 11:56

cyryllo: Z tego, co pamiętam, blog to nie siedzisko troskliwych misiów, ale między innymi miejsce do komentowania zamieszczanych wpisów. Pewnie, zdarzają się ludzie chcący zwyczajnie dowalić autorowi, ale postawa "Napisz, że się nie zgadzasz, to wyzwę cię od trolla albo fanatyka" też nieszczególnie służy budowaniu dyskusji i/lub dzieleniu się opiniami.

cyryllo   16 #17 07.09.2014 13:58

@Frankfurterium: czy nazwałem kogoś trollem? Nie.

Frankfurterium   9 #18 07.09.2014 14:18

A fanatykiem?

mikolaj_s   13 #19 07.09.2014 20:10

@aeroflyluby: Będzie jeszcze więcej. Nie każdy jest tak zdolny jak podejrzewam jesteś Ty, że nauczy się nowego języka z jednego artykułu ;)
Poczytaj sobie, nie musisz w tym programować. Znajomość podstaw różnych języków jest bardzo rozwijająca. Każdy programista powinien znać więcej języków, a nie tylko ten w którym pisze. Jeśli nie znasz więcej języków to skąd wiesz czy wybrałeś dobrze? Podejrzewam też, że spojrzenie na rozwiązania w Scali może pomóc w zrozumieniu nowych elementów funkcyjnych w Javie 8.

Poza tym co to za moda obecnie panuje dzisiaj, że język musi być tak prosty, żeby nauczyć się go w 3 dni? Czy taki prosty język będzie wystarczająco ekspresyjny? Najbardziej smakują osiągnięcia, które zdobywa się z trudem. ;) A w przypadku Scali najlepsze, że po poznaniu na jako takim poziomie języka można tworzyć szybciej oprogramowanie, które w innych językach wymaga dużo więcej pracy i wysiłku. Po prostu moim zdaniem nauka i początkowy wysiłek zwraca się z zyskiem. Zobacz na Clojure jeśli uważasz, że Scala jest trudna.

  #20 07.09.2014 21:57

@mikolaj_s:
Akurat Clojure w porównaniu do Scali jest prosty jak cep. Wszystko działa prawie że intuicyjnie, a nie jak w Scala, że na jednej kolekcji z Java jedna funkcja działa a na drugiej już nie. Przez co w praktyce kod pisany w Scala nie różni się niczym od Java a dodatkowo jest zaciemniony przez dziwne skróty składniowe, których nie ma w Java, co powoduje, że człowiek po chwili zastanawia się dlaczego od razu tego nie pisał w Java lub innym języku i że Scala to syf, bo dodatkowo kompilacja jest nieakceptowalnie długa.

Wiele osób (w tym ja) uważa, że po wprowadzeniu Java 8 Scala tak na prawdę mało co oferuje, a dodatkowo komplikuje kod. Co tak naprawdę oferuje Scala? Czy posiada STM (pamięć transakcyjna znana z Clojure)? Nie. Czy posiada niemutowalne trwałe kolekcje (znane z Clojure)? Nie. Czy posiada możliwość zmiany lub dodania ficzerów za pomocą biblioteki bez zrywania kompatybilności wstecznej (jak to robi Clojure)? Nie. I tak mogę wymieniać dalej...

Co takiego jest w Scali oprócz niezdrowego i tego nieuzasadnionego hype rozsiewanego przez programistów C++ jakby złapali jakiegoś bożka za nogi?

Nie chcę tu być niemiły, ale zamiast niezdrowej fascynacji Scalą radzę się zająć Java 8, a dla ambitnych polecam Clojure lub Frege.

Tutaj daję świetny przykład jak inne języki (w tym Scala) bledną przy Java 8: http://aruld.info/why-java-8-will-be-a-top-contender-for-java-next-languages/

cyryllo   16 #21 07.09.2014 22:39
mikolaj_s   13 #22 08.09.2014 09:09

@Anonim (niezalogowany): "Akurat Clojure w porównaniu do Scali jest prosty jak cep."

Sam w to wierzysz? Clojure jest całkiem fajny, ale zupełnie odmienny do języków pochodzących do C. Jeśli na co dzień daję radę pisać równocześnie w JavaScript i Scali, a jak mam potrzebę to i w C++ to nie byłbym w stanie przestawiać się na Clojure. Po prostu filozofia tego języka jest odmienna, choć warto się z nim zaznajomić, chociażby dla rozwoju osobistego.

"Wszystko działa prawie że intuicyjnie, a nie jak w Scala, że na jednej kolekcji z Java jedna funkcja działa a na drugiej już nie."

Kolekcje z Javy konwertuje się do tych ze Scali, jest do tego prosta w użyciu biblioteka. Wtedy nie martwisz się o kompatybilność.

" Scala to syf, bo dodatkowo kompilacja jest nieakceptowalnie długa. "

Czas kompilacji jest niewiele dłuższy od Javy, do tego korzystam z kompilacji przyrostowej. Kompiluje mi tylko te części, które się zmieniły. Trwa to bardzo krótko.

"Wiele osób (w tym ja) uważa, że po wprowadzeniu Java 8 Scala tak na prawdę mało co oferuje, a dodatkowo komplikuje kod."

Masz prawo tak powiedzieć bo nie znasz Scali. Dużo jeszcze jest do zrobienia w Javie, żeby choć trochę zbliżyła się do Scali. Dodanie funkcji anonimowych i przetwarzania kolekcji w stylu funkcyjnym to tylko fajny dodatek. Nie zmieni to większości rozwlekłej składni, chociaż pozwoli się trochę zbliżyć do tego co oferuje Scala.

"Czy posiada niemutowalne trwałe kolekcje (znane z Clojure)? "

Nawet nie przeczytałeś treści mojego kursu, ale się wypowiadasz ;)

"Co takiego jest w Scali oprócz niezdrowego i tego nieuzasadnionego hype rozsiewanego przez programistów C++ jakby złapali jakiegoś bożka za nogi? "

Co ma wspólnego Scala z C++? Jakaś teoria spiskowa? Masz ogólnie jakiś problem ze Scalą? Nie chcesz nie używaj, nie czytaj, omijaj szerokim łukiem. ;)

"ale zamiast niezdrowej fascynacji Scalą radzę się zająć Java 8,"

Jedno drugiemu akurat nie przeszkadza. A nawet więcej część nowych elementów wyglądaj jakby była prawie żywcem wyjęta ze Scali.

"Tutaj daję świetny przykład jak inne języki (w tym Scala) bledną przy Java 8"

I co w tym przykładzie takiego nadzwyczajnego. Składnia kodu w Java 8 wygląda jakby skopiowali ją ze Scali. Zamienili tylko znaczek => na -> i nie umożliwiają skracania nazwy zmiennych za pomocą znaku _. W Scali jest nawet prościej chociażby z powodu użycia metody capitalize, tylko w przykładzie bezpodstawnie użyto metody reduce skoro wystarczyło wywołać mkString(", "). Do tego w Javie musimy kolekcję zamienić w stream.
Same przetwarzanie kolekcji wielowątkowo jest równie proste w Scali wystarczy użyć metody par. To bardzo fajnie, że wprowadzili podobne rozwiązania w Javie, ale do paradygmatu funkcyjnego jeszcze daleka droga. Rzucasz słowa bez pokrycia.

aeroflyluby   14 #23 08.09.2014 10:26

@mikolaj_s: Uczę się haskella żeby się rozwijać.

mikolaj_s   13 #24 08.09.2014 10:56

@aeroflyluby: To świetnie, bardzo fajny język. I co wystarczył Ci do nauczenia się go jeden artykuł? ;)

aeroflyluby   14 #25 08.09.2014 11:07

@mikolaj_s: Na szczęście nie, czytam na jego temat książkę, więc nie wiem jak to przekłada się na artykuły, ale same podstawy języka są dosyć trudne i odmienne.

mikolaj_s   13 #26 08.09.2014 12:34

@aeroflyluby: Dla kogoś kto używał tylko języków z rodziny C przejście na język funkcyjny wymaga trochę wysiłku. Scala pod tym względem i tak jest bardzo łaskawa ;)

  #27 08.09.2014 12:36

@mikolaj_s:

No właśnie. Skoro Java 8 wygląda jak Scala, to ki grzyb używać Scali?
Poza tym od kiedy Scala posiada prawdziwie trwałe (persistent) kolekcje? Słyszałem, że jest plan by zerżnąć je z Clojure, ale wątpię czy to już ruszyło.

Ostatnio Scala tylko zrzyna i nie widać nic, co sugerowałoby, że wyjdzie na prowadzenie w jakiejś dziedzinie. Typowy C++. Osobiście radzę unikać Scali.

Poza tym, czego ktoś ma się nauczyć nowego ze Scali skoro sama Scala, Java , C++ i inne podobne jadą na składni C a różnią je tylko skróty składniowe, które za każdym razem trzeba kuć na blachę?

Scala to już przeżytek. Szkoda, że ludzie zachwycają się nią dopiero w momencie, kiedy inne języki ją dawno przegoniły lub odrobiły lekcje - jak Java 8. Poza tym jaki jest sens nauki kolejnego języka C-podobnego? Poszerza horyzonty? Absolutnie nie, bo to wciąż świat zamknięty w klamry i wykonanie imperatywne linijka po linijce.

Ciekawi mnie co takiego Scala musi dziś zerżnąć, by nadrobić to, co sama wypracowała jeszcze kilka lat temu. A, że nie przychodzi mi nic do głowy, bo albo musiałaby stać się Lispem, albo Haskellem czy innym bo składnia C ją wyraźnie dziś ogranicza.

mikolaj_s   13 #28 08.09.2014 16:13

@Anonim (niezalogowany): "Skoro Java 8 wygląda jak Scala, to ki grzyb używać Scali"

Wprowadzenie lambd i przetwarzania danych w łańcuchowo to jeszcze nie programowanie funkcyjne. To tylko wierzchołek góry lodowej. Skoro twierdzisz, że znasz Clojure to dziwne, że tego nie wiesz. Żebyś chociaż potrafił wymienić prawdziwe zalety, które przemawiają za użyciem Javy, bo tych jest sporo, a tak piszesz byle pohejtować.

"Poza tym od kiedy Scala posiada prawdziwie trwałe (persistent) kolekcje? "
Ale chodzi ci o całkowicie trwałe, częściowo trwałe czy zbieżnie trwałe. Kolekcje mają wersje niemutowalne. Stan kolekcji przed zmianą możesz sobie zapamiętać w referencji i uzyskujesz całkowicie trwałą.

"wyjdzie na prowadzenie w jakiejś dziedzinie."
W tym właśnie siła Scali, że adoptuje najlepsze wzorce z innych języków jak chociażby Aktorów z Erlanga, czy Traits odpowiednik mixins z Rubiego. To wszystko daje w spójnej i znośnej składni.

"Osobiście radzę unikać Scali"

Dziękuję za radę EXPERTA, ale nie skorzystam ;) Każdy niech sam oceni język.

"Poza tym, czego ktoś ma się nauczyć nowego ze Scali ..."

Podobieństwo jest głównie w wyglądzie. Natomiast można nauczyć się pisać funkcyjne.

"wykonanie imperatywne linijka po linijce. "

Proponuje zobaczyć Akkę i dopiero potem się wypowiadać.

"bo składnia C ją wyraźnie dziś ogranicza."

Jakoś nie czuję się ograniczony, a wręcz przeciwnie. Jak chcesz Lispa czy Heskella to sięgnij po oryginał. Skoro do tej pory języki czysto funkcyjne nie stały się powszechne to i teraz pewnie się to nie stanie. Za to Scala nawiązując do tradycyjnej składni ma spore szanse zachęcić więcej osób do wejścia w świat funkcyjny. Może też być dobrym startem w ten świat. Twórca Lifta pisze równocześnie projekt w Heskellu, ale ciągle też używa Scali.

Nie podoba Ci się Scala to nie czytaj i przestań marudzić. Daj innym ocenić ją samodzielnie, a nie zgrywasz eksperta.

Autor edytował komentarz.
  #29 08.09.2014 19:31

@mikolaj_s:

"Podobieństwo jest głównie w wyglądzie. Natomiast można nauczyć się pisać funkcyjne. "

Nauka programowania funkcyjnego w Scali jest analogiczna do nauki pływania w wannie. Nikt mi nie wmówi, że umie programować funkcyjnie jeżeli nie liznął Lispa, Haskella czy innego funkcyjnego języka (akurat Lisp może być wszystkim, bo to prawie czyste AST - w HAskellu działa się na AST w momencie uzycia Template Haskella, ale nie twierdzę, że Haskell to coś cudownego, owszem ciekawy, ale ciągnie za sobą błędy języków imperatywnych).


" Skoro do tej pory języki czysto funkcyjne nie stały się powszechne to i teraz pewnie się to nie stanie."

Nikt nie powiedział, że tak być musi, ale doświadczenie dowodzi, że droga C++ także nie jest zbyt szczęśliwa.

"Daj innym ocenić ją samodzielnie, a nie zgrywasz eksperta."

Jak ktoś ma sobie wyrobić o czymś zdanie skoro ma podany tylko jeden punkt widzenia? Ja piszę jak jest. To nie są moje opinie tylko z pierwszej ręki dane o tym skąd Scala się wzięła i dokąd zmierza. Nie jest to optymistyczny obrazek, przyznaję, ale taki sobie twórcy Scali obrali cel i trudno, sorry ale taki jest tam klimat. Wystarczy czytać newsy z Ycombinatora i odpowiednie działy z reddita.

Skoro przywołałeś Akkę, to przypomnę, że tam, gdzie potrzebna jest masowa skalowalność nie używa się Akka ani innego wynalazku na JVM tylko ... Erlanga.
Akka to zabawka. No, może od biedy dla kogoś kto siedzi w Java i nie umie nic innego, ale to sporadyczne przypadki, które szybko weryfikuje rzeczywistość w postaci kopa w 4 litery.

"W tym właśnie siła Scali, że adoptuje najlepsze wzorce z innych języków jak chociażby Aktorów z Erlanga, czy Traits odpowiednik mixins z Rubiego. To wszystko daje w spójnej i znośnej składni. "

Co z tego, skoro całość działa bardzo biednie?


"Dziękuję za radę EXPERTA, ale nie skorzystam ;) Każdy niech sam oceni język. "
Nikt cię nie zmusza, ale w imię uczciwości dodałbym tu i ówdzie porównanie do innych języków, tak by dać ludziom choć cień szansy na tę opinię. Takie jednostronne porównywania cechują tylko makreterów Microsoftu.

" Żebyś chociaż potrafił wymienić prawdziwe zalety, które przemawiają za użyciem Javy, bo tych jest sporo, a tak piszesz byle pohejtować. "
To ty piszesz blogi. Nie ja. Nie muszę się wysilać.

PS. Radzę porzucić to małostkowe myślenie w polskich kategoriach i wziąć przykład z amerykańców, których cechuje dość widocznie wola eksploracji nowego. Ty pisząc o Scali tak naprawdę piszesz o Fiacie 126p, kiedy wszyscy są już w salonie Peugeot.

Ostatnio słyszę, że Scala zdobywa szturmem polskie firmy. Nie wiem czy śmiać się czy płakać. Nie po to ktoś wymyślił w latach 90 Java by dziś znów wracać do C++. C++ którego wszelkie cechy posiada Scala: kulawą bibliotekę standardową i niedopracowane kolekcje (lekko powiedziane), przeładowaną składnię, nic nie mówiące błędy typów na kilka ekranów, pierdyliard kompilatorów do różnych wersji, przez co nawet flagowa Akka jest kilku wersjach i nie wiadomo czego używać na przyszłość, itd...

  #30 08.09.2014 21:42

Ten kod woła o pomstę do nieba:

--
val powitanieNapisy = new Array[String](3)
powitanieNapisy(0) = "Witaj"
powitanieNapisy(1) = "w świecie"
powitanieNapisy(2) = "programowania!"

println(powitanieNapisy.mkString(" "))
--

Co to za kulfon? Co to za postawianie do elementów na sztywnych indeksach?

Nie lepiej użyć starej Javy?:

helloStr = String.join(" ", Arrays.asList("Witaj", "w świecie", "programowania!"));
System.out.println(helloStr);

albo:

helloStr = Arrays.asList("Witaj", "w świecie", "programowania!")
.stream().collect(Collectors.joining(" "));
System.out.println(helloStr);


Myślałem, że w Scala programuje się funkcyjnie.

Taki kod jak na tym blogu to najlepszy przykład dlaczego nie powinno się uczyć dzieci języków takich jak C++, bo wchodzi taki do Scali czy innego w miarę nowego języka i nie pisze w nim poprawnie tylko dalej płodzi w C++.

Już wiem dlaczego tak psioczysz na Lispa i Haskella. Tam, by programować w jak w C++ trzeba się nieźle napocić.

I dlaczego piszesz o mutowalnych kolekcjach, skoro świat już od nich odchodzi?

Słowo daję. Z polskimi programistami jest jak z Helionem. 10 lat za resztą cywilizowanego świata.

Na koniec:

(println (clojure.string/join " " ["Witaj" "w świecie" "programowania!"]))

albo:

(->> ["Witaj" "w świecie" "programowania!"] (clojure.string/join " ") println)

Czy to takie trudne? Myślę, że dla kogoś, kto zabiera się za taki śmietnik jak Scala raczej nie.

mikolaj_s   13 #31 08.09.2014 22:58

@Anonim (niezalogowany): "Nikt mi nie wmówi, że umie programować funkcyjnie jeżeli nie liznął Lispa, Haskella czy innego funkcyjnego języka"

Przypomina mi to fanatyzm religijny. Jedyna prawdziwa religia, jedyny prawdziwy język funkcyjny. Zamiast bawić się w religię warto sprawdzić coś w praktyce.

"Jak ktoś ma sobie wyrobić o czymś zdanie skoro ma podany tylko jeden punkt widzenia? Ja piszę jak jest. "

No i do tego jesteś megalomanem. Oczywiście Ty wiesz jak jest i Twoje zdanie jest prawdą i objawieniem. ;) Podobnie widzę traktujesz C++. Też nie przepadam za tym językiem, ale doceniam jego użyteczność.

"Nikt cię nie zmusza, ale w imię uczciwości dodałbym tu i ówdzie porównanie do innych języków"

Raczej celuję w osoby, które chcą go poznać, a znają już jakiś inny język. Stąd wolę przedstawiać fakty jaki ten język jest, a nie rozwodzić się nad mało użyteczne porównania. Porównywanie do innych języków ma też problem, że podobnie jak podałeś w linku dwa posty wyżej facet porównywał inne języki do Javy 8, nie znając ewidentnie niektórych z nich lepiej. Jaką wartość ma to porównanie?

"Co z tego, skoro całość działa bardzo biednie? "

Napisałeś coś większego panie Ekspercie?

"Takie jednostronne porównywania cechują tylko makreterów Microsoftu. "

Porównanie wymaga co najmniej dwóch języków. Ja przedstawiam jeden. Każdy może sobie sprawdzić jak wyglądają inne. Opisując język i jego działanie nigdzie nie prowadzę propagandy. Ocenę zostawiam czytelnikowi. Twoją już usłyszałem, daj szansę teraz innym ;)

"Wystarczy czytać newsy z Ycombinatora i odpowiednie działy z reddita. "

Poszukaj lepiej. Nie widziałem jeszcze, żeby nie pisali negatywnie o jakimś języku. Są różni ludzie i różne gusta. Poza tym jeśli Twoja wiedza wiedza wynika tylko z przeczytania wybiórczych artykułów to w jaki sposób Twój głos ma być obiektywny i znaczący?

"Skoro przywołałeś Akkę, to przypomnę, że tam, gdzie potrzebna jest masowa skalowalność nie używa się Akka ani innego wynalazku na JVM tylko ... Erlanga. "

Bzdury wypisujesz. Mnóstwo projektów nie tylko Scalowych korzysta z Akki, bo można pisać również w Javie, choć Scala w tym przypadku jest wygodniejsza. Erlang ciągle ma i będzie mieć sporo projektów, bo sam model Aktorów jest bardzo dobry w pisaniu aplikacji wielowątkowych. Nikt nagle nie przerzuci projektów na inny język, nawet dla świetnej JVM.

"Ten kod woła o pomstę do nieba: "

To był tylko przykład, że są takie kolekcje i można je używać podobnie jak w Javie. Chyba nie jesteś na tyle ograniczony, aby nie rozumieć, że ten kod wcale nie ma zamiaru wypisać Stringa bo są na to znacznie lepsze sposoby. To tylko przykład, że tak można. W Scali można pisać nie funkcyjnie i dlatego jest dobra dla kogoś kto chce od razu pisać coś sensownego i z czasem uczyć się pisać w stylu funkcyjnym.

"Już wiem dlaczego tak psioczysz na Lispa i Haskella. "

Masz duża wyobraźnię i sobie dodajesz teksy do tego co ja piszę. Pokaż, mi gdzie psioczę na te języki. Napisałem tylko, że dla mnie ich składnia jest zbyt odmienna. Być może gdybym nie musiał używać innych języków z rodziny C to pewnie chętniej bym się do nich przekonał. A tak w Scali jest mi wygodniej pisać.

"Czy to takie trudne? Myślę, że dla kogoś, kto zabiera się za taki śmietnik jak Scala raczej nie."

To napisz sam o tym bloga. Dla mnie używanie odwrotnej notacji polskiej raczej nie jest wygodne. Każdy niech decyduje za siebie. I obiecuję, że jak napiszesz własne artykuły o tych językach to nie napiszę nawet jednego złego słowa. ;)

"To ty piszesz blogi. Nie ja. Nie muszę się wysilać. "

Ale nie muszę Ci odpowiadać, skoro posuwasz się tylko do hejtu, bez sensownych merytorycznych argumentów. Dobrze, że się przynajmniej do tego przyznajesz. I na tym zakończę dyskusję, która do niczego nie prowadzi.

Autor edytował komentarz.
  #32 08.09.2014 23:18

@mikolaj_s: Ja bym olał tego anon-a, bo mam duże podejrzenie, że to nie jaki @RaveStar. Był sobie tu swego czasu głosząc kolejny rok Clojure i tego typu brednie. Po pewnym czasie zrobił się taką miejską legendą, każdy traktował go z pobłażaniem, nie wiem czy zrezygnował, czy dostał bana. Jednak widać, że wrócił. Próbowałem wygooglać jego posty, by poddać je analizie na podobieństwo, nie mniej chyba wszystkie ślady zostały zatarte. Przykład: http://www.dobreprogramy.pl/Microsoft-przewiduje-sukces-Windows-Phone-w-Chinach,... Wystarczy poszukać po "RaveStar". Nie jest możliwym, by tyle ludzi go tagowało, a nie ma w komentarzach ani jednego jego postu.

Wnioski są dość podobne, czyli:

1. Funkcyjność uber alles, w tym Clojure jako wyzwoliciel nas ciemiężonych przez obiektowe języki.

2. Brać przykład z "Amerykańców" (dokładnie identyczne sformułowanie) na temat języków funkcyjnych.

Jak widać przyjął inną strategię, bo gdyby podpisał się nikiem to szybko skojarzono by go z tym bzdurami i znowu zaczęto olewać. Moja rada, jeśli jakiś anonim tylko zaczyna pisać funkcyjny, lisp, clojure, nalezy to ignorować - nie karmić.

Jego po prostu nie dało się inaczej pozbyć, jego celem jest mieć ostatni post, dyskusja może trwać do kilku tygodni.

Prosiłbym o przeklejenie tego co napisałem pod każdy wpis, w którym ktoś zaczyna go karmić.

BTW. Rave, jak tam leci, kope lat ;)

mikolaj_s   13 #33 09.09.2014 07:39

@Anonim (niezalogowany): Mi to zajęło sporo komentarzy, żeby zorientować, że to troll. Ale z RaveStarem nie skojarzyłem ;)

  #34 09.09.2014 19:16

Kod imperatywny w języku, który pretenduje do funkcyjnego. ;)
Jak widać blogi przyjmują wszystko jak papier.

@up anon.

Czytałem ten post i niczego tam nie ma. Co ten ravestar takiego nabroił? WP to plankton dziś i kupa śmiechu. Ma chłop rację i tyle.

A ty, panie mikolaj, zamiast mędrkować radzę poczytaj po co tworzy się nowe języki programowania, a potem wróć i przeczytaj swój blog.

  #35 11.09.2014 22:03

Niezły wpis, tylko szkoda, że kierowany do dziadków i to już tych ostatnich z żyjących.