Scala - język przyszłości

Opublikowane przez Jarosław Zabiełło Sat, 28 Mar 2009 06:17:00 GMT

Kiedy zapytano Jamesa Goslinga (twórcę Javy) o to, który z języków programowania współpracujących z JVM (wirtualną maszyną Javy) by użył teraz, pomijając samą Javę, odpowiedź była zaskakująco szybka i bardzo jasna – Scala.

Nazwa “Scala” pochodzi od “Scalable language” (język skalowalny). Język ten nadaje się równie dobrze do krótkich, zwartych skryptów jak i do tworzenia wydajnych, ogromnych, bezpiecznych systemów sieciowych. W swych założeniach Scala nawiązuje do minimalizmu składni Lispa i Smalltalka (większość rzeczy oparta jest na bibliotekach a nie na składni) dzięki czemu język ten praktycznie nie ma ograniczeń rozwoju i doskonale się skaluje (w miarę potrzeb można tworzyć nowe typy i całe nowe struktury wyglądające jak nowa składnia języka).

Scala jest językiem kompilowanym do bytecodu JVM dzięki czemu potrafi się integrować w sposób praktycznie przezroczysty, z całą platformą Javy (istnieje co prawda implementacja Scali dla platformy .NET ale jest jeszcze niedojrzała). W Scali mamy też wygodną konsolę do interaktywnego testowania kodu (tak jak to jest w Pythonie i Ruby). W Scali każda wartość jest obiektem, każda funkcja zwraca wartość. Zatem każda funkcja też jest obiektem (first class object). Funkcje są też obiektami wyższego rzędu (higher order kinds), można je zagnieżdżać, przekazywać w parametrach, a nawet stosować mechanizm dziedziczenia.

Java jako platforma i jako język

Słowo “Java” oznacza z jednej strony język programowania, z drugiej platformę JVM. Sam język Java jest co prawda prosty, ale też dosyć toporny. Nic dziwnego, że pada wiele słów krytyki pod jego adresem. Co innego platforma Javy. JVM jest dopracowana, stabilna i szybka (ze swoim HotSpotem potrafi pobić kod napisany w języku C). Biblioteki są dojrzałe i używane masowo w biznesie i instytucjach finansowych. Każda nowość błyskawicznie znajduje swoje odzwierciedleniew Javie (ilość projektów w Javie wielokrotnie przewyższa to, co jest dostępne dla platformy .NET). Platforma Javy mocno prze do przodu i zwiększa stale swoją pozycję. Wydaje się tylko, że sam język nie za bardzo nadąża za tymi zmianami.

Gdy Microsoft “wyskoczył” ze swoją koncepcją .NET umożliwiającą tworzenie aplikacji na tą platformę w kilku językach a nie “jedynym prawidłowym”, można było odebrać to jako prztyczek w nos dla starej doktryny lansowanej kiedyś w środowisku Javy (jako jednego języka do wszystkiego). W rzeczy samej, patrząc dziś, Microsoft ze swymi językami zgodnymi z CLR niczym specjalnym nie zachwyca. Po pierwsze, istnieje dziś już ok. 240 różnych języków zgodnych z platformą Javy (jakieś 5x tyle co dla CLR). Javowe implementacje powstały nawet do języków dynamicznie typowanych (Groovy) oraz takich jak Python (Jython), Ruby (JRuby), JavaScript (Rhino) czy PHP (Quercus).

Po drugie, w przeciwieństwie do .NET, Java jest prawdziwie multiplatformowa (istnieje co prawda projekt Mono, ale wciąż odstaje jakością od windowsowego .NET). Mówiąc krótko, platforma Javy trzyma się mocno. Ale sam język jest przestarzały i wszyscy się zastanawiają nad tym, co by mogło go zastąpić. Moim zdaniem, coraz więcej wskazuje, że tym językiem może być Scala. (Swoją drogą język Java tak całkiem to pewnie nigdy nie zniknie. Raczej zredukuje się do miana assemblera XXI wieku. Zresztą już dziś tak wielu myśli o Javie, jako o assemblerze dla JVM)

Scala jako pure OOP

Scala jest językiem obiektowym w stopniu większym niż Java. W Scali nie ma sztucznego podziału na obiekty i typy prymitywne (int, float, string). Każda wartość jest w Scali pełnym obiektem (choć pod spodem kompilator Scali, tam gdzie się da, sam dokonuje inteligentnych konwersji na javowe prymitywy).

Każdy operator jest też metodą. Np. zapis 1 + 2 odpowiada dokładnie temu samemu co (1).+(2). Innymi słowy obiekt “1” używa tu metody ”+” operującej na parametrze będącym obiektem “2”. A to, że można opuścić nawiasy związane jest z tzw. notacją operatorową jaka jest możliwa w Scali. O ile Ruby pozwala opuszczać nawiasy w niektórych sytuacjach (w definicji i wywołaniu metody), to Scala pozwala na opuszczanie ich w wypadku każdej metody pomiędzy dwoma wyrażeniami. W efekcie Scala pozwala na pisanie testów BDD przypomijących jeszcze bardziej język naturalny niż RSpec do Ruby’ego (też scalaz, scalatest). Także tworzenie nowych języków specjalnego zastosowania, tzw. DSL’i, dzięki notacji operatorowej wyglądają w Scali ładniej niż w Ruby. W ramach żartu pokazującego elastyczność składni Scali napisano nawet interpreter języka BASIC.

W Scali, w przeciwieństwie do Javy, nie ma też statycznych metod ani zmiennych (żałosne jest to, że tak nieobiektowe konstrukcje w ogóle wprowadzono do PHP). Zamiast nich Scala używa singletonów i metod klasowych. Oczywistą przewagą takiego podejścia jest m.in. możliwość dziedziczenia.

Podczas gdy Ruby i Python trzymają definicje metod klasowych i instancji razem, Scala trzyma je zgrupowane oddzielnie.

# Python:
class C(Object):
    def metoda_instancji(self):
        return "Jestem metodą instancji" 
    @classmethod
    def metoda_klasowa(cls):
        return "Jestem metodą klasową" 
print C.metoda_klasowa()
print C().metoda_instancji
# Ruby:
class C
  def self.metoda_klasowa
    "Jestem metodą klasową" 
  end
  def metoda_instancji
    "Jestem metodą instancji" 
  end                       
end
puts C.metoda_klasowa
puts C.new.metoda_instancji
# Scala
class C {
  def metoda_instancji = 
    "Jestem metodą instancji"    
}          
object C {
  def metoda_klasowa = 
    "Jestem metodą klasową" 
} 
println((new C).metoda_instancji)
println(C.metoda_klasowa)         

Scala jako język statycznie typowany z inteligentną inferencją typów

Scala jest językiem statycznie typowanym. Z pewnością ucieszy to tych, co nie chcą pisać tony dodatkowych testów jednostkowych. Statyczna kontrola typów zapewnia większą kontrolę nad kodem. Można się zdziwić, jakim cudem przedstawiony wyżej kod działa, skoro nie ma w nim żadnej deklaracji typów. Właściwie to powyższa deklaracja klas i singletonu formalnie wygląda tak

class C {
  def metoda_instancji(): String = 
    return "Jestem metodą instancji";
}          
object C {
  def metoda_klasowa(): String = 
    return "Jestem metodą klasową";
} 

Jednak nie trzeba pisać tak rozwleklego kodu. Scala posiada wyrafinowany mechanizm inferencji typów pozwalający na ograniczenie niepotrzebnego deklarowania typów w wypadkach kiedy kompilator jest w stanie to sobie samemu wywnioskować (podobną inferencję typów stosują inne języki, np. Haskell).

W Scali także (podobnie jak w Ruby czy JavaScript) końcowe średniki zamykające wyrażenie można pominąć, nawiasy dla metod bez parametrowych są opcjonalne i nie trzeba używać komendy return aby zwrócić wartość z metody. W Scali (podobnie jak w Ruby) zawsze zwracana jest ostatnia wartość wyrażenia.

Scala, podobnie jak Java i Ruby, nie posiada dziedziczenia wielobazowego. W przeciwieństwie do Javy, Scala nie posiada interfejsów. I bardzo dobrze, bo ich przydatność jest wysoce wątpliwa (oczywiście do PHP5 dodano bezmyślnie te nieszczęsne interfejsy). Ich główną wadą jest to, że nie mogą posiadać żadnej implementacji ani deklaracji zmiennych. Z kolei klasy abstrakcyjne w Javie mogą posiadać częściową implementację, ale nie można dziedziczyć po wielu klasach abstrakcyjnych tylko po interfejsach które nie mają żadnej implementacji. Bardzo niewygodne. Scala rozwiązuje ten problem za pomocą traits. Traits działają podobnie do modułów w Ruby. Nie mają konstruktorow ani nie można stworzyć ich instancji więc odpada efekt konfliktu kolejności konstruktorów. Traits mogą jednak podlegać dziedziczeniu, mogą mieć częściową lub pełną implementację metod, oraz mogą posiadać zadeklarowane zmienne. I każda klasa może dziedziczyć po kilku traitsach. Proste i wygodne.

Niejawne konwersje (implicit conversion)

Idea niejawnych konwersji nie jest w zasadzie niczym nowa. Występuje już w języku C. Gdy dodawane są dwie zmienne o typach short i long to ta pierwsza zostaje domyślnie przekształcona do long. Nie trzeba wykonywać żadnego jawnego rzutowania typu.

Scala idzie dalej. Za pomocą mechanizmu implicit conversions potrafi uzyskać efekty podobne jak w Ruby, ale bardziej bezpieczne. Zobaczmy jednak wpierw jak to się robi Ruby (który wykorzystuje swoją koncepcję otwartych klas).

class Integer
  def kb
    self * 1024
  end     
  def mb
    self * 1024 * kb
  end  
end                   

class String 
  def welcome
    "Hello " + self
  end
end

puts 10.kb # => 10240
puts 10.mb # => 10485760
puts "Jarek".welcome # => Hello Jarek

Co prawda Ruby potrafi “zamrozić” swoje obiekty uniemożliwiając ich modyfikację

Fixnum.freeze

class Integer
  def kb
    self * 1024
  end
end   
# => TypeError: can't modify frozen class                     

ale technika ta (zwana też trochę niepoprawnie jako “monkey patching”) jest używana dosyć powszechnie w Ruby. Główną jej wadą jest to, że takie zmiany w klasach są globalne i to może prowadzić do różnych nieporozumień w innych częściach kodu.

Scala nie ma tego problemu. Pozwala na uzyskanie podobnych efektów bez konieczności globalnych zmian w obiekcie. Zamiast otwierania klas, Scala dodaje definicje niejawnych konwersji. Jeśli wywołujemy metodę obiektu której on nie posiada, Scala patrzy na leksykalny kontekst definicji dostępnych konwersji dla danego typu (jak pamietamy, Scala jest językiem statycznie typowanym). Jeśli znajdzie sygnaturę metody taką jak nazwa wywoływanej metody, użyje jej tak jakby należała do obiektu.

