Linus Torvalds: Java is a Horrible Language

Konu:

Adam dobra biri. Bir Javacı olarak nedenleri ve sonuçları hakkında düşünmek ve konuşmak lazım.

Fonksiyonel Programlama ve 'Yan Etki' Mevzuu - Monad

Konu:

Fonksiyonel Programlama hala tam olarak anlamını kavrayamadığımız bir olgu. Bir de içinde 'fonksiyon' geçtiği için C gibi fonksiyon kullanan dillerle karıştırdığımız çok oluyor. Fonksiyonel programlama benim de yeni yeni anlamaya başladığım bir şey. Bu bağlamda Scala'nın babası olan Martin Oderski'nin verdiği Coursera'daki Functional Programming Principles in Scala adlı dersten çok faydalandım, size de tavsiye ederim. Bunun yanında bazı şeyleri de not olarak yazmak istiyorum. Kopyalamak pek beğendiğim bir yol değil ama internette bulduğumuz şeyi ikinciye bulmak bazen zor olabiliyor, hatta bazen silinmiş olabiliyor. O yüzden Ekşisözlük'te ssg'nin yazdığı bu entry'yi buraya kopyalamak ve bu anı ölümsüzleştirmek istiyorum.

fonksiyonel programlamada yan etki kavramiyla basa cikmak icin kullanilan konseptlerden biri. ama monad'i anlatmadan yan etki nedir ve yan etkiyle fonksiyonel programlamanin alip veremedigi ne var ona bakmak lazim.

genel olarak programlamada bir fonksiyonun kendisinden istenen degeri dondurmek disinda yol actigi gozlenebilir degisikliklerin tamamina yan etki deniyor. imperatif programlamada bu gayet dogal, mesela void'in varligi bile basli basina "bu fonksiyon tamamen yan etkilerden ibarettir" anlamina gelir. yan etkiye ornek verecek olursak:

int topla(int a, int b)
{
    int toplam = a + b;
    return toplam;
}

