Scala i bezpieczny "duck typing"

Opublikowane przez Jarosław Zabiełło Sat, 23 Jan 2010 06:40:00 GMT

Duck typing (opisywany przeze mnie wcześniej na przykładzie Pythona) to dosyć użyteczna technika popularna w językach dynamicznie typowanych. W typowym języku statycznie typowanym, takim jak Java, nie da się jej stosować. Ale ograniczeniem nie jest statyczne typowanie, lecz to że Java, jako język, jest po prostu słaba. W statycznie typowanej Scali “duck typing” to żaden problem. Mało tego. Fakt, że Scala jest statycznie typowana daje jej tu dodatkową przewagę na językami dynamicznie typowanymi.

Duck typing w języku dynamicznie typowanym ma pewne wady od których Scala jest wolna. Wpierw przykład dla języka Ruby:

class Kaczka
  def kwacz
    puts "kwa kwa" 
   end
end   

class Slowik
  def kwacz
    puts "fiu fiu" 
  end
end

class Kot
  def miau
    puts "miau miau" 
  end
end

def kwacz_kaczuszko(k)        
  k.kwacz
end

kwacz_kaczuszko(Kaczka.new) # => kwa kwa
kwacz_kaczuszko(Slowik.new) # => fiu fiu
kwacz_kaczuszko(Kot.new) 
# => NoMethodError: undefined method ‘kwacz’ for #<Kot:0x000001010195d8>

Błędy tego typu są trudne do wyłapania w językach dynamicznie typowanych, bo o ich wystąpieniu można się dowiedzieć dopiero w trakcie działania programu. I jeśli taki fragment kodu jest wykonywany rzadko, to trudno powiedzieć kiedy zostanie wychwycony. Jedynym sposobem aby tak błąd odpowiednio wcześniej wyłapać jest pisanie dodatkowych testów jednostkowych.

Co prawda, powyższy kod można co prawda lekko zmodyfikować (bo Ruby pozwala na ładne odpytanie obiektu, czy jest w stanie wywołać daną metodę)

def kwacz_kaczuszko(k)        
  if k.respond_to? :kwacz      
    k.kwacz                
  else
    puts "ja nie kwaczę!" 
  end
end

kwacz_kaczuszko(Kot.new) # => ja nie kwaczę!

Tylko czy to coś zmienia? Zamiast pisać dodatkową obsługę takiego błędu, nie lepiej go po prostu nie mieć?

Scala takie błędy wyłapuje już na etapie kompilacji. Tym samym gwarantuje (statycznie) że do kodu nic takiego się nie prześliznie. Można powiedzieć, że Scala obsługuje “duck typing” w sposób bezpieczny, prawidłowy. Odpada pisanie testów jednostkowych i obsługiwanie takich błędów bo w Scali one nigdy się nie pojawią!

class Kaczka {
  def kwacz {
    println("kwa kwa")
   }
}

class Slowik {
  def kwacz {
    println("fiu fiu")
   }  
}

class Kot {
  def miaucz {
    println("miau miau")
  }
}                     

def kwacz_kaczuszko(k : {def kwacz}) {
  k.kwacz
}

kwacz_kaczuszko(new Kaczka) 
kwacz_kaczuszko(new Slowik)
kwacz_kaczuszko(new Kot)

/*
(fragment of przyklad.scala):25: error: type mismatch;
 found   : this.Kot
 required: AnyRef{def kwacz: Unit}
kwacz_kaczuszko(new Kot)
                 ^
one error found

!!!
*/

Tagi , ,  | 37 comments