class StrConvert(s: String) {
  def welcome = "Hello " + s
}                         

class IntConvert(x: Int) {
   def kb = 1024 * x
   def mb = x * 1024 * kb
}                    

implicit def str_convert(s: String) =  new StrConvert(s)
implicit def int_convert(i: Int) =  new IntConvert(i)

println(10.kb)
println(2 mb)
println("Jarek" welcome)

Kropki w wywołaniach metod są oczywiście w Scali opcjonalne ze względu na notację operatorową.

Niejawne konwersje Scali przydają się w wypadku korzystania z cudzego kodu. Nie musimy (tak jak w Ruby) ingerować i zmieniać cudzych bibliotek. Zamiast tego wystarczy dodać lokalne definicje niejawnych konwersji typów. Przykładem toporności i ograniczeń Javy jest konieczność korzystania z innej składni do operacji na typach BigInteger. Jeśli początkowo pisaliśmy kod używający zwykłych typów int to w wypadku kiedy musi on operować na większych liczbach, czeka nas niezła refaktoryzacja kodu a kod mógłby wyglądać mniej więcej tak jak poniższy kod (przykład dotyczy składni Scali w ktorej też można pisać po “javowemu”)

                        
import java.math.BigInteger 

def factorial(x: BigInteger): BigInteger = 
 if (x == BigInteger.ZERO) 
   BigInteger.ONE 
 else 
   x.multiply(factorial(x.subtract(BigInteger.ONE)))      

Dzięki możliwościom implicit conversion, znacznie wygodniej jest pisać tak:

def factorial(x: BigInt): BigInt = 
 if (x == 0) 1 else x * factorial(x - 1) 

Warto zwrócić uwagę, że to nie jest jakaś dodana nowa składnia do Scali. Wrapper do BigInt jest stworzony w bibliotece. Nie trzeba żadnego przebudowania kodu Scali tak, jak to musi być uczynione w innych językach.

Scala jako język funkcyjny (FP)

Mam wrażenie, że programowanie funkcyjne przeżywa jakiś swój renesans. Od jakiegoś czasu więcej słychać o Erlangu, Clojure (świetny dialekt Lispa w Javie), Haskellu czy F#. Zalety programania funkcyjnego w stosunku do programowania imperatywnego są znane. Przede wszystkim, brak zmiennych i brak efektów ubocznych. Odpadają problemy związane z synchronizacją wątków, semaforami i blokowaniem dostępu do wspólnych obszarów pamięci. Kod pisany funkcyjnie znacznie łatwiej jest też testować. Funkcja niczym ma tylko jedno wejście i jedno wyjście. Nic innego ukradkiem nie zmieni. Programowanie funkcyjne jest też prostsze, choć osoby spaczone latami spędzonymi na programowaniu imperatywnym, mogą mieć na początku pewne problemy z przestawieniem sposobu myślenia. Np. w typowo funkcyjnym podejściu nie ma w ogóle pętli w programie. Zastępuje ją rekursja (która nie przepełnia stosu, jest to tzw. tail recursion)

Przykład różnic w podejściu imperatywnym oraz funkcyjnego dla Ruby’ego i Scali.

Ruby:

# Podejście imperatywne:

class Imper
  attr_accessor :x, :y
  def initialize(x,y)
    @x, @y = x, y
  end     
  def move_by(dx, dy)
    @x += dx
    @y += dy
  end
  def show
    puts "x:#{x}, y:#{y}" 
  end
end                                                                

x = Imper.new(1,2)
x.move_by(3,4)
x.show

# To samo funkcyjnie:

class Func
  attr_reader :x, :y
  def initialize(x,y)
    @x, @y = x, y
  end     
  def move_by(dx, dy)
    Func.new(@x+dx, @y+dy)
  end
  def show
    puts "x:#{x}, y:#{y}" 
  end
end

x = Func.new(1,2)
x = x.move_by(3,4)
x.show        

# lub to samo, ale bez tworzenie zmiennych:

Func.new(1,2).move_by(3,4).show

Scala:

                          
// Kod w stylu imperatywnym:

class Imper(x: Int, y: Int) {
  var iks: Int = x
  var igrek: Int = y           
  def move_by(dx: Int, dy: Int) {
    iks += dx
    igrek += dy
  }
  def show {
    println(iks,igrek)
  }
}                 
val p = new Imper(1,2)
p.move_by(3,4)
p.show

// i to samo funkcyjnie:

class Func(x: Int, y: Int) {
  val iks: Int = x
  val igrek: Int = y           
  def move_by(dx: Int, dy: Int) = new Func(iks+dx, igrek+dy)
  def show {
    println(iks,igrek)
  }
}                 
(new Func(1,2)).move_by(3,4).show

Obiekty deklarowane jako val są niemutowalne, nie można zmienić ich wartości (odpowiadają javowej deklaracji final). Z kolei deklaracja var oznacza zmienne mutowalne, mogące zmienić swoją wartość.

Kod pisany funkcyjnie, może być znacznie krótszy, prostszy i tym samym mniej podatny na błędy. Zobaczmy, jak bardzo można zredukować w Scali kod napisany w stylu imperatywnym do funkcyjnego (przykład z książki “Programming in Scala”)

                          
def printArgs(args: Array[String]): Unit = { 
  var i = 0 
  while (i < args.length) { 
    println(args(i)) 
    i += 1 
  } 
}

Pozbywamy się zmiennej var:

                          
def printArgs(args: Array[String]): Unit = { 
  for (arg <- args) 
    println(arg) 
} 

To samo, inaczej wyrażone:

                          
def printArgs(args: Array[String]): Unit = { 
  args.foreach(println) 
} 

Metoda nie jest jeszcze “czysto” funkcyjna bo posiada efekt uboczny w postaci drukowania wartości w funkcji println. Pozbywamy się więc i jej.

                          
def formatArgs(args: Array[String]) = args.mkString("\n") 

Wywołanie:

                          
println(formatArgs(args))

Warunki zwracające wynik

W Scali warunki logiczne także zwracają wartość. Weźmy na przykład kwestię operatora trynarnego. W wielu językach można spotkać (odziedziczoną po C) następującą składnię:

                          
wynik = warunek ? wyrazenie1 : wyrazenie2

Przez wiele lat w Pythonie trzeba było pisać w taki sposób:

                          
if warunek:
    wynik = wyrazenie1
else:
    wynik = wyrazenie2

Pod naciskiem społeczności, Guido van Rossum dodał w końcu odpowiednik takiej konstrukcji i teraz można pisać tak:

                          
wynik = wyrazenie1 if warunek else wyrazenie2

Tymczasem w Scali taki problem jest zupełnie sztuczny. Skoro warunek zwraca wynik, to nie trzeba wymyślać żadnej nowej składni naśladującej język C. Wystarczy po prostu napisać:

                          
val wynik = if (warunek) wyrazenie1 else wyrazenie2

Ogólnie, cała Scala promuje podejście funkcyjne, ale nie zmusza do niego. Scala nie stosuje oddzielnych nazw dla wersji mutowalnej i niemutowalnej. Dzięki temu unika się niepotrzebnego refactoringu kodu w wypadku potrzeby zmiany jednej wersji na drugą.

Domyślnie typy są niemutowalne.

                          
scala> val x = Map[Int, String]() 
# => x: scala.collection.immutable.Map[Int,String] = Map()

Aby mieć tym mutowalny, trzeba to jawnie wskazać.

                          
scala> import scala.collection.mutable.Map
scala> val x = Map[Int, String]()         
# => x: scala.collection.mutable.Map[Int,String] = Map()

Lift – komponentowy framework w Scali

