Po wideokonferencji z Matzem

Opublikowane przez Jarosław Zabiełło Thu, 21 Feb 2008 00:08:00 GMT

Zapowiadana wcześniej wideokonferencja z twórcą języka Ruby, została dobrze przygotowana przez Google. Obraz był wyświetlany na dużym ekranie, i co ważniejsze można było zadawać pytania prelegentowi i udało mi się nawet dwa zadać. :)

Prawdę mówiąc oczekiwałem że Matz powie coś nowego. Nic takiego nie było. Mam wrażenie że nawet slajdy jakie były wyświetlane gdzieś już wcześniej widziałem. Moim zdaniem, Matz mówi tak słabo po angielsku, że powinien mówić w swoim języku, po japońsku, i korzystać z tłumacza. Nie sądzę że byłoby wolniej, a nie trzeba by było też powtarzać po kilka razy tego samego pytania.

Zapytałem się go, czy istnieje jakaś oficjalna specyfikacja języka Ruby (lub coś podobnego do pythonowej publicznej listy proponowanych ulepszeń). Brak jednego i drugiego powoduje, że jest pewne zamieszanie co do składni jaka ma wejść do Rubiego 2.0. Tak naprawdę to nikt nie wie w jakim kierunku ta składnia podąża. Np. nie wiadomo czy wcześniej prezentowane przez Matza slajdy to tylko takie luźne myśli, czy też jakieś poważne propozycje. Nie wiadomo też czy cokolwiek z takich “pomysłów” jest dyskutowane w jakimś szerszym gronie poza wąską grupą japońskich samurajów (rozmawiających oczywiście tylko po japońsku).

Matz powiedział że jakaś specyfikacja języka jest tworzona przez grupę tworzącą projekt Rubiniusa i że jest z nimi w kontakcie. Widzę, że Matz zaczyna się z kimś liczyć. To bardzo dobrze. Bo Ruby nie jest taki całkiem młody (jest w tym samym wieku co Java i tylko rok młodszy od Pythona) i już dawno przestał być tylko prywatnym językiem Matza do zabawy.

Zapytałem się Matza też o kwestię składni tzw. named parameters w Rubim. Czy już jest jakaś ustalona składnia i dlaczego po prostu nie skopiuje dobrego i przejrzystego rozwiązania jakie występuje od dawna w Pythonie? Dla tych co nie znają Pythona, przypominam, że chodzi o wygodne wywoływanie funkcji z parametrami występującymi w dowolnej kolejności. Najlepiej zobaczyć to na przykładzie.

def test(a, b, c='C', d='D', *args, **kwargs):
  print a, b, c, d, args, kwargs
test(1, 2)  # => 1 2 C D () {}
test(1, 2, d=3) # => 1 2 C 3 () {}
test(1, 2, 3, 4, 4, 5, 6, 7) # => 1 2 3 4 (4, 5, 6, 7) {}
test(1, 2, d='DE', foo='blah') # => 1 2 C DE () {'foo': 'blah'}

Parametry a i b są obligatoryjne, c i d posiadają domyślne wartości. *args to lista dowolnych parametrów (można dzięki temu wywoływać funkcję z dowolnie wielką liczbą parametrów). Zaś **kwargs to słownik pozwalający na dodanie dowolnej ilości kolejnych named parameters. W Pythonie jest to dosyć czytelne i łatwe do zrozumienia.

W Ruby sytuacja wygląda trochę inaczej. Z jednej strony mamy duże ulepszenie w stos. do Pythona w postaci możliwości wysyłania bloków kodu do metody. Z drugiej strony, nie mam w ogóle możliwości wywołania parametrów w dowolnej kolejności lub wywołania tylko niektórych z nich, resztę zostawiając wartościom domyślnym.

def test(a, b, c='C', d='D', *args, &block)
  print "#{a.inspect} #{b.inspect} #{c.inspect} " 
  puts #{d.inspect} #{args.inspect} #{block.inspect}"
end

W Ruby nie ma jak wywołać test(1,2,d=3). Takie wygodne pominięcie na liście parametru c (bo ma domyślną wartość) i tylko tych parametrów jakie nam pasuje możliwe jest tylko w Pythonie. W Ruby aby zmienić parametr d trzeba wywołać też parametr c, czyli w tym wypadku test(1,2,'C',3). To jest bardzo niewygodne i powszechnie stosowanym trickiem na pominięcie tego ograniczenia jest przekazywanie hasza oraz opuszczanie klamer, które w Ruby są nieobowiązkowe. Zatem dla

