2 puan yazan GN⁺ 6 시간 전 | 2 yorum | WhatsApp'ta paylaş
  • JavaScript sözdizimi, iç içe parantezler ve callback'lerle kolayca karmaşık hale geliyor; küçük bir UI için bile çok sayıda kütüphane çekilen bir şişkinleşme ortaya çıkıyor
  • WebAssembly, tarayıcıda başka dilleri çalıştırmanın yolunu açıyor; ancak Pyodide örneğinde olduğu gibi JavaScript event loop ile asenkron bağlantının maliyeti yüksek
  • Tarayıcı kaynakları ve WebAssembly belleği sınırlı olduğundan, JavaScript'i değiştirmeye çalışmak yerine onunla müzakere eden bir yaklaşım gerekiyor
  • LispE, 3.3 MB'lık tek bir WASM ikilisinde 450'den fazla fonksiyon barındırıyor ve string, hesaplama, matris, düzenli ifade işlevlerini birlikte sunuyor
  • evaljs ve asyncjs ile JavaScript fonksiyonları ve DOM kullanılırken, çok sayıda harici kütüphane yerine denetlenebilir tek bir ikiliyle kod şişkinliği azaltılıyor

JavaScript şişkinliği ve tarayıcı kısıtları

  • JavaScript sözdizimi, parantez, küme parantezi ve köşeli parantezlerin iç içe geçmesi ve kapanış sırasının doğru tutulması gerektiği için kodu kolayca karmaşıklaştırır
    • forEach callback'i içinde birden fazla nesneye değer atayan ve koşullu cache güncelleyen bir örnek veriliyor
newNames.forEach((name, i) => {
    allAgentContents[name] = contents[i];
    agentModes[name] = modes[i];
    if (compiled[i]) agentCompiledCache[name] = compiled[i];
    agentViewingCompiled[name] = viewing[i];
});
  • Temel bir programlama dilinde çoğunlukla yerleşik gelen işlemler için JavaScript tarafında çok sayıda kütüphane indirmek gerekiyor
    • C ya da C++ tarafında da iş yapmak için include gerekir; ancak JavaScript kütüphanelerinde bunu kimin yazdığı ve kimin bakımını yaptığı çoğu zaman belirsizdir
    • Küçük bir pencerede hello göstermek için bile sanki “internetin yarısı” yükleniyormuş gibi duran sayfalar ortaya çıkabiliyor
  • İnternet JavaScript'e bağımlı; TypeScript ile gizlense bile, tarayıcıda bir sayfa her açıldığında geçilmesi gereken bekçi olmaya devam ediyor
  • Bir zamanlar tarayıcının nihai işletim sistemi olup Windows ya da Mac OS'u gereksiz kılacağı hayali vardı ve bu hayali gerçekleştirecek dil olarak JavaScript seçildi

WebAssembly ile JavaScript arasındaki ilişki

  • WebAssembly, kendi makine diline sahip bir sanal makineye daha yakın olduğu için tarayıcı içinde farklı biçimde kod yazma olanağını açıyor
  • Pyodide, tarayıcıda Python çalıştıran etkileyici bir mühendislik başarısı; ancak JavaScript alanı içinde hareket etmenin maliyetini de gösteriyor
    • Python'un asyncio yapısı ile JavaScript event loop'u olan iki asenkron dünyanın birbiriyle konuşması gerekiyor
    • Bu iki dünya arasındaki köprü kırılgan ve her await ifadesinin hangi dünyaya ait olduğunu hatırlamak gerekiyor
  • Tarayıcı kaynakları sınırlı olduğundan, bilgisayar biliminin ilk dönemlerindeki gibi her komuta ve yapıya bit düzeyinde bakılan bir düşünme biçimi gerekiyor
    • 1981'de elinde tam olarak yalnızca 15772 bytes kalan bir bilgisayarda programlamaya başladığını ölçüt olarak sunuyor
    • Modern tarayıcı belleği ilk bilgisayarı kadar sınırlı değil; ancak WebAssembly, sıradan bir program gibi belleğe özgürce sahip olamıyor ve önce sınırlı bir biçimde izin almak zorunda kalıyor
  • Temel tutum, JavaScript ile savaşmak değil onunla müzakere etmek

LispE'nin sunduğu alternatif

  • LispE, tek bir ikili içinde 450'den fazla fonksiyon sunuyor
    • WASM ikilisinin boyutu 3.3 MB
    • String, hesaplama, matris ve düzenli ifade işleme işlevleri tek yerde toplanmış durumda
    • WASM ikilisi binaries/wasm altında bulunuyor
  • Küçük bir yorumlayıcı olmasına rağmen dönüş değeri olarak string, Float64Array, tamsayı, ondalık sayı ve string dizileriyle çalışabiliyor
  • LispE, Lisp tabanlı olduğu için canlı bir AST yapısına sahip
  • Lisp sözdizimi size uymuyorsa, Python ya da Basic'ten ayırt edilmesi zor diller için transpilasyon sözdizimi kullanılabiliyor
    • İstenen stilde bir dil oluşturmak için grammar değiştirilebiliyor
    • Yunanca da mümkün; hatta hazır bir Yunanca örnek var
  • LispE, JavaScript ile savaşmak yerine JavaScript fonksiyonları ve DOM özelliklerini kullanan işbirlikçi bir yaklaşım izliyor

