SmooshGate Hakkında SSS

Ne smoosh oldu?!

Array.prototype.flatten adlı bir JavaScript dil özelliği için yapılan teklif web ile uyumlu değildir. Özelliğin Firefox Nightly'de gönderilmesi, en az bir popüler web sitesinin bozulmasına neden oldu. Sorunlu kodun yaygın MooTools kitaplığının bir parçası olduğu düşünüldüğünde, çok daha fazla web sitesi etkilenmiş olabilir. (MooTools 2018'de yeni web siteleri için yaygın olarak kullanılmasa da eskiden çok popülerdi ve birçok prodüksiyon web sitesinde hâlâ mevcut.)

Teklif yazarı, uyumluluk sorununu önlemek için flatten öğesinin smoosh olarak yeniden adlandırılmasını şakayla önerdi. İşin esprisini herkes anlayamadı. Bazı kişiler yanlışlıkla yeni adın zaten belirlendiğini sanıyor ve işler hızla yükseliyor.

Array.prototype.flatten ne işe yarar?

Başlangıçta Array.prototype.flatten olarak önerilen Array.prototype.flat, dizileri belirtilen depth değerine kadar yinelemeli olarak birleştirir. Bu değer, varsayılan olarak 1 değerine ayarlanır.

// Flatten one level:
const array = [1, [2, [3]]];
array.flat();
// → [1, 2, [3]]

// Flatten recursively until the array contains no more nested arrays:
array.flat(Infinity);
// → [1, 2, 3]

Aynı teklif Array.prototype.flatMap içerir. Tek fark, sonucu yeni bir diziye dönüştürmesi için Array.prototype.map benzeridir.

[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]

MooTools neden bu soruna neden oluyor?

MooTools kendi standart olmayan Array.prototype.flatten sürümünü tanımlar:

Array.prototype.flatten = /* non-standard implementation */;

MooTools'un flatten uygulaması, önerilen standarttan farklıdır. Ancak sorun bu değil! Tarayıcılar Array.prototype.flatten uygulamasını yerel olarak gönderdiğinde MooTools, yerel uygulamayı geçersiz kılar. Bu, MooTools davranışına dayanan kodun, yerel flatten kullanılıp kullanılmadığına bakılmaksızın beklendiği gibi çalışmasını sağlar. Şu ana kadar her şey yolunda!

Ne yazık ki başka bir şey gerçekleşir. MooTools, tüm özel dizi yöntemlerini Elements.prototype öğesine kopyalar (burada Elements, MooTools'a özel bir API'dir):

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

for-in, "enumerable" (enumerable) özellikleri üzerinde yinelenir. Burada Array.prototype.sort gibi yerel yöntemler bulunmaz ancak Array.prototype.foo = whatever gibi düzenli olarak atanan özellikler bulunur. Ancak (örneğin, Array.prototype.sort = whatever) numaralandırılamayan bir özelliğin üzerine yazarsanız bu özellik, numaralandırılamaz olarak kalır.

Şu anda Array.prototype.flatten = mooToolsFlattenImplementation, numaralandırılabilir bir flatten özelliği oluşturmaktadır. Bu nedenle, daha sonra Elements öğesine kopyalanmaktadır. Ancak tarayıcılar flatten yerel sürümünü gönderirse bu sürüm numaralandırılamaz ve Elements ürününe kopyalanmaz. MooTools'un Elements.prototype.flatten uygulamasını kullanan kodlar artık çalışmıyor.

Yerel Array.prototype.flatten öğesini numaralandırılabilir olarak değiştirmek sorunu çözecek gibi dursa da muhtemelen daha fazla uyumluluk sorununa yol açacaktır. Bir dizide yineleme yapmak için for-in kullanan her web sitesi (bu kötü bir uygulamadır, ancak olur) aniden flatten özelliği için ek bir döngü yinelemesi alır.

