v1.0.0 — Kararlı Sürüm

PHP gibi kur,
Go gibi yaz,
C++ gibi koş.

LOOK, framework olmadan web uygulaması yazmanın en sade yolu. Apache'ye at, çalış — terminal yok, config yok.

⇓ İndir — Ücretsiz Kod Örnekleri →
index.lk
# DB bağlantısı — bir kez, warm start ile kalıcı
$conn = db::connect("mysql://root:@127.0.0.1/blog");

# Routing dile gömülü — framework yok
route("GET", "/", function() use ($conn) {
    $yazilar = db::query($conn, "SELECT * FROM yazilar ORDER BY id DESC LIMIT 10", []);
    print(json::encode(["ok" => true, "data" => $yazilar]));
});

route("POST", "/yazi/{id}/begeni", function($id) use ($conn) {
    db::exec($conn, "UPDATE yazilar SET begeni=begeni+1 WHERE id=?", [int($id)]);
    print(json::encode(["ok" => true]));
});

route("404", function() {
    response::status(404);
    print(json::encode(["ok" => false, "hata" => "Bulunamadı"]));
});
Performans
Gerçek sayılar, gerçek sunucu

looktest.tobiyo.com.tr üzerinde AlmaLinux 8, MariaDB, 32 worker ile ölçüldü.

0
RPS
HTTP + VM, router
c=100, 0 hata
0
RPS
Hesaplama yoğun (fib40)
VM bytecode, c=100
0
RPS
Peak yük (c=1000)
200K istek, 0 hata
7.8
× hız
Bytecode VM speedup
interpreter'a göre
8
MB
Bellek (32 worker)
10 dakika, 4.7M istek
0
hata
72 saat WebSocket
500 eşzamanlı bot

Tüm testler looktest.tobiyo.com.tr canlı ortamında, wrk / ab ile bağımsız olarak ölçülmüştür. DB-bound endpoint'ler ~380 RPS — darboğaz MySQL RTT (~2.6ms), LOOK değil.

İhtiyacınız olan her şey dahil

Framework kurmadan, paket yüklemeden doğrudan yazın.

🔀

Routing Dile Gömülü

route("GET", "/urun/{id}", fn) — tek satır, framework yok, Express yok, Laravel yok.

🗄️

MySQL · SQLite · PostgreSQL

Sıfır bağımlılık, wire protocol doğrudan. Aynı API: db::query / db::exec.

WebSocket + SSE

route("WS", "/chat", fn) — chat, canlı veri, bildirimleri tek dosyada yaz.

🔄

parallel() + channel()

Go goroutine stili eşzamanlılık — 3 paralel DB sorgusu, fan-out pattern, pipeline.

🚀

Bytecode VM

AST → register-based bytecode → switch dispatch. Compute-heavy workload'da 7.8× hız.

📦

Warm Start

DB bağlantısı bir kez açılır, her istekte yeniden kullanılır. Sıfır connection overhead.

🧩

Zengin Stdlib

cache:: · queue:: · jobs:: · mail:: · template:: · auth:: · validator:: — hepsi dahil.

🧪

Test Runner + REPL

look test ile 10 assertion built-in. look repl ile interaktif geliştirme.

📁

Dosya Modül Sistemi

use "routes/auth.lk" — Go paketi gibi, sadece fonksiyonlar export, $var izolasyonu.

Gerçek kodla tanışın
index.lk — REST API + Auth
$conn = db::connect("mysql://root:@127.0.0.1/blog");
use auth;
use validator;

function admin_kontrol() {
    session::start();
    if (session::get("admin_id") == null) {
        response::status(401);
        print(json::encode(["ok" => false, "hata" => "Yetkisiz"]));
        return false;
    }
    return true;
}

route("GET", "/api/yazilar", function() use ($conn) {
    $rows = db::query($conn, "SELECT * FROM yazilar ORDER BY id DESC", []);
    print(json::encode(["ok" => true, "data" => $rows]));
});

route("POST", "/api/yazilar", function() use ($conn) {
    if (!admin_kontrol()) { return; }
    $v = validator::check(request::json(), [
        "baslik"  => ["required", "min:3", "max:200"],
        "icerik"  => ["required", "min:10"]
    ]);
    if (!$v["ok"]) {
        response::status(422);
        print(json::encode($v)); return;
    }
    $data = request::json();
    db::exec($conn, "INSERT INTO yazilar (baslik,icerik) VALUES (?,?)",
             [$data["baslik"], $data["icerik"]]);
    print(json::encode(["ok" => true, "id" => db::last_id($conn)]));
});
chat.lk — Gerçek zamanlı chat (WebSocket)
# --mode http ile çalışır
$hub = channel();   # broadcast kanalı

route("WS", "/chat", function($ws) use ($hub) {

    # Gelen mesajları bu client'a ilet
    parallel(function() use ($ws, $hub) {
        while (true) {
            $msg = receive($hub);
            if ($msg == null) { break; }
            ws::send($ws, $msg);
        }
    });

    # Mesaj gelince hub'a gönder → tüm clientlar duyar
    ws::on($ws, "message", function($data) use ($hub) {
        $p = json::decode($data);
        send($hub, json::encode([
            "from" => request::ip(),
            "msg"  => $p["msg"]
        ]));
    });

    ws::on($ws, "close", function() {
        log::info("Chat bağlantısı kapandı");
    });
});

# 30s keepalive ping — SSE ile aynı pattern
timer::every(30000, function() {
    ws::broadcast(json::encode(["type" => "ping"]));
});
parallel.lk — Fan-out: 3 paralel DB sorgusu
$conn = db::connect("mysql://root:@127.0.0.1/qrmenu");