Comments

  1. Avatar Chyba Cię pogło ;P powiedział about 4 hours later:

    Kiedy wreszcie zrozumiesz, że dobry język to nie jest język, do którego nawpierdalano wszystkich możliwych ficzerów?

    Jestem fanem Javy (a od jakiegoś czasu i Rubiego). Z początku byłem sceptycznie nastawiony do Rubiego, bo denerwowało mnie to, że niektóre rzeczy można robić na kilka sposobów (nadużywanie aliasów też mnie wkurzało) i chociaż nadal nie rozumiem tej manii aliasowania, to uważam, że chociaż ma 2 składnie na tworzenie domknięć, 2 na tworzenie Hasha itd, to jednak Ruby ma pomysł na siebie i nie wrzuca wszystkiego co się jeszcze da (np. parametrów nazwanych).

    Java jest świetnym językiem. Prostym, jednoznacznym – widzę coś w kodzie i od razu wiem co to znaczy, a nie tak jak w innych językach wszystko poprzeładowywane, np. w Rubym przeginają z przeładowywaniem operatorów ;P

    Jedyne co mogłoby być lepsze w Javie, to typy generyczne (powinny nie być wymazywane) – ale powodem tego jest kompatybilność wstecz, które też jest dobra.

    Myślisz, że programiści z Sun-a nie potrafią napisać takich śmiesznych ficzerów jakie ma Scala?

    Ta Scala to taki troszkę lepszy C# – ale to niby język funkcjonalny więc wszyscy muszą ohać i ahać bo nie wypada nic mówić xD

  2. Avatar Jarosław Zabiełło powiedział about 4 hours later:

    Java nie jest nawet językiem w pełni obiektowym. Aby móc porównywać języki programowania trzeba znać najpotężniejszy z nich, a ty co znasz? :) Polecam doskonałą prezentację Are we there yet? oraz obowiązkowo esej Paula Grahama Beating the Averages – otwierają umysł.

  3. Avatar zuber powiedział about 4 hours later:

    A czy kompilator Scala wykrywa już błędy logiczne? Bo, jeśli nie, to nadal trzeba pisać testy jednostkowe.

  4. Avatar Jarosław Zabiełło powiedział about 4 hours later:

    zuber: nigdzie nie twierdzę, że nie należy pisać testów jednostkowych. Twierdzę tylko, że dzięki statycznemu typowaniu trzeba ich pisać mniej. A kolega (koleżanka?), co napisał wyżej, że “java to świetny język” bredzi, bo nie wie o czym pisze. W następnym tekście dostanie się interfejsom…

  5. Avatar Chyba Cię pogło ;P powiedział about 5 hours later:

    Rozumiem, że znasz się bardziej na Scali, więc mam pytanie wolne od wszelkich docinków. Nie ma w tym języku statyczności, a jest za to: object SomeClass { }

    czy jest to jakoś ładnie połączone z metaprogramowaniem (jak jest to zrobione w Rubym)? Mogę tego obiektu teraz jakoś elegancko odpytywać o metody itd?

  6. Avatar Marek Dominiak powiedział about 6 hours later:

    Problem z Javą jest taki że gdy była wersja 1.4 i był pomysł aby dodać typy generyczne, i ze względu na wsteczną kompatybilność musieli je spaprać … One są do kitu :-) W .NET nie mieli tego problemu – mieli mniej wdrożeń więc pozwolili sobie na wsteczną niekompatybilność i dzięki temu mają tam normalne typy generyczne.

    Java już jest w użyciu od 95 roku i teraz ciężko wrzucić im jakieś udogodnienia dla developerów, chociaż w javie 7 mają być dodane proste closures .

    Zaletą javy jest jej prostota, język nie utrudnia czytania kodu, oczywiście dotyczy też to scali czy ruby’ego jeśli programista nie będzie mieć celu napisać to najkrócej i najciemniej jak się tylko da ;-)

    Jest dużo rzeczy w javie które mi nie pasują:

    - interfejsy (wole traitsy :-), - MIXINS (chociaż powstał framework http://www.qi4j.org/ w którym można robić MIXIN-y, to i tak wolę mięć to na poziomie możliwości samego języka) - wkurza mnie ciągłe pisanie nazwy typu gdzie to jest oczywiste - brak closures - niezrozumiałe typy generyczne - pewnie wiele więcej

    Podoba mi się podejście w scali że programiści sami zdecydują które feature’y będą w bibliotece standardowej po pewnym czasie – (biblioteki wyglądają jakby były wbudowane w składnię języka) niż wrzucanie durnych feature’ów do składni języka…

    Siłą javy są jej frameworki – Spring, Hibernate, EJB, Seam i 1000 innych :-)

    Jeśli miałbym wybór w pracy wolałbym pisać w scali – zresztą do małych problemów pewnie będę próbować.

  7. Avatar Jarosław Zabiełło powiedział about 6 hours later:

    Do odpytywania obiektu o metody w Scali używa się tego samego mechanizmu co w Javie – refleksji. Zaimplementować znane w Ruby .methods w Scali jest proste. Co do samej znajomości Scali, to wypada wpierw zapoznać się z podstawami, a potem dopiero krytykować. Nie wiem czy czytałeś mój wcześniejszy tekst o Scali. Polecam też świetną serię artykułów o Scali napisanych dla programistów Javy: Roundup: Scala for Java Refugees.

    Frameworki Javy to bardziej frameworki JVM, więc są dostępne tak samo dla Javy jak i dla Scali, czy Clojure. Nic nie stoi na przeszkodzie aby użyć Wicketa w Scali (choć na pewno bardziej naturalne byłoby użyć Lifta)

    Tak w ogóle, to komentarze w blogu niezbyt się nadają do dyskusji. Zapraszam zatem na nasz polski kanał IRC’owy #scala.pl (dostępny też z poziomu zwykłej przeglądarki)

  8. Avatar :P powiedział about 8 hours later:

    Linki, które podałeś już widziałem xD Niestety mi Scala nie podchodzi. Ma dużo niepotrzebnych ficzerów, w dodatku brak im lekkości. Muszę przyznać, że na Scalowej refleksji się zawiodłem. Myślałem, że tutaj coś z Rubiego zostanie zaczerpnięte.

    Aczkolwiek statyczne języki mają w tym miejscu problem. Bo ciężko w nich zrobić elegancką refleksję, gdyż kilka metod może mieć tę samą nazwę :/

  9. Avatar lopex powiedział about 8 hours later:

    Jak można się zawieść na refleksji scali skoro ona nie ma własnego api do tego ? 20 Linijek z implicitami i możesz mieć nawet lepiej niż w ruby.

  10. Avatar ziom powiedział 1 day later:

    @P A które to ficzery scali są nie potrzebne według Ciebie?

  11. Avatar Jiima powiedział 2 days later:

    @JZ Trochę jesteś już męczący z tym “A Scala to to, a Java to tamto”. Tekst o generyczności scali brzmiałby dużo lepiej bez wynurzeń jak to w języku o wiele niższego poziomu jest gorzej. “Duck typing” to jedno, interfejsy to drugie. Rozwiązanie które podajesz jest czymś pośrednim (constraint, czyli coś jakby anonimowy interfejs który nie musi być explicite deklarowany). Nie pamiętam jednak czy Scala ma obsługę sygnału “method missing” czyli głównego piękna duck typing. Scalę z resztą nazwał bym raczej językiem pseudo-statycznie typowanym, właśnie ze względu na takie kwiatki jak ten constraint. Podobnie jest ze wspomnianym tu wcześniej C# 3.0 – odkąd wprowadzono w nim bezklasowe obiekty anonimowe i LINQ, oraz dynamiczne interfejsy (dla lepszej pracy z COM) język ten trudno nazwać statycznie typowanym (raczej “opcjonalnie statycznie typowanym” – tak jak FAN). Czy to źle, czy dobrze? Zależy od stylu programowania.

    Mnie w javie jedyne czego NAPRAWDĘ brakuje, to funkcji jako obiektów języka, lub chociaż namiastki tego takiej jak w .NET delegaty. No i sensownej składni – np podanie Klasa.nazwaFunkcji – (bez nawiasów) zwraca nam obiekt Function. No i po raz kolejny sensownej generyczności, ale to wiele razy powtarzano.

    Co do frameworków JVM jak ty to nazywasz, większość jednak ciężko sensownie użyć ze Scalą. Inne idiomy, inna logika programowania. Nie możesz łatwo np. ustawić funkcji scalowej jako listenera, musi istnieć jakaś warstwa pośrednia.

    Lift mi się nie podoba. Jest dziwaczny i ostatnio cicho na jego sajcie. Największą “zbrodnią” tego frameworka jest ciężkie wykorzystanie sesji – coś jak JSF i ASP.NET, ale one potrafią składować stan strony nie w sesji (pomijam czy jest to dobre rozwiązanie). Zrobienie lekkiego sajtu czy rozwiązań REST jest tu trudne. Co więcej nie da się tego replikować, a autorzy radośnie oświadczają, że replikacja sesji na serwerach J2EE w zasadzie nie działa, więc nie ma się czym martwić. Wyklucza to zastosowanie LIFTa w wielu miejscach, gdzie jednak trzeba pracować w klastrze.

    A co do interfejsów, rzeczywiście lepiej od deklarowania implementacji interfejsu powinna być możliwość przetestowania czy obiekt PASUJE do interfejsu i dynamicznie generować jakiś class cast exception. Tyle że coś za coś – takie podejście będzie prawdopodobnie wolniejsze w działaniu. No i gorzej się będzie pisać do tego narzędzia, takie jak IDE.

  12. Avatar Jarosław Zabiełło powiedział 2 days later:

    Jiima, wpadnij na #scala.pl to sobie wygodniej obgadamy kwestie jakie tu poruszyłeś. W ogóle, zanim ktoś coś większego napisze w komentarzu, niech lepiej wpadnie na nasz kanał IRC. Tak można szybciej wyjaśnić jakieś nieporozumienia.

  13. Avatar Jiima powiedział 3 days later:

    @JZ Może się pojawię, ale nie będę obiecywał. Mam mało czasu wolnego, a w robocie mamy poblokowane wszystko oprócz www i ssh jak to w firmach bywa…

  14. Avatar Jarosław Zabiełło powiedział 3 days later:

    Jiima: no to odpal ff z foxyproxy i ustaw sobie tunel, podalem przeciez link do webowego klienta do irca

  15. Avatar Moro powiedział 3 days later:

    Najbardziej przeładowany język to C++. Aż włos mi się języ na głowiek jak widzę co dodali w 0x. Myślałem, że jednym języku nie może być więcej “języków” a jednak w 0x jest kolejny :)

  16. Avatar psk powiedział 8 days later:

    Słaby pomysł z tym przenoszeniem wątku na irca. Zazwyczaj sporo się można było dowiedzieć na tym blogu właśnie z ciekawych komentarzy… Pozdrawiam

  17. Avatar mikołajS powiedział 9 days later:

    Scala bardzo mi się podoba. Jednak o ile się orientuje to zachwalane “concise” scali powoduje, że czytelność kodu scali może być zbliżona do kodu Perla, a sam język jest dużo trudniejszy do opanowania niż Java (ale to akurat mi się podoba :) ). Myślę więc, że nie będzie to nigdy popularny język programowania,

  18. Avatar eror powiedział 2 months later:

    :psk

    Pomysł stąd, że JZ nie chce utrwalać tu więcej bredni, które wypisuje, heh. Mechanizm “bezpiecznego duck-typingu”, który pokazał jest nic nie wart. Albo mamy dynamiczne (runtime) sprawdzanie, czy na obiekcie da się wywołać jakąś metodę (sens w przypadku dynamicznego tworzenia obiektów/klas), albo sprawdzamy statycznie posługując się starożytnym mechanizmem dziedziczenia (w Javie: void foo( MojInterfejs x ) { ... } ) bez żadnego cudowania.

    Statyczne (compile-time) sprawdzanie dynamicznie (runtime) przypisywanych właściwości obiektów jest w 99% przypadków bezsensem a zapotrzebowanie na takie akcje wskazuje na błędy projektowe i luki w edukacji programisty.

  19. Avatar Jarosław Zabiełło powiedział 2 months later:

    Jiima, moim zdaniem statyczna gwarancja wywołania poprawnej metody dla duck typing jest lepsza od method_missing. Bo błąd jest wyłapywany od razu i nie trzeba tracić czasu na pisanie jego obsługi. No i odpada pisanie dodatkowych testów jednostkowych odnośnie takich sytuacji. Po prostu tego typu błąd w Scali nigdy się nie pojawi, bo to jest gwarantowane statycznie.

    eror, a tobie widocznie się w główce nie mieści, że może istnieć język dynamiczny statycznie typowany. Możliwość dynamicznego dziedziczenia (jest też statyczne) i przestawiania kolejności dziedziczenia (linearyzacja) po traitsach jest bardzo wygodną techniką. Tak samo jak duck typing czy dynamiczne dodawanie metod do obiektów bez naruszania ich integralności (implicity).

  20. Avatar eror powiedział 2 months later:

    W główce to mi się wszystko mieści, tylko jak napisałem wyżej – to jest w większości przypadków zbędny ficzer (a jeśli okazuje się przydatny, to trzeba się zastanowić dlaczego).

    Wykaż, że rozwiązuje to jakikolwiek REALNY problem, z którym nie poradzi sobie obecny już język bez takiej właściwości.

    (Gwoli ścisłości, język nie może być statycznie czy dynamicznie typowany, a może wspierać takie czy inne typowanie zmiennych. Wiem – wyżej to był skrót myślowy.)

  21. Avatar eror powiedział 2 months later:

    Dodając jeszcze, gwoli jasności. Konstrukcja:

    def kwacz_kaczuszko(k : {def kwacz}){ // ...

    to nic innego jak użycie na liście argumentów formalnych anonimowego interfejsu (czyli, wg niektórych, “nieobiektowego wymysłu Javy”). Rozwiązanie niedobre choćby ze względy na kuszenie do łamania zasady DRY (o nieczytelności kodu nie wspomnę). Coś jak wstawianie stylów inline do HTML-a. Niby działa, niby fajnie, ale pracy jakby zazwyczaj więcej.

  22. Avatar lopex powiedział 2 months later:

    “to nic innego jak użycie na liście argumentów formalnych anonimowego interfejsu”

    Chcesz powiedzieć że typowanie strukturalne (http://en.wikipedia.org/wiki/Structural_type_system) ma coś wspólnego z anonimowymi klasami ? Póki co, nie podałeś ani jednego argumentu na poparcie żadnej ze “swoich tez”

  23. Avatar eror powiedział 2 months later:

    Nie trzeba podawać dowodów, czy argumentów w tak oczywistych sprawach. Wystarczy wiedzieć co się robi, aby umieć to nazwać. Jeśli jednak tak bardzo byś chciał jakieś zobaczyć (argumenty), to proszę, cytat spod adresu, który podałeś: “(...) [Structural type system] permits the creation of ad hoc types and interfaces”. Rozumiesz pojęcie “ad hoc interface”, czy też przetłumaczyć?

  24. Avatar lopex powiedział 2 months later:

    Widać że nie rozumiesz co to jest ad hoc. Anonimowa klasa nie jest ad hoc, ponieważ ciągnie ona za sobą ograniczenia/bagaż super klasy/interfejsu. Tutaj właśnie z pomocą przychodzi strukturalne typowanie np:

    type HasLength = {def length: Int}
    def foo(i: HasLength) = println(i.length)
    foo można użyć teraz dla tablic i Stringów pomimo że nie dzielą one wspólnego interfejsu dla length w hierarchii na którą nie masz wpływu.

    można też zawęzić wymagania:

    type HasIsEmpty = {def isEmpty: Boolean}
    def foo(i: HasLength with HasIsEmpty) = ...
    
    Typowanie strukturalne nie ma nic wspólnego z anonimowymi klasami ponieważ jest tutaj inny poziom granulacji – ficzer kwintesencja.

    Polecam też poczytać o klastrach i protokołach w CLU (ostatnio też implementowane w clojure) bo bliżej do tego jak już.

  25. Avatar eror powiedział 2 months later:

    Nie pisałem o anonimowych klasach, tylko anonimowym interfejsie. Jakbyś nie nazwał tego co tam wypisujesz, nie zmieni to faktu, że

    type HasLength = {def length: Int}

    to w tym przypadku definicja interfejsu, jaki ma implementować argumentem foo(). Ponieważ interfejs jest nienazwany, niezdefiniowany osobno, użyty inline, to jest anonimowy. Inna sprawa to właściwości takiego tworu w Scali czy innym języku.

    def foo(i: HasLength with HasIsEmpty) można zrealizować przez

    interface HasLength; interface HasIsEmpty; interface XX extends HasLength, HasIsEmpty; void foo( XX i );

    więc nie ma w kodzie Scali niczego, co nie można byłoby zrobić wcześniej (i wg mnie lepiej – bez łamania zasady DRY a nawet KISS). Kwestia, czy chcemy robić inline’owe, nie-reużywalne interfejsy, czy zdefiniować takowy globalnie, czyli dostępny dla wszystkich zawsze i wszędzie w niezmiennej (a przez to łatwo kontrolowalnej) formie.

    Właściwości i nomenklatura poszczególnych języków nie ma tu nic do gadania i mam nadzieję, że nie usłyszę “a w Scali to nie ma interfejsów”, bo to guzik prawda. Oficjalnie w C++ też nie ma (nie było, ściślej pisząc) interfejsów, ale jak programiście C++ powiesz, żeby taki stworzył, to stworzy nie narzekając na brak słowa kluczowego “interface” (mówię – na potrzeby tego przykładu – o stanie sprzed kilku /kilkunastu lat, gdy uczyłem się w nim programować, teraz mnóstwo łajdactwa wrzucili do C++ – można się przerazić).

  26. Avatar Jarosław Zabiełło powiedział 2 months later:

    eror: no to powiedz jak byś zrobił tą. podaną wyżej, metodę length która bierze stringa albo tablicę bez użycia structural typing? Ani string ani tablica nie implementuje takiego interfejsu coś podał. Na dodatek nie możesz mieć na nie wpływu gdy np. pochodzą z jakiejś zewnętrznej biblioteki.

  27. Avatar eror powiedział 2 months later:

    Do tego celu wynaleziono przeciążenie funkcji. Dzięki temu mam nie tylko informację o tym, że obiekt posiada taką czy taką metodę, ale i o jego pełnej specyfikacji.

  28. Avatar eror powiedział 2 months later:

    Aby dokładnie napisać:

    foo( Object[] x ); foo( String x );

  29. Avatar lopex powiedział 2 months later:

    I całe DRY diabli wzięli

  30. Avatar eror powiedział 2 months later:

    W zasadzie DRY nie chodzi o to, żeby napisać jak najmniej linii kodu, jeśli to miałoby wpłynąć negatywnie na jego jakość. Tu chodzi o to, żeby nie powielać funkcjonalnie tożsamych partii.

    Spać mi się chce, nie mam ochoty tego tłumaczyć, ani tego w jaki sposób należy podzielić kod na funkcjonalne bloki (tu metody). To są podstawy.

    Dobranoc ;]

  31. Avatar lopex powiedział 2 months later:

    “Tu chodzi o to, żeby nie powielać funkcjonalnie tożsamych partii.”

    Przecież właśnie to zrobiłeś wprowadzając dwie metody.

    I rest my case.

  32. Avatar eror powiedział 2 months later:

    Nie, nie zrobiłem. Rozumiesz co to znaczy “funkcjonalnie tożsame”?

    http://pastebin.org/131537 – tutaj jest na szybko napisana odpowiedź, jak należy programować w Javie, aby w tej sytuacji zachować zasadę DRY całkowicie suchą.

    (Pierwszy raz chyba widzę, żeby ktoś pisał, iż przeciążanie funkcji wiąże się z łamaniem zasady DRY!)

  33. Avatar lopex powiedział 2 months later:

    Zapomniałeś chyba jak wygląda implementacja tej metody: println(i.length)

    Złamałeś DRY.

  34. Avatar Damian powiedział 3 months later:

    Metoda ,,length’’ wyróżnia pewną klasę (interface) obiektów. Pytanie co jeżeli taki interface na początku nie był potrzebny/nie został zauważony? Wtedy faktycznie przydaje się taki anonimowy interfejs (tak to nazwijmy). Ale skoro nie był zdefiniowany interfejs to zewnętrzne obiekty mogą nie być świadome jego istnienia. Jeżeli zamiast ,,length’’ używają ,,size’’? Można pewnie stworzyć drugą wersję funkcji z interfejsem anonimowym z metodą ,,size’’. A co wtedy z obiektami, które maja obie te metody (jak np. kontenery w Qt – programista wybiera co mu wygodniejsze)?

    Może nie rozumiem kwintesencji tego co takie coś daje. W każdym bądź razie wydaje mi się, że jeżeli coś zostało przemyślane to użyte zostałyby interfejsy a jeżeli nie zostało przemyślane to mam wrażenie, że jest to takie łatanie dziur…

    P.S. z góry dzięki za konstruktywną ripostę/komentarz etc.

  35. Avatar Piotr Mąsior powiedział 3 months later:

    Wiecie, że kłócicie się o bzdury… wasza dyskusja troszkę przypomina spór na temat wyższości assemblera nad czystym C. Tylko gdzieś po drodze zapominacie o tym, że każdy język miał swoje jakieś strategiczne zastosowanie – dlatego właśnie powstał. Ja uwielbiam Rubiego, ale pewnego dnia musiałem go również znienawidzić z uwagi na brak dobrego wsparcia dla jakiegokolwiek GUI, jego przenośności między platformami + obsługi wielu wątków (dokładnie chodziło o nasłuch danych z jednego urządzenia). Żadne GUI w rubym nie jest w stanie tego połączyć. Problem jest do obejścia z poziomu rubiego ale wymaga dosłownie głupiego hacku w postaci “pętli uwalniającej” – z wysoką częstotliwością – zasoby poprzez Thread.pass… a dla mnie i ten sposób zawiódł.(dla GUI w wersji rubiego 1.9.1 przyszłość rysuje się weselej z uwagi na dołączenie nareszcie native threads) Natłok danych – strumień video – i tak nie pozwolił odzsykać wątkowi z GUI kontroli nad aplikacją. Co zrobić? Powiesić się! Ala Swing Javy sprawuje się w tej materii świetnie… Dlaczego nie połączyć więc obu rozwiązań? Nagle olśnienie przejście na jRuby, zastosowanie Monkeybars, rawr i wszystko działa, aż się łezka w oku kręci. Przy okazji macie połączone swoje dynamiczne typowanie Rubiego z wielkim doświadczeniem JaVy w dziedzinach, których ruby nie pokrywa.

    Nie ma doskonałych języków… nie było, nie będzie… bo nie o to w tym chodzi.

    Panie Jarosławie… Java jako język może i jest “słaba”, jak to Pan nazwał. Ale nic lepszego jeszcze nie wymyśliliśmy. Największą siłą Javy są właśnie jej słabości, o których każdy programista wie. Bo najgorzej, gdy pewnego dnia zostajemy “z ręką w nocniku”, a nasz ukochany ‘doskonały’ język wykazał się słabością… Nie wiem co wtedy bardziej boli – nadwyrężone ego i stwierdzenie “przecież to nie jakaś popularna Java”, czy zaskoczenie faktem, że słabemu językowi wyszło lepiej, niż naszemu doskonałemu kompanowi…

    Pozdrawiam Piotr Mąsior

  36. Avatar Jarosław Zabiełło powiedział 3 months later:

    Nowe języki wymyśla się dla ludzi, a nie dla maszyn, po to aby można było pracować wygodniej i produktywniej w zadanych dziedzinach. Java (jako język) jest w tym sensie słaba, że jest mało ekspresyjna i ma np. dosyć słaby model obiektowy, słabe wparcie dla FP itp. Nie sądzę aby ktokolwiek na poważnie wierzył że język Java jest tym wszystkich co można było wymyśleć najlepiej. No, chyba że mówimy o platformie Javy, o JVM i Hotspocie, bo to niezła rzecz. Ale czy najlepsza? Zależy do czego. Gierki do iPhona na tym się nie napisze…

    Ruby 1.9.x nie ma natywnych wątków (ma fibers, ale to nie to samo). Natywne, systemowe wątki ma JRuby. Scala ma dużo ciekawsze rozwiązanie w postaci asynchronicznych Aktorów (zresztą skopiowane z Erlanga).

    Zresztą, jeśli chodzi o możliwości ekspresji to wiadomo że tu najpotężniejszy jest Lisp. :P Będąc językiem “homoikonicznym” może przekształcać sam siebie bez większych organiczeń dostosowując do nowych potrzeb. Dlatego obok Scali drugim, niezmiernie ciekawym językiem jest Clojure – javowy dialekt Lispa. Polecam tą, b. ciekawą prezentację twórcy Clojure: Are we There Yet?

  37. Avatar Piotr Mąsior powiedział 3 months later:

    Przyznam, że chyba jedno z ciekawszych “olśnień” jakich można dostać w pracy. Wytrąca z szablonowego myślenia. Clojure wygląda naprawdę ciekawie. Jak zobaczyłem listy to odrazu prolog mi się przypomniał. Prezentacja Hickey-a jest troszke jednak wredna. Straciłem przez niego cały dzień na rozmyślanie, o tym jego alternatywnym podejściu do współczesnych języków programowania. W sumie doszedłem do jednego wniosku z całej tej rozkminki. Wracamy do lat 70! Tylko, że wtedy to było marzenie niespełnionych twórców SF, a teraz zwycazjnie zaczynamy obserwować coraz większy popyt na produkty na pograniczu sztucznej inteligencji, a tylko języki pseudo-Lispowe to umożliwią. Stąd pojawił się CLojure.

    ps.(CL w jego nazwie) ciekaw jestem czy jest przypadkowe czy to faktycznie rozszerzenie trendu CommonLisp

    Pozdrawiam Piotr Mąsior

(leave url/email »)

   Pomoc języka formatowania Obejrzyj komentarz