yan etkiye sahip degilken (cunku mudahale edilen her sey fonksiyonun scope'u icindedir):

int topla(int a, int b)
{
    int toplam = a + b;
    geneltoplam += toplam;
    return toplam;
}

yan etkiye sahiptir. fonksiyonun kendi scope'u disinda biseyleri degistirmektedir cunku. geneltoplam belli ki fonksiyon disinda bir yerde tanimlanmistir.

bir fonksiyonun yan etkiye sahip olup olmadigini anlamak basittir aslinda: fonksiyonu cagiran kodu direkt fonksiyonun dondurdugu degerle degistirince kod hic fark olmadan calismaya devam ediyor mu? ediyorsa bu yan etkiye yol acmayan fonksiyonlara "saf" (pure) fonksiyon deniyor.

amma velakin saf fonksiyonel programlamada "degisken" diye bir kavram olmadigindan ve her sey eninde sonunda bir fonksiyon oldugundan "degistirebileceginiz" degiskenler ve state'ler aslinda yok. yani yukardaki yan etkiye yol acan c# orneginin aslinda saf fonksiyonel bir dilde karsiligi yok. cunku saf fonksiyonel dillerde sizin degistirebileceginiz degiskenler yok. sadece ve sadece deger donduren fonksiyonlar var. bu da dili tasarlayanlarin mazosistliginden degil fonksiyonel programlamanin yapabilecegi bir yigin optimizasyon ve hata kontrolunun aslinda bu kisitlara dayaniyor olmasindan ileri geliyor. mesela saf fonksiyonlarin en buyuk avantaji, kendilerini dogru sirada cagirma zorunlulugu olmamasi, dolayisiyla derleyicinin isterse bunlari rahat rahat paralel (ornek erlang) ya da nasil hizli olacaksa o sirada calistirabilmesi ve lazy evaluation'a izin vermesi.

monad burada, yani saf fonksiyonel programlamaya "kontrollu yan etki" destegini katmak icin mevcut. mantigi da su: eger her seyi bir fonksiyonun donus degeri olarak tanimlayacaksak, o zaman state veya global degiskeni de fonksiyonun hem aldigi parametre hem de donus degeri olarak tanimlariz. mesela yan etkiye yol acan topla fonksiyonumuzu c# yapilari kullanarak soyle tanimlasaydik:

pair topla(int a, int b, int geneltoplam)
{
    int toplam = a + b;
    return new pair(toplam, toplam + geneltoplam);
}

state'i de parametre olarak alip donuste de yeni degerini, dondurmesi gereken degerle bir pakete toplayip donduren bir fonksiyon tanimlardik. boylece fonksiyonu cagiran fonksiyonlari soyle yazmak mumkun olur:

int biseylertoplavegeneltoplamiekranayaz()
{
    console.writeline("genel toplam = {0}", topla(2,4,topla(3,5,0).second).second);
}

iste bu sekilde hic geneltoplam degiskeni tutmadan fonksiyon cagrilarinda state'i tutmayi basardik. monad da tam olarak bu teknigin adi oluyor. yani bir fonksiyonun giris ve cikis degerlerinde "yan etki"lerin tamamini da paslamada yapilan "enkapsulasyon" islemini saglayan fonksiyonel dil yapilarina monad deniyor.

aslinda monad sunu der: fonksiyon aldigi parametrelere ek olarak kainati parametre alir ve donus degeri olarak da kainatin yeni halini dondurur. cenabi hakkin yarattigi kainatin tamamini baska fonksiyona paslamak biraz uzun sureceginden sadece fonksiyonun yan etkilerle etkiledigi seyleri almak yeterlidir. o yuzden geneltoplam fonksiyonumuz bu konuda yeterlidir mesela.

yan etki illa ki degisken olmasi gerekmez. konsola cikti yazmak, loglama yapmak, ekrana pencere cikarmak vs vs, bunlarin hepsi gayetle gozlenebilir yan etkilerdir. elbette "konsolun icerigini yolla sonra geri tamamini al" yerine dissal olaylar icin (dosya islemleri, konsol, window, isletim sistemiyle genel munasebet), fonksiyonel diller genel gecer bir monad saglarlar. oradaki faraziya "bu cagridan sonra senin programin kendi tip sistemi disindaki her sey degisti"dir. o yuzden derleyici yan etkiye yol acan fonksiyonlari sirali olarak cagirir, paralel calismalarina izin vermez boylece kainati degistiren bir fonksiyonun ciktisi olan kainatin obur fonksiyona girdi olacagi garantilenir.

via https://twitter.com/fkadev/status/390340426290716672 & https://eksisozluk.com/entry/22578104

Nginx ile Çoklu Site Yayını (Proxy Pass)

Konu:


Birden fazla siteyi tek makinadan yayınlamak isterseniz bunu nginx kullanarak yapabilirsiniz.

Nginx'i kurduktan sonra configurasyon dosyasını (Linux ve Mac OS X için /etc/nginx/sites-enabled/default) değiştirmek gerekiyor. Her bir site için aşağıdaki gibi bir server{} bloğu eklenecek:

server {
    listen 80;
    server_name   www.example1.com example1.com;
    location / {
        proxy_pass http://localhost:8000;
    }
}
server {
    listen 80;
    server_name   www.example2.net example2.net;
    location / {
        proxy_pass http://localhost:9000;
    }
}

Bu örnekte makina üstünde 8000 ve 9000 portlarından yayın yapan iki ayrı web server yapılandırılıyor (konfigüre ediliyor). nginx, 80 portunu dinliyor ve gelen istekleri ilgili domain'lere göre yönlendiriyor. example1.com domaini adına gelen istekler 8000 portuna, example2.net domaini adına gelen istekler ise 9000 portuna yönlendiriliyor. Böylece iki ayrı web server'ı aynı makinadan nginx kullanarak yayınlayabiliyoruz.

NodeJS Sunucuya Dosya Yükleme (Upload Server)

NodeJS ile bir sunucu oluşturup, sunucuya dosya yükleme işlemini basitçe şöyle yapabiliriz:

var fs = require('fs');
var http = require('http');

http.createServer(function(req,res){
  var newFile = fs.createWriteStream("benioku.txt");
  req.pipe(newFile);
  req.on('end',function(){
    res.end('Dosya yükleme tamamlandı...');
  });
}).listen(8080);

Bu kod çalıştırıldığında, sunucuya gelen her dosyayı benioku.txt adıyla kaydeder. Yükleme tamamlandığında ise 'Dosya yükleme tamamlandı...' cevabını gönderir.

Örneğin istemci (client) tarafından bunu curl ile deneyelim. Yükleme yapmak üzere bir dosya oluşturduktan sonra ya da uygun bir dosya bulduktan sonra;

curl --upload-file uygunDosya.txt http://localhost:8080

NodeJS Dosya Kopyalama

Konu:

NodeJS ile basit bir dosya kopyalama işlemini şu şekilde yapabiliriz:

var fs = require('fs');

var file = fs.createReadStream('kaynak.md');
var newFile = fs.createWriteStream('hedef.md');

file.pipe(newFile);

Sayfalar

Subscribe to hoşaf.org RSS