osa1 feed

Bir dili/kütüphaneyi sevmemek için gereken süre

April 26, 2012 - Tagged as: tr.

30 saniye ile 3 saat arasında değişiyor. 3 saat sonunda hala seviyorsanız büyük ihtimalle seviyorsunuz.

Örnek 1: CoffeeScript (3 saat)

CoffeeScript’te birşeyler ciddi anlamda yanlış. Bir kısmı fikir olarak bence kötü, bir kısmı da hata gibi. Örneğin aşağıdaki koda bakalım:

@e('')
    .color('rgb(255,0,0)')
    .attr( x: 20,
           y: 100,
           w: 10,
           h: 100 )

.attr çağrısına dikkat edin. Parametresinin nasıl bir JS koduna derlenmesini beklersiniz? Referansına bakarak ben şöyle düşünüyorum: x, y, w ve h anahtarlarını içeren bir map(veya object veya her ne derseniz). Peki aslında nasıl derleniyor?

this.e('').color('rgb(255,0,0)').attr({
  x: 20
}, {
  y: 100,
  w: 10,
  h: 100
})

x’i diğerlerinden ayırıyor. Sanki x’den sonraki virgülü parametreleri birbirinden ayıran virgülmüş gibi yorumluyor. Ama bunu yapmaması lazım çünkü 1) parametre syntaxına uymuyor(: karakteri) 2) madem onu parametre gibi ayırdın neden y, w ve hyi birbirinden ayırmadın?

Hadi neyse, klasik object gösterimini kullanalım, şu şekilde:

@e('')
    .color('rgb(255,0,0)')
    .attr({ x: 20,
            y: 100,
            w: 10,
            h: 100 })

Herşey yolunda gibi, normal {} ile object syntaxını kullandım. Bu seferde, çok komik gelecek, yni olduğu satırda Unexpected '{' hatası veriyor. Şaka gibi. O satırda öyle bir karakter bile yok. Bu hatadan emin olmak için birkaç deneme yaptım. Öyle bir olmamasına rağmen derleyici hata veriyor. Bana bariz bir bug gibi geldi.

Kodu istediğim gibi bir tek şu şekilde derleyebildim:

@e('')
    .color('rgb(255,0,0)')
    .attr
           x: 20,
           y: 100,
           w: 10,
           h: 100

Şaka gibi, bir karakter aşağıda, ve indent edilmiş. Burda .attrdan sonra parantez koyarsam da derleniyor. Eğer xi ilk örnekteki gibi .attr ile aynı satıra alırsam yine ilk örnekteki hatayı alıyorum.

Bu kodda bir de öncesinde başka bir parametre koyacaksam syntax şöyle oluyor:

.attr 4,
    x: 20
    y: 100
    w: 10
    h: 100

Daha fazlasını kaldıramayacağım :) .

Bir başka dikkat edilmezse çok uğraştıracak kısım da şu, eğer .color(..) kısmında, color methoduna tek parametre göndermeme rağmen parantez kullanmazsam, .attr kısmı .colora gönderdiğim stringe çağırılıyor. Bu şekilde alt alta bir üstteki methodun dönüş değerine methodlar çağırırken, her methodun parametrelerini paranteze almamız gerekiyor yani.

Bunun gibi şeyleri farketmem için yaklaşık 3 saat gerekti.

DÜZENLEME: Xaph’ın yorum olarak yazdıklarını mutlaka okuyun, CoffeeScript’in nesne gösteriminin nasıl çalıştığını daha iyi açıklıyor. Bir programlama dili trollü olarak CoffeeScript’in IRC kanalını bastım ve bu bahsettiklerimi orda da anlattım. Daha sonra farkettiğim bir problem bir fonksiyona birden fazla object göndermekti. Syntax kısmı yine her seferinde çakılıyordu. JS olarak şöyle birşey yapmak istiyordum yani:

func({a: 1,
      b: 2},
     {a: 10,
      b: "??"});

Bulabildiğim tek çözüm, IRC kanalından birinin yardımıyla, şu oldu:

func({
   a: 1
   b: 2
}, {
   a: 10
   b: 2
});

Ne kadar çirkin olduğu bariz sanırım. Bir de bu parametrelerin arasına başka tiplerde(string, int vs.) parametreler girdiğini düşünün.

Bizim böyle bir blog yazısında, SO başlıklarında ve IRC kanalında böyle birşeyi tartışmamız bile dilin syntaxındaki bariz bir kusurdur bence.

Buna göre CoffeeScript nesne gösteriminde kurallar şöyle gibi: 1) {} karakterinden sonra(bu karakterleri koymuyorsanız da farketmez, nesneyi gösterimine başlamadan önce), eğer nesneyi birden fazla satıra bölecekseniz, mutlaka alt satıra geçin. 2) Nesneyi gösterirken tüm anahtarları aynı kolona yerleştirin. Hangi kolon olduğu farketmez ama aynı kolonda olmalı.

Örnek 2: Crafty (30 saniye)

Kendisi bir Javascript oyun frameworkü. Eğer oyun yapımıyla uğraşmışsanız farkındasınızdır, inheritance çok faydalı oluyor. Çoğu zaman entity sınıflarınız oluyor ve bunları özelliklerine göre başka sınıflardan derive ediyorsunuz. Örneğin tüm cisimlerin sahip olması gereken belirli fiziksel özellikleri(kütle, hacim, yani çarpışmaların tespit edildiği özellikler/methodlar) bir sınıf haline getirirsiniz ve cisimleri bunun alt sınıfları olarak tanımlarsınız.

Bu adamlar kendi inheritance sistemlerini yapmışlar, superclass’ları bir stringde “Paddle, 2D, DOM, Color, Multiway” gibi belirtiyorsunuz. Dökümantasyonu açar açmaz bu kod karşılıyor sizi.

Dilin sana izin vermediği şeyleri bu şekilde aşmak bana kötü geliyor. Aslında dil izin vermiyor değil sanırım, örneğin CoffeeScript’de sınıflarla OOP yapabiliyorsunuz, multiple inheritance desteği olmasa da kolayca aynı davranışı elde edebiliyorsunuz(CoffeeScript FAQ sınıflar bölümüne bakın). JS nesne sistemine hakim değilim ama demek ki bunu yapmanın bir yolu var. Her halükarda bu yol kötü bir yol yani.


Tabi tüm bunlar bu dilleri/kütüphaneleri kullanmayacağım anlamına gelmiyor, hatta saatlerdir de bu ikisi ile kod yazıyorum. Ben bunları programlama dillerine meraklı, kendi dili/derleyicisi/yorumlayıcısı üzerinde çalışan ve bu konularda katı fikirlere sahip biri olarak söylüyorum.

Yoksa Java’dan da nefret ediyorum ama 14 hafta neredeyse full-time Java yazdım. Ayrı mesele.