def test2(x, opts={})
  puts "#{x.inspect} #{opts.inspect}"
end
test2(1, :d=>4) # => 1 {:d=>4}
test2(1, {:d=>4, :c=>'C'}) # => 1 {:d=>4, :c=>"C"}
# to samo bez nawiasów i klamer:
test2 1, :d=>4, :c=>'C' # => 1 {:d=>4, :c=>"C"}

Pozornie uzyskuje się to samo. Faktycznie jest to tylko “dirty hack” i odpowiednik pythonowej konstrukcji

def test2(x, **opts):
    print x, opts
test2(1, d=4, c='C') # => 1 {'c': 'C', 'd': 4}

Po pierwsze, tym sposobem można do metody przekazać dowolny hasz. Nie ma kontroli na poziomie deklaracji metody, trzeba samemu ją sobie dodatkowo zaimplementować. Np. tak:

def params_check(*args)
  x = args[0].keys - args[1..-1]
  raise "Forbiden params: #{forbiden.inspect}" unless x.empty?
end

def fun(x, opt={})
  params_check opt, :c, :d
  puts "#{x.inspect} #{opt.inspect}"
end

fun(1, :c=>'CE') 
# => 1 {:c=>"CE"}

fun(1, :c=>'C', :d=>4) 
# => 1 {:d=>4, :c=>"C"}

fun(1, :c=>'C', :d=>4, :foo => 'bar', 'hello' => 'world')
# => RuntimeError: Forbiden params: [:foo, "hello"]

Po drugie, w wypadku przekazywania dodatkowego hasza, pierwszy musi posiadać klamry, bo inaczej nie ma możliwości rozróżnienia które dane mają wejść do pierwszego, a które do drugiego hasza.

Ale wracając do tego co odpowiedział Matz. Przyznał wprost, że te named parameters jakie miałyby wejść do Ruby 2.0 są tak naprawdę zwykłym… haszem! (zobacz ten slajd z wcześniejszej prezentacji Matza)

def fun(x, c : 'C', d : 4)
  # ...
end

co naprawdę znaczy tyle co

def fun(x, {c : 'C', d : 4})
  # ...
end

Taka innowacja nie jest w zasadzie żadną innowacją, ale sprowadza nas z powrotem do tego co już jest. Jeśli zaś jedyna zmiana jaka tu ma miejsce dotyczy tylko zastąpienia znaków => jednym znakiem dwukropka (tak jak w Pythonie nawiasem mówiąc) to albo ja tu czegoś nie rozumiem, albo to w ogóle jest bez sensu.

Tagi , , ,  | 30 comments

