martedì 9 luglio 2013

Mandelbrot in Go

Era da un po' di tempo che mi stuzzicava l'idea di provare il linguaggio Go di Google (vedi precedente post) e questa volta ci ho riprovato scrivendo il codice per Mandelbrot da solo senza utilizzare script gia' fatti

Come si puo' vedere ci sono riuscito ma ci sono un paio di considerazioni


al di la' del fatto se Go sia destinato all'oblio (come alcuni progetti di Google) o diventera' lo standard del futuro (personalmente propendo per la prima ipotesi .. ma di solito sbaglio) il linguaggio e' particolarmente ostico per un principiante


  • non si possono eseguire operazioni tra tipi di variabile differenti (pena un errore  mismatched types int float32 invalid operation) a meno di un esplicito cast
  • l'assegnazione di un valore ad una variale mediante il segno "=" e' differente da ":=". In pratica usando := non solo si assegna ma si definisce anche una variabile. Se non si comprende questo meccanisco e si dichiara per esempio var s = "Luca" e subito dopo  s:="Luca" si avra' l'errore variable declared and not used a causa di una doppia dichiarazione della variabile s
  • il linguaggio non e' a formattazione libera e la posizione della parentesi graffa (per esempio) deve essere posizionato in posti precisi pena un errore di compilazione
  • in generale la filosofia del compilatore e': tutti warnings sono errori. Il che puo' essere fastidioso ma mi ha permesso di eliminare una variabile che di fatto non utilizzavo mai (e' la variabile test dei precedenti esempi). In questo senso se si importa una libreria che non viene utilizzata il compilatore genera un errore e non esegue il programma

---------------------------------------------------------------
package main

import (
 "image"
 "image/png"
 "image/color"
 "log"
 "os"
)

func main() {

var SCREEN_WIDTH int = 400
var SCREEN_HEIGHT int =  400

var re_min float32  = -2.0
var im_min float32  = -1.2
var re_max float32  = 1.0
var im_max float32  = 1.2

var iterazioni int = 1024

var a,b float32 
var x,y,x_new,y_new,somma float32
var k,i,j int

var re_factor float32 = (re_max-re_min)
var im_factor float32 = (im_max-im_min)

m := image.NewRGBA(image.Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)) 

for i=0;i<SCREEN_HEIGHT;i++ {
for j=0;j<SCREEN_WIDTH;j++ {
a = re_min+(float32(j)*re_factor/float32(SCREEN_WIDTH))
      b = im_min+(float32(i)*im_factor/float32(SCREEN_HEIGHT))
x = 0
      y = 0
     
for k=0;k<iterazioni;k++ {
        x_new = (float32(x)*float32(x))-(float32(y)*float32(y))+float32(a)
y_new = (float32(2)*float32(x)*float32(y))+float32(b)
somma = (x_new*x_new)+(y_new*y_new)
        if somma > 4   {
if k%2 == 0 {
m.Set(j, i, color.RGBA{0, 0, 0, 255})
} else {
m.Set(j, i, color.RGBA{255, 255, 255, 255})
}
break
}
        x = x_new;
        y = y_new;
    }
}
}

 f, err := os.OpenFile("mandelbrot.png", os.O_CREATE | os.O_WRONLY, 0666)
 if(err != nil) {
  log.Fatal(err)
  }
 if err = png.Encode(f, m); err != nil {
  log.Fatal(err)
  }
}