Buradaki daha büyük temel sorun, yerleşik nesnelerin değiştirilmesidir. Yerel prototipleri genişletmek, diğer kitaplıklar ve üçüncü taraf kodlarıyla güzel beste yapılmadığı için günümüzde genellikle kötü bir uygulama olarak kabul edilir. Sahibi olmadığınız nesnelerde değişiklik yapmayın!

Neden mevcut adı koruyup web'i bozumuyoruz?

1996'da, CSS yaygınlaşmadan ve "HTML5" ortaya çıkmadan çok önce Space Jam web sitesi yayına girdi. Bugün, web sitesi hâlâ 22 yıl önce olduğu gibi çalışıyor.

Bu nasıl oldu? Bu web sitesini yıllarca yöneten biri, tarayıcı tedarikçileri her yeni özellik gönderdiğinde siteyi güncelleyerek bu web sitesini mi düzenledi?

Görünüşe göre HTML, CSS, JavaScript ve web'de yaygın olarak kullanılan diğer standartlar için bir numaralı tasarım ilkesi "Web'i kırmayın". Yeni bir tarayıcı özelliği göndermek, mevcut web sitelerinin çalışmamasına neden oluyorsa bu herkes için kötü bir durumdur:

  • etkilenen web sitelerinin ziyaretçileri aniden kötü bir kullanıcı deneyimi yaşar;
  • web sitesi sahipleri, hiçbir değişiklik yapmadan, kusursuz çalışan bir web sitesine geçerek çalışmayan bir web sitesine geçti.
  • yeni özelliği gönderen tarayıcı tedarikçilerinin pazar payını kaybetmesi, kullanıcıların "tarayıcı X'te çalıştığını" fark etmesi nedeniyle,
  • uyumluluk sorunu bildirildiğinde, diğer tarayıcı satıcıları bunu göndermeyi reddeder. Özellik spesifikasyonunun gerçekliğiyle eşleşmediği durumlar ("Hayal ürünü dışında bir şey yok"). Bu durum, standartlaştırma süreci açısından kötü bir durumdur.

Elbette, geçmişe baktığımızda MooTools yanlış bir şey yapmıştı. Ancak web'i kırmak onları değil, kullanıcıları cezalandırıyor. Bu kullanıcılar "moo" aracının ne olduğunu bilmiyor. Alternatif olarak, başka bir çözüm bulabiliriz ve kullanıcılar web'i kullanmaya devam edebilirler. Bu seçimi yapmak kolaydır.

Bu, kötü API'lerin hiçbir zaman Web Platformu'ndan kaldırılamayacağı anlamına mı geliyor?

Duruma bağlı. Nadir durumlarda kötü özellikler web'den kaldırılabilir. Bir özelliği kaldırmanın mümkün olup olmadığını anlamak bile çok zorlu bir iştir. Kaç web sayfasının davranışının değişeceğini ölçmek için kapsamlı bir telemetri gerektirir. Ancak söz konusu özellik yeterince güvenli değilse, kullanıcılar için zararlıysa veya çok nadiren kullanılıyorsa yapılabilir.

<applet>, <keygen> ve showModalDialog(), Web Platformu'ndan başarıyla kaldırılan kötü API örnekleridir.

MooTools'u düzeltmeye ne dersiniz?

MooTools'un yerleşik nesneleri genişletmemesi için yama uygulamak iyi bir fikirdir. Ancak bu, mevcut sorunu çözmüyor. MooTools yama uygulanmış bir sürüm yayınlasa bile, uyumluluk sorununun ortadan kalkması için bu sürümü kullanan tüm web sitelerinin güncellenmesi gerekir.

Kullanıcılar ellerindeki MooTools kopyasını güncelleyemezler mi?

Kusursuz bir dünyada, MooTools bir yama yayınlardı ve MooTools kullanan her web sitesi ertesi gün sihirli bir şekilde güncellenirdi. Sorun çözüldü, değil mi?