JavaScript çağrısı: evaljs ve asyncjs

  • LispE içinde JavaScript kodu çalıştırmak için evaljs ve asyncjs kullanılabiliyor
    • evaljs, JavaScript kodunu çalıştırıp bir değer döndürüyor
    • asyncjs, sayfada tanımlı kullanıcı JavaScript fonksiyonlarını asenkron callback'lerle bağlıyor
(setq a (evaljs "10 + 20 + 30")) ; execute some JS code

; call_llm is a user-defined JS function in the page
(asyncjs `call_llm("Implement a piece of code in Python to sort strings");` 'mycallback)

(defun mycallback(theresult) ...)
  • asyncjs, iş bittiğinde geri döneceğini taahhüt eden bir Promise gibi çalışıyor

Kod şişkinliğini azaltma

  • 1995 tarihli Wirth alıntısı, daha hızlı bilgisayarların ve daha büyük modellerin sorunu çözmeyeceği; kodu ince ve hafif tutmak gerektiği sonucuna bağlanıyor
  • LispE, tarayıcıya açılan 450 fonksiyonu tek ve denetlenebilir bir ikili olarak sunuyor
    • Her özelliği ayrı ayrı kurmak için sayısal hesaplama adına mathjs, koleksiyonlar için lodash, string işleme için voca, istatistiksel dağılımlar için simple-statistics gibi kütüphaneler yüklemek gerekir
    • Bu yaklaşım, farklı yazarlar, hatalar ve bakım takvimleri olan yüzlerce MB koda dönüşebilir
  • LispE, bu işlevleri tek bir bakımı yapılan kod tabanıyla sağlıyor ve açık kaynak olduğu için tüm kod denetlenebiliyor
  • Garbage Collector'ın en kötü anda kod performansını çökertmediği görüşü savunuluyor
  • JavaScript ile basit API çağrıları üzerinden şeffaf biçimde iletişim kuruyor ve önceden tanımlı yapılar döndürebiliyor
// floats here is a Float64Array
const floats = callEvalLispEToFloats(0, `(normal_distribution 100)`);

2 yorum

 
crawler 5 시간 전

Yazı biraz durup dururken ortaya çıkmış gibi geldiği için kaynağından şüphe etmiştim, meğer Naver'mış, vay be.
Ama görünen o ki tepkiler de pek iyi değil... Açıkçası JavaScript'in abartılıp üstüne 3.3 MB'lık bir WASM bile yükleyerek Lisp kullanmaya kalkmak, kolay anlaşılır bir şeyden çok over-engineering gibi duruyor, haha.

Bunun neden Naver hesabından paylaşıldığıyla ilgili olarak, Claudius adlı projenin geliştiricisi bir yorum bırakmış; kendisinin Naver Labs Europe'ta çalıştığını ve bunun Naver tarafından bir açık kaynak projesi olarak onaylandığı için bu şekilde yayınlandığını söylemiş.
Naver'la çok büyük bir ilgisi yok gibi, sanki sadece Lisp'i gerçekten çok seven insanlarmış gibi...

 
GN⁺ 6 시간 전
Lobste.rs görüşleri
  • JavaScript'i daha az şişirmekten söz edip opak bir 3.3MB WASM yığını eklemek ve uygulamayı Lisp ile yazmamızı söylemek biraz tuhaf geliyor
    Saf JavaScript ve sıfır ek bağımlılıkla bile o boyutun onda birine yaklaşmadan önce oldukça fazla şey yapılabilir

    • Belgenin yalnızca küçük bir kısmına bakıp hemen geçiştirmesek iyi olur
      Bu kullanım biçimine katılmıyorum ama son zamanlarda pek görülmeyen türden tuhaflığı olan, ilginç bir Lisp tutku projesi ve tüm belgelerde insan eliyle yazıldığı belli olan kendine özgü bir üslup var, bu da hoşuma gidiyor
  • Standart kütüphaneye yeni eklenecek şeyler için öneriler her zaman açık
    Yakın zamanda eklenenler arasında küme birleşimi/kesişimi, sum, base64 gibi şeyler var
    Buna karşılık kalkülüs fonksiyonları için neredeyse hiç talep duymadım; string tarafında düzenli gelen istekler daha çok .reverse ya da .titleCase oluyor
    .reverse, oyuncak problemler dışında çok ikna edici kullanım alanlarına sahip değil; .titleCase ise mümkün, ancak uluslararasılaştırma verisi gerektirdiği için hâlâ tartışılıyor
    Üstelik bu ikisinin hiçbiri bu kütüphanede de yok

    • Pek çok kişi tc39 üyelerini doğrudan tanımıyor ya da onların aslında çevremizde olduğunu fark etmiyor gibi görünüyor
      Bir öneri yapsalar bile bunun gerçekten kabul edilmesinin 3 yıl süreceğini düşünüp denemeye değmez buluyorlar; utils/ klasörünün pek iyi olmadığını ama en azından hemen oluşturulabildiğini de düşünüyorlar
    • Standart kütüphane benim takip ettiğimden daha fazla değişmiş, bu yüzden yazıyı biraz düzeltmem gerekecek
      Benim argümanım, JavaScript'te fonksiyon eksikliğinden çok dağıtım modeli ile ilgili
      Standart kütüphane dopdolu olsa bile ortalama bir uygulama yine de megabaytlarca transitif npm bağımlılığı taşıyor
      LispE-as-WASM; 3.3MB boyutu, yaklaşık 450 belgelenmiş fonksiyonu, C++ çekirdeği ve GitHub'da açık kaynak koduyla, denetlenebilir bir çalışma zamanının nasıl görünebileceğine dair bir deney
      Hatta bunun üzerine bir ajan harness'i kurdum ve LispE kurallarını tarayıcı içinde anında çalıştırıyorum
      JavaScript event loop'u da çok hoşuma gidiyor
  • Birisi sözdiziminin şiştiğini söylediğinde geriliyorum
    Minimal sözdizimi, görsel ayrım için farklı karakterler kullanan sözdizimlerine göre çok daha zor okunabilir
    LispE'nin alternatif olarak sunduğu şey de şu:

    (defun gol8(⍵) ((λ(⍺) (| (& (== ⍺ 4) r) (== ⍺ 3))) (⌿ '+ (⌿  '+ (° (λ (x ⍺) (⊖ ⍺ x)) '(1 0 -1) (↑ (λ (x) (⌽ ⍵ x)) '(1 0 -1)))))))  
    

    ... !?
    https://github.com/naver/lispe/wiki/5.3-A-la-APL

  • Bu projeye giriş noktası biraz tuhaf; https://github.com/naver/lispe/wiki/1.-Introduction tarafı daha iyi görünüyor
    WASM hedefi de olan yerel bir Lisp projesi ve programlama dili meraklılarının hoşuna gidecek eğlenceli yönleri var

  • İlk izlenimim, bunun oldukça zorlama bir JavaScript örneği olduğu yönündeydi
    JavaScript nefreti denilen şeyin büyük kısmı erken dönem tarayıcı uyumsuzluklarından, acı verici DOM API'lerinden ve sözdizimsel tuzaklardan geliyor gibi duruyor; bunların bugün günlük hayatımda fiilen bir etkisi yok
    Modern JavaScript, özellikle TypeScript ve makul lint kurallarıyla birlikte kullanıldığında, dil olarak gayet yeterli
    Hâlâ CJS ve ESM karşıtlığı, tedarik zinciri riski, ekosistem oynaklığı gibi sorunlar var ama bunların çoğu dilin kendisinin dışında

  • Parantez dengesini kurmak o kadar can sıkıcı ki insanlar bunun için editör eklentileri yazdı; demek övülen deneyim bu
    Eğer bu tarz programlama, yani düşük sözdizimi yoğunluğu ve fonksiyonel yaklaşım isteniyorsa, yönü ters çevirip concatenative dillere gitmek daha mantıklı

  • Bir Lisp yorumlayıcısının derlenmiş çıktısının nasıl 3.3MB'a ulaştığını merak ediyorum
    Buna mı daha az şişkinlik deniyor?

    • Muhtemelen içinde büyük bir standart kütüphane bulunduğu içindir
      Yine de kullanılmayan kodları da içeren büyük bir standart kütüphaneyi birlikte dağıtmanın, daha az şişirmekle pek ilgisi olmadığına katılıyorum
  • Şok! Dehşet!
    Kapanış parantezlerini doğru sırayla kapatmak gerekiyormuş, ne büyük sürpriz

    • Doğru sırayla kapatmaya gerek olmayan bir dil istiyorsanız J var
      JavaScript gibi dillerin laf kalabalığından nefret eden Lisp hayranları bile APL ailesi dillerle karşılaşınca geri çekilip, mümkün olan en kısa ifadeden ziyade açıklık ve okunabilirliğin çok daha önemli olduğunu savunmaya başlıyor
      LispE yazarının APL temel işlemlerine belirli bir sevgisi var gibi görünüyor; ama böylesine yoğun bir notasyona sahip dillerle karşılaşıp da Conway'in Life örneğini APL, J, K hatta Q sürümlerinden daha uzun ve seyrek, derin iç içe geçmiş s-expression sürümüyle tercih etmesini anlamak zor