1 / 35

Peter Borovansk ý, KAI, I-18, borovan (a)ii.fmph.uniba.sk

Go. Peter Borovansk ý, KAI, I-18, borovan (a)ii.fmph.uniba.sk. 199 1 , Python , Guido van Rossum , http://www.python.org/ 199 5 , Ruby , Yukihiro Matsumoto , http://www.ruby-lang.org/en/ 2003, Scala , Martin Odersky, http://www.scala-lang.org/

Télécharger la présentation

Peter Borovansk ý, KAI, I-18, borovan (a)ii.fmph.uniba.sk

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Go Peter Borovanský, KAI, I-18, borovan(a)ii.fmph.uniba.sk • 1991, Python, Guido van Rossum, http://www.python.org/ • 1995, Ruby, Yukihiro Matsumoto, http://www.ruby-lang.org/en/ • 2003, Scala, Martin Odersky, http://www.scala-lang.org/ • 2009, Go, Rob Pike, KenThompson http://golang.org/ Literatúra: http://www.golang-book.com/assets/pdf/gobook.pdf http://golang.org/ • http://golang.org/ref/spec - špecifikácia jazyka • http://talks.golang.org/2010/ExpressivenessOfGo-2010.pdf • http://www.abclinuxu.cz/clanky/google-go-1.-narozeniny IDE: • LiteIDE: https://code.google.com/p/golangide/ • SciTE: http://go-lang.cat-v.org/text-editors/scite/

  2. C++(Java) vs. Python(JavaScript) • kým C++ (Java) oplýva komplikovanosťou a ťažkopádnosťou často spôsobenou statickou typovou kontrolou, interpretované a dynamicky typované jazyky ako Python, Ruby, JavaScript ponúkajú ľahkosť, elegantnosť pri písaní, kódu, malých prototypov. -- aj preto si ich ľudia veľmi obľúbili • dynamické typovanie je ale smrť pre väčšie projekty -- osobný názor, s ktorým môžete nesúhlasiť... • tradičné kompilované a staticky typované jazyky ako C, C++, Delphi (Java) ponúkajú efektívnosť na úkor pohodlia pri písaní kódu Go chce uspieť ako: • efektívny (t.j. kompilovaný) jazyk vhodný pre veľké projekty • s rýchlym kompilátorom • ako jazyk s podporou distribuovaných, konkurentných a sieťových aplikácií http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

  3. Typovanie • no typing - assembler • weak static typing (C, C++, Objective C) char z = “hello”;// núti definovať typy všetkých objektov, ale interne … // si pamätá, koľko bajtov zaberá printf(“%i”,z);// keď ju chceme formátovať, treba pripomenúť typ viac a viac typových obmedzení počas času kompilácie (C->C++) • strong static typing (Java) informácia o type je prístupná v čase behu, a VM teda môže kontrolovať typ ak chceme pretypovať objekt na iný typ, Java v čase behu realizuje kontrolu výsledok: menej hackov ako C, C++, jazyk je viac rigidnejší • strong dynamic typing (Python, Ruby, JavaScript) if ... : z = “aaa” else: z = 5 print z z = z+z // typ z sa zisťuje až v čase behu programu http://coding.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/

  4. Statici vs. dynamici “Static typing only catches some bugs, and you can’t trust the compiler to do your testing.” “Dynamic languages are easier to read because you write less code.” “Just because the code compiles doesn’t mean it runs.” “The compiler doesn’t stop you from writing bad code.” “Static typing catches bugs with the compiler and keeps you out of trouble.” “Static languages are easier to read because they’re more explicit about what the code does.” “At least I know that the code compiles.” “I trust the static typing to make sure my team writes good code.” http://coding.smashingmagazine.com/2013/04/18/introduction-to-programming-type-systems/

  5. Prečo Go • procedurálny a statickytypovaný jazyk, ako C++, Java, Pascal • poskytuje možnosti/pohodlie dynamicky typovaných jazykov, ako javaScript, Python, Ruby, ... • je kompilovaný (žiadna virtuálna mašina) • je objektový, ale nepozná(pod)triedy, abstraktné metódy ani dedičnosť • podporuje tzv. implicitný interface(ak objekt má predpísané metódy) • nepodporuje preťažovanie(metód ani operátorov) • zatiaľ(Go-1) nepodporuje generics/templates • ... má len “metódy”, ale aj pre základné typy (int, string, float, …) • podporuje funkcionálnu paradigmu, podobne ako Lisp, Python, či Haskell • podporuje konkurentú paradigmu • nemá predprocesor • má garbage collector (... aj pre konkurentné rutiny) • nemá hlavičkové súbory, viditeľnú informáciu z modulu exportuje do .a • … a lebo Python učí A.Blaho, po-ut 9:50, A http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

  6. TIOBE Programming Community Index 2013 http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

  7. Kompilácia Go Implementácia: • windows/386, linux/386, linux/amd64, freebsd/386, freebsd/amd64 • interpretovaný aj kompilovaný (existujúce dva hlavné kompilátory gc, 6g) Analýza závislostí: • zisťuje, či importované moduly, definované premenné sú naozaj použité • zrýchlila kompiláciu proti C++ • C:#include <stdio.h> importuje 360 riadkov/9 súborov • C++:#include <iostream> importuje 25.326 riadkov/131 súborov • Objective-C:#include <Cocoa/Cocoa.h> importuje 112.047 riadkov/689 • Go:import “fmt” importuje 195 riadkov/6 Má niečo jazyk Go s Androidom ? • nemá Zdroj:https://www.youtube.com/watch?v=7VcArS4Wpqk

  8. Hello world jednoduchosť a čitateľnosť Prvý program v Go: // package je povinne 1.príkaz modulu packagemain // spustiteľný package musí mať package main import"fmt"// konvencia: package name je najhlbší podadresár // fmt implementuje formátované I/O funcmain(){// hlavná spustiteľná metóda main() fmt.Println("Hello"+"world!")//viac na golang.org/pkg/fmt/ } >go run hello.go Hello world ! >go build hello.go >dir hello.* 10. 09. 2013 07:38 1 282 048 hello.exe 10. 09. 2013 07:37 82 hello.go >hello.exe Hello world ! Hello/hello.go

  9. Základné typy a literály orientovaný na reálny HW Aby sme vedeli niečo programovať, potrebujeme základné dátové typy • uint (uint8=byte, uint16, uint32, uint64) • int (int8, int16, int32=rune, int64)// int = int32 alebo int64 podľa • 28, 0100, 0xdeda,817271910181011// konkrétnej implementácie • float (float32, float64) • 3.1415, 7.428e-11, 1E6 • complex (complex64, complex128) • 5i, 1.0+1i • bool • true, false • string • `hello` = "hello" • `\n // reťazec cez niekoľko riadkov \n` = "\\n\n\\n" • "你好世界" • "\xff\u00FF”

  10. Operátory a pretypovanie uznáva/priznáva svet C++/Java Prioritypre binárne operátory: • *, /, %, <<, >>, &, &^(bitový clear, t.j. and-xor) • +, -, |, ^ (xor) • ==, !=, <, <=, >, >= • && • || Unárne operátory: • ^ bitová negácia int • ! not pre bool Konverzie (ani medzi číselnými typmi) nie sú implicitné, použi pascalovskú syntax na pretypovanie typ(výraz) • float32(3.1415) // 3.1415 typu float32 • complex128(1) // 1.0 + 0.0i typu complex128 • float32(0.49999999) // 0.5 typu float32 občas sa primieša aj Pascal...

  11. Premenné a ich deklarácie • inferencia typu premennej pri deklarácii z výrazu inicializácie • premenná = výraz priradí do premennej • premenná := výraz deklaruje premennú packagemain import("fmt""strconv") funcmain(){ varhellostring="Hello" // hello:string, bez : world:="world"// deklarácia world s inicialializáciou // jej typ sa inferuje z výrazu v pravo constdots=`...`// konštanta typu string fmt.Println(hello+dots+world + strconv.Itoa(123)) fmt.Println(hello+string(dots[0])+world) str,err:=strconv.Atoi("3.4") // str:string,err:Error iferr==nil{ fmt.Println(str) } else{ fmt.Println(“chyba:"+err.Error())} } a opäť Pascal... Variables/hello1.go

  12. Fibonacci V ďalšom ilustrujeme jazyk Go na triviálnom príklade Fibonacciho postupnosti 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, … Prejdeme • od triviálnej implementácie, • cez tabelizáciu, • výpočet pomocou veľkých čísel, • logaritmickú metódu • až po konkurentnú metódu • naivnú • efektívnu

  13. Fibonacci a cyklus • for výraz {…} je while • for …; …; … {…} podobne ako v Java • Go má “paralelné priradenie“ packagemain import"fmt" funcmain(){ var( // viacnásobná deklarácia a=1 bint=1 nint) _,_=fmt.Scanf("%d",&n) // čítanie do n for;n>0;n--{ // c/java-like for fmt.Println(b) //a,b=a+b,a // paralelné priradenie a=a+b b=a-b } } >fibo 10 1 1 2 3 5 8 13 21 34 55 fib.go fibCyklus.go

  14. Fibonacci a rekurzia func meno(argumenty) výsledný typ {…} packagemain  import"fmt" funcFib(nint)int{// pascal-like fib(n:int):int ifn<=2{ return1 }else{ returnFib(n-2)+Fib(n-1) }} funcmain(){ varnint _,_=fmt.Scanf("%d",&n)// čítanie do n forj:=1;j<= n;j++{ fmt.Println(Fib(j)) }} fibRek.go

  15. Fibonacci a pole typ pole je [ ]element Indexovanie 0 .. len() vartabulka[]int// array[] of int, inic [0,0,0…] funcFibPole(nint)int{// tabulka[i] = fib(i+1) iftabulka[n]==0{// ak sme hodnotu ešte nepočítali tabulka[n]=FibPole(n-2)+FibPole(n-1)// počítajme }// a zapamätajme do tabuľky returntabulka[n] // inak ju len vyberme z tabuľky } funcmain(){ varnint_,_=fmt.Scanf("%d",&n) tabulka=make([]int,n)//alokácia array[0..n-1]ofint  tabulka[0]=1// fib(1) = 1 tabulka[1]=1// fib(2) = 1 forj:=0;j<len(tabulka);j++{ fmt.Println(FibPole(j)) }} fiboPole.go

  16. typeIntstruct{ negbool//sign abs[]uintptr// arrayofdigitsofa multi-precisionunsigned int. } Fibonacci a big packagemain  import("fmt""math/big") funcFibBig(nint)*big.Int{ ifn<2{ returnbig.NewInt(1) } a:=big.NewInt(0) b:=big.NewInt(1) forn>0{//pascal-likewhile a.Add(a,b)//a=a+b b.Sub(a,b)//b=b-a n-- } returna } pozri http://golang.org/pkg/math/big/ fibBig(1024) = 4506699633677819813104383235728886049367860596218604830803023149600030645708721396248792609141030396244873266580345011219530209367425581019871067646094200262285202346655868899711089246778413354004103631553925405243 fiboBig.go

  17. Fibonacci logaritmicky Základný hint pochádza odtiaľto (Fj je alias pre Fib(j)): http://www.cs.utexas.edu/users/EWD/ewd06xx/EWD654.PDF !!! Domáca úloha: dokážte to (indukciou :-) Logaritmická idea ako vypočítať Fj , resp. Fib(j), pre veľké j! • F1024=F0b10000000000 (F512,F513)<-(F256,F257)<-(F128,F129)<-(F64,F65)<-(F32,F33)<-…(F1,F2) =(0,1) ... a ako bonus dostaneme aj F1025:-) • F10=F1010 (F10,F11)<-(F5,F6)<-???(F4,F5)<-(F2,F3)<-(F1,F2)=(0,1)

  18. Viac výstupov funkcie func meno(argumenty) (typ1, … typN){…} Funkcia môže mať viac výstupných hodnôt :-) :-) :-) funcFibPair(Fjint,Fj1int)(int,int){ returnFj*Fj+Fj1*Fj1,(Fj+Fj+Fj1)*Fj1 funcFibLog(nint)(int,int){// funguje pre n = 2^i ifn<2{// return pre viac hodnôt return0,1//F1 = 0, F2 = 1 }else{ fj,fj1:=FibLog(n/2)// výstup rekurzie (dvojicu) returnFibPair(fj,fj1)// môžeme priamo poslať }} // return FibPair(FibLog(n/2)) F2j= Fj2+ Fj+12F2j+1=(2* Fj+ Fj+1)* Fj+1 fibonacci.go

  19. FibLog pre párne aj nepárne func meno(argumenty) (typ1, … typN){…} Doriešime prípad, ak n nie je mocnina 2 funcFibLog(nint)(int,int){ if n < 2 {  return 0, 1     } elseifn%2==1{// pre n nepárne x,y:=FibPair(fibLog(n/2)) returny,y+x } else { // pre n nepárne returnFibPair(fibLog(n / 2)) }} funcFibLog1(nint)int{ // vráť druhý z výsledkov _,y:=FibLog(n) // neviem to šikovnejšie urobiť returny // snáď to niekto objaví ... } ako (F5,F6)<-???(F4,F5) Idea: (F5,F6) = (F5,F5+F4) fibonacci.go

  20. FibLogBig F2j= Fj2+ Fj+12F2j+1=(2* Fj+ Fj+1)* Fj+1 Jednoduchým spôsobom upravíme FibPair z int na *big.Int, funcFibPair(Fjint,Fj1int)(int,int){ returnFj*Fj+Fj1*Fj1,(Fj+Fj+Fj1)*Fj1 modul math/big z.Add(x,y) je z = x+y, z.Mul(x,y) je z = x*y, detaily k math/big hľadať v http://golang.org/pkg/math/big/ funcFibPairBig(Fj*big.Int,Fj1*big.Int) (*big.Int,*big.Int){ tmp:=new(big.Int)//pomocná prem :: big F2j1:=new(big.Int)// - … - F2j+1 F2j1.Mul(tmp.Add(tmp.Add(Fj,Fj),Fj1),Fj1) F2j:=new(big.Int)// - … - F2j F2j.Add(Fj.Mul(Fj,Fj),Fj1.Mul(Fj1,Fj1)) returnF2j,F2j1 } fibonacci.go

  21. FibLogBig Potom už logaritmický fibonacci s veľkými číslami dostaneme priamočiaro z rekurzie nad int: funcFibLogBig(nint)(*big.Int,*big.Int){ ifn<2{ returnbig.NewInt(0),big.NewInt(1)//F1=0, F2=1 }elseifn%2==1{ x,y:=FibPairBig(FibLogBig(n/2)) returny,x.Add(y,x) }else{ returnFibPairBig(FibLogBig(n/2)) } } fibonacci.go

  22. FibTest Go podporuje písanie unit-testov a benchmarkov: packagemain  import"testing“// modul potrebný na testovanie funcTestFib2(t*testing.T){ fori:=1;i<1000;i++{ ifFibBig(i).Cmp(FibLogBig1(i))==0{ t.Logf("fib(%d)ok",i) }else{ t.Errorf("fib(%d)=%verror\n",i,FibBig(i)) t.Errorf("fibLog(%d)=%verror\n",i,FibLog1(i)) t.Errorf("fib(%d)error\n",i) } }} fibonacci_test.go

  23. Go rutiny (príklad z “džavi”) go f(args) spustí extra vlákno na výpočet f() packagemain  import("fmt""math/rand""time") funcf(nint){ fori:=5;i>0;i--{ fmt.Println("#",n,":",i) time.Sleep( time.Duration(rand.Intn(500))*time.Millisecond) }} funcmain(){ fori:=0;i<5;i++{ gof(i) } varinputstring// toto čaká na input, v opačnom fmt.Scanln(&input)// prípade, keď umrie hlavné fmt.Println("mainstop")}// vlákno, umrú všetky ostatné

  24. Kanály Do not communicate by sharing memory; instead, share memory by communicating. • make(chan int) // nebufrovaný kanál int-ov • make(chan *big.Int, 100) // bufrovaný kanál *big.Int Nebufrovaný kanál ch typu chan e umožnuje • komunikovať medzi rutinami, • ch <- val jesynchronizovanýzápis do kanálu, kde val je typu e • val <- ch je synchronizované čítanie z kanála, kde val je typu e My použijeme jednoduchý pattern: ch:=make(chanint)// vytvorí nebufrovaný kanál s int-ami goPocitajNieco(..., ch)// spustí nezávislé vlákno … // hlavné vlákno počíta ďalej vysledok := <-ch// čaká na výsledok, blokujúca operácia funcPocitajNieco(..., ch chan int) { trápenie, veľa trápenia, ..., inferno ch <- vysledok// koniec ťažkého výpočtu, pošle do ch } // tiež blokujúca operácia, kým to neprežíta

  25. FibPara funcFibPara(nint,chchanint){ ifn<2{ ch<-1 }else{ ch1:=make(chanint) goFibPara(n-2,ch1) ch2:=make(chanint) goFibPara(n-1,ch2) n2:=<-ch1// čakáme na Fib(n-2) n1:=<-ch2// čakáme na Fib(n-1) ch<-n1+n2// spočítame a kanalizujeme }} „Elegantný“, navyše konkurentný, kód...ale ??? Ale, zamyslime sa, koľko vlákien sa vytvorí na výpočet, napr. Fib(20) ??? fibonacci.go

  26. Priveľa vlákien ch:=make(chanint) goFibPara(20,ch) res:=<-ch fmt.Printf("FibPara(20)%v\n",res) Koľko vlákien to vygeneruje (qíz)?? • 10 • 100 • 1000 • 10000 Poďme teda radšej paralelizovať viaceré násobenia veľkých čísel: Fib(105) má cca 25tis. cifier, násobenie takých čísel nie je elementárna operácia funcmultipicator(a*big.Int,b*big.Int,chchan*big.Int){ tmp:=new(big.Int) ch<-tmp.Mul(a,b) } fibonacci.go

  27. Paralelizuj s rozvahou funcFibPairBigPara(Fj*big.Int,Fj1*big.Int)(*big.Int,*big.Int){ tmp:=new(big.Int) tmp.Add(tmp.Add(Fj,Fj),Fj1) ch1:=make(chan*big.Int) gomultipicator(tmp,Fj1,ch1)// spusti 1.násobenie v 1.vlákne F2j:=new(big.Int) ch2:=make(chan*big.Int) gomultipicator(Fj,Fj,ch2) // spusti 2.násobenie v 2.vlákne ch3:=make(chan*big.Int) gomultipicator(Fj1,Fj1,ch3)// spusti 3.násobenie v 3.vlákne F2j.Add(<-ch2,<-ch3)// čakaj na 2. a 3. výsledok returnF2j,<-ch1 // a potrebuješ aj 1.výsledok } fibonacci.go

  28. Fibonacci a matice !!! A opäťdomáca úloha: dokážte to (indukciou :-) packagemain  typeMatrixstruct{// struct ako v C++ a11,a12,a21,a22int}// reprezentácia matice 2x2 func(m*Matrix)multiply(n*Matrix)*Matrix{ varc=&Matrix{// konštruktor struct m.a11*n.a11+m.a12*n.a21,// násobenie matíc 2x2, m.a11*n.a12+m.a12*n.a22,// hardcode-žiadne cykly m.a21*n.a11+m.a22*n.a21, m.a21*n.a12+m.a22*n.a22} returnc // vráti pointer na maticu } // teda Go má pointre, operátory &, *skoro ako C++ funcFibMatrix(nint)int{ m:=&Matrix{a11:1,a12:1,a21:1,a22:0} p:=m.power(n) returnp.a12} fibMatrix.go

  29. Logaritmický power A už len to nezabiť tým, že power(), alias mocninu urobíme lineárnu... Lepšia bude logaritmická verzia func(m*Matrix)power(nint)*Matrix{ ifn==1{ returnm }elseifn%2==0{// mn = (mn/2)2, pre n párne m2:=m.power(n/2) returnm2.multiply(m2) }else{ // mn = m*(mn-1), pre n nepárne returnm.power(n-1).multiply(m) }} fibMatrix.go

  30. Go heľpovník http://golang.org/ref/spec • package & import package id // prvý riadok v module import "path" import ( "path" "path" ... ) // import viacerých • const, type, var, func const id ,... type = value, ...// deklarácia konštánt s explicitným typom const id ,... = value ,... // deklarácia konštánt s implicitným typom type id different_type // typové synonymum var id ,... type = value ,... // deklarácia premenných s explicitným typom var id ,... = value ,... // deklarácia premenných s implicitným typom const|type|var ( spec; ... ) // viacnásobná deklarácia

  31. Go heľpovník http://golang.org/ref/spec • if-then[-else] if [statement;] condition { block } [else if-or-block] • statement expression // výraz, napr. 5*6 function call // exp(2.71) target ,... = expression ,... // parallelné priradenietarget op= expression // a += 5 target ++, target -- // !!! nie je to výraz id ,... := expression ,... // skrátená deklarácia • for cyklus for { block } // for ;; {}, resp. while (true) {} for condition { block } // while for init; condition; post { block } // ako v Jave for index, value = range expression { block } // cyklus cez pole, slice, kanál, ...

  32. Go heľpovník http://golang.org/ref/spec • arrays type id [ length ] type // typ poľa s konštantou dĺžkou type id [ length ] [ length ] type // matica 2, 3-dimen.len( array ) // veľkosť poľa expression [ expression ] // indexovanie od 0..len(array)-1 new([ length ] type ) // vytvorenie pola s dĺžkou length [ length ] type { expression ,... }// konštanta typu pole s dĺžkou[ ] type { expression ,... } // konštanta typu pole bez dĺžky • slices [] type // slice type (without length) make([] type, length) // construction, slice and array make([] type, length, capacity) len( slice ), cap( slice )// length and capacity expression [low : high] // construction from array or slice expression [low :] expression [ expression ] // element, index from 0

  33. Go heľpovník http://golang.org/ref/spec • function func id ( parameters ) { body } // procedúra func id ( parameters ) result { body } // fcia s výstupným typom func id ( parameters ) ( results ) { body } // viac výstupov func ( parameters ) ( results ) { body } // anonymná funkciafunc ( types ) ( types ) // type // funkčný typ id ,... type // parametre, výstupné premenné id ... Type // neurčený počet argumentov • methods func (id type) id ( parameters ) ( results ) { body } func (id *type) id ( parameters ) { body } // definíciafunc ( type ,... ) ( results ) // typexpression . id ( arguments ) // volanie metódytype . id // metóda ako funkcia(* type ). id

  34. Go heľpovník http://golang.org/ref/spec • switch switch statement; expression { case expression ,...: statement; ... default: statement; ... } switch statement; id := expression .(type) { case type ,...: statement; ... default: statement; ... } • maps var id map [ type1 ] type2// deklarácia zobrazenia type1 -> type2 make(map[type1 ] type2 ) // vytvorenie zobrazenia type1 -> type2 make(map[type1] type2, initial-size) map [ key ] = value // pridanie (key -> value)map [ key ] = dummy, false // zmazanie keymap [ key ] // vyhľadanie value pre keyvalue, ok = map[ key ] // ok je true alebo false

  35. Go heľpovník http://golang.org/ref/spec • struct type id struct { // deklaráciaid ,... type // named field } • new-make-nil new( type ) // alokuje štruktúru a vráti *type make([] type, capacity ) // pre slice, alokuje []type make([] type, length, capacity ) make(chan type ) // pre kanál, alokuje chan type make(chan type, capacity ) make(map[ type ] type ) // pre map, alokuje map[type]type make(map[ type ] type, initial-capacity )

More Related