Comments

  1. Avatar Konrad Delong powiedział about 7 hours later:

    Też irytują mnie argumenty formalne w ruby’m. Właściwie to nie jest nawet odpowiednik takiego kodu w Pythonie:

    def test2(x, **opts): print x, opts test2(1, d=4, c=’C’) # => 1 {‘c’: ‘C’, ‘d’: 4}

    ponieważ wywołanie: test2(zmienna, slownik) jest niepoprawne – należy “rozpakować” słownik za pomocą dwóch gwiazdek.

    W ruby takie wywołanie podstawi słownik pod domyślny drugi argument. Boli to szczególnie przy zmiennej liście argumentów, gdyż wymaga implementowania wciąż na nowo logiki ich rozpakowania.

  2. Avatar Michal powiedział about 19 hours later:

    Japońscy samuraje to takie samo stwierdzenie jak mokra woda :P

  3. Avatar Radarek powiedział 1 day later:

    Jarek, Matz już od pewnego czasu liczy się z innymi (tu podany był przykład Rubiniusa). Do tej pory nie było specyfikacji, ale takowa de facto już w dużej mierze istnieje dzięki specom z Rubiniusa (w połączeniu z testami JRubiego stanowi dobrą bazę do testów).

    Co do parametrów nazwanych. Wiem, że programujesz też w Pythonie i brakuje ci tego w Rubym. Jednakże będę się upierał, że hashe w 90% je zastępują.

    Z całym szacunkiem dla Ciebie, ale czy uważasz, że Matz jest jaki przygłupawy czy co? Zdaje się on chyba lepiej zna się na tworzeniu i implementacji języków niż my ;). Nie da się zadowolić wszystkich. Cóż, życie :). I czy aż tak często korzystasz z named parameters w Pythonie?

    Angielski Matza jest faktycznie słaby, ale chyba to typowe dla Japończyków (ko1 i reszta ruby-team mówi jeszcze słabiej). W sumie to najtrudniej jest mu odpowiadać (i zrozumieć) na zadawane pytania. Tłumacz IMHO by tu jednak nie pasował.

    “Nie wiadomo też czy cokolwiek z takich “pomysłów” jest dyskutowane w jakimś szerszym gronie poza wąską grupą japońskich samurajów (rozmawiających oczywiście tylko po japońsku).”

    Pytałes czy tak Ci sie wydaje. Wierz mi, że Matz sam nie implementuje Rubiego, a wiele zmian wczesniej omawia na ruby-core.

  4. Avatar Jarosław Zabiełło powiedział 1 day later:

    @Michal: Co do tego japońskiego, to była wcześniej spora dyskusja na polskim kanale IRC Rubiego (czy Rails, nie pamiętam na którym) Z tym japońskim to chciałem podkreślić że wszystkie główne dyskusje i ustalenia co do rozwoju języka Ruby są prowadzone przez japończyków i po japońsku. Brakuje jakiejś międzynarodowej zorganizowanej formy wprowadzania zmian składni języka Ruby. Coś w stylu Python Enhancement Proposals. To ułatwiłoby możliwość szerszej debaty, zebrania większej ilości ciekawych spostrzeżeń, i lepiej chroniłoby przed jakimiś nieprzemyślanymi propozycjami (tak jak z tymi parametrami nazwanym). Co prawda Matz kiedyś wspominał że chciałby aby coś takiego powstało, ale jakoś nikt tego tematu poważniej nie podjął. Może po części dlatego, że większość sympatyków Rubiego nie ma niestety korzeni pythonowych i dlatego im nawet taka myśl nie powstała w głowie, że coś można tak dobrze rozwiązać.

    @Radarek: Uważasz, że zastąpienie hasza takim samym haszem, tylko z kosmetyczną zmianą składni, to owe czekiwane named parameters? Nie chcę oceniać Matza. Ja prostu kompletnie nie rozumiem co on chce w ten sposób uzyskać? Jeszcze większe zamieszanie? Stare znaki => zastąpimy dwukropkiem i co to niby ma zmienić? Nadal to nie będą żadne named parameters tylko ten sam, stary hack jaki jest do tej pory używany. Co prawda, można jakoś z tym żyć, ale na pewno Ruby zyskałby na przejrzystości gdyby je jednak dodano. Tylko nie to, co podał Matz, bo to nic nie zmienia. I to jest mój punkt w tej dyskusji.

    BTW, już wiem gdzie widziałem niektóre slajdy jakimi ostatnio posługiwał się Matz. Znaleźć je można screencaście RubyConf 2007 Keynote Address: Does Language Matter?. Tam też padła dziwaczna propozycja Matza odnośnie parametrów nazwanych. Nawet nie chodzi o te dwukropki. Zobaczcie sami.

  5. Avatar Radarek powiedział 2 days later:

    Jakby co to prezentacja dostępna jest pod adresem: http://youtube.com/watch?v=oEkJvvGEtB4.

    @Jarek, odnośnie tych parametrów nazwanych. Zapytam na ruby-core, ale jestem pewien, że póki co nowa składnia dla hashy (par1: val1, par2: val2) to jeszcze nie jest ostateczna forma dla tej konstrukcji. Dlaczego tak myślę? Bo przecież Matz ciągle podkreśla, że named params będą dopiero w 2.0, a ta nowa składnia dla hashy jest dostępna już w 1.9 (zresztą padło hasło, że to jest tylko namiastka).

    Skopiować składni bezpośrednio z Pythona nie można, m.in. dlatego, że wywołanie metoda(a=1, b=2) inaczej jest interpretowane przez Rubiego niż w Pythonie (przypisanie do zmiennych podczas wywołania, python nie pozwala na taką semantykę).

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

    @Radarek: tylko że nikt nie wie co tam się znajdzie w tym Ruby 2.0. Matz pokazuje jakieś bezsensowne namiastki i najwyraźniej nie ma pomysłu na ostateczne rozwiązanie tego problemu. Co do tego przypisania zmiennych w wywołaniu funkcji Rubiego, to jest to do niczego niepotrzebne. Na miejscu Matza, ja bym to wywalił w Ruby 2.0 i nic by wtedy nie stało na przeszkodzie uzyskania pięknej, czytelnej składni named parameters tak, jak to jest w Pythonie.

  7. Avatar lopex powiedział 3 days later:

    Z tym pięknem bym nie przesadzał i wybrał jednak dwukropek. Składnia pythona jest delikatnie mówiąc nieintuicyjna, ktoś może pomyśleć że to deklaracja zmiennej lokalnej. W Rubym tak jak w lispie wszystko ma wartość i głupio było by w zależności od kontekstu zmieniać operator przypisania. Co do haszy nie wypowiadam się, póki co.

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

    @lopex: coś za coś. Sądzę, że warto mieć lepsze, przejrzyste named parameters niż jakieś przypisywanie zmiennych w parametrach formalnych. Składnia Pythona jest tu bardzo intuicyjna. Dużo bardziej niż dzikie pomysły z wartościami domyślnymi do parametrów formalnych występujące przed parametrami wymaganymi.

    A co do tych dwukropków, to one absolutnie nic nie wnoszą do tematu. Powiedziałbym, że są w ogóle nie na temat. To jest przecież ten sam stary hasz co wcześniej, tylko że o pythonowym, a nie perlowym, wyglądzie. Aktualnie w Ruby 1.9 robi się tu mały burdel, bo hasze mają teraz dwa rodzaje składni (jedna z dwukropkiem, druga z =>).

    Czy Ruby 2 ma używać dwie składnie haszy, czy starsza składnia wyleci ze standardu? A jak wyleci to co z kluczami będącymi stringami a nie symbolami? W Ruby 1.9 { foo: 'bar'} jest tym samym co { :foo => 'bar'}, zaś już {'foo':'bar'} wywala wyjątek (trzeba więc użyć starej składni {'foo'=>'bar'}). Dziwactwo jakieś się porobiło.

  9. Avatar lopex powiedział 3 days later:

    Dwukropki właśnie wnoszą bardzo dużo, a to dlatego że mogłbyby nie tworzyć hasha.

  10. Avatar Jiima powiedział 4 days later:

    Hej. Nie odnosicie wrażenia, że dyskutujecie nad wyższością Bożego Narodzenia nad Wielkanocą? Nie chcę marudzić, ale tak naprawdę nie ma to większego znaczenia czy jest to hash czy nie. W Perlu wszystkie argumenty są przekazywane jako lista (dla purystów perlowych – tablica). W Javascript tak naprawdę też, a konkretne zmienne parametrów to jedynie cukierek syntaktyczny. @JZ Trochę nie rozumiem twojej niekonsekwencji. Wcześniej dyskutowałeś ze mną nad tym, jakie jest statyczne sprawdzanie typów i że dobre unit testy są dużo lepsze (ostatnio powoli zaczynam się z tobą zgadzać, ale to chyba Squeak rzuca mi się na mózg :P) . A tutaj narzekasz że w Ruby nie ma statycznego sprawdzania istnienia bądź nie argumentów nazwanych (moim zdaniem jeszcze lepiej by było, gdyby te pozycyjne też były opcjonalne). Poza tym porównywanie Ruby i Pythona jest trochę bez sensu – każdy z tych języków ma swoje mocne i słabe strony i co gorsza, jedynym sposobem na ich pogodzenie jest… stworzenie nowego języka. Tylko jak cudowny by on nie był, raczej się nie przyjmie, przynajmniej dopóki Microsoft albo Sun nie uznają że da się na nim zarobić…

  11. Avatar Jarosław Zabiełło powiedział 4 days later:

    Pomijając to, że nie podoba mi się składnia dwukropka, może to i byłoby jakieś rozwiązanie ale pod warunkiem, że to ta składnia nie byłaby alternatywną składnią hasza (w tak to funkcjonuje teraz w Ruby 1.9). Jak sobie wyobrażasz wywołanie funkcji z named parameters oraz dodatkowym haszem? Będą wtedy same dwukropki czy jedno i drugie?

    Ja bym tam głosował aby nie można było przypisywać zmiennych w parametrach formalnych (tak jak w Pythonie). Ustępstwo niewielkie a korzyści spore.

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

    @Jiima: Jeśli to hasz to nic to nie zmienia. Używanie hasza w Ruby do symulacji named parameters już jest od dawna. Nie pamiętam abym bronił samych unit testów, chodziło mi Shoulda który dostarcza BDD na bazie unit testów. Głównym problemem z RSpec była magia składni. Jednak książka “The Rails Way” mi to trochę wyklarowała. Już to nie jest problemem, a RSpec zaczyna stawać się wiodącą biblioteką Rubiego do BDD. Jest bardziej zaawansowany niż Shoulda czy test/specs. Widziałeś RSpec Stories?

    Statycznego sprawdzania typów nigdy nie broniłem, zawsze byłem jego przeciwnikiem, więc tu ci się coś pomyliło.

  13. Avatar Jiima powiedział 4 days later:

    @JZ
    No właśnie o to chodzi, że zawsze byłeś jego przeciwnikiem, tymczasem zarzucasz rozwiązaniu haszowemu, że nie wymusza dyscypliny podawania wymaganych parametrów :) Tymczasem są to dość podobne zagadnienia.

    Ja tam jestem raczej za tym, żeby składnia słowników wykorzystywała : zamiast tej debilnej perlowej strzałki =>. Mniej pisania i też wszystko się zunifikuje :).

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

    Przeciwnikiem czego? Z tymi haszami to jest nawet nie podobnie, to jest identycznie i dlatego to jest bez sensu nazywać to named parameters o których potrzebie dodania trąbiło się już od dawna. Jestem przeciwko stosowaniu hasza jako protezy named parameters jeśli byłaby możliwość mieć je z prawdziwego zdarzenia, tak jak np. w Pythonie. A z braku laku, mniej tam perlowy dwuznak nie przeszkadza.

  15. Avatar Jiima powiedział 4 days later:

    Przeciwnikiem statycznego typowania. Wiem, że czasem trudno mnie zrozumieć, ostatnio zamiast krwi mam energy drinki (zamykamy projekt mocno po terminie), więc sorry za niejasne zdania.

    Więc zbierając to do kupy, bo chyba się w ogóle nie rozumiemy, chodzi mi o to, że IMAO właśnie te nazwane parametry nie są do niczego potrzebne, generalnie idealnym rozwiązaniem byłoby kompletnie dynamiczne rozpatrywanie listy argumentów, tak jak w ECMAScripcie. Skoro chcemy dynamizmu i wolności, to czemu potrzebne są takie rozwiązania jak statyczne named parameters? Czy teraz wyksztusiłem z siebie składne zdanie :P?

  16. Avatar Jarosław Zabiełło powiedział 4 days later:

    Wyksztusiłeś :) Nie wiem jakie znowu statyczne parametry? W Pythonie są (1) parametry wymagane, (1) z przypisaną wartością domyślną, (3) w dowolnej, nieokreślinej ich liczbie i (4) w dowolne, nieokreślonej liczbie jako named parameters. Jest to bardzo czytelne i łatwe w użyciu. Nie wiem o co ci chodzi z tymi dynamicznymi parametrami, te w Pythonie (jak trzeba) też są dynamiczne, ale bez wariactwa. Podałbyś jakiś przykład lepiej.

  17. Avatar MacRayers - YAR powiedział 4 days later:

    Jarku, chwaliłeś się już, że w Helionie w zapowiedziach o ROR szykowana jest pozycja Twojego autorstwa ?

    IMHO : bardzo dobry ruch. Kupię i ocenię, mam nadzieję, że się nie zawiodę.

  18. Avatar rsz powiedział 5 days later:

    “Z jednej strony mamy duże ulepszenie w stos. do Pythona w postaci możliwości wysyłania bloków kodu do metody”

    - w jakim sensie w Pythonie nie można wysyłać bloków? Możesz zarówno funkcje nazwane, jak i anonimowe “wysyłać”...

  19. Avatar Jarosław Zabiełło powiedział 5 days later:

    rsz: Python potrafi przesłać blok kodu, ale nie potrafi nic w nim zmienić. Stąd np. nie jest możliwe zaimplementowanie w Pythonie czegoś podobnego do railsowych szablonów RJS.

    MacRayers: Pochwalę się jak skończę. Nie będzie to jednak wcześniej niż za jakieś 3 miesiące.

  20. Avatar lopex powiedział 5 days later:

    Nie, python nie potrafi przesłać nienazwanego bloku kodu (jeśli macie na myśli lambdę to nie rozśmieszajcie mnie). Brak domknięć w pythonie to jest jeszcze większa bolączka, btw, mało jest języków które nie mają domknięć (m.in. c/c++/java/python/pascal itp).

  21. Avatar Jiima powiedział 5 days later:

    @lopex

    Zgadzam się, że lambda nie jest żadnym rozwiązaniem, btw Guido podobno rozważał jej wywalenie (więc dziwi mnie że została). Blok to nie to samo co funkcja, przy czym “klasyczny” blok w Ruby nie jest również domknięciem. Z resztą to w sumie nie taki zły pomysł, domknięcia potrafią wyczyniać dziwne rzeczy z pamięcią, więc lepiej mieć wybór czy robimy domknięcie czy zwykły blok.

    Ale nie wiem, czemu brak domknięć jest “bolączką”. Dla mnie w Rubym bolączką jest nieciekawa implementacja kontynuacji (póki co), ale doskonale wiem, że sporo ludzi sobie bez nich radzi i nawet uważa je za pomyłkę. To po prostu inny styl programowania. W Javie masz anonimowe funkcje wewnętrzne, a w C# delegacje anonimowe i cały ten bajzel dostarczany przez LINQ, więc za domknięciami bym tak bardzo nie płakał. Z drugiej strony w JS każdy blok jest domknięciem (podobnie jak w Perlu) i sporo z tego wynika często kłopotów…

    Jedynym “bólem” składni Pythona jest to, że nie daje się w nim tak ładnie i czysto tworzyć języków specyficznych dla domeny, jak w Ruby czy Smalltalku. Ale czy naprawdę jest to taka straszna wada?

  22. Avatar Jiima powiedział 5 days later:

    @JZ
    Właśnie o te parametry wymagane mi chodziło. Nie widzę dlaczego miałyby być tak istotne, a zdaje się na to najbardziej narzekałeś. Rozwiązanie które aktualnie jest stosowane w Ruby nie przeszkadza mi specjalnie, jedyne w czym przeszkadza to tworzenie sensownej autokompletacji składni w IDE, dlatego nie rozumiem czemu miałoby być to takie złe jak mówisz.

  23. Avatar Jarosław Zabiełło powiedział 5 days later:

    @Jiima: nie mam nic do parametrów wymaganych. Czepiam się tylko tego, że Matz jedną protezę proponuje zastąpić drugą protezą (z hasza na hasz – ale mi inowacja)

  24. Avatar lopex powiedział 5 days later:

    @Jiima

    “klasyczny” blok w Ruby nie jest również domknięciem ?

    Anoniowe klasy w javie dają dokładnie to samo co zagnieżdżonej fukcje pythonowe. C# to jest już inna bajka.

    Domknięcia w rubym nie mogą być optymalizowane bo blok można zawsze potraktować jako Binding. Ale to jest problem Rubiego a nie samych domknięć.

  25. Avatar Jiima powiedział 6 days later:

    @lopex

    Raczej jest “nie – do – końca” domknięciem. Różnice są subtelne ale istotne. Nie rozwodząc się, odsyłam do “the Ruby Way”.

    Anonimowe klasy nie dają do końca tego co funkcje zagnieżdżone, ponieważ są w stanie “domknąć” stan obiektu z którego zostały wzięte, a także nawet stan wewnętrzny funkcji, ale tylko w odniesieniu do zmiennych finalnych. Z tego co wiem, są prace nad tym by to zmienić i dostarczyć Javie “prawdziwych” domknięć.

    C# to niezupełnie inna bajka. Poza dużą ilością przydatnych jak również zupełnie nie trafionych cukierków syntaktycznych jest to Java, z resztą język powstał po to, by odebrać developerów Javy Sunowi i skłonić ich do korzystania z narzędzi Microsoftu.

    Mówiąc o problemach z domknięciami, miałem na myśli inne języki niż Ruby, takie w których stosuje się je częściej, czasem zupełnie nieświadomie. Takimi językami są Perl i ECMAScript, zwłaszcza ten ostatni. Generalnie Closure zaciemnia sporo rzeczy, choć ułatwia tworzenie języków specyficznych dla domeny i niektóre inne sprawy, tak że nie wiem czy to taka super – konstrukcja. Jest też w dużej mierze niezgodna z zasadami OOP (nic dziwnego, w sumie pochodzi z języków funkcyjnych)

  26. Avatar lopex powiedział 6 days later:

    @Jiima

    “nie – do – końca” domknięciem: może jednak rozwiniesz ? Dlaczego “the Ruby Way” ma być dla mnie autorytetem ? Znam dobrze bebechy MRI i jruby, chcesz mnie oświecić ?

    “ponieważ są w stanie “domknąć” stan obiektu z którego zostały wzięte” Haha!, jak to każda metoda obiektu ;). Dlatego powtarzam: zagnieżdżone funkcje pythonowe dają dokładnie to samo co klasy anonimowe w javie.

    C# to zupełnie inna bajka pod względem domknięć, bo są, póki co… (taki zresztą był kontekst postu). A kosmicznie inna bajka jeśli rozchodzi się o całą resztę (wliczając JIT/AOT a nawet semantykę bytecodu)

    Faktycznie, dla początkujących domknięcia mogą być zaciemniające, ale są zbyt mocnym narzędziem aby z nich rezygnować. Obiektówka też jest zaciemniająca bo jest niejawny self/this ?

    Niezgodna z zasadami OOP ? A co ma piernik do wiatraka ? Jakoś w Smalltalku, Scali czy IO spisują się wyśmienicie, co to za herezje ?

  27. Avatar Jiima powiedział 6 days later:

    @lopex

    Co kto lubi… Ja też znam i nie mam ochoty się przepychać.

    Jedna uwaga – co do klas wewnętrznych, nie tylko anonimowych w Javie, to wypaczasz to co powiedziałem. Klasa wewnętrzna nie jest metodą, tylko klasą, która może funkcjonować niezależnie od obiektu z którego została wzięta i niezależnie od metody która ją utworzyła. Stąd jest pewną odmianą domknięcia.

    A co do zaciemniania – problem wbrew pozorom dotyczy nie tylko początkujących. Im czytelniejszy kod, tym lepiej, a closure potrafi to nieźle zagmatwać. Nie mówię, że trzeba z nich zrezygnować, a jedynie, że ich brak nie jest powodem do rozpaczy.

    A co do programowania obiektowego, niejawny self / this też nie jest wszędzie, skoro już o tym mówimy.

    Zamiast mówić że domknięcia są w Smalltalku czy innych językach, powiedz mi jak to umieścić w paradygmacie – tzn. gdzie masz tu obiekt, sygnał itp. To, że jakiś język programowania je posiada, nie oznacza że wsio OK. Nie ma “czystych” języków, implementujących jeden paradygmat, no może poza niszowymi rozwiązaniami takimi jak Haskell.

    I czego się denerwujesz, szkoda zdrowia :)

  28. Avatar lopex powiedział 6 days later:

    Przecież nikt się tu nie piekli. Klasyczna różnica zdań ;).

    Wołania wirtualne też mogą nieźle zagmatwać… Powinny być zlikwidowane.

    No tak, w pythonie też można przekazywać self’a/this’a jawnie: Klasa.metoda(Klasa()). Ale raczej nikt tego nie robi.

    Oj, dlatego mówi się o wielu paradygmatach, nie trzeba tłumaczyć jednego w kontekście drugiego.

  29. Avatar Jiima powiedział 7 days later:

    @lopex

    Czy ja mówię, że coś trzeba zlikwidować? :). Nie noszę sweterków w romby i nie mieszkam w Białymstoku. Po prostu nie płaczę za brakiem domknięć w Pythonie czy brakiem kontynuacji w JVM. Każdy język ma swoje zboczenia i trzeba do nich przywyknąć, jak się będzie próbowało wsadzić wszystko do jednego języka to wyjdzie nam Visual Basic .NET…

  30. Avatar rsz powiedział 7 days later:

    Ależ oczywiście że domknięcia są dostępne w Pythonie, chyba że mówicie o jakiejś innej definicji domknięcia (polecam jakąś książkę albo wykład z informatyki – teoretycznej). I oczywiście że w pythonie można w domknięciu grzebać – tyle że bardzo dookoła. Wg waszej linii ataku, należałoby uznać, że również np. Haskell nie ma domknięć, a to już by było co najmniej niepoważne.

    Jak by nie było, to zarzut że w pythonie nie można przesłać bloku w przeciwieństwie do rubyego jest nieuzasadniony.

    A może, rubinowe chłopaki, wytłumaczycie mi, co to jest dla Was blok i czym się różni od funkcji anonimowej i od domknięcia bo może jest to poprostu różnica terminologiczna.

(leave url/email »)

   Pomoc języka formatowania Obejrzyj komentarz