route("GET", "/panel/ozet", function() use ($conn) {

    # 3 sorguyu paralel çalıştır — toplam süre max(t1,t2,t3)
    $ch = channel(3);

    parallel(function() use ($ch, $conn) {
        send($ch, db::col($conn, "SELECT count(*) FROM firmalar", []));
    });
    parallel(function() use ($ch, $conn) {
        send($ch, db::col($conn, "SELECT count(*) FROM urunler", []));
    });
    parallel(function() use ($ch, $conn) {
        send($ch, db::col($conn, "SELECT count(*) FROM kategoriler", []));
    });

    $firmalar    = receive($ch);
    $urunler     = receive($ch);
    $kategoriler = receive($ch);

    print(json::encode([
        "firmalar"    => $firmalar,
        "urunler"     => $urunler,
        "kategoriler" => $kategoriler
    ]));
});
jobs.lk — Arka plan iş kuyruğu (e-posta gönderimi)
use jobs;
use mail;

# Route: isteği anında yanıtla, işi kuyruğa at
route("POST", "/kayit", function() use ($conn) {
    $data = request::json();
    db::exec($conn, "INSERT INTO kullanicilar (email,ad) VALUES (?,?)",
             [$data["email"], $data["ad"]]);

    # Kuyruğa at — max 3 deneme, hemen çalıştır
    jobs::push("hosgeldin_email", [
        "to" => $data["email"],
        "ad" => $data["ad"]
    ], 3, 0);

    print(json::encode(["ok" => true]));
});

# worker.lk — ayrı process (systemd servisi)
jobs::recover("hosgeldin_email");   # crash recovery

jobs::worker("hosgeldin_email", function($job) {
    $r = mail::send(
        $job["payload"]["to"],
        "Hoş geldiniz!",
        "Merhaba " . $job["payload"]["ad"] . ", kaydınız tamamlandı."
    );
    return $r["ok"];  # false → retry (max 3)
});
jobs::run(5000);   # 5 saniyede bir — blocking
blog.lk — Struct + template engine
use template;

struct Yazi {
    id
    baslik
    icerik
    tarih
    begeni: 0
}

$tpl = env("VIEWS_DIR", "/app/views");

route("GET", "/blog", function() use ($conn, $tpl) {
    $rows = db::query($conn, "SELECT * FROM yazilar", []);
    print(template::render($tpl . "/blog/index", [
        "baslik"  => "Blog",
        "yazilar" => $rows
    ]));
});

# views/blog/index.html:
# {#extends "views/layout/base"}
# {#block "content"}
# {#each $yazilar as $y}
#   <h2>{$y.baslik}</h2>
# {/each}
# {/block}
PHP ile farkı
Özellik PHP 8.x LOOK
Routing Framework gerekir Dile gömülü
DB bağlantısı Her request'te yeniden Warm start — bir kez
Global değişken $_GET, $_POST, $_SESSION... Yok — request::, session::
WebSocket Ek kütüphane (Ratchet/Swoole) Yerleşik
Goroutine / async Yok (veya Swoole) parallel() + channel()
Bellek (32 worker) ~1.8 GB (Apache) 8 MB
Karma array İzin verilir (karışıklık) Kasıtlı yok
Closure capture use() zorunlu değil use() zorunlu — temiz
Deployment Apache/cgi Apache/cgi + HTTP server
5 dakikada çalışır

Platform seçin:

  1. Tek komutla kur

    Ubuntu 22/24 veya AlmaLinux 8 — distro otomatik algılanır.

    curl -fsSL https://get.codlook.com | sudo bash
  2. Apache vhost'u yapılandır

    Kurulum scripti Apache/nginx config'i otomatik yazar. Sadece restart:

    systemctl restart apache2 # veya httpd
  3. İlk uygulamayı yaz

    /var/www/html/index.lk dosyasını oluştur, tarayıcıda aç — bitti.

    look version # LOOK 1.0.0 (linux/amd64)
  1. XAMPP kurun

    XAMPP zaten kuruluysa bu adımı atlayın.

    https://www.apachefriends.org/
  2. install.bat'ı yönetici olarak çalıştırın

    Binary'leri kopyalar, Apache'yi yapılandırır, Windows servisi olarak kaydeder.

    install.bat --xampp C:\xampp
  3. XAMPP Apache'yi yeniden başlatın

    XAMPP Control Panel → Apache → Stop → Start. Ardından tarayıcıda http://localhost/saglik açın.

  1. Extension'ı yükleyin

    Plesk → Extensions → ZIP Yükle → look-lang-1.0.0.zip seçin.

  2. Domain ekleyin

    LOOK → Domain Ekle → domain seç, script yolu yaz, worker sayısı seç → Başlat.

  3. Bitti

    Terminal yok. SSH yok. Config yok. systemd servisi ve nginx vhost otomatik oluşturuldu.

İndir
Ücretsiz ve açık kaynak

v1.0.0 — Tüm platformlar için kararlı sürüm.

🐧 Linux

Ubuntu 22/24, AlmaLinux 8, Debian 11/12. x86_64 + ARM64.

curl -fsSL https://get.codlook.com | sudo bash
⇓ look-linux-x64.tar.gz AlmaLinux 8 (glibc 2.17)

🪟 Windows

Windows 10/11 + XAMPP. IOCP — sınırsız bağlantı. Task Scheduler ile otomatik başlatma.

⇓ look-windows-x64.zip install.bat (XAMPP)

🖥️ Plesk Extension

Plesk 18+ için tek tıkla kurulum. Domain ekle, başlat — terminal yok.

⇓ look-lang-1.0.0.zip GitHub →

🧩 VS Code Extension

Sözdizimi renklendirme, snippet'lar, bracket matching. v0.2.1

Marketplace → VSIX (offline)