71. spotkanie Warszawa JUG - Cezary Bartoszuk z "Sztuczki w językach programowania"

36 views
Skip to first unread message

Jacek Laskowski

unread,
Nov 6, 2010, 11:46:31 AM11/6/10
to Warszawa-JUG
Cześć!

Warszawska Grupa Użytkowników Javy (Warszawa JUG) [1] zaprasza na 71.
spotkanie, które odbędzie się w najbliższy wtorek, 9. listopada o
godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w
Warszawie.

Temat: Sztuczki w językach programowania
Prelegent: Cezary Bartoszuk

Rozwijane obecnie języki programowania pełne są sztuczek: technik,
wzorców, metod lub przepisów, których przyjęło się używać do
osiągnięcia konkretnego celu. Sądzę, że aby poszerzyć swoją wiedzę o
programowaniu warto poznać smaki ciekawych sztuczek stosowanych w
różnych językach programowania.

Pogadankę o "sztuczkach" (jak będę je nazywał ze względu na to, że są
bytami bardzo różnych rodzajów) podzieliłem na trzy zasadniczo różne
części:

1) Typowanie
2) Przepływ danych
3) Przepływ sterowania

W każdej z tych części w sposób dość popularnonaukowy (i w dużej
mierze opierając się na intuicjach) omówię kilka sztuczek jakie
stosowane są w językach programowania. Każda sztuczka będzie miała
charakter informacyjny wraz z krótkim przejrzeniem plusów i minusów
danego rozwiązania.

Do worka ze sztuczkami wrzucę między innymi: funkcje i typy wyższych
rzędów, kontynuacje, jedną lub dwie monady i polimorfizm w różnych
smakach.

Cezary Bartoszuk jest studentem Wydziału Matematyki, Informatyki i
Mechaniki, kierunku informatyka. Interesuje się programowaniem
funkcyjnym, współbieżnością i clean-codem. Zawodowo programista
Pythona.

Planowany czas prezentacji to 1,5h, po których planuje się
15-30-minutową dyskusję.

Wstęp wolny

Zapraszam w imieniu prelegenta i grupy Warszawa JUG!

[1] http://warszawa.jug.pl

Jacek

--
Jacek Laskowski
Notatnik Projektanta Java EE - http://jaceklaskowski.pl

Michal Margiel

unread,
Nov 9, 2010, 5:39:24 PM11/9/10
to warsza...@googlegroups.com
Dzięki za spotkanie!

z ciekawości na szybko przetestowałem, czy implementacja isBlank o której mówiłem faktycznie jest równoznaczna z tą z Apache commons.

Moja implementacja wygląda tak:

public class StringUtilities {
   public static boolean isBlank(String string) {
      return string == null || string.trim().isEmpty(); 
   }
}

a to testy które mi przyszły do głowy:


assertTrue(StringUtilities.isBlank(null));
assertTrue(StringUtils.isBlank(null));

assertTrue(StringUtilities.isBlank(" "));
assertTrue(StringUtils.isBlank(" "));

assertTrue(StringUtilities.isBlank("\t"));
assertTrue(StringUtils.isBlank("\t"));

assertTrue(StringUtilities.isBlank("\n"));
assertTrue(StringUtils.isBlank("\n"));

assertTrue(StringUtilities.isBlank("\n \t"));
assertTrue(StringUtils.isBlank("\n \t"));

(StringUtils pochodzi z Commons-lang)

Wszystkie testy przeszły, więc zakładam że moja implementacja jest działa tak samo jak  ta z commons-lang.
--
Pozdrawiam/Best regards
Michał Margiel

http://www.javarsovia.pl
http://www.linkedin.com/in/MichalMargiel
http://poligloci.margiel.eu

Sebastian Konkol

unread,
Nov 9, 2010, 5:47:46 PM11/9/10
to warsza...@googlegroups.com
Hej!
Idąc za Javadocami z 1.3.1 (nie mogłem wygrzebać późniejszych)

Determines if the specified character is white space according to Java. A character is considered to be a Java whitespace character if and only if it satisfies one of the following criteria:
  • It is a Unicode space separator (category "Zs"), but is not a no-break space (\u00A0 or \uFEFF).
  • It is a Unicode line separator (category "Zl").
  • It is a Unicode paragraph separator (category "Zp").
  • It is \u0009, HORIZONTAL TABULATION.
  • It is \u000A, LINE FEED.
  • It is \u000B, VERTICAL TABULATION.
  • It is \u000C, FORM FEED.
  • It is \u000D, CARRIAGE RETURN.
  • It is \u001C, FILE SEPARATOR.
  • It is \u001D, GROUP SEPARATOR.
  • It is \u001E, RECORD SEPARATOR.
  • It is \u001F, UNIT SEPARATOR.

Zatem przydałoby się dla spokoju ducha sprawdzić czy działa dla każdego typu obsługiwanego przez metodę isWhiteSpace. No i może w takim razie parametryzowalny test... :-)

Pozdrawiam
Sebastian Konkol

Wiadomość napisana przez Michal Margiel w dniu 2010-11-09, o godz. 23:39:

--
Otrzymujesz tę wiadomość, ponieważ subskrybujesz grupę dyskusyjną Google o nazwie „Warszawa Java User Group (Warszawa JUG)”.
Aby zamieszczać posty w tej grupie, wyślij e-mail na adres warsza...@googlegroups.com.
Aby anulować subskrypcję tej grupy, wyślij e-mail na adres warszawa-jug...@googlegroups.com.
Aby uzyskać więcej informacji, odwiedź tę grupę pod adresem http://groups.google.com/group/warszawa-jug?hl=pl.

Jacek Laskowski

unread,
Nov 10, 2010, 3:08:47 AM11/10/10
to warsza...@googlegroups.com
2010/11/9 Sebastian Konkol <sebastia...@gmail.com>:

> No i może w takim razie parametryzowalny test... :-)

Rozwiń proszę.

Jacek Laskowski

unread,
Nov 10, 2010, 3:13:59 AM11/10/10
to warsza...@googlegroups.com
2010/11/9 Michal Margiel <michal....@gmail.com>:

> assertTrue(StringUtilities.isBlank(null));

Rozumiem, że skorzystałeś z assertTrue zamiast po prostu assert, bo
daje co miało być i co jest przy błędzie?

Arkadiusz Borek

unread,
Nov 10, 2010, 3:14:35 AM11/10/10
to warsza...@googlegroups.com
To powinno lekko rozwiać wątpliwości:
--
Otrzymujesz tę wiadomość, ponieważ subskrybujesz grupę dyskusyjną Google o nazwie "Warszawa Java User Group (Warszawa JUG)".