Maalesef bu durum gerçekçi değil. Birisi bir şekilde etkilenen web sitelerinin tamamını tanımlasa, her birinin iletişim bilgilerini bulmayı başarsa, tüm web sitesi sahiplerine başarılı bir şekilde ulaşsa ve onları güncellemeyi gerçekleştirmeye ikna etse (bu durumda tüm kod tabanını yeniden düzenlemek gerekebilir) sürecin tamamı en iyi ihtimalle yıllar sürer.

Bu web sitelerinin çoğunun eski olduğunu ve büyük olasılıkla bakımsız olduğunu unutmayın. Hesap yöneticisi hâlâ orada olsa bile sizin gibi son derece yetenekli bir web geliştiricisi olmayabilir. Bir web uyumluluğu sorunu nedeniyle herkesin gidip 8 yıllık web sitesini değiştirmesini bekleyemeyiz.

TC39 süreci nasıl işler?

TC39, JavaScript dilini ECMAScript standardı aracılığıyla geliştirmekten sorumlu komitedir.

#SmooshGate bazı kullanıcıların "TC39'un flatten adlı kişiyi smoosh olarak yeniden adlandırmak istiyor" şeklinde düşünmesine neden oldu, ancak bu, şirket dışında iyi bir şekilde iletişim kurulamayan bir şakaydı. Bir teklifi yeniden adlandırmak gibi önemli kararlar hafife alınmamıştır, tek bir kişi tarafından alınmaz ve tek bir GitHub yorumuna dayanarak kesinlikle bir gecede alınmaz.

TC39, özellik teklifleri için net bir hazırlık süreci uygular. ECMAScript teklifleri ve bu tekliflerde gerçekleştirilen önemli değişiklikler (yöntem yeniden adlandırma dahil) TC39 toplantılarında tartışılır ve bunların resmi hale gelmeden önce tüm komite tarafından onaylanması gerekir. Array.prototype.flatten durumunda, teklif 3. Aşamaya kadar çeşitli anlaşma aşamalarından zaten geçmiştir. Bu da, özelliğin web tarayıcılarına uygulanmaya hazır olduğunu gösterir. Uygulama sırasında ek spesifikasyon sorunlarının ortaya çıkması yaygın bir durumdur. Bu durumda en önemli geri bildirim, onu göndermeye karar verdikten sonra ortaya çıkmıştır: Özellik, mevcut haliyle Web'i bozar. Bunlar gibi tahmin edilmesi zor sorunlar, TC39 sürecinin yalnızca tarayıcılar bir özelliği gönderdikten sonra sona ermemesinin nedenlerinden biridir.

TC39, fikir birliği temelinde çalışır. Yani, komite yeni değişiklikler konusunda anlaşmak zorundadır. smoosh ciddi bir öneri olsa bile, muhtemelen bir komite üyesi buna itiraz ederek compact veya chain gibi daha yaygın bir ad tercih edecektir.

flatten adının smoosh olarak adlandırılması (şaka olmasa bile) daha önce bir TC39 toplantısında ele alınmamıştır. Bu nedenle, TC39'un bu konuyla ilgili resmi duruşu şu an bilinmemektedir. Bir sonraki toplantıda fikir birliğine varılana kadar hiçbir kişi TC39 ekibi adına konuşamaz.

TC39 toplantılarına genellikle çok farklı arka planlara sahip kişiler katılır: Bazıları yıllarca programlama dili tasarım deneyimine sahiptir, bazıları bir tarayıcı veya JavaScript motoru üzerinde çalışır ve JavaScript geliştirici topluluğunu temsil eden katılımcıların sayısı her geçen gün artmaktadır.

SmooshGate sonunda nasıl çözümlendi?

Mayıs 2018 tarihli TC39 toplantısı sırasında #SmooshGate, flatten adı flat olarak değiştirilerek resmi olarak çözüldü.

Array.prototype.flat ve Array.prototype.flatMap, V8 v6.9 ve Chrome 69 sürümlerinde sunulmuştur.