Mówiąc o Scali nie sposób nie wspomnieć o świetnym frameworku webowym jakim jest Lift. Framework ten inspirowany jest różnymi frameworkami (głównie Wicket’em ale też Django, Rails czy smalltalkowym Seaside). Lift jest przede wszystkim frameworkiem komponentowym (odcina się tu od klasycznego modelu MVC promowanego przez Rails). Podejście komponentowe ma przewagę nad MVC, dużo lepiej się nadaje do złożonych aplikacji (innym przykładem dobrego podejścia komponentowego jest pythonowy CMSPlone.

Inne frameworki:

Podsumowując.

Scala to nowoczesny język będący hybrydą pure OOP i FP, statycznie typowany ale z inteligentną inferencją typów, o bardzo elastycznej składni i kompilowana do bytecodu JVM. Dzięki zaawansowanej inferencji typów i implicit conversions nie odczuwa się narzutu związanego z faktem że Scala jest statycznie typowana (a dostaje zalety ściślejszej kontroli kodu). Scala nie ma operatorów, operatory są zwykłymi metodami definiowanymi w bibliotekach.

Jednak tym co jest największym atutem Scali to jej minimalizm składniowy. Scala umożliwia tworzenie nowych typów i struktur językowych bez konieczności zmian w samej zasadniczej składni języka. To oznacza, źe podobnie jak Lisp, Scala nie ma praktycznie żadnych ograniczeń w rozwoju. Tym samym Scala jest w stanie przetrwać różne tendencje i upodobania składniowe i “przeskalować” się do nowych potrzeb.

Scalę używa już gdzieś parę banków w UK. Na Scalę niedawno przeszedł Twitter, ma wkrótce przejść też Github.

Linki



Tagi , , , , , , , , , , ,  | 108 comments

Comments

  1. Avatar dmilith powiedział about 3 hours later:

    bardzo dobry artykuł. zainteresowałeś mnie bardzo tym językiem. zaraz idę pisać :}

  2. Avatar Paweł Ryznar powiedział about 3 hours later:

    ciekawe, gdzieś obiła mi się o uszy ta nazwa. Hmm, JAVA chyba traci na rzecz .NETu, sądzisz że Scala może być wyrosnąć na mocną konkurencję M$ ? Czy Scala ma szansę zaistnieć zarówno w internecie jak i w aplikacjach dla biznesu? Ogólnie inspirujący wpis :) jak zresztą większość na tym blogu :) dziękuję za ciekawą notkę i pozdrawiam

  3. Avatar kwiateusz powiedział about 5 hours later:

    Bardzo interesujące, nawet nie wiedzialem ze takie cos istnieje :)

  4. Avatar hm powiedział about 8 hours later:

    Na co dzień programuję w Javie. O Scali po raz pierwszy usłyszałem jakiś rok temu. Nie zwróciłem na nią szczególnej uwagi. Od miesiąca jestem bombardowany informacjami i zachwytami na jej temat. Ciekawe jak się sprawa rozwinie.

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

    Trochę zaktualizowałem treść artykułu (m.in. o implicit conversions). Można by też wspomnieć o pattern matching i wielu innych cechach tego ciekawego języka. Temat jest dosyć obszerny.

    @Paweł Ryznar: mam wrażenie że tyś się trochę urwał z choinki. Java ma 5x tyle projektów co .NET i jest multiplatformowa. To raczej .NET musi się starać aby dogonić Javę. :P

  6. Avatar Rafal powiedział about 19 hours later:

    proponuje przestac jechac po php na ktorym jest oparte wiekszosc projektow webowych i skupic sie na temacie a nie za kazdym razem dodawac ze php to bezmyslny jezyk w ktorym nigdy nic nie dziala!

    Pozdrawiam

  7. Avatar calder powiedział about 20 hours later:

    @Rafał: Ale kiedy to prawda :) Z zalewem aplikacji w PHP jest jak z chińskimi zabawkami: jest ich masa bo są tanie – tani hosting, niższy koszt znalezienia programisty (dzisiaj każdy żółtodziób jest “specjalistą” od PHP), co wcale nie oznacza, że język jest tak dobry :) PHP to bardzo dobry punkt odniesienia, bo w tej chwili chyba każdy nowy język programowania wypada przy nim lepiej :)

  8. Avatar Paweł Ryznar powiedział 1 day later:

    A tam zaraz z choinki :P raczej źle się wyraziłem. Ja wiem że Java jest bardziej rozbudowana, przenośna, masa narzędzi, Java RTS etc etc, pisząc że traci nie miałem na myśli że .NET jest lepszy czy gorszy, tylko że rynek się zmienia i sporo firm przechodzi z Javy na C#. Nie chce tu zaczynać kolejnej sprzeczki o to co jest lepsze a co nie.

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

    Chcesz powiedzieć, że coraz więcej firm przechodzi z systemów POSIX do Windozy? Pierwsze słyszę, zwłaszcza w świetle fatalnych wyników sprzedaży Visty uważanej powszechnie za ta kiepski system. Ale Scala jest ponad te podziały – jest przecież implementacja Scali dla .NET.

  10. Avatar Paweł Ryznar powiedział 1 day later:

    Ja kojarzę chyba ze 3 firmy w mojej okolicy które wcześniej pisały aplikacje na JEE a zaczynają używać.NET. Raz na coś prowadzący na zajęciach wspomniał że któryś bank ma system oparty na .NET, że jakaś korporacja stopniowo przechodzi na .NET, nvm

    coś Wiki nie działa http://scala.sygneca.com w sumie odkąd pojawił się Twój wpis

  11. Avatar Bolo powiedział 1 day later:

    Obok NET i Javy dodał bym także Qt. Odkąd Nokia przejęła trolltecha, rozwój Qt nabrał rozpędu. Co prawda zastosowanie jest może i trochę inne, jednak Qt to także kompletne środowisko do tworzenia multiplatformowych aplikacji. Kompilowanych co prawda natywnie na dany system, jednak wydajność jest porażająca w stosunku do Javy. Mimo tego, że niektóre testy twierdzą, że Java może być szybsza od C czy C++ dzięki wbudowanemu garbage collector to są to śmieszne porównania bo wszystko zależy od tego jak napiszemy kod w C czy C++. Qt także daje dobre wsparcie dla embedded pythona co jest bardzo ciekawym połączeniem. Oprócz tego oferuje wewnętrzny system skryptów. Do tego sama aplikacja jest dużo lżejsza od odpowiednika w Javie i uruchamia się natychmiast bez potrzeby odpalenia całego jvm.

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

    Bolo: JVM (bo tu chodzi o wirtualną maszynę Javy a nie język) nabiera szybkości nie dzięki GC, ale dzięki swemu HotSpotowi który nieustannnie analizuje i optymalizuje kod już działający, a nie tylko jednorazowo, w fazie kompilacji. JVM generalnie jest najszybsza w zastosowaniach serwerowych, bo tam ma czas aby się odpowiednio rozgrzała. We wszystkich benchmarkach JVM można zauważyć, że czas ich wykonywania maleje w miarę kolejnej iteracji. jeśli tak nie jest, to benchmark jest źle odpalony, bez opcji -J-Server.

    Co do opóźnienia związanego z odpaleniem JVM, to receptą na to jest Nailgun” który powoduje jednorazowe odpalenie JVM w pamięci (używałem tego do pracy z JRuby , znacznie skraca czas reakcji, nie ma opóźnień przy odpalaniu skryptów) Java7 ma to mieć też ulepszone.

  13. Avatar Bolo powiedział 1 day later:

    “QT to tylko biblioteka do aplikacji okienkowych i może być używana zarówno z C++ jak i Javą, więc przeciwstawianie tego Javie jest zupełnie bez sensu. Ani to język, ani tylko do C++.” Wiele osób właśnie myli Qt z biblioteką tylko do Gui. Qt posiada także swój framework, posiada świetny interfejs do baz danych. Zmiana bazy danych np. z sqllite do XMLa to tylko podmiana sterownika. Sam rzuć okiem na dokumentację http://doc.trolltech.com Oczywiście główny obszar zastosowania Qt to jednak interfejsy użytkownika co nie umniejsza innych możliwości tej biblioteki. Jeśli chodzi o GC to nie widziałem jeszcze testów, które pokazywały by Java vs C++ z GC. Przecież do C czy C++ też są dostępne GC chociażby polski śmieciuch. Java nie ma prawa być szybsza. Wystarczy porównać jakiś program do obróbki np. video. Java bez JNI legnie.

  14. Avatar Piotr Sarnacki powiedział 1 day later:

    W których miejscach github ma używać scali? Jako middleware między railsami a gitem? Mógłbyś rzucić linka do źródła tych informacji?

  15. Avatar jarosław Zabiełło powiedział 1 day later:

    Usunąłem wzmiankę o QT, ale byłeś szybszy. :) Nie żebym miał coś do QT, ale ono mnie nie interesuje. Jakieś tam GUI, niezależne od OS, nigdy nie wykorzysta pełnych możliwości GUI natywnego. Zwłaszcza przy tak dopracowanym intefejsie Mac OS-X Leopard jakieś tam wrappery to tylko ograniczenie. Nie wiem o co ci chodzi z tymi “interfejsami do baz”. Chodzi o jakieś drivery, czy API do (obsysających) RDBMS? Mają w QT może obsługę baz obiektowych, grafowych, dokumentacyjnych czy transparent persistent memory jak to ma Terracota? Widzisz…, Java ma to wszystko.

    Co do twego “Java nie może być szybsza” to się po prostu ośmieszasz. Zamiast pleść takie bzdury poczytaj sobie coś na temat HotSpota bo cały czas mylisz go z GC. A co do wydajności gdzie Java bije C/C++ to sobie chociaż popatrz na to http://www.stefankrause.net/wp/?p=4 lub http://www.stefankrause.net/wp/?p=6.

    BTT, dyskusja odbiega od tematu. Tematem artykułu była Scala, a nie Java vs .NET, czy QT.

  16. Avatar pi0tr powiedział 1 day later:

    Osobiście nie wierzę (niestety) w większe powodzenie takich języków jak Scala, Clojure czy Erlang. One są po prostu za dobre :) Może to dziwnie zabrzmi, ale większość programistów ich po prostu nie potrzebuje. Anegdota: swego czasu armia amerykańska zastąpiła wysłużony M1 Garand karabinem M14. Broń była dobra, nawet bardzo dobra, ale okazała się… zbyt celna. Trafiała w cele oddalone o więcej niż 1 km. Przeciętny żołnierz walczy efektywnie na dystansie do 300, 400 m. M14 został zastąpiony przez M16, a M14 jest używany do dziś, ale jako wyspecjalizowana broń snajperska. Co to ma wspólnego ze Scalą? Analogie nasuwają się same…

  17. Avatar Bolo powiedział 1 day later:

    Jeśli chodzi o Java vs Qt to nawet nie chcę tego porównywać bo fakty są takie, że Java ma najlepsze biblioteki i długo tego nikt nie pobije. Chodziło mi bardziej o zauważenie, że powstaje 3 gracz. Qt opiera się na C++, więc rynek programistów jest duży. Do tego możliwość łatwego łączenia z pythonem daje duże możliwości. Java nigdy nie będzie szybsza od C++. I to nie ja się ośmieszam tylko ty. Tak jak Ci pisałem Jave optymalizują pod konkretne zastosowania tak żeby była jak najszybsza ale zawsze przegra z kretesem bo kod w C zawsze możesz zoptymalizować tak aby był szybszy. Jak chcesz porównania to zapronuj jakiś algorytm i napisz go a javie a ja napiszę w c i porównamy wyniki. Ty zrobisz benchamark u siebie a ja u siebie :) Np. wyliczenie zadanej ilości liczb pierwszych umieszczenie ich w tablicy i później stworzenie kopii tablicy w reprezentacji listowej. Co ty na to :) ? Oczywiście musimy użyć ten sam algorytm do obliczenia żeby to miało sens :)

  18. Avatar lopex powiedział 1 day later:

    @Bolo, “ale zawsze przegra z kretesem bo kod w C zawsze możesz zoptymalizować tak aby był szybszy”, możesz rozwinąć ? Czy mamy Ci wierzyć na słowo ? To trochę jak: ja mam rację bo tak.

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

    Pi0tr: Troche przesadzasz. Np. taki Erlang jest wykorzystywany komercyjnie od ponad 20 lat w wielkich sieciach telekomunikacyjnych. Ten język już osiągnąl sukces w swojej dziedzinie.

    Co do potrzeb, to takie są (mówię tu o platformie Javy, a nie potrzebach całego świata). Java jako język jest trochę za toporna i przydałoby się coś lepszego. Jest co prawa 240 języków do JVM ale wydaje mi się, że Scala posiada pewne unikalne cechy ktore dają jej największe szanse aby uzyskać szeroką akceptację w tym środowisku. Przede wszystkim łączy paradygmaty OOP i FP więc łatwiej jest się na nią “przesiąść” osobom od lat “wypaczonym” programowaniem imperatywnym.

  20. Avatar pi0tr powiedział 1 day later:

    Właśnie o to mi chodziło z tą dygresją o M14 :) Erlang jest językiem dość specyficznym i wyspecjalizowanym. Sprawdził się, ale moim zdaniem trudno oczekiwać jego masowej popularności.

    Scala jako “lepsza Java” (ze względu na OOP, dobrą integrację z istniejącymi bibliotekami Javy, akceptację platformy JVM nie tylko przez “technicznych”, ale i management) – jak najbardziej, ale jakoś w ogólne przyswojenie samych idei zaczerpniętych z FP nie mogę uwierzyć. Ale może się mylę (bardzo chciałbym).

    Wracając do tematu: nie było wzmianki o jeszcze jednej ciekawej cesze Scali, a mianowicie o współbieżności opartej o Actor Model (co ściśle wiąże się ze wspomnianym przez Ciebie pattern matchingiem). Bo skąd to ogólne nagłe zainteresowanie tematami OOP vs FP, shared state vs. immutable state, message passing concurrency vs. STM (zaimplementowana np. w Clojure) vs. “klasyczna” współbieżność wątkowa itp. itd.? Moim zdaniem u podstaw tego zamieszania z nowymi językami stoi właśnie współbieżność…

    Tak czy inaczej – czekam na kolejne posty o Scali bo temat ciekawy :)

  21. Avatar Bolo powiedział 1 day later:

    lopex: Wiesz jak działa JVM? Bierze instrukcje z bytecodu i przetwarza ją na instrukcje zrozumiałe dla danego procesora. Pisząc w C nie masz tego etapu przetwarzania. Dlatego właśnie powstają rozwiązania dla Javy, który teoretycznie pozwalają być Javie szybszą od C. Piszę teoretycznie dlatego, że ta pozorna większa szybkość bierze się z faktu zarządzania pamięcią. W C musisz sam dbać o to kiedy przydzielić/zwolnić pamięć, jeśli to robisz klasycznie to robisz to nieoptymalnie. Rozwiązania z Javy działają na tej zasadzie, że przydzielają w jednym czasie więcej pamięci niż potrzeba i później nie muszą prosić systemu operacyjnego o dodatkową pamięć co trwa dość długo. Podobnie jest sprawa ze zwalnianiem pamięci. Java nie zwalnia od razu pamięci tylko robi to jakby w wolnej chwili przez co staje się jakoby wydajniejsza. Oczywiście to tylko jedna ze sztuczek Javy poczytaj w dokumentacji to znajdziesz ich więcej. W C sam panujesz nad całym kodem i sam decydujesz co i kiedy ma być zwolnione co jest jednoznaczne, że im lepiej napisany program tym większą wydajność będzie posiadał. Kompilatory także potrafią dobrze zoptymalizować kod w czasie kompilacji i taki kod potrafi być bardzo wydajny. Cały problem polega na tym, że rynek potrzebuje rozwiązań i programistów a nauka Javy jest dużo łatwiejsza niż C. Dlatego właśnie Java jest tak popularna. Gdyby Java była tak szybka jak to wygląda w tych benchmarkach to standardowe biblioteki Javy niebyły by pisane w C tylko w Javie.

  22. Avatar Paweł Ryznar powiedział 1 day later:

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

  23. Avatar lopex powiedział 1 day later:

    Bolo: Orientuję się trochę w źródłach hotspota i przeczytałem wiele publikacji o nim, pracując nad jruby bardzo często analizujemy kod natywny wyprodukowany przez jvm. I muszę przyznać że tak uogólniłeś, że odniosłem wrażenie, że nie orientujesz się zbytnio w temacie. Zarządzanie pamięcią to jest tylko jeden problem. Największy boost maszyn javowych to agresywny inlining którego statyczna kompilacja nie przeskoczy (nawet z PGO). Dodatkowo, C/C++ mają cały szereg własności które uniemożliwiają zastosowanie całej klasy optymalizacji dokonywanych przez np: hotspota. Te własności to np: aliasing, wskaźniki do funkcji, brak możliwości dewirtualizacji metod, utrudniona analiza ucieczki itp. Z doświadczenia w rozwijaniu np jruby, notorycznie zauważam że złożony kod javowy (pracujący kompletnie in-place bez nowych alokacji) jest często szybszy niż analogiczny kod c. Też uogólniam, bo temat jest bardzo złożony, nie twierdzę też że java jest zawsze szybsza – to zależy od przypadku. To co obserwuję w tej chwili, to to że dynamiczna kompilacja ma większe potencjalne możliwości, i podejrzewam że kolejne wersje maszyn wirtualnych będą coraz częściej bić C/C++.

  24. Avatar Bolo powiedział 1 day later:

    lopex: może ty podejmiesz rękawice? :) Rozwiążemy spór raz na zawsze, szczególnie, że dość często się przewija :)

  25. Avatar lopex powiedział 1 day later:

    Bolo: No przecież możesz sprawdzić kod z: http://www.stefankrause.net/wp/?p=4, czy http://www.stefankrause.net/wp/?p=6. A na szybko wymyśliłem coś takiego: http://gist.github.com/87516, http://gist.github.com/87518

  26. Avatar Bolo powiedział 1 day later:

    lopex: tutaj się właśnie kłania optymalizacja C++. Nie kompilowałem jeszcze obu kodów, ale pewnie Java wypadnie lepiej. Dałeś typowy przykład dużej liczby odwołań do przydziału pamięci. Pisałem o tym wcześniej. Kod Javy będzie lepszy od nie zoptymalizowanego C++. Bo w C++ możesz zrobić samemu to co JVM zrobi z kodem Javy. W żadnym programie oczywiście w taki sposób się tego nie wykona. To co podałeś to przełożenie kodu Javy na kod C++ bez uwzględnienia faktu, że C++ wymaga innego podejścia do tego typu problemu. Każdy rozsądny programista zrobi to zupełnie inaczej. Piewcy szybkości Javy właśnie tego typu kody dają za przykład siejąc niepotrzebny zamęt. Wywal z pętli A*x i zrób wcześniej przydział pamięci a zobaczysz, że Java legnie.

  27. Avatar lopex powiedział 1 day later:

    Bolo: Nie przyjrzałeś się, tam są dokładnie 4 alokacje w całym benchmarku (nie mają znaczenia). Jak koniecznie chcesz wywal je do static, ale i tak nie zmieni to niczego. Resztę komentarza z litości przemilczę ;).

  28. Avatar Bolo powiedział 2 days later:

    lopex: Zrobiłem standardowa kompilacje obu programów i java jest dwa razy szybsza. Dodałem dla gcc opcje -O3 i -mcpu=pentium4 i wyszło, że Java jest minimalnie szybsza. Zbadałem z grubsza sprawę i rzuciłem okiem na obciążenie procesora. Wyszło na to, że Program Javy obciąża moje wszystkie rdzenie procka w 100% podczas działania (łącznie odpalonych jest 10 wątków). JVM zrobiła nic innego jak przetwarzanie równoległe. Zrobiłem więc inny test, odpaliłem 4 programy jednocześnie tak aby zrównoważyć obciążenie. Programy w C++ pokazywały dokładnie taki sam wynik jak przy odpaleniu jednego programu natomiast programy w Javie wypadły już około 2,5 raza gorzej od programów w C++. Podziwiam JVM, że potrafi coś takiego zrobić, jednak wydajność jest jak już pisałem gorsza :) C++ też potrafi już wiele rzeczy robić równolegle wykorzystując openmp. lopex nie ma opcji żeby Java kiedykolwiek był szybsza od C++. Szybkość Javy wynika z bardzo wydajnych algorytmów, ale dobry programista w C/C++ też sobie napisze wydajne.

  29. Avatar calder powiedział 2 days later:

    Bolo przypominasz mi znaną swego czasu historię kolesia, który wysłał swoje CV do firmy szukającej programisty Javy i w liście motywacyjnym napisał, że on w Javie nie pisze bo to jakiś badziewny pseudo-język, on pisze tylko w C bo jest najlepszy, a w ogóle to powinni wywalić cały swój system w Javie i przepisać go na C :) Na szczęście trendy w IT nie wyznaczają fanboy’e, bo inaczej do dzisiaj wszyscy klepali by w assemblerze, a dominującą przeglądarką www były Lynx :)

  30. Avatar lopex powiedział 2 days later:

    Bolo: na jedno-prockowej maszynie java też jest szybsza. Jak to wytłumaczysz ? Coraz bardziej się pogrążasz nie wiedząc jak to działa.

  31. Avatar Bolo powiedział 2 days later:

    calder: do czego pijesz bo nie zrozumiałem chyba twojej wypowiedzi? Nikogo nie namawiam na używanie C. Rozmawiamy na temat wydajności obu języków. Nie twierdzę, że Java jest zła i nie należy jej stosować. Napisałem tylko, że c/c++ są wydajniejsze.

  32. Avatar lopex powiedział 2 days later:

    Bolo: A hasła typu “Wywal z pętli A*x…” sugerują że c++ też nie do końca kumasz..

  33. Avatar Bolo powiedział 2 days later:

    lopex dla mnie fakty są jasne, dla Ciebie chyba nie bardzo. Próbujesz udowodnić, że mimo tego, że procesor ma więcej pracy to działa jak perpetum mobile specjalnie dla Javy. Wydaje mi się, że to ty się właśnie pogrążasz bo testy zmiażdżyły twój punkt widzenia. Java nie może być szybsza bo ma więcej pracy do wykonania. Gdybym użył kompilatora ICC do testów to Java byłaby jeszcze bardziej w tyle. Koniec dywagacji na ten temat, rozmowa powinna być o Scali :)

  34. Avatar Bolo powiedział 2 days later:

    “A hasła typu “Wywal z pętli A*x…” sugerują że c++ też nie do końca kumasz..” nie pogrążaj się takimi tekstami, czytałem na szybko kod i źle go zinterpretowałem. Chyba przez to, że wmówiłem sobie, że ten test polega właśnie na przydziale dużej liczby pamięci bo w Javie to działa bardzo optymalnie.

  35. Avatar lopex powiedział 2 days later:

    Bolo: jakiej pracy ? co zmiażdżyło ?

  36. Avatar Bolo powiedział 2 days later:

    lopex: nie chwytaj się brzytwy bo nie ma sensu już dalsza dyskusja. Sam przygotowałeś programy testowe. Nie trzeba było nawet optymalizować kodu w C++ żeby wykazać jak słaba jest Java.

  37. Avatar lopex powiedział 2 days later:

    Bolo: to jest assembler wyprodukowany przez jave dla metody bench(): http://pastie.org/431250. Porównaj go sobie z tym z gcc/icc to zrozumiesz dlaczego nie będą szybsze.

  38. Avatar lopex powiedział 2 days later:

    Bolo: no już nie ma sensu bo dyskysję wygrałem, java może być szybsza od c++ :) i to bez żadnej alokacji.

  39. Avatar Bolo powiedział 2 days later:

    lopex: Dzięki za dyskusję, każdy z nas ma swoje racje :)

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

    Bolo: pleciesz jakieś bzdury. Sprawdziłem na moim PoweMakyu z 8 rdzeniami. Oba programy wykorzystuja na 100% jeden rdzeń. Java miażdży C++, jest ponad 2x szybsza. Podałem dokładne parametry sprzętu, kompilatorów, źródła i wyniki.

    http://gist.github.com/87746

    Zanim palniesz kolejne głupstwo, zastanów się 2x i jak masz coś pisać, to podaj konkretny, możliwy do uruchomienia kod z wszystkimi opcjami i parametrami sprzętu aby można było to zweryfikować. Inaczej uznaję, że po prostu zmyślasz.

  41. Avatar Bolo powiedział 2 days later:

    Użyłem ubuntu 8.04. Pisałem jakie opcje brałem do kompilacji. Dla c++ -O3 -march=pentium4 Dla Javy żadnych opcji nie brałem. Ustaw więcej wywołań dla funkcji bench i odpal równoległe kilka programów a zobaczysz różnicę. Dla jednego wywołania Java jest minimalnie szybsza o czym pisałem wcześniej.

  42. Avatar dmilith powiedział 2 days later:

    Istotą problemu jest to, że w tym przypadku Java to JVM. To działanie JVM’a sprawia że kod pisany pod ów VM jest taki szybki. Ciekawe czy ten sam kod w Scali będzie równie szybki. Powinien też być szybszy niż C++

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

    Bolo ty nadal kompletnie nic nie kumasz. Ten kod wykorzystuje 1 (słownie: jeden rdzeń) procesora, więc czy zapuścisz go jako 1 proces czy jako 100, to nic nie zmieni. Aby JVM używała optymalizacji trzeba dodać opcję -server. Inaczej oszukujesz bo dla C++ włączasz optymalizację a Javie tego samego zabraniasz.

    Aby nie odbiegać za dużo od tematu, dodałem do tego kod w Scali (http://gist.github.com/87760) i połaczyłem z wynikami Javy i C++ (http://gist.github.com/87746). Niestety, ale C++ przegrywa nie tylko z Javą ale także ze Scalą!

  44. Avatar Bolo powiedział 2 days later:

    więcej szczegółów tutaj: http://pastie.org/431307

  45. Avatar Bolo powiedział 2 days later:

    Jarek ależ ja to rozumiem. Dodałem także opcje -server i poprawiło to wyniki trochę wyniki dla Javy ale nie za dużo. Zapchaj cały procek obliczeniami i wtedy będziemy mogli mówić o miarodajnych testach. Zauważ też, że jest to przykład typowo Javowy specjalnie dobry by pokazać wyższość Javy. Dla zwykłych pętli obliczających robiłem testy i nie trzeba było wcale tak kombinować aby C było szybsze od Javy.

  46. Avatar lopex powiedział 2 days later:

    Bolo: no to teraz już się kompletnie ośmieszyłeś.

  47. Avatar dmilith powiedział 2 days later:

    LOL. to się uśmiałem..

    @bolo: ładnie Cię prosimy, doucz się.. nie dość że startujesz maszynę wirtualną parę razy, to jeszcze bez optymalizacji.. jeśli chcesz żeby było fair.. zrób tak:

    ./a.out && reboot && ./a.out && reboot ;>>

  48. Avatar lopex powiedział 2 days later:

    Bolo: po za tym, jeśli nie wiedziałeś o server compiler, to sam fakt wdawania się w dyskusję na ten temat to dla mnie najzwyklejsza bezczelność. Po drugie: odpalasz jave za każdym razem, jeśli chcesz żeby było sprawiedliwie – odpalaj kompilacje c++ za każdym razem.

  49. Avatar Bolo powiedział 2 days later:

    Dobra to może inaczej. Taki test najlepiej pokazuje różnice: http://pastie.org/431327 Ja nie znam się na javie i wcale tego nie ukrywam. Jak robię źle z odpalaniem kilkukrotnie JVM to powiedzcie mi jak mam to odpalić żeby test był miarodajny.

  50. Avatar calder powiedział 2 days later:

    “java Bench & java Bench & java Bench…”

    ROTFL!!! Aż się popłakałem :))

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

    Bolo: nie wiem co ty masz nachrzanione w komputerze, ale na moim PowerMaku Java jest 5x (słownie: pięć razy) szybsza od C++ dla tego kodu coś podał nhttp://pastie.org/431327. I to bez żadnego tuningowania, bo można by jeszcze trochę z Javy wycisnąć) Wyniki: http://gist.github.com/87773.

    >

    Z opcją g++ -O3 -funroll-loops C++ ma trochę lepsze wyniki, bo schodzi do 70, ale i tak Java jest szybsza, bo schodzi do 56.

  52. Avatar Bolo powiedział 2 days later:

    Jarek: Mówię Ci, że java mi zżera całą moc na obu rdzeniach, podejrzewam, że u Ciebie zżera twoich ileś tam rdzeni i dlatego wypada szybciej. Zrobię testy na lampku jak będę w domu i wtedy będzie wiadomo na 100% czy to od tego zależy. Na lapku mam jednordzeniowy procek. Odpalenie iluś JVM zostało wyśmiane choć nikt nie podał jak to odpalić wielokrotnie, więc nie widzę innego rozwiązania jak test na jednordzeniowym komputerze.

  53. Avatar Bolo powiedział 2 days later:

    Jarek u mnie z opcją funroll-loop zeszło C++ do 110 :) i wychodzi teraz, że jest 3 razy szybsze od javy mimo tego, że obciąża mi tylko jeden rdzeń a nie dwa tak jak java.

  54. Avatar JO powiedział 2 days later:

    Dla mnie zabardzo przypomina to Pascal’owa składnie. Scala jest dość mocno typowana. Są tacy co to lubią i tacy którzy tego nie cierpią.

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

    Bolo: ten kod Javy wykorzystuje przcież JEDEN rdzeń. Masz nowszą wersję gcc i to być może powoduje różnicę w tym 2 przykładzie. W 1-szym C++ nie będzie szybszy, bo nie ma bimorphic inlining. Zatem nie jest prawdą, że Java zawsze będzie wolniejsza od C++. Proponuję trochę dać spokój już temu wątkowi, bo tematem byla Scala, a nie kwestie wydajnościowe Java vs C++.

    JO: Scala jest statycznie typowana, ale to nie jest uciążliwe, bo ma zaawansowaną inferencję typów, więc to nie przeszkadza. W wielu przypadkach w ogóle nie trzeba nic podawać. Zaletami za to są lepsza optymalizacja wydajnościowa i kontrola kodu (nie trzeba pisać aż tyle unit testów).

  56. Avatar Bolo powiedział 2 days later:

    Jarek już dawno chciałem zakończyć ten wątek ale przybyło niedowiarków :) Tutaj jeszcze wklejam tylko testy z jednordzeniowego lapka http://pastie.org/431458 Teraz już chyba nikt nie będzie miał złudzeń. Żeby osoba, która ledwo co potrafi napisać w Javie hello world musiała takie rzeczy udowadniać ‘specom’ od Javy :)

  57. Avatar lopex powiedział 2 days later:

    Bolo: tylko że Ty nic nie udowodniłeś

  58. Avatar Bolo powiedział 2 days later:

    lopex ty dalej swoje, masz kody sprawdź u siebie. Z mojej strony EOT.

  59. Avatar dmilith powiedział 2 days later:

    @bolo:

    Uważam, że wypowiadając się na temat czegoś, czego sam przyznałeś że nie znasz, nie umiesz nawet uruchomić (nie wspominając o tym że nie wiesz jak działa) sprawia, że jesteś po prostu fanboyem a nie kimś kto sugeruje się wynikami testów przeprowadzonych w sposób obiektywny/ profesjonalny.

    Poza tym kod C++ będzie działał inaczej w zależności od platformy systemowej (zobacz sobie ile musi kod C zrobić by zaalokować dynamicznie pamięć w Windowsie a ile pod Linuxem), a kod oparty o JVM będzie działał tak samo.

    Zgoda, że część algorytmów będzie szybsza w C++ a część w Javie. Rzecz w tym że JVM to coś co się rozwija (co za tym idzie -przybywa algorytmów które pod kontrolą JVM’a są szybsze niż kod w C), czego o C++ powiedzieć niestety nie można (ICC nie wnosi tu wiele)

  60. Avatar lopex powiedział 2 days later:

    Bolo: Twoja teza brzmiała: c++ jest zawsze szybsze. My udowodniliśmy że tak nie jest. Jasne, są przykłady faworyzyjące javę i faworyzujące c/c++, ale to nie zmienia faktu że nie miałeś racji.

  61. Avatar dmilith powiedział 2 days later:

    @hipertracker:

    w zasadzie flame pt. “Java vs C+” to niemal to samo co “Scala vs C+”. Kod Scali jest zazwyczaj tak samo wydajny jak kod Javy(języka)

  62. Avatar dmilith powiedział 2 days later:

    @bolo:

    jeszcze jedna sprawa. jak używasz ostatniej stabilnej wersji C++, to obiektywniej byłoby użyć Javy 1.6.0_12 (ostatniej stable)

  63. Avatar Bolo powiedział 2 days later:

    Podsumuję jeszcze: nie zobaczyłem żeby kod Javy był szybszy jak macie jakieś propozycje to czekam na nie. To że JVM wykorzystuje ileś rdzeni nie oznacza, że kod jest szybszy bo na jednordzeniowym procesorze widać wyraźnie różnice (testowałem oba programy testowe). Proszę Was skończcie wreszcie, nie macie rzeczowych argumentów i zaczynacie obrażać mnie i moją wiedzę nie mając kompletnie pojęcia kim jestem i czym się zajmuję ale to tylko o Was świadczy. To, że w Javą miałem niewiele wspólnego nie oznacza, że testy są do bani bo jeden test zaproponował lopex, który chyba się zna na Javie. Przypominam też, że ten test dotyczył WYDAJNOŚCI niczego innego, więc jak zaczynacie się czepiać składni i innych rzeczy zaczynacie siać flame na temat wyższości jednego języka nad drugim a zupełnie nie o to w tym chodzi.

  64. Avatar lopex powiedział 2 days later:

    Bolo: czy Ty masz problemy z logicznym myśleniem ? Nigdzie nie widzę żebyś wykazał że dla mojego benchmarku c++ jest szybsze. Tym samym twoja teza “c++ jest zawsze szybsze od javy” jest nadal fałszywa.

  65. Avatar JJThompson powiedział 2 days later:

    Może ja Was pogodzę.

    Nie widzę sensu w porównywaniu języków, których filozofia działania jest diametralnie różna. Java jest językiem przenośnym, sprawdzającym się w zastosowaniach sieciowych, natomiast C++ jest językiem, w którym napisane programy nie potrzebują się “rozgrzewać”, ale tracą przy tym na przenośności.

    @Bolo Chciałbym zobaczyć Twoje C++ Advocacy w starciu ze zwolennikami Asemblera. Porównaj wydajność programów napisanych w obu tych językach, a dojdziesz do wniosku, że C++ jest nieefektywny.

    “zaczynacie obrażać mnie i moją wiedzę nie mając kompletnie pojęcia kim jestem i czym się zajmuję ale to tylko o Was świadczy.”

    Póki co nie zauważyłem w tej dyskusji argumentacji ad personam. Poza tym zapewne nikogo nie obchodzi kim jesteś, ale jakiej argumentacji używasz.

  66. Avatar Bolo powiedział 2 days later:

    lopex: przeczytaj co napisałem wcześniej, odpaliłem twój test i swój na jednoprocesorowej maszynie i C++ zwyciężył. Jesteś tak zaślepiony Javą, że nie możesz odpalić u siebie tych testów? Nie oszukuj sam siebie i zejdź na ziemię. Naprawdę kończmy już ten temat bo znowu wracasz do gdybania i sugerujesz mi rzeczy z którymi widzę, że to ty masz problem. Nie podałeś żadnego przykładu na to że Java jest szybsza ale wciąż idziesz w zaparte.

  67. Avatar dmilith powiedział 2 days later:

    @Bolo:

    http://pastie.org/431684

    komentarz nie jest chyba potrzebny?

  68. Avatar pietia powiedział 2 days later:

    moje wyniki: http://pastie.org/431698

    java 6.0, 7.0(stara)

  69. Avatar teamon powiedział 2 days later:

    A to moje: http://pastie.org/431738 (MacBook) Jakby ktoś chciał sprawdzić u siebie to:

    $ curl http://pastie.org/431704.txt > bench.sh && chmod +x bench.sh && ./bench.sh

  70. Avatar lopex powiedział 2 days later:

    Bolo: nie jestem zaślepiony javą a w c/c++ już niejedną klawiaturę zajechałem, po prostu znam słabości jednego i drugiego środowiska.

  71. Avatar Bolo powiedział 2 days later:

    Jak widać zależy dużo od konkretnych wersji Javy i Gcc. Najbardziej miarodajny test byłby wtedy gdyby użyć najnowsze jvm i gcc. Oboje robiliście testy na dwurdzeniowych prockach a jak już pisałem wcześniej Java korzysta z obu rdzeni a program w C++ tylko z jednego. pietia potwierdził moje wyniki oraz wyniki Jarka, któremu podobnie wyszło dla drugiego testu z tego co napisał. dmilith wydaje mi się, że ty kompilowałeś pierwszy test, który u mnie też wyszedł (co prawda minimalnie) szybszy na dwurdzeniowym procesorze niż dla C++. U Jarka, który ma chyba 4 rdzeniowy procesor, różnica dla drugiego testu była jeszcze większa na korzyść Javy. Cała dyskusja potwierdza jak ciężko wykonać dobre i miarodajne testy i ile są tak naprawdę warte te testy.

  72. Avatar lopex powiedział 2 days later:

    Bolo: tu liczba rdzeni nie ma znaczenia, coś pokręciłeś.

    A tak przy okazji:

    http://pastie.org/431774 http://pastie.org/431776

    Kto zgadnie na czym polega oszustwo javy ?

  73. Avatar Bolo powiedział 2 days later:

    lopex to czemu na jednordzeniowym komputerze działa wolniej i dlaczego zżera całą moc dla obu rdzeni na dwurdzeniowym? Oświeć nas :)

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

    Bolo: Ten kod w Javie działa na JEDNYM rdzeniu, co widzę jak na dłoni na moim 8 rdzeniowym PowerMaku. Zamiast testować to na jakimś ZX Spectrum, weź do tego jakiś mocniejszy komp, bo widocznie ten jest za cienki, aby cokolwiek na nim miarodajnie testować i cholera wie co tam jeszcze go obciąża.

    BTW, dodałem drugi film (na końcu artykułu).

  75. Avatar lopex powiedział 2 days later:

    Bolo: no idea, u mnie na jednym core java też jest szybsza.

  76. Avatar calder powiedział 3 days later:

    “zaczynacie obrażać mnie i moją wiedzę nie mając kompletnie pojęcia kim jestem”

    Bolo, swoją “wiedzą” to Ty już się popisałeś odpalając testy w Javie za każdym razem wraz z całą maszyną wirtualną i twierdząc na tej podstawie, że kod wygenerowany przez kompilator C++ jest szybszy. A tekstem “Wy nie wiecie kto ja jestem” tylko udowadniasz dokładnie, kim jesteś. Panowie, nie szkoda Wam czasu na bezsensowne dyskusje z tym człowiekiem? On i tak zawsze będzie miał rację, a jego racja jest lepsza, bo to jest jego racja :)

  77. Avatar Bolo powiedział 3 days later:

    calder: tobie płacą za nabijanie nic nie wnoszących komentarzy? Sprawdź swoje wypowiedzi i zacytuj, która z nich wniosła cokolwiek wartościowego do dyskusji? Mam wrażenie, że masz nie odpartą chęć wypowiedzenia się a nie masz zupełnie pojęcia o czym się tu dyskutuje. Dowartościowujesz się z ten sposób czy co?

  78. Avatar calder powiedział 3 days later:

    Bolo, nie zamulaj, bo ja nie dam się wciągnąć w bezsensowną gadkę jak inni. Podziwiam tylko Jarka, lopexa i innych, że chce im się marnować swój czas na dyskusje z kimś, kto nie dość, że nie ma podstawowej wiedzy o działaniu JVM to jeszcze próbuje to nadrabiać pluciem się na lewo i prawo.

  79. Avatar sfdasnfdka powiedział 3 days later:

    Mało profesjonalne te kłótnie w komentarzach. Każdy język pokazuje swoje możliwości w innym projekcie/algorytmie. Napiszcie kilka różnych algorytmów (np. wyznaczanie zbioru Mandelbrota, algorytm Bellmana-Forda itd.) bo na jednym fragmencie kodu to sobie możecie testować… Co do samego języka Scala, jest on godny uwagi.

  80. Avatar lopex powiedział 3 days later:

    Imho, wyprowadzenie kogoś z błędu nie jest stratą czasu. Odnośnie benchmarku Bola, zauważcie ze bez -funroll-loops czasy wychodziły te same a nawet trochę na korzyć javy. Prawdopodobnie wygenerowany został dokładnie ten sam kod. Nie wiem dlaczego hotspot nie rozwija tej pętli, ale nie ma absolutnie żadnego powodu dla którego nie mógł by tego zrobić, c++ i java mają identyczne informacje o typach itp. Dlatego fakt że ten drugi benchmark jest wolniejszy w javie trochę mnie dziwi i bardziej bym go rozpatrywał jako błąd hotspota. Miejsca gdzie java traci na rzecz c/c++ to głównie kod który operuje na tablicach w sposób uniemożliwiający eliminację sprawdzeń zakresów (np: gdy index nie jest zmienną sterującą pętli lub gdy krok nie jest stały i nie może podlec reducji siły) oraz często kod na operacjach zmiennoprzecinkowych (ale to tylko dlatego że java musi się trzymać swojej specyfikacji). Benchmarki na liczbach stałopozycyjnych powinny być tak samo wydajne (a jeśli niektóre jeszcze nie są, to będą w kolejnych wersjach jvm). Kod gdzie java absolutnie miażdży c/c++ to przede wszystkim agresywny inlining (w tym inlining metod wirtualnych) gdzie zainlinowany kod podlega takim samym optymalizacjom co kod statycznie wiązanych funkcji/metod oraz kod ze skomplikowanymi ścieżkami wywołań który po dynamicznej kompilacji jest bardziej zwarty (skompilowane są tylko ścieżki które do tej pory były używane) i lepiej wykorzystuje cache cpu. Koronnym przykładem jest właśnie http://pastie.org/431774 (oczywiście chodzi mi o sytuację gdzie implementacja metody wirtualnej nie jest znana na etapie kompilacji) gdzie c++ po prostu za MAŁO może (c tak samo ze swoimi wskaźnikami do funkcji). Częściowym ratunkiem dla c++ jest PGO (profile guided optimization) ale ma to dwie bolączki: ogromny code-bloat oraz niemożność przystosowania kodu do zmienionych warunków pracy. Biorąc pod uwagę jakie postępy poczyniła dynamiczna kompilacja w stosunku do statycznej kompilacji (a granicy możliwości jeszcze nie widać) uważam ze to jest jedyny rozsądny kierunek na przyszłość.

  81. Avatar Bobo powiedział 3 days later:

    lopex: zastanów się teraz dlaczego Jvm wykorzystuje dwa rdzenie u mnie w testach? Może dlatego, że musi w drugim wątku wykonać właśnie tą optymalizacje w locie i wygenerować kod assemblera. Optymalizacja w locie zajmuje jvm właśnie dość sporo czasu i dlatego na 1 rdzeniowym procesorze programy w Javie działają wolniej. Żeby dobrze to sprawdzić potrzebny byłby test, który odpala np. 10 wątków i w każdym liczy coś innego i żeby to na tyle długo trwało żeby odpalenie JVM było pomijalne. Bo jak Java robi sobie optymalizacje w osobnym wątku, to ten czas też powinien być doliczony do czasu obliczeń dla Javy, bo przecież zużywa czas procesora. lopex im więcej mi ciekawych rzeczy piszesz na ten temat tym mnie bardziej przekonujesz, że mam jednak rację. Zauważ także, że z tego co napisałeś jasno wynika, że kod w czystym C zawsze będzie szybszy bo JVM daje kopa głównie dla programowania obiektowego. Zauważ także, że w C++ można unikać np. metod wirtualnych czy choćby wielokrotnego dziedziczenia i napisać po prostu program w inny sposób, np. z ostatnio modnym metaprogramowaniem w C+. Pisząc jakiś większy program napiszesz go inaczej w C+ a inaczej w Javie. Ta optymalizacja o której piszesz sprawdzi się tylko w niektórych zastosowaniach i jak sądzę raczej do małych projektów.

  82. Avatar lopex powiedział 3 days later:

    Bolo: 1) kompilator optymalizujący faktycznie działa na osobnym wątku, ale on zadziała tylko raz (dlaczego go chcesz wliczać ? następne przejścia benchmarku już będą uruchomione zoptymalizowane, w innym razie dodawaj do każdego przejścia czas kompilacji c++). 2) “że z tego co napisałeś jasno wynika, że kod w czystym C zawsze będzie szybszy bo JVM daje kopa głównie dla programowania obiektowego”: W żadnym wypadku, przecież i java i C++ kompilują natywnie, dlaczego miałoby tak być ? 3) W żadnym dużym/poważnym systemie nie unikniesz metod wirtualnych/wskaźników do funkcji. 4) Metaprogramowanie w C++ to jest to samo co podstawianie funkcji na żywca (a pamiętaj że java jest dobra w inlinowaniu) 5) Ta optymalizacja jest właśnie po to żeby dawała kopa złożonym programom, patrz 4) napisz duży system bez metod wirtualnych/wskaźników do funkcji. 6) Sprawdź wydajność implementacji cruby (nawet cruby 1.9) i jruby, będziesz miał porównanie java/c dla bardzo złożonego projektu.

  83. Avatar Bolo powiedział 3 days later:

    lopex z testów jakie zrobiłem u siebie wynika, że to nie zoptymalizowany kod tak mulił na jednoprocesorowej maszynie ale właśnie ten kompilator, bo innego wytłumaczenia spadku wydajności nie widzę. Zauważyłeś zapewne, że dla pierwszych dwóch wywołań funkcji bench czas javy jest dużo wyższy niż dla kolejnych. Jeśli teraz weźmiesz i zrobisz kopie tych funkcji i nazwiesz je np. bench1 bench2 itd. i wykonasz program to zawsze wyjdzie ci czas dużo większy od C++. Właśnie dlatego, że kompilator javy musi zoptymalizować kod. Ta optymalizacja jak widać nie trwa chwili i zabiera dużą liczbę czasu dla procesora. Nie chce się bawić w porównania programów w C i javie, bo tutaj sprawa jest oczywista, weźmy chociaż msvs i eclipse :) eclipse na moim lapku muli że się nie da pracować a w msvs da się sporo pracować bez problemu.

    PS.mówiąc eclipse mam na myśli avr32studio czyli = eclipse+dodatki.

  84. Avatar lopex powiedział 3 days later:

    Bolo: poczytaj o online profiling i chociaż troszeczkę o tym jak działa java, ludzie podesłali swoje wyniki dla mojego testu na niezależnych maszynach. Ja wykazałem swoje – java potrafi być szybsza. To się robi narawdę nudne, dla mnie to jest definitywny EOT.

  85. Avatar Bolo powiedział 3 days later:

    lopex każde robił testy na wielordzeniowych maszynach co potwierdza wyniki i twoją wypowiedź na temat jak działa jvm. Nie może do Ciebie dotrzeć, że JVM działa na innym wątku i stąd większa prędkość javy. Podsumowując Java potrafi być szybsza dla kodu C++ napisanego w taki sam sposób jak kod Javy. Z mojej strony również EOT.

  86. Avatar riklaunim powiedział 4 days later:

    .NET biorą te firmy, które robią jakieś aplikacje GUI/Windows chcące jak najbardziej uzależnić od siebie klienta. Jeżeli powiedzmy dział marketingu lub sprzedaży zażyczy sobie program X do księgowości-cośtam napisany pod windowsa wyłącznie to dział IT nie będzie mógł zaszaleć. Jeżeli do tego dorzucą jakąś abstrakcyjną bazę danych typu firebird albo coś podobnego to tylko lepsze działy IT będą miały to na własnych serwerach, a mniejsze firmy zmuszone będą np. na dokupienie hostingu takiej bazy u producenta softu :D Vendor Lock-in pod przykrywką ładnej aplikacyjki.

    A producenci masowego softu robią go dla kasy, a nie dla finezji kodu i obsługi wielu platform.

  87. Avatar riklaunim powiedział 4 days later:

    A co do PHP – jak wszystko nie jest idealne, ale np. nie wymaga kupowania dedyka i stawiania przez ssh Django na FastCGI żeby walnąć stronę domową. Każde rozwiązanie ma swoje zastosowania i niszę “na rynku”. Nie każdy potrzebuje bloga na klastrze.

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

    Passenger obsługuje frameworki używające Rack’a (Ruby) i WSGI (Python), więc nie trzeba żadnego kombinowania i dostęp do SSH nie jest niezbędny. Wystarczy sam FTP, czyli tak, jak dla typowego hostingu PHP.

  89. Avatar Jiima powiedział 6 days later:

    @JZ Nie nękałem cię Scalą, bo zauważyłem w blipie że cię zainteresował temat (to dobrze, Scalą zająłem się ze 2 lata temu jak nikt jeszcze nawet o Lifcie nie myślał i stwierdziłem “zarąbisty język, szkoda że nigdy nie będzie czymś więcej jak akademickim projektem” – zabawne, z 5 – 6 lat temu to samo pomyślałem o Ruby. Kiepski na szczęście ze mnie prorok)

    Za to pamiętam nasz spór na JUG na temat statycznego / dynamicznego typowania. Czyżbyś zmienił zdanie?

    Co do Scali, ma pewną słabość, która może pogrzebać rozwój tego języka – otóż JVM nie jest niestety dla języków funkcyjnych. Istnienie typów Function1 do bodajrze Function8 i podobnie dla Tuple dowodzi, że aby zaimplementować podobny do haskella język na JVM konieczne są obejścia. Maszyna CLR ma tę drobną przewagę, że istnieją tam obiekty anonimowe (od v. 3 wprawdzie, ale M$ ma mniejsze opory co do rozszerzania instrukcji w bytecode, twórcy Javy mają na tym punkcie obsesję, stąd spaprana obsługa generyków na ten przykład) i delegaty. Jest też kilka innych VM które leżą sobie w cieniu a mają spory potencjał – Lua, NekoVM, LLVM

    Co do większej szybkości C, sprawa jest prosta, jeszcze szybszy jest Assembler. Pytanie o produktywność. Za to prędkość C++ jest conajmniej taka sobie, zwłaszcza jak programuje się na obiektach dynamicznych, ze względu na powalone mechanizmy alokacji przez new. C++ jest UWAŻANY za szybki, bo w końcu to C z dwoma plusami. Tymczasem szybszy jest nawet Objective C (choć jest dynamiczny), o produktywności nie wspomnę, bo większość ludzi nie zna smalltalka, więc na ObjC ciężko im się przesiąść.

    Co do PHP… po głębszym zanurzeniu w język, infrastrukturę, budowę modułów, muszę ci ostatecznie przyznac rację, to szajs. 5.3 z typami funkcyjnymi i przestrzeniami nazw nie nadchodzi i możliwe że wyjdzie za późno. Najgorszy jest jednak GC, który w zasadzie nie działa, “bo po co” – nie mówię że takie jest oficjalne stanowisko, ale skoro program w PHP jest w zasadzie skryptem CGI i jest w całości dealokowany po wyrenderowaniu strony, to po co się starać z zarządzaniem pamięcią… Za to koncepcja lekkiego języka osadzonego jako mod_ jest ze wszechmiar słuszna. Ruby i Python są za ciężkie, Perl w sumie też, poza tym zbyt dziwaczny (lista wad mod_python jest powszechnie znana). Model wykonania CGI dla takiego języka też nie jest niczym złym. Nie wiem… Lua? JavaScript? może Scheme?

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

    Jiima: pamiętam te dyskusje. :) Faktycznie, trochę zmieniłem zdanie na temat statycznego typowania. Dzięki inferencji typów statyczne typowanie nie musi być upierdliwe. Jednakże, z drugiej strony języki takie jak Erlang czy Clojure, pokazują, że dynamiczne typowanie nie musi być ograniczeniem do tworzenia złożonych aplikacji. W sumie: różnica nie jest dla mnie już tak istotna.

    Generalnie wchodzimy w erę dużego równoległego przetwarzania (mowi się że wkrótce zwykłe komputery domowe mogą mieć setki/tysiące rdzeni/procesorów na pokładzie). Rola programowania funkcyjnego będzie rosnąć.

    Scala jest bardzo ciekawa, ale od niedawna zaczynam coraz bardziej odkrywać potęgę pure FP i muszę przyznać, że Scala ma godnego konkurenta w postaci Clojure, który jest od niej dużo prostszy (choć niekoniecznie łatwiejszy dla tych, co latami programowali w stylu imperatywnym).

  91. Avatar Jiima powiedział 7 days later:

    @JZ Clojure jest ciekawy… ale podobnie jak w wypadku ObjC odstręczać może nieco składnia. Ja tam lubię Lisp’a i Smalltalka ale jestem w swych poglądach dość odosobniony. Clojure z resztą nie jest wcale taki dynamiczny jak by wyglądał (w porównaniu z innymi Lisp’ami na przykład stawia duży nacisk na wartości stałe) no i nie ma wersji 1.0, ani frameworka webowego. A przetwarzanie równoległe jest super, z tym że nie wszyscy potrzebują go aż w takim stopniu, większość aplikacji to tępe frontendy do bazy danych.

    W Clojure brakuje mi takich bajerów zwiększających wydajność, jak pattern matching – z resztą w scali też mógłby być on bardziej dostępny. Za to jest CLOS, który mi osobiście się podoba, ale wielu fanów programowania obiektowego może odstręczać. Tak więc nie wiadomo co stanie się popularniejsze. Na pewno nie Java jako taka, ze swoją niechęcią do jakichkolwiek zmian (odrzucono properties i domknięcia które miały wejść w Javie 7 i wybitnie poprawiłyby produktywność w tym języku)

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

    Clojure ma swój web framework Compojure choć pewnie jeszcze jest niedojrzały. Na razie Scala wygrywa dojrzałością, bogatszym API, ma też dwa frameworki Lift i Sweet a hybryda FP i pure OOP też pewnie łatwiej przemówi do javowców niż tylko pure FP.

  93. Avatar Jiima powiedział 9 days later:

    Niedojrzały to mało powiedziane… poza tym akurat nie jestem do końca pewien, czy siła Clojure jest w tworzeniu YAWF-J (yet another web framework for Java), do tego nadaje się Groovy (Grails mi się całkiem podoba, poza tym statyczno – dynamiczna dyscyplina języka, nastawiona na unit testy w tym pomaga, a GPath jest świetnym wynalazkiem), czy Scala (multiparadygmatowość, natywny XML, pattern matching). Clojure jest pisany pod współbieżność, a jeśli znasz platformę Java, to wiesz że w środowiskach webowych jest ona niezbyt przydatna (tzn – nad współbieżnością czuwa kontener, kod kliencki nie powinien spawnować własnych wątków). Za to genialnie byłoby w Clojure napisać właśnie rzeczony kontener… Jedyne, co może być zaletą CL w wypadku tworzenia web frameworka, to SXML (czyli XML zapisany jako S-wyrażenia), jednak jako język template może być zbyt wkurzający (podobnie jak język Seaside, Markaby czy nawet Haml), zaś w klasycznym web frameworku nie ma zwykle zbyt wiele “wejściowego” XML – z resztą mimo wszystko Scala lepiej się do tego nadaje, ze względu na wbudowany XPath i pattern matching po tagach. Problem w tym, że trzeba spojrzeć na sprawę całościowo – tworzenie oprogramowania to nie tylko tworzenie kolejnego tępego frontendu do jakiejś bazy danych. Owszem, tu roboty jest najwięcej, bo świat nie uczy się na błędach i wciąż powstają nowe takie aplikacje, dzięki temu takie psy korporacji jak ja mają na swoje psie żarcie. Ale te aplikacje chodzą na serwerach, te łączą się z bazami danych, a po godzinach developerzy odprężają się grająć w gry… i śmiem twierdzić, że to właśnie tu jest prawdziwy development, a nie przy pisaniu kolejnej super inteligentnej aplikacji której jedyna rola to pobrać dane od skretyniałej urzędniczki piszącej jednym palcem na klawiaturze, sprawdzeniu czy pani się gdzieś nie “rypła” i wsadzeniu tego do bazy (o wygenerowaniu z tych danych wykresu kołowego by prezes firmy mógł na jego widok dostać orgazmu nie wspomnę – vide któryś z nowych Dilbertów)... Sorry że marudzę, ale właśnie siedzę nad czymś takim i powoli zaczynam rozumieć znaczenie zwrotu “going postal” choć nie pracuję bynajmniej dla poczty…

  94. Avatar Nowaker powiedział 29 days later:

    > W przeciwieństwie do Javy, Scala nie posiada interfejsów. I bardzo dobrze, bo ich przydatność jest wysoce wątpliwa (oczywiście do PHP5 dodano bezmyślnie te nieszczęsne interfejsy).

    1. Jak stworzysz sortowalną kolekcję, nie mając interfejsu typu Comparable? Nie interesuje mnie, jaką kolekcję dostanę do posortowania – byle tylko implementowała Comparable. Bez interfejsu – pewnie, będziesz sprawdzał przez reflection, czy obiekt ma metodę compareTo. A może ma compare? A może jeszcze inaczej?

    2. W jaki sposób utworzyłbyś drivery do MySQL i PgSQL w taki sposób, aby miały wspólne API? Ja bym utworzył interfejs DatabaseDriver, po poczym utworzył MysqlDatabaseDriver i PgsqlDatabaseDriver poprzez implementację tego interfejsu.

    3. W jaki sposób utworzyłbyś obiekt pełniący kilka różnych funkcji? Przykładem jest chociażby midlet, który będzie zarazem słuchaczem zdarzeń. Ja to zrobię implementując dwa interfejsy.

    Oczywiście klasy abstrakcyjne się przydają, aby nie powielać części kodu. Należy jednak pamiętać o tzw. problemach ułomnej klasy bazowej, który prowadzi do trudnych to wykrycia błędów w programie.

    W wolnym czasie poczytaj trochę literatury na ten temat, np. Alien Holub – Wzorce projektowe.

  95. Avatar Jarosław Zabiełło powiedział about 1 month later:

    Nowaker: Scala nie potrzebuje żadnych intefejsów bo ma o wiele lepszy mechanizm – traits. Zobacz też The busy Java developer’s guide to Scala: Of traits and behaviors

  96. Avatar Nowaker powiedział about 1 month later:

    Ja odebrałem Twoją wypowiedź o interfejsach w taki sposób, że są całkowicie bez sensu i niepotrzebne. Nie wypowiadam się o Scali, ponieważ jej (go?) nie znam.

    Doświadczenie uczy – z biegiem czasu oczywiście powstają lepsze mechanizmy.

    Traits, z tego co rozumiem, czerpie zarówno z rozszerzania klas (dziedziczenie implementacji), jak i interfejsów. Nie zapominajmy tylko, że dziedziczenie implementacji nie zawsze jest bezpieczne w kontekście ułomnej klasy macierzystej.

  97. Avatar Jarosław Zabiełło powiedział about 1 month later:

    Traits są podobne do modułów Ruby’ego. Można wstrzykiwać do klasy (lub singletona) metody zdefiniowane w takim module. Interfejsy może nie są całkiem bez sensu, ale są dużo gorszym rozwiązaniem od traits’ów.

  98. Avatar bartek powiedział 2 months later:

    Mam nietypowe pytanie – w jakim programie powstal wykres UML w tym wpisie (Map, HashMap, etc.)?

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

    bartek: OmniGraffle Pro (UML to za duże słowo, to wykres z książki “Programming in Scala”, z tą różnicą, że zamiast robić screenshot’a, stworzylem go od zera w tym programie)

  100. Avatar dmilith powiedział 2 months later:

    Bolo: Wiesz, porównywanie Eclipse’a (IMHO jednak paskudnego i DARMOWEGO oprogramowania) do komercyjnego kombajna (MSVS) to kolejny wygłup z Twojej strony.

    Jak tego potrzebujesz to porównaj sobie MSVS choćby z Intellij IDEA. To też IDE, w które JetBrains włożyło kupę kasy. (Ale myślę, że i tak M$ włożył w MSVS więcej). Takie produkty można porównywać OBIEKTYWNIEJ.

    Myślę że by Ci szczena opadła jak byś zobaczył wydajność tego IDE. I też działa w oparciu o JVM.

  101. Avatar dmilith powiedział 2 months later:

    Co do tematu postu, mnie najbardziej podoba się to, że mogę tworzyć implicit definitions. Otwarte klasy i Monkey Patching są moim zdaniem jednak zbyt dużym niebezpieczeństwem przy pisaniu poważnego kodu.

    Kolejna kwestia to to, że Scala jest niemal tak szybka jak Java (zależy od algorytmu i rodzaju problemu jak zawsze), gdzie nawet implementacji jRuby wciąż bardzo daleko do takiej wydajności.

    Jest to dla mnie kolejny argument na NIE dla Rubiego od czasu kiedy piszę w Scali. (w zasadzie od mojego pierwszego komentarza w tym artykule :})

  102. Avatar bart powiedział 5 months later:

    “wynik = warunek if wyrazenie1 else wyrazenie2”

    Powinno być:

    wynik = wyrazenie1 if warunek else wyrazenie2

  103. Avatar Jiima powiedział 5 months later:

    @Nowaker

    Interfejsy są wyłącznie sposobem na obejście ograniczeń statycznego typowania i – w wypadku Javy, C# itp jako obejście braku funkcji jako obiektu pierwszej klasy (w C# masz jeszcze delegaty) Na przykład dlatego w PHP interfejsy są kompletnie bezużyteczne, jest to język dynamicznie i słabo typowany. Rzeczy takie jak API powinno załatwiać się przez konwencję (vide DBApi w Pythonie). W Scali masz traitsy, które są czymś pośrednim między interfejsem a mixinem.

    Co do sortowania czy callbacków, to załatwia się funkcjami jako obiektami pierwszej klasy. Zamiast “kulawego interfejsu” z jedną funkcją przekazujesz po prostu tę funkcję.

  104. Avatar kojot powiedział 5 months later:

    Ech, Panowie, tyle bzdur sie mozna naczytac… ale pomijajac. Mam kilka uwag: 1. dobrze jest dodac polskie tlumaczenia do angielskich terminow, albo pisac po angielki calosc, mnie wszystko jedno. btw. trait oznacza ‘cecha’

    2. Jesli nie wiesz co to Qt to sie dowiedz zanim zaczniesz pisac glupoty. Qt jest wiecej niz frameworkiem i nie ma nic wspolnego z GUI oprocz tego ze rowniz je obsluguje, to jest troche jak biblioteka standardowa nabudowana na C+, a nawet wiecej, jest to rozszerzenie C+ poprzez metakompilator dodajacy takie mozliwosci jak metaptogramowanie i system slotow i sygnalow. Polecam doczytac na ten temat, wiedza nie boli a pomaga sie nie skompromotowac

    3. C++ vs. Java – to porownaie nie ma sensu. To jest porownywanie jablek do pomaranczy. Obszar zastosowan sie nie pokrywa. C++ stosuje sie od zastosowan osadzonych po wydajne aplikacje pracujace z przetwarzaiem obrazu lub dzwieku. Java natomiast glownie jest uzywana (zgodnei z zamierzeniami projektowymi) jako jezyk wokol sieci w systemach rozproszonych, aplikacjach serwerowych, oraz aplikacjach mobilnych (android). Co wiecej, potrzeby w tych zastosowaniach sa inne wiec inne narzedzia sa potrzebne. Pierwsze zastosowania wymagaja szybkiego startu, mozliwie malej zajetosci pamieci i wysokiej wydajnosci obliczeniowej, natomiast drugie, wymagaja przede wszystkim bezpieczenstwa i szyblosci dzialania pod katem dlugo zyjacych procesow, szybkosc startu jest malo istotna, podobnie zajetosc pamieci.

    4. “Jesli jedynym narzedziem jakie znasz jest mlotek, kazdy problem zaczyna wyglac jak gwozc” – zatem znaj swoje narzedzia i umiej je dobrac. Jak ktos mnie pyta czy jezyk X jest lepszy od Y zazwyczaj odpowiadam ze oba (chyba ze jednym z nich sa C# lub PHP ktore ogolnie sa bez sesu ;P )

    5. z jezykow ktore znam kazdy jest dobry, kazdy w swojej dziedzinie: C, C++/Qt, Java, Python, Scala. Mamy tyle jezykow do wyboru zeby umiec wybrac najlepszy do zadania, a nie wszczynac bezcelowe flamewars

    Pozdrawiam

  105. Avatar Pawel powiedział 11 months later:

    A moim zdaniem, ten jezyk wcale nie bedzie jezykiem przyszlosci. olejny twor, znajdzie na pewno swoich wyznawcow ale przemknie tak samo niezauwazony jak ruby, gruwy, qbasic itd

  106. Avatar Radek powiedział over 2 years later:

    Przed chwilą dowiedziałem się co to Scala… Jestem poczatkującym, ba – raczkującym programistą C i to całe programowanie funkcyjne to jakaś ciemna masa, ale może kiedyś…:) Dobrze że jest ktoś, kto o tym pisze. Nie wiem ile jest prawdy w Twoim tekscie gdyż sie zwyczajnie nie znam :) Ale dziękuję za sam fakt rozszerzenia moich horyzontów poza stareńskie C, C++ i Pascala :))

  107. Avatar Orzechowski powiedział over 3 years later:

    Artykuł ciekawy, mam tylko jedno zastrzeżenie – czepiles się interfejsów.

    Interfejsy są niezbędne w językach statycznie typowanych o dziedziczeniu jednobazowym. Skąd inne klasy maja wiedzieć co dana klasa “umie”?

    Druga sprawa ze interfejsy w Java pozwalają na tworzenie w nich pól: Poprzez metody get/set. A to jest prawidlowa technika tworzenia pól Publicznych w Javie. to już nie moja wina że Java nie ma tak wygodnego tworzenia pól jak c# w którym to wygląda bardzo naturalnie. Ale nie należy wypuszczać w świat zmiennych publicznych bez pokrycia ich get/set i tak wiec ja nie widzę problemu z interfejsami.

    Na tegorocznej konfiturze jeden z prelegentów podsumował te 20 lat istnienia Javy i stwierdził ze okazało się przez ten czas ze wcale nie dziedziczenie było najważniejsze tylko właśnie interfejsy. Interfejsy są jak najbardziej konstrukcjami obiektowymi, może jeszcze nie zrozumiałeś do czego tak naprawdę są? :)

  108. Avatar Dominik powiedział over 4 years later:

    Ktoś poleci jakiś fajny hosting dla Play i Scala ?

(leave url/email »)

   Pomoc języka formatowania Obejrzyj komentarz