Aby zamieszczać posty w tej grupie, wyślij e-mail na adres warsza...@googlegroups.com.
Aby anulować subskrypcję tej grupy, wyślij e-mail na adres warszawa-jug...@googlegroups.com.
Aby uzyskać więcej informacji, odwiedź tę grupę pod adresem http://groups.google.com/group/warszawa-jug?hl=pl.




--
Pozdrawiam,
Arkadiusz Borek

Michal Margiel

unread,
Nov 10, 2010, 3:44:40 AM11/10/10
to warsza...@googlegroups.com


W dniu 10 listopada 2010 09:13 użytkownik Jacek Laskowski <ja...@laskowski.net.pl> napisał:
2010/11/9 Michal Margiel <michal....@gmail.com>:

> assertTrue(StringUtilities.isBlank(null));

Rozumiem, że skorzystałeś z assertTrue zamiast po prostu assert, bo
daje co miało być i co jest przy błędzie?


Deja vu :) już o tym "assert" rozmawialiśmy w komentarzach na Twoim blogu.

IMHO nigdy nie powinnismy używać słowa kluczowego "assert" w testach. Czemu ? bo ono nie jest do tego przeznaczone- taka jest krótka odpowiedź.

Dłuższa odpowiedź :
- "assert" można wyłączyć,
- metody assertXXX z frameworków testowych (junit, fest-assert, hamcrest...) tworzą pewnego rodzaju DSL który dużo wygodniej się czyta
- jak sam napisałeś  - przy użyciu "assert" nie dostaniesz właściwego komunikatu który dostarczy Ci za darmo własciwa metoda z frameworku.

Akurat w tym konkretnym przypadku argument nr 3 nie jest prawdziwy gdyż junitowa metoda assertTrue zgłosi po prostu "assertation error" (czy coś w ten deseń), co nie jest tym co chciałbym zobaczyć.
Dlatego też na co dzień w pracy do takich asercji używam biblioteki fest-assert oraz konstrukcji:

assertThat(string.isEmpty()).isTrue();

ta linia w razie niepowodzenia zgłosi że spodziewał się true a dostał false[2]. w tym wypadku nie zrobiłem tego gdyż nie chciało mi się włączać dodatkowej biblioteki.

Widzę Jacku, że przydało by Ci się szkolenie z TDD, ale masz szczęście!! moja firma już wkrótce organizuje otwarte szkolenie gdzie będzie mógł poszerzyć swą testową wiedzę. Więcej info na http://agile-coaching.pl/


[1] http://easytesting.org/assert/
[2] konkretnie to zgłgosi coś takiego: expected <[tru]e> but was <[fals]e> (w nawiasach kwadratowych zaznaczy część różniącą się)  

Jacek Laskowski

unread,
Nov 10, 2010, 3:52:49 AM11/10/10
to warsza...@googlegroups.com
2010/11/10 Michal Margiel <michal....@gmail.com>:

> - "assert" można wyłączyć,

W testach jest *zawsze* włączone. Argument obalony :) I jest tak
stary, jak sam assert :P

> - metody assertXXX z frameworków testowych (junit, fest-assert, hamcrest...)
> tworzą pewnego rodzaju DSL który dużo wygodniej się czyta

Jasne. W ogólności pełna zgoda, ale

assertTrue(StringUtilities.isBlank(null));

vs

assert StringUtilities.isBlank(null);

słabo wypada :)

> - jak sam napisałeś  - przy użyciu "assert" nie dostaniesz właściwego
> komunikatu który dostarczy Ci za darmo własciwa metoda z frameworku.

I tu mnie właśnie zastanowiło, dlaczego nie użyłeś assertThat, który
jest w JUnit?!

> assertThat(string.isEmpty()).isTrue();

Dlaczego nie assertThat(string.isEmpty(), is(true)) ? Pytam z czystej
ciekawości, chcąc trochę uszczknąć z Twojego doświadczenia. Poważnie.

Jacek Laskowski

unread,
Nov 10, 2010, 3:56:36 AM11/10/10
to Warszawa-JUG
2010/11/6 Jacek Laskowski <ja...@laskowski.net.pl>:

> Warszawska Grupa Użytkowników Javy (Warszawa JUG) [1] zaprasza na 71.
> spotkanie, które odbędzie się w najbliższy wtorek, 9. listopada o
> godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w
> Warszawie.
>
> Temat: Sztuczki w językach programowania
> Prelegent: Cezary Bartoszuk

Film już jest gotowy do publikacji. Około 400 MB (czas: 1:50:00) w
formacie flv. Czekam tylko na upload na javatv. Poszłoby na parleys,
ale już wspominałem, że nie potrafię tego ustrojstwa obsługiwać, więc
jak się już znajdzie filimik publicznie, ktoś mi pomoże (= zrobi to za
mnie :))

p.s. Jeśli ktoś ma serwer do użyczenia na film, proszę o kontakt.

Paweł Lipiński

unread,
Nov 10, 2010, 3:58:23 AM11/10/10
to warsza...@googlegroups.com
>> - metody assertXXX z frameworków testowych (junit, fest-assert, hamcrest...)
>> tworzą pewnego rodzaju DSL który dużo wygodniej się czyta
>
> Jasne. W ogólności pełna zgoda, ale
>
> assertTrue(StringUtilities.isBlank(null));
>
> vs
>
> assert StringUtilities.isBlank(null);
>
> słabo wypada :)

No nie. Samo assert nie mówi czego dotyczy asercja. assertTrue jest bardziej określone, a więc lepsze.
A że nie ma w assert nawiasów...

Generalnie skoro piszemy testy to używamy bibliotek testowych. Assert javowe jest do czego innego.

>
>> - jak sam napisałeś - przy użyciu "assert" nie dostaniesz właściwego
>> komunikatu który dostarczy Ci za darmo własciwa metoda z frameworku.
>
> I tu mnie właśnie zastanowiło, dlaczego nie użyłeś assertThat, który
> jest w JUnit?!
>
>> assertThat(string.isEmpty()).isTrue();
>
> Dlaczego nie assertThat(string.isEmpty(), is(true)) ? Pytam z czystej
> ciekawości, chcąc trochę uszczknąć z Twojego doświadczenia. Poważnie.

Są 2 powody:
1) FEST ma lepsze komunikaty w wyjątkach
2) FEST ma wygodniejsze api (ja podobnie jak Michał wolę method chaining od parametrów).

Paweł

--
http://blog.pragmatists.pl

Michal Margiel

unread,
Nov 10, 2010, 4:01:59 AM11/10/10
to warsza...@googlegroups.com


W dniu 10 listopada 2010 09:58 użytkownik Paweł Lipiński <lipinsk...@gmail.com> napisał:

>
>> - jak sam napisałeś  - przy użyciu "assert" nie dostaniesz właściwego
>> komunikatu który dostarczy Ci za darmo własciwa metoda z frameworku.
>
> I tu mnie właśnie zastanowiło, dlaczego nie użyłeś assertThat, który
> jest w JUnit?!
>
>> assertThat(string.isEmpty()).isTrue();
>
> Dlaczego nie assertThat(string.isEmpty(), is(true)) ? Pytam z czystej
> ciekawości, chcąc trochę uszczknąć z Twojego doświadczenia. Poważnie.

Są 2 powody:
1) FEST ma lepsze komunikaty w wyjątkach
2) FEST ma wygodniejsze api (ja podobnie jak Michał wolę method chaining od parametrów).


Dokładnie, osobiście nie przepadam za hamcrestem.

Jacek Laskowski

unread,
Nov 10, 2010, 4:08:10 AM11/10/10
to warsza...@googlegroups.com
2010/11/10 Paweł Lipiński <lipinsk...@gmail.com>:

> Assert javowe jest do czego innego.

Do czego?

Czy nie do sprawdzenia poprawności naszego kodu? Na produkcji jest
wyłączony. Do włączenia wymaga zmiany w JVM - zatrzymanie aplikacji i
ponowne jej uruchomienie, więc odpada, jako narzędzie diagnostyczne.
Hmmm, chyba, gdzieś widziałem możliwość włączania assert
programistycznie, więc można byłoby wyobrazić sobie interfejs
administracyjny, którym włączamy/wyłączamy asserty, np. JMX.

Tomasz Łasica

unread,
Nov 10, 2010, 4:15:12 AM11/10/10
to warsza...@googlegroups.com
Dnia 2010-11-10 10:08 Jacek Laskowski napisał(a):

>2010/11/10 Paweł Lipiński <lipinsk...@gmail.com>:
>
>> Assert javowe jest do czego innego.
>
>Do czego?
>
>Czy nie do sprawdzenia poprawności naszego kodu? Na produkcji jest
>wyłączony. Do włączenia wymaga zmiany w JVM - zatrzymanie aplikacji i
>ponowne jej uruchomienie, więc odpada, jako narzędzie diagnostyczne.
>Hmmm, chyba, gdzieś widziałem możliwość włączania assert
>programistycznie, więc można byłoby wyobrazić sobie interfejs
>administracyjny, którym włączamy/wyłączamy asserty, np. JMX.

Wydaje mi się, że w niektórych zastosowaniach jak najbardziej warto
wykorzystać do defensive programming.
Powiedzmy, że liczymy jakąś skomplikowaną operację bankową.
Jasne - mamy testy. Masę testów.
Ale mimo wszystko czasem lepiej się wyłożyć po asercji niż np. pobrac sobie
z konta A i nie przelać na konto B :-)

Tomek

>
>Jacek
>
>

--
pozdrawiam
Tomek Łasica

Paweł Lipiński

unread,
Nov 10, 2010, 4:21:55 AM11/10/10
to warsza...@googlegroups.com
>> Assert javowe jest do czego innego.
>
> Do czego?
Ja nie używam. Assert zwykle używa się do zweryfikowania niskopoziomowych założeń (wartość zmiennych, warunek logiczny, itp) Jak się nie pisze testów tylko kod testuje manualnie to daje to możliwość zweryfikowania założeń. Czyli ustawiasz assert tak / tam, by pokrył przypadek, który nigdy nie powinien się wydarzyć.
Jak się pisze testy, to sytuacja jest trochę inna. Kod weryfikacji nie jest w tym samym miejscu co implementacja, czyli de facto nie testujemy szczegółów implementacyjnych tylko kontrakt metod.

Do tego assert zawsze rzuca to samo, a festowe (a nawet hamcrestowe) asercje są dużo bardziej dostosowane do różnych przypadków. Popróbuj przez parę dni i poczujesz różnicę...

>
> Czy nie do sprawdzenia poprawności naszego kodu? Na produkcji jest
> wyłączony. Do włączenia wymaga zmiany w JVM - zatrzymanie aplikacji i
> ponowne jej uruchomienie, więc odpada, jako narzędzie diagnostyczne.
> Hmmm, chyba, gdzieś widziałem możliwość włączania assert
> programistycznie, więc można byłoby wyobrazić sobie interfejs
> administracyjny, którym włączamy/wyłączamy asserty, np. JMX.

Jacek! Assert włączony na produkcji? A chcesz w kodzie produkcyjnym obsługiwać AssertionError!?!?!?

Paweł

--
http://blog.pragmatists.pl

Jacek Laskowski

unread,
Nov 10, 2010, 4:37:08 AM11/10/10
to warsza...@googlegroups.com
2010/11/10 Paweł Lipiński <lipinsk...@gmail.com>:

> Jacek! Assert włączony na produkcji? A chcesz w kodzie produkcyjnym obsługiwać AssertionError!?!?!?

Pytanie "Skąd w ogóle AE na produkcji"? Tutaj widzę zaletę tego błędu.
Inaczej, skoro był testowany, to może właśnie oddzielić
odpowiedzialności komu przyjdzie pisać asserty (swego rodzaju
programming by contract), a komu testy i mieć oba rozwiązania (?) Nie
wiem, jak duży narzut ma assert i tym samy, czy uruchomić aplikację z
-ea na produkcji.

Patrz "appropriate" w Why not provide a full-fledged
design-by-contract facility with preconditions, postconditions and
class invariants, like the one in the Eiffel programming language?
[1]:

"The assert statement is appropriate for nonpublic precondition,
postcondition and class invariant checking. Public precondition
checking should still be performed by checks inside methods that
result in particular, documented exceptions, such as
IllegalArgumentException and IllegalStateException."

[1] http://download.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general

Paweł Lipiński

unread,
Nov 10, 2010, 4:55:06 AM11/10/10
to warsza...@googlegroups.com
> "The assert statement is appropriate for nonpublic precondition,
> postcondition and class invariant checking. Public precondition
> checking should still be performed by checks inside methods that
> result in particular, documented exceptions, such as
> IllegalArgumentException and IllegalStateException."


Wg mnie chcą bronić złej decyzji projektowej w jezyku. Dla mnie, z punktu widzenia czytelności, łączenie definicji kontraktu z właściwym ciałem metody to pomyłka. Widzę dużo lepsze rozwiązania:
1) A'la eiffel - na zewn. ciała metody
2) Aspekty
3) Testy jednostkowe

ad 1) wymaga zmian w języku, więc na razie odpada;
ad 2) wymaga aspectj'a, więc chyba nie jest rozwiązaniem dla wszystkich;
ad 3) testy i tak mamy (nie?), więc dlaczego nie użyć ich do tego. Część kontraktu metody często jest de facto wymaganiem biznesowym, więc i tak jest w testach.

Paweł
--
http://blog.pragmatists.pl

iirekm

unread,
Nov 10, 2010, 4:55:33 AM11/10/10
to Warszawa Java User Group (Warszawa JUG)
> >> Assert javowe jest do czego innego.
>
> > Do czego?
>
> Ja nie używam. Assert zwykle używa się do zweryfikowania niskopoziomowych założeń (wartość zmiennych, warunek logiczny, itp) Jak się nie pisze testów tylko kod testuje manualnie to daje to możliwość zweryfikowania założeń. Czyli ustawiasz assert tak / tam, by pokrył przypadek, który nigdy nie powinien się wydarzyć.
> Jak się pisze testy, to sytuacja jest trochę inna. Kod weryfikacji nie jest w tym samym miejscu co implementacja, czyli de facto nie testujemy szczegółów implementacyjnych tylko kontrakt metod.
>

Można to rozumieć tak:

Stanów jakie może osiągać klasa i parametrów jakie przyjmuje metoda
jest nieskończenie wiele (np. funkcja Math.pow() - nieskończenie wiele
parametrów, String.trim() - nieskończenie wiele stanów).
Przetestowanie tej nieskończoności jest niemożliwe - możliwe jest
przetestowanie tylko na konkretnych "reprezentatywnych" przykładach i
to właśnie robią testy i asercje w nich.

Z kolei assert w kodzie zwykłej (nietestowej) metody bada zachowanie
dla każdego przypadku jaki się pojawi, np. do metody silnia(n) możesz
zrobić aserta: assert parametr >= 0, ale nie zrobisz assert wynik ==
silnia(n) - by by zbadać poprawność wyniku tej metody musisz użyć jej
samej, co jest bez sensu, ale np. assert wynik > parametr jest tu jak
najbardziej na miejscu (np. wykrywa przepełnienie dla dużych silni).

Dlatego potrzebne jest jedno i drugie: i testy na danych przykładowych
(by zbadać wynik całej metody), jak i asercje w kodzie (albo zrzucanie
wyjątków odpowiednio wcześnie, np. IllegalArgumentException,
IllegalStateException, NoSuchElementException) - niektórzy nazywają to
"fail fast".

> Jacek! Assert włączony na produkcji? A chcesz w kodzie produkcyjnym obsługiwać AssertionError!?!?!?
Wg mnie lepiej nawet mieć byle jak obsłużony wyjątek (np. internal
server error + stack trace w logu), niż zapisać złe dane do bazy. Z
tego co wiem, Java daje możliwość włączania/wyłączania assertów na
konkretne pakiety, więc jak jakieś aserty zamulają aplikację, to te
najbardziej wolne można wyłączyć, albo po prostu usunąć.

Jacek Laskowski

unread,
Nov 10, 2010, 5:14:15 AM11/10/10
to warsza...@googlegroups.com
2010/11/10 iirekm <iir...@gmail.com>:

> Z kolei assert w kodzie zwykłej (nietestowej) metody bada zachowanie
> dla każdego przypadku jaki się pojawi, np. do metody silnia(n) możesz
> zrobić aserta: assert parametr >= 0, ale nie zrobisz assert wynik ==
> silnia(n) - by by zbadać poprawność wyniku tej metody musisz użyć jej
> samej, co jest bez sensu, ale np. assert wynik > parametr jest tu jak
> najbardziej na miejscu (np. wykrywa przepełnienie dla dużych silni).

To mi się b. podoba, ale kiedy się zastanowić, nie różni się niczym od
if (...) return ...;

Momento, czyżby? :)

Gdyby się tak zastanowić, to konstrukcja if (...) return ...; wymaga
określenia, co należałoby zwrócić, a to może być nietrywialne, np. dla
silni mogłoby to być modulo względem największego akceptowanego
parametru.

Ktoś mógłby powiedzieć, że tutaj IllegalArgumentException jest lepszy
od AssertionError, tylko, że oba i tak nie są w publicznym kontrakcie,
więc klapa (zakładając, że -ea jest włączone).

I tak źle, i tak niedobrze.

iirekm

unread,
Nov 10, 2010, 5:55:10 AM11/10/10
to Warszawa Java User Group (Warszawa JUG)

>
> Ktoś mógłby powiedzieć, że tutaj IllegalArgumentException jest lepszy
> od AssertionError, tylko, że oba i tak nie są w publicznym kontrakcie,
> więc klapa (zakładając, że -ea jest włączone).
>
> I tak źle, i tak niedobrze.

Każda, nawet prosta metoda w Javie i tak może czasem zwrócić
przynajmniej 2 wyjątki: StackOverflowError i OutOfMemoryError? Im
dłuższa metoda, tym lista tych "automatycznych" wyjątków rośnie
(NullPointerException, NoClassDefFoundError,
IndexOutOfBoundsException) - czy każdy programista o nich pamięta?
Nawet w C każda metoda może spowodować SIGSEGV czy w przypadku
Windowsa: EXCEPTION_ACCESS_VIOLATION - to nic innego jak wyjątki,
tylko zrobione trochę inną techniką.

Zawsze należy przyjąć, że dana metoda ma prawo zwrócić jakiś wyjątek
(nawet jeśli nie ma go wypisanego w throws ani w @throws), i zawsze
dobrze jest niezłapane i nawet "nieznane" wyjątki jakoś obsłużyć,
choćby tylko przez wypisanie ich do loga (co zresztą serwery aplikacji
czynią), a w throws i @throws dawać tylko te wyjątki, które występują
stosunkowo często i do tego wymagają jakiejś specjalnej obsługi, np.
FileNotFoundException.

Jacek Laskowski

unread,
Nov 10, 2010, 7:28:10 AM11/10/10
to Warszawa-JUG
2010/11/6 Jacek Laskowski <ja...@laskowski.net.pl>:

> Warszawska Grupa Użytkowników Javy (Warszawa JUG) [1] zaprasza na 71.
> spotkanie, które odbędzie się w najbliższy wtorek, 9. listopada o
> godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w
> Warszawie.
>
> Temat: Sztuczki w językach programowania
> Prelegent: Cezary Bartoszuk

Nagranie dostępne na http://javatv.pl:8080/index5.html. Miłego oglądania!

Lukasz Lenart

unread,
Nov 15, 2010, 2:41:58 AM11/15/10
to warsza...@googlegroups.com
W dniu 10 listopada 2010 13:28 użytkownik Jacek Laskowski
<ja...@laskowski.net.pl> napisał:

> Nagranie dostępne na http://javatv.pl:8080/index5.html. Miłego oglądania!

A można prosić o podpięcie slajdów z boku? Można wykorzystać jakiś
gotowy serwis jak slideshare?


Pozdrawiam
--
Łukasz
+ 48 606 323 122 http://www.lenart.org.pl/
Kapituła Javarsovia 2010 http://javarsovia.pl

tomi613

unread,
Nov 15, 2010, 3:44:22 AM11/15/10
to warsza...@googlegroups.com
jasne podeślij mi plik to podepnę to w formie linku lub slideshare,
pozdrawiam. 

Tomasz Szymański

unread,
Nov 15, 2010, 3:59:11 AM11/15/10
to warsza...@googlegroups.com
A możecie mi podać choćby jeden powód dlaczego nie wrzuciliście tego na parleys ?

T.

Michal Margiel

unread,
Nov 15, 2010, 5:13:49 AM11/15/10
to warsza...@googlegroups.com
Jackowi nie chce się tego robić.
Dobry?:)

Tomasz Szymański

unread,
Nov 15, 2010, 5:53:31 AM11/15/10
to warsza...@googlegroups.com
No tak.

Najpierw 100 postów na temat konwersji, a w koncu wrzucone na jakąś strone która wygląda jak zrobiona w wordpadzie...

T.

Michal Margiel

unread,
Nov 15, 2010, 6:14:54 AM11/15/10
to warsza...@googlegroups.com
znaczy przekonwertować tak czy siak musiał. potem tylko trzeba zsynchronizować video ze slajdami.

tomi613

unread,
Nov 15, 2010, 6:32:36 AM11/15/10
to warsza...@googlegroups.com
to jaki masz problem, wrzuć na Perelys, widocznie Jackowi tak było wygodnie. 

Tomasz Szymański

unread,
Nov 15, 2010, 6:44:32 AM11/15/10
to warsza...@googlegroups.com
No mam problem, bo jest super platforma do udostępniania prezentacji, gdzie mamy większość naszych wrzuconych, podpięte slajdy, cuda wianki aż tu nagle nie wiadomo po co jakaś taka biała strona ni z gruszki ni z pietruszki, do której link zaginie razem z tym wątkiem jak spadnie pare waidomości do dołu za 2-3 miesiące.

Jak coś robimy, to róbmy to porządnie, bo tak to szkoda czasu.

T.

tomi613

unread,
Nov 15, 2010, 6:57:30 AM11/15/10
to warsza...@googlegroups.com
przecież już pisałem, wrzuć na Perelys!, wiem że docelową stroną jest Perelys i tak zostanie, najwyraźniej Jackowi było wygodniej wrzucić na jakąś białą stronę :) .
pozdrawiam.

Bartek Zdanowski

unread,
Nov 15, 2010, 7:02:29 AM11/15/10
to warsza...@googlegroups.com
2010/11/15 Tomasz Szymański <szi...@szimano.org>:

> No tak.
> Najpierw 100 postów na temat konwersji, a w koncu wrzucone na jakąś strone
> która wygląda jak zrobiona w wordpadzie...
LOL!

--
Pozdrawiam,
Bartek Zdanowski

Kapituła Javarsovia 2010 - http://javarsovia.pl
Komitet organizacyjny Warsjawa 2010 - http://warsjawa.pl

Artur Karazniewicz

unread,
Nov 15, 2010, 7:57:09 AM11/15/10
to Warszawa Java User Group (Warszawa JUG)
Niestety nie byłem na samej prezentacji ale temat jest bardzo ciekawy.
Fajnie, że jest nagranie. Byłoby super fajnie, gdyby jednak wrzucić to
na parleys, bo można tam umieszczać również prezentacje, tak aby było
lepiej widać co się na slajdach dzieje.

Co do samego tematu. To Czarek poruszył bardzo ciekawe aspekty
języków, szczególnie w kontekście Javy. Mnie osobiście zabrakło jednak
trochę pogłębienia tematu przykładami, choć wiem, że omawianych cech
nie da się ująć sensownie w 1,5h. Czasami może było trochę zbyt
abstrakcyjnie i może trochę za szybko; tak mi się wydawało po
pytaniach dotyczących np. higher kinds. Ciekawe byłoby zaprezentowanie
w innych językach niż Scala. Scala oczywiście ma wsparcie większości
tych cech, o których mówił Czarek ale czasami nie jest najlepszym
językiem do wyjaśnienia pewnych rzeczy. Fajnie byłoby porównać to do
innych języków, i wówczas może byłoby jaśniejsze skąd dana konstrukcja
wzięła się w Scali. Inaczej można odnieść wrażenie, że Scala jest
jednym wielkim śmietnikiem do którego wrzucono całą masę dziwnych
konstrukcji. A tak nie jest - po prostu Scala wprowadza to co
najlepsze z innych języków. Przy większej ilości czasu może uda mi się
zrobić coś w stylu prezentacji ("Making sense of scala with Haskell" -
to dopiero byłoby wyzwanie na 1,5 wykład - Jacek od razu odpowiadając
na Twoje ewentualne pytanie - nie dam rady tego zrobić na 23 ;)).

Tymczasem kilka moich komentarzy do tego o czym mówił Czarek:

1. Type classes (klasy typów)

Czarek nazwał to klasami abstrakcji ale ma to niewiele wspólnego z
klasami abstrakcji (choć w pewnym sensie kategoryzuje typy). Niestety
Scala nie jest tutaj najprostszym przykładem tej koncepcji i
generalnie 'emuluje' typeclasses. Dużo lepszym i czytelniejszym
przykładem jest Haskell, o którym warto powiedzieć kilka słów.

(poniżej moje 5 minutowe wprowadzenie do Haskella i klas typów z
przejściem do Scali ;)

- 0. Na początek należy zapomnieć wszystko co się wie o językach
programowania, w Haskellu pojawia się masa konstrukcji o podobnie
znajomych nazwach ale oznaczających zupełnie coś innego ;).

- 1. Nie można mówić o klasach typów bez algebraicznych typów danych
(Algebraic Data Type - dalej ADT).

W Haskellu definiuje się je natywnie w następujący sposób

data Foo = Bar
| Baz

Foo jest nazwą "typu danych" Bar i Baz są "konstruktorami". Może być
ich dowolnie wiele. "|" oznacza alternatywę. Typ Foo ma dwa
alternatywne konstruktory.

Np. w Haskellu typ Boolean można zdefiniować tak:

data Boolean = True | False

(całkiem sensowne)

można teraz zdefiniować wartość Boolean następująco:

lat b = True

(nie mamy tutaj słowa kluczowego new)

Konstruktory mogą przyjmować argumenty. Np. Odpowiednik Scala
Option[T] (w Haskellu Maybe) można zdefiniować tak:

data Maybe t = Just t | Nothing

Maybe jest typem parametrycznym (generycznym; t jest parametrem typu
(type parameter); tak jak T w scali z tym, że Haskell jest o wiele
bardziej spójny :>. W Haskellu każdy typ zaczyna się od dużej litery a
każdy parametr od małej. t powyżej jest parametrem generycznego typu
więc jest z małej litery)

możemy teraz użyć powyższego typu następująco:

let a = Just "foo"

Just jest wywołaniem konstruktora (Just) typu Maybe. Haskell jest tak
domyślny, że sam jest w stanie domyślić się odpowiedniego typu
parametru t (String). Parametry funkcji w Haskellu nie wymagają
nawiasów. Latwo sprawdzić (:t x w GHCi - haskellowym REPL zwraca typ
danych wyrażenia). Zatem

:t a
a :: Maybe [Char]

(W Haskellu String to lista znaków).

Generalnie można myśleć o typach danych jak o rodzaju struktury w C,
czy POJO, tylko, że o niebo lepszej :> . Tu niestety wszelkie analogie
do języków imperatywnych się kończą.

W jaki sposób definiujemy operacje na powyższym typie danych? Ano
właśnie przy pomocy klas typów (znowu jest to bardzo adekwatna nazwa w
Haskellu). Załóżmy, że chcielibyśmy wyświetlić nasz typ Maybe na
ekranie (odpowiednik javovego toString):

class Print t where
print :: t -> [Char]

Zdefiniowaliśmy klasę typów. Klasę, ponieważ nie mówi ona nic
konkretnego o danym typie. Jest generyczna. Definuje jedną funkcję o
nazwie print; która jak łatwo się domyśleć przyjmuje jako argument
wartość typu t i zwraca... string. Znowu można myśleć o tym jak o
rodzaju interfejsu w Javie (o nazwie Print i jednej metodzie print); a
raczej trait w Scali (ponieważ typeclass może mieć implementację)
tyle, że jest on o niebo lepszy :).

Jak ta klasa ma działać na naszym typie Maybe? Tworzymy instancję dla
naszego typu (mówimy Haskellowi w jaki sposób ma zaaplikować powyższą
funkcję do naszego typu. Robimy to poprzez utworzenie instancji naszej
klasy typów dla typu Maybe):

instance Print Maybe where
print (Just a) = "Just " ++ (show a)
print Nothing = "Nothing"

Trochę tu oszukuję używając wbudowanej funkcji show, która robi
dokładnie to co print - wypisuje zawartość argumentu jako ciąg znaków,
oraz używając pattern matchingu - ; ale tylko trochę (aha ++ to
konkatenacja w Haskellu) (Powyżej definicja funkcji print może
wyglądać dziwnie. W Haskellu możemy definiować funkcje wariantowo
wypisując wszystkie warianty (to tak jakbyśmy mówili, że jeśli
argumentem będzie (Just a) to ma się zachowywać tak, a jeśli Nothing
to inaczej. Znowu, jest to bardzo spójne i wygodne, i generalnie tak
jak się definiuje funkcje w matematyce. Np. definicja fibonacci w
Haskellu:

fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

Ale wracając do tematu. Teraz możemy używać naszej funkcji print dla
naszego typu.

> print Just "foo"
Just foo

> print Nothing
Nothing

Dlaczego to jest ciekawe i jaki ma to sens? Nie łatwiej czegoś takiego
zrobić w Javie z wykorzystaniem dziedziczenia? No więc czasami łatwiej
a czasami trudniej. Powiedzmy, że w Javie chcemy dodać operację add do
typów numerycznych. Jak to zrobimy? Idealnie by było gdyby można było
to zrobić na poziomie Number. Ale nie można. Nawet gdybyśmy mogli to
musielibyśmy zaimplementować tę metodę w każdej podklasie lub
odwoływać się do rzutowania. W Haskellu jest to proste i jak
najbardziej możliwe.

Jakie ma to wady? A no takie, że w Haskellu jeśli rozszerzymy nasz typ
danych (załóżmy, że do naszego Maybe dodamy nowy konstruktor np.
SomeCrap a b, przyjmujący dwa argumenty) to musimy zmienić każdą
funkcję operującą na naszym typie). To jest tzw. "expression problem":

http://en.wikipedia.org/wiki/Expression_Problem

(świetny artykuł na ten temat jest tutaj:
http://journal.stuffwithstuff.com/2010/10/01/solving-the-expression-problem/
Uprzedzam również odpowiedź, że żaden język dynamiczny tutaj nie
rozwiązuje problemu, nawet clojure :>)

W językach funkcyjnych łatwo jest dodać funckje do istniejących typów,
w językach obiektowych odwrotnie, łatwo jest rozszerzyć istniejące
typy. Świetny opis jest tutaj:

http://journal.stuffwithstuff.com/2010/10/01/solving-the-expression-problem/

Jak to wszystko ma się do Scali i typów klas, prezentowanych przez
Czarka?

Ano w Scali case classes to mniej więcej odpowiednik ADT. Powiedzmy,
że Option mogłoby być zdefiniowane mniej więcej (mniej niż więcej bo
się nie skompiluje, jako, że case classes bezparametrowe są deprected
ale można to wyłączyć;)) tak w Scali:

abstract sealed class Maybe[T];
case class Just[T](a:T) extends Maybe[T]
case class Nothing[T] extends Maybe[T]

Mamy nasz ADT w Scali, analogiczny do Haskellowego, nawet trochę
podobne, tyle, że więcej pisania.

Ale wracając teraz do przykładu Czarka i bezpiecznego sumowania list.

Weźmy przykład

sum(List(1, 2, 3, 4))

List[Int] jest naszym ADT a sum jest naszą operacją jaką chcemy dodać
do naszego ADT.

Wykorzystujemy do tego funckcję

def sum[A](nums: Seq[A])(implicit tc: Num[A]) =
nums.foldLeft(tc.zero)(tc.add)

a odpowiednikiem typeclass w Haskelu, w tym przypadku jest:

trait Num[A] {
val zero: A
def add(x: A, y: A): A
}

A odpowiednikiem instancji w Haskellu jest:

implicit object IntNum extends Num[Int] {
val zero = 0
def add(x: Int, y: Int) = x + y
}

Za całą resztę magii odpowiedzialna jest scala i jej umiejętność
zgadnięcia parametru w wywołaniu funkcji, czyli zamiast tego:

sum(List(1, 2, 3, 4))(IntNum)

Mamy to:

sum(List(1, 2, 3, 4))

Inny świetny opis typeclass w Scali jest tutaj:

http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-i.html

Szczególnie ciekawe są uwagi końcowe o globalnym kontekście typeclass
w haskellu i lokalnym w Scali.

Jak znajdę chwilkę to napiszę też trzy zdania o higher-kinds (również,
dużo bardziej czytelnie się to przedstawia w Haskellu, głównie z
dzięki jego świetnemu systemowi typów) oraz o Monadach ;). O tych
drugich warto tylko wspomnieć, że są panaceum na problemy języków
funkcyjnych, szczególnie tych z etykietką 'pure' jak Haskell, które
nie mają wsparcia dla typowo imperatywnych konstrukcji jak np. pętle.
Są po prostu sposobem na sekwencyjne wykonywanie obliczeń i raczej
mają niewielki sens w językach imperatywnych gdzie mamy np.
konstrukcję for; może dlatego wydają się dość dziwnym tworem (zresztą
w skali każda Monada może być wykorzystana w pętli for).

Aha - kod z mojego posta na pewno się nie skompiluje :).

Chętnych zapraszam do dyskusji na nową grupę:

Warsaw Area Scala User Group :)
http://groups.google.com/group/waseg

A.

On 6 Lis, 16:46, Jacek Laskowski <ja...@laskowski.net.pl> wrote:
> Cześć!
>
> Warszawska Grupa Użytkowników Javy (Warszawa JUG) [1] zaprasza na 71.
> spotkanie, które odbędzie się w najbliższy wtorek, 9. listopada o
> godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w
> Warszawie.
>
> Temat: Sztuczki w językach programowania
> Prelegent: Cezary Bartoszuk
>
> Rozwijane obecnie języki programowania pełne są sztuczek: technik,
> wzorców, metod lub przepisów, których przyjęło się używać do
> osiągnięcia konkretnego celu. Sądzę, że aby poszerzyć swoją wiedzę o
> programowaniu warto poznać smaki ciekawych sztuczek stosowanych w
> różnych językach programowania.
>
> Pogadankę o "sztuczkach" (jak będę je nazywał ze względu na to, że są
> bytami bardzo różnych rodzajów) podzieliłem na trzy zasadniczo różne
> części:
>
> 1) Typowanie
> 2) Przepływ danych
> 3) Przepływ sterowania
>
> W każdej z tych części w sposób dość popularnonaukowy (i w dużej
> mierze opierając się na intuicjach) omówię kilka sztuczek jakie
> stosowane są w językach programowania. Każda sztuczka będzie miała
> charakter informacyjny wraz z krótkim przejrzeniem plusów i minusów
> danego rozwiązania.
>
> Do worka ze sztuczkami wrzucę między innymi: funkcje i typy wyższych
> rzędów, kontynuacje, jedną lub dwie monady i polimorfizm w różnych
> smakach.
>
> Cezary Bartoszuk jest studentem Wydziału Matematyki, Informatyki i
> Mechaniki, kierunku informatyka. Interesuje się programowaniem
> funkcyjnym, współbieżnością i clean-codem. Zawodowo programista
> Pythona.
>
> Planowany czas prezentacji to 1,5h, po których planuje się
> 15-30-minutową dyskusję.
>
> Wstęp wolny
>
> Zapraszam w imieniu prelegenta i grupy Warszawa JUG!
>
> [1]http://warszawa.jug.pl

iirekm

unread,
Nov 15, 2010, 8:36:29 AM11/15/10
to Warszawa Java User Group (Warszawa JUG)


On 15 Lis, 13:57, Artur Karazniewicz <karaz...@gmail.com> wrote:
> Niestety nie byłem na samej prezentacji ale temat jest bardzo ciekawy.
> Fajnie, że jest nagranie. Byłoby super fajnie, gdyby jednak wrzucić to
> na parleys, bo można tam umieszczać również prezentacje, tak aby było
> lepiej widać co się na slajdach dzieje.
>
> Co do samego tematu. To Czarek poruszył bardzo ciekawe aspekty
> języków, szczególnie w kontekście Javy. Mnie osobiście zabrakło jednak
> trochę pogłębienia tematu przykładami, choć wiem, że omawianych cech
> nie da się ująć sensownie w 1,5h. Czasami może było trochę zbyt
> abstrakcyjnie i może trochę za szybko; tak mi się wydawało po
> pytaniach dotyczących np. higher kinds. Ciekawe byłoby zaprezentowanie
> w innych językach niż Scala.

No właśnie: tylko nieliczni z nas mogą poużywać Scali w pracy w
firmie. Nieważne czy była to decyzja kogoś z góry, albo inna przyczyna
(np. niewiele dobrych narzędzi do Scali), większość z członków WJUG
zapewne pracuje w "czystej" Javie, i nieprędko to się zmieni. Trzeba
szukać rozwiązań "zastępczych" by wypełnić braki w samym języku Java.
Takimi zastępnikami mogą nimi być:
- Annotation Processing Tool - używane m.in. przez całkiem już
słynnego Lomboka, czy JPA 2.0
- AspectJ - używane m.in. przez Springa
- refleksja, bajtkod - Javassist
- dla wielu bolączką w Javie jest brak wygodnej składni do domknięć
czy wyrażeń lambda, co niemal eliminuje Javę jako język do
programowania funkcyjnego. Jest jednak pewien sposób za pomocą
podwójnych klamer: new Closure(){{result = wyrażenie;}} - lepsze to,
niż nic, a mając wyrażenia lambda czy closures można już robić wiele
ciekawych rzeczy, bez czekania aż wprowadzą wyrażenia lambda w Javie 8.

Jacek Laskowski

unread,
Nov 15, 2010, 8:38:40 AM11/15/10
to warsza...@googlegroups.com
2010/11/15 Tomasz Szymański <szi...@szimano.org>:

> A możecie mi podać choćby jeden powód dlaczego nie wrzuciliście tego na parleys ?

Jest tylko jeden, więc łatwo - nie wiem, jak to zrobić. Pisałem o tym
i jedyne, co dostałem spowrotem, to coś ala "U mnie działa". Zależało
mi na szybkim udostępnieniu, a tomi się zgłosił, więc skorzystałem z
możliwości. Jedno nie przekreśla drugiego, a dodatkowo poszerza grono
osób, które mogą wrzucić filmik na parleys. Są chętni? Mogę pomóc,
jeśli wyjaśni mi się cały proces łopatologicznie. Na MBP nie działa -
nie mogę wczytać filmu - klient nie reaguje na wskazanie go :(

Jacek Laskowski

unread,
Nov 15, 2010, 8:42:12 AM11/15/10
to warsza...@googlegroups.com
2010/11/15 Tomasz Szymański <szi...@szimano.org>:

> Jak coś robimy, to róbmy to porządnie, bo tak to szkoda czasu.

Nie szkoda czasu, jeśli efektem było szybkie (liczone w dniach, nie
tygodniach, czy m-cach) udostępnienie filmu szerokiej publiczności.
Liczę, że znajdą się chętni na synchronizację ze slajdami i
upublicznienie na parleys.

Lukasz Lenart

unread,
Nov 15, 2010, 8:49:12 AM11/15/10
to warsza...@googlegroups.com
W dniu 15 listopada 2010 14:42 użytkownik Jacek Laskowski
<ja...@laskowski.net.pl> napisał:

> Liczę, że znajdą się chętni na synchronizację ze slajdami i
> upublicznienie na parleys.

tia.... ;-)

Adam Warski

unread,
Nov 15, 2010, 9:42:57 AM11/15/10
to warsza...@googlegroups.com
Bardzo ciekawy post :)
Co do prezentacji to +1.

> W językach funkcyjnych łatwo jest dodać funckje do istniejących typów,
> w językach obiektowych odwrotnie, łatwo jest rozszerzyć istniejące
> typy.

I tutaj jeden z kolejnych plusów Scali: w zależności od problemu, można wybrać albo rozwiązanie rozszerzalne o typy (czyli "tradycyjne" OO) lub funkcje ((sealed) case class-y). Ciekawe swoją drogą w ilu przypadkach rzeczywiście potrzebna jest rozszerzalność w obu kierunkach - przypuszczam że rzadko, ale to bym musiał zdecydowanie dłużej w Scali popisać.

Bo jednak Java zmusza nas do wykorzystania jednego mechanizmu do wszystkiego. Co prowadzi do różnych dziwnych hacków aby ten jedyny słuszny mechanizm obejść ;).

--
Adam Warski
http://www.warski.org
http://www.softwaremill.eu


iirekm

unread,
Nov 15, 2010, 10:14:25 AM11/15/10
to Warszawa Java User Group (Warszawa JUG)


On 15 Lis, 15:42, Adam Warski <a...@warski.org> wrote:
> Bardzo ciekawy post :) (...)
> I tutaj jeden z kolejnych plusów Scali: w zależności od problemu, można wybrać albo rozwiązanie rozszerzalne o typy (czyli "tradycyjne" OO) lub funkcje ((sealed) case class-y). Ciekawe swoją drogą w ilu przypadkach rzeczywiście potrzebna jest rozszerzalność w obu kierunkach - przypuszczam że rzadko,

Nie tak rzadko - użytecznie jest i OOP, podejście imperatywne, jak i
podejście funkcyjne - zależy co do czego, weźmy np. poniższy (jakże
funkcyjny) kawałek kodu z C#:

public class MainClass {
public static void Main() {
Employee[] employees = jakieś przykładowe dane
EmployeeOptionEntry[] empOptions = jakieś przykładowe dane

var employeeOptions = employees.SelectMany(e => empOptions
.Where(eo => eo.id == e.id)
.Select(eo => new {
id = eo.id,
optionsCount = eo.optionsCount
}));

foreach (var item in employeeOptions)
Console.WriteLine(item);
}
}


Całość jest tutaj: http://www.java2s.com/Code/CSharp/LINQ/AMoreComplexExampleoftheFirstSelectMany.htm
Podobny kod można zapewne wyprodukować w Groovym czy Scali - tylko
nazwy używanych funkcji będą inne. Spróbujcie odpowiednik tego kodu
zrobić w Javie w podejściu imperatywnym - potrzebne będą zapewne
zagnieżdżone pętle for, haszmapy, itd, a czytelność takiego kodu by
była opłakana. Naprawdę wstyd, że Java nie ma wyrażeń lambda - wtedy i
w Javie można by było łatwo zaimplementować powyższy przykład.

Tomasz Szymański

unread,
Nov 15, 2010, 10:16:59 AM11/15/10
to warsza...@googlegroups.com
A moim zdaniem efekt bedzie taki, ze juz nikt na pewno tego nie wrzuci "bo skoro jest, to lepiej wrzucic co innego..."

T.

Adam Warski

unread,
Nov 15, 2010, 10:23:26 AM11/15/10
to warsza...@googlegroups.com

> On 15 Lis, 15:42, Adam Warski <a...@warski.org> wrote:
>> Bardzo ciekawy post :) (...)
>> I tutaj jeden z kolejnych plusów Scali: w zależności od problemu, można wybrać albo rozwiązanie rozszerzalne o typy (czyli "tradycyjne" OO) lub funkcje ((sealed) case class-y). Ciekawe swoją drogą w ilu przypadkach rzeczywiście potrzebna jest rozszerzalność w obu kierunkach - przypuszczam że rzadko,
>
> Nie tak rzadko - użytecznie jest i OOP, podejście imperatywne, jak i
> podejście funkcyjne - zależy co do czego, weźmy np. poniższy (jakże
> funkcyjny) kawałek kodu z C#:


Chodziło mi o to w ilu przypadkach potrzebna będzie rozszerzalność naraz. Tzn. że masz typ który jednocześnie potrzebujesz rozszerzać łatwo w obu kierunkach. A właśnie w tym że możesz wykorzystać i OOP i FP zależnie od sytuacji widzę zaletę Scali.

Artur Karazniewicz

unread,
Nov 15, 2010, 11:46:02 AM11/15/10
to Warszawa Java User Group (Warszawa JUG)
>Ciekawe swoją drogą w ilu przypadkach rzeczywiście potrzebna jest rozszerzalność w obu kierunkach - przypuszczam że rzadko, ale to bym musiał zdecydowanie >dłużej w Scali popisać.

To co napisałem generalnie powinno brzmieć dość znajomo: 'łatwe
dodawanie operacji (funkcji) do typów'. Dokładnie to robi Visitor. W
pewnym sensie właśnie data types oraz typeclasses to odpowiedź na ten
wzorzec. Więc przydają się równie często jak Visitor, tyle, że dużo
mocniejszy.

Dla przykładu często chcemy dodać nowe operacje do jakichś złożonych
struktur danych. Podwiedzmy typowe operacje "toString", "toXml",
"toJSON", parsowanie etc. Weźmy żeby było łatwo drzewo binarne. W
scali przy pomocy ADT można zrobić to tak:

abstract sealed class Tree[T]
case class Tip[T](v:T) extends Tree[T]
case class Node[T](l:Tree[T], r:Tree[T])

Teraz np. proste drzewo binarne możemy definiować tak:

def l = Node(Tip(1), Node(Tip(12),Tip(22)))

Powiedzmy, że chcemy dodać operację "dump"

Możemy to zrobić tak:

def dump[T](t:Tree[T]):String = t match {
case Tip(a) => "Tip " + a
case Node(l,r) => "Node \n" + dump(l) + "," + dump(r) }

dump(l)

Node
Tip 1,Node
Tip 12,Tip 22

Mało tego równie dobrze, dzięki implicit konwersji możemy zrobić
prostą operację:

l.dump()

A.

Artur Karazniewicz

unread,
Nov 15, 2010, 11:48:03 AM11/15/10
to Warszawa Java User Group (Warszawa JUG)
Mała poprawka; powinno być:

case class Node[T](l:Tree[T], r:Tree[T]) extends Tree[T]

A.
Reply all
Reply to author
Forward
0 new messages