Ters Sapir-Whorf ve programlama dilleri
(lukeplant.me.uk)- Ters Sapir-Whorf, dilin neyi düşünmeyi zorlaştırdığına değil, neyi söylememeyi zorlaştırdığına ve hangi bilgileri açığa çıkarmaya zorladığına odaklanır
- İngilizcedeki şimdiki zaman, cinsiyetli zamirler, Fransızcadaki cinsiyetli isimler ve Türkçedeki -mış geçmiş zamanı; geçicilik, cinsiyet, bilgi kaynağı ya da güvenilirlik gibi bilgileri konuşanın belirtmesine iter
- Programlama dillerinde de hesaplama sırası, async olup olmadığı, bellek ayırma ve serbest bırakma, kapsam ve tipler gibi geliştiricinin aslında önemsemeyebileceği konuların koda dahil edilmesi sıkça zorunludur
- Python veya Javascript'teki
async, C'deki bellek yönetimi, Rust'taki yaşam süreleri (lifetime) ve statik tipli dillerdeki tip gösterimleri seçimleri açıkça belirtmeyi zorunlu kılar; Haskell ise katı olmayan semantik ve katılık analiziyle bazı seçimleri dile bırakabilir - Daha erişilebilir programlama dilleri, Ters Sapir-Whorf engeli daha düşük olduğu için, henüz anlaşılmamış ya da hakkında görüş oluşmamış konular üzerine konuşmaya daha az zorlayan özellikler taşıyabilir
Ters Sapir-Whorf ne anlama geliyor?
- Sapir-Whorf hipotezi, basitleştirirsek, konuşulan dilin düşünceyi etkilediği fikridir
- Sapir-Whorf'un güçlü biçimi, özellikle de dilin düşünceyi denetlediğini ya da belirli düşünceler için belirli bir dilin gerektiğini savunan dilsel determinizm, bugün dilbilimde yaygın biçimde ciddiye alınmaz
- Bir dilde dilbilgisel zaman olmaması, o dili konuşanların zaman hakkında daha sınırlı düşündüğü sonucunu doğurmaz; zamanı ifade etmenin başka yolları her zaman vardır
- Konuşulan dilin belirli alanlardaki algıyı, beceriyi ve tutumu etkileyebileceğine dair epey kanıt vardır, ancak büyük ve doğrudan etkileri kanıtlamak genellikle zordur
- Ters Sapir-Whorf, dilin neyi söylemeyi veya düşünmeyi zorlaştırdığına değil, neyi söylememeyi zorlaştırdığına odaklanır
- Bu bakışta asıl mesele, dilin hangi bilgileri söylemeye ittiği ya da hangi düşüncelerden kaçınmayı zorlaştırdığıdır
Doğal dillerde görülen zorunluluklar
-
İngilizce şimdiki zamanda geçicilik ve kalıcılık
- “I’m living in London” ve “I live in London” ikisi de Londra'da yaşamak anlamına gelir, ama ilki bu durumun geçici olduğu bilgisini açığa çıkarır
- Anadili olmayan biri bu farkı fark etmeyebilir; anadili İngilizce olanlar da bunu yalnızca bilinçsizce algılıyor olabilir
- “Geçici” anlamı, gerçek ikamet süresinden çok, kişinin Londra'yı ne kadar sevdiğiyle ilgili bile olabilir
- İngilizcede zaman seçmek gerekir ve bu seçim çoğu zaman bilinçsizce yapıldığı için dil, ikamet süresi ya da duygular gibi bilgileri açığa çıkarmaya neden olur
-
İngilizce, Türkçe ve Fransızcada cinsiyetli zamirler ve isimler
- İngilizcede günlük konuşmada belirli bir kişiden söz ederken genellikle “he” ya da “she” kullanmak gerekir
- “singular they” vardır, ama cinsiyeti bilinen ya da tahmin edilen belirli bir kişi için kullanıldığında çok doğal gelmez
- Türkçede he/she/it karşılığı olarak tek bir “o” kullanılır; bu cinsiyetli zamirlerin yokluğu, insanın birinin cinsiyeti hakkında düşünmesini ya da konuşmasını engellemez
- Bu noktada klasik Sapir-Whorf'u desteklemek zordur, ama İngilizce zamirlerin istense de istenmese de cinsiyeti belirtmeye zorlaması bakımından Ters Sapir-Whorf çok belirgindir
- Tanınan bir kişiden anonim biçimde söz etmeye çalışırken bile yanlışlıkla “him” ya da “her” kullanmak, cinsiyeti açığa çıkarıp kimliğin tahmin edilmesini kolaylaştırabilir
- Fransızcada isimlerin cinsiyeti vardır; “my friend” ifadesini çevirirken “mon ami” ile “mon amie” ya da “mon copain” ile “ma copine” arasında seçim yapmak gerekir ve bu da bilgi açığa çıkarır
- İyelik zamirleri de hem İngilizcede hem Fransızcada cinsiyetlidir, ancak İngilizcedeki his/her sahibin cinsiyetini, Fransızcadaki son/sa ise sahip olunan şeyin cinsiyetini göstererek farklı bilgileri açığa çıkarır
-
Türkçede “-mış” geçmiş zamanı
- Türkçede, kabaca İngilizcedeki simple past'a benzeyen genel geçmiş zaman ile “-mış” biçimi olmak üzere iki temel geçmiş zaman vardır
- “-mış” biçimi birden fazla işleve sahiptir; geçmiş bir olay anlatılırken bilginin başkasından duyulmuş olduğunu ya da güvenilirliğinin daha düşük olduğunu göstermek için kullanılır
- “Fred pazartesi işe geldi mi?” sorusuna, bunu doğrudan gördüyseniz normal geçmiş zaman “geldi”, duyduysanız “gelmiş” denir
- İngilizcede sadece simple past ile bilginin kaynağını ya da güvenilirliğini belirtmeden konuşmak mümkündür; Türkçede ise belirli durumlarda kesinlik düzeyini ya da doğrudan tanıklığı da dahil etmek zorunlu hale gelir
- “-mış” biçimi bulunduğu için normal geçmiş zaman nötr bir seçenek değildir; iki seçenekten hiçbiri tam uymadığında ifade doğal gelmeyebilir
- Türkçede “-mış” eki çoğu zaman cümlenin sonundaki sözcüğe geldiğinden, İngilizce bir cümleyi bitirdikten sonra “bu duyulan bir bilgi, doğrudan görmedim” işaretini koymadığını fark edip sona “-mış” ekleme alışkanlığı bile gelişebilir
- İngilizcede de “apparently” gibi sözcüklerle aynı şey kolayca ifade edilebilir, ama İngilizce bunu açıkça belirtmeyi zorunlu kılmaz; Türkçe ise büyük ölçüde zorlar
-
Anadili konuşurlarının kolay fark etmediği dilsel zorlamalar
- Bu farklar, başka diller öğrenene ya da kendi dilini yabancılara öğretmeye çalışana kadar fark edilmesi zor olabilir
- Simple present ile present continuous arasında seçim yapılan çoğu anda, bu seçimin ne ima ettiği bilinçli olarak düşünülmez
- Dil bir ifadeyi zorunlu kıldığında bu her zaman bir şey ekleyerek olmaz; anlam bazen eksiltme yoluyla da sabitlenebilir
- “I love cake” genel olarak keki severim demektir, “I love the cake” ise belirli bir kekten söz eder
- İlk cümlede “the” olmadığı için genel olarak kekten bahsedildiği netleşir; belirli bir kek kastediliyorsa “the” ya da “this” gibi bir işaretin mutlaka kullanılması gerekir
- Başka dillerde bu ayrıma doğrudan karşılık gelen ifadeler olmayabilir
Programlama dillerinde Ters Sapir-Whorf
- Programlama dillerinde klasik Sapir-Whorf da bir bakıma daha geçerli olabilir
- Python ya da Haskell gibi dillerde bellek ayırmadan söz etmek zordur, ama imkânsız değildir
- Programlama dillerinin sınırları genellikle o dilde ifade edilmesi zor şeyler üzerinden anlatılır
- Hillel Wayne'in Sapir-Whorf does not apply to Programming Languages yazısı bu konuyu daha ayrıntılı ele alır
- Ters Sapir-Whorf açısından asıl soru, programlama dilinin gerçekten ilgilenmediğiniz konular hakkında da konuşmaya zorlayıp zorlamadığıdır
- Bu tür zorlamaları görmek, çoğu zaman birden fazla dil öğrenirken oluşan yabancı dil öğrencisi bakışını gerektirir
Programlama dillerindeki başlıca örnekler
-
Hesaplama sırası
- Çoğu dil, hesaplamanın yapılacağı sırayı ifade etmeyi zorunlu kılar
- Python'daki
x = some_func(y + 1, z + 2)ifadesi öncey + 1in, sonraz + 2nin hesaplandığını ve ardından bu iki değerinsome_funca argüman olarak verildiğini söyler - Bu sırayı bilinçli olarak düşünmeyebilirsiniz, ama Python'da bu hesaplamayı sırayı belirtmeden ifade etmenin bir yolu yoktur
- Çoğu dil benzerdir, ama bazı dillerde değerlendirme sırası çok karmaşık hale gelir
- Haskell'deki
some_func (y + 1) (z + 2)gibi eşdeğer ifade ise katı olmayan semantik nedeniyle değerlendirme sırasını hiç belirtmez - Bu özellik, henüz tanımlanmamış değerlere başvurulan Tying the knot gibi teknikleri mümkün kılar
-
async fonksiyon rengi
- async function coloring iyi bir örnektir
- Javascript ya da Python gibi açık
asyncanahtar sözcüğüne sahip dillerde, kodun senkron mu asenkron mu olduğunu söylemek gerekir - Senkron fonksiyonlarda bu,
asyncanahtar sözcüğünü atlayarak ifade edilir, ama yine de iki seçenekten birini seçmiş olursunuz - Bu konuda kararsız kalabilen bir kod yazmanın yolu yoktur
-
Bellek ayırma ve serbest bırakma
- Garbage collection) olmayan çoğu dil, bellek ayırma ve serbest bırakmadan söz etmeyi zorunlu kılar
- C gibi dillerde bu genellikle oldukça açık biçimde yapılır ya da örtük olarak stack allocation kullanılır; her durumda bir seçim yapmak gerekir
- Başka dillerde bu mesele daha gizli olabilir, ama ortadan kalkmaz
- Rust'ta bu konu yaşam süreleri (
lifetime) ya da açık referans sayımı hakkında konuşmaya dönüşür - “Bu belleğin ne zaman ayrılıp ne zaman serbest bırakıldığıyla ilgilenmiyorum, bunu benim yerime hallet” seçeneği gerçekte sunulmaz
- Bellek ayırmadan bahsetmemenin de bir maliyeti vardır
- Böyle diller, neredeyse kesin olarak çok sayıda değeri heap üzerinde tutar ve çalışma zamanında bir garbage collector gerektirir
- Buna karşılık dilin seçim yapma özgürlüğü çok daha yüksektir; örneğin Haskell bu seçimleri sık sık katılık analizi ile yapar
-
Kapsam
- Bilinen tüm modern diller kapsam hakkında düşünmeye zorlar
- Çoğu durumda kapsam, değişkenlerin fiziksel olarak yerleştirildiği konumla ifade edilir; farklı bir davranış istiyorsanız Python'daki global ya da nonlocal gibi ek sözdizimi kullanmanız gerekir
- Kapsam hakkında hiç düşünmek istemiyorsanız, muhtemelen assembly seviyesine inip tek bir küresel adres alanını kabul etmeniz gerekir
-
Tipler
- Statik tipli diller genellikle her değişkenin tipi hakkında düşünmeyi ve konuşmayı zorunlu kılar
- Tip çıkarımı, daha akıllı bir dinleyicinin bağlamdan daha fazlasını anlaması gibi, bu yükü azaltır; ancak konuşmanın kendisi ortadan kalkmaz
- Tamamen dinamik tipli diller de Python'daki
isinstancekontrolü gibi yollarla tiplerden söz etmeye izin verir, ama bu daha doğal değildir ve teknik olarak da farklı bir şeydir - Kademeli tiplenen dillerin çekiciliklerinden biri, Ters Sapir-Whorf sorunundan gerçekten kaçınabilmeleri ve tercihe göre tipler hakkında konuşup konuşmama özgürlüğü vermeleridir
- Bunun pratikte ne kadar iyi çalıştığı net değildir; mevcut kod tabanının gelenekleri ve kullanılan linter'lar her zaman bir yöne doğru baskı uygular
Erişilebilir diller ve düşük engel
- Daha “erişilebilir” ya da “okunabilir” programlama dillerinin birçok özelliği, Ters Sapir-Whorf açısından analiz edilebilir
- Bu diller, Ters Sapir-Whorf engeli daha düşük olduğu için, henüz fikir sahibi olunmayan ya da tam anlaşılmayan şeyler hakkında konuşmayı zorunlu kılmayan özellikler taşıyabilir
- Programlama dilinin zorunlu kıldığı konular, kullanılan dile dair farkındalığı ve tercihleri etkileyebilir
1 yorum
Lobste.rs görüşleri
Dil tasarımı, ister programlama dili ister doğal dil olsun, dile hangi unsurların konduğuyla kullanıcının dikkatini nereye yöneltmesi gerektiğini belirleme işi olarak görülebilir
C örtük olarak “bellek yönetimine dikkat et” der, Haskell ise “değişkenlerin ve ifadelerin taşıyabileceği tiplere dikkat et” der
Dil beni gerçekten dikkat etmek istediğim yöne çekerse o işe çok uygun bir araç gibi gelir; çekmezse, kokteyl partisinde sessiz konuşan birini duymaya çalışırken odanın öbür ucunda birinin bağırması gibi olur
Dikkat en kıymetli kaynaktır; bu yüzden araçların onu nasıl yönlendirdiğinin ve şekillendirdiğinin farkında olmak gerekir
İngilizcede
thekullanımının açıkça belirtilmesi ya da atlanması, söz konusu şeyin belirli olup olmaması konusunda tarafsız değildir; Türkçede-mişkullanıp kullanmamak da bilginin doğrudan mı edinildiği yoksa başkasından mı duyulduğu konusunda tarafsız değildirBu, “dilin söylenebilen şeyi sınırlandırdığı” yönündeki standart Sapir-Whorf hipotezinin, yani ifadenin tarafsızlığının karşı ucu olarak da görülebilir
Böylece bir dilin belirli bir konuda tarafsız olup olmadığını açıklayabilir ve dil tasarımcısı olarak kullanıcının dikkatini dağıtacak ya da odaklayacak şekilde ayarlama yapabilirsiniz. Örneğin garbage collection, heap allocation konusunda ifadeyi tarafsızlaştırır; effect tracking ise yan etkiler ve giriş/çıkış konusunda ifadeyi tarafsız olmaktan çıkarır
Yazının özünü tamamen kavradım mı emin değilim ama Rust hakkında uzun zamandır tekrar edip durduğum bir düşünceyi aklıma getirdi
Rust, referanslarla çalışmaya izin verir ama bellek güvenliğini garanti etmek için katı kurallar koyduğu tuhaf bir noktadadır
C++'ta bir şeyin referans olması gerektiğini düşünürseniz onu referans yapar ve sorun çıkmamasını umarsınız; Python'da ise böyle bir kontrolünüz olmadığından veriyi çekinmeden kopyalarsınız
Ama Rust'ta “kopyalama verimsiz, o halde referans yapalım” diye bir optimizasyon çukuruna düşebilirsiniz; borrow checker bağırmaya başlayınca da bu referansın güvenli olduğundan emin olsanız bile bir saat boyunca kodu refactor edersiniz
İyi Rust programcıları “gidip
.clone,RC,Boxvb. kullan” der ve buna katılıyorum, ama referansın gözünüzün önünde olması ve güvenle kullanılabilecek gibi görünmesi gerçeği değişmiyorBu yüzden borrow checker'ı yatıştırmak için işleri daha kötü hale getirmişim gibi tuhaf bir his kalıyor ve neden bazı insanların “borrow checker bana fazla geliyor” diyerek vazgeçtiğini de anlayabiliyorum
Konu güzel ve Türkçe dilbilgisinden biraz söz edilmesi de hoşuma gitti
Bir başka yaygın örnek de bazı dillerin çoğulluk gibi ayrıntıları atlayabilmesi; Vietnamca buna örnek
“exaggerated” sözcüğünün bağlantılı olduğunu görünce “acaba Arrival ile ilgili bir yazı mı?” diye düşündüm; gerçekten öyle çıkması da eğlenceliydi
Birçok kişinin sevdiği bir film ama kişisel olarak inancımı askıya almakta zorlandım; çünkü bilimkurgu olduğunu söylese de o “bilim” bana bir tür büyü gibi işleyen dilbilim gibi gelmişti
Çoğu uygulama programlama dili, tekil değeri bir tür atomik temel kabul eder. Bunun üzerine listeler ya da map'ler kurabilirsiniz ama bunlar da sonuçta tek birer şeydir ve çoğu zaman birbirleriyle tam uyumlu değildirler
Rust'ta bu yapılar arasında sık sık kopyalama yapmanız gerekir; SQL'de ise buna daha az kafa yorarsınız ama bu kez index'ler ve query plan'larla uğraşırsınız. Özellikle de veritabanı, sorduğunuz şeyi gereksiz yere karmaşıklaştıran bariz derecede aptalca bir plan kurduğunda; SQL NULL konusuna hiç girmeyelim
Sonuç olarak yazılımlarımızın çoğu, tek tek değerler düzeyine kadar inanılması güç ölçüde aşırı belirlenmiş durumda ve PC performansı 1000 kat artmış olsa da en iyi UI gecikmeleri eskisinin 10 katı seviyesinde
Nesne yönelimli programlama dogmatizmasının da bunda kısmen payı var. Asenkron işi de bir ara denedik ama bağımsız işleri tek tek
awaitederek ağacı görüp ormanı kaçırma durumuna çok kolay geriliyorhttps://www.uiua.org/ adresinin mutlu olduğunu hayal etmek gerekir
Güzel noktalar. Bütün modern diller, programcıyı otların arasına dalar gibi ayrıntılarla uğraşmaya zorlar ya da buna çok güçlü biçimde iter
Betik dilleri, programlar veya web sayfaları gibi biraz daha az ayrıntılı hedefler üzerinde işlem sunar ama yine de ayrıntıları ortadan kaldırmaz
Hâlâ sayılar, dizgeler, hata kodları gibi çok küçük ayrıntıları düşünüp yönetmenizi gerektirir
Yılların eğitimi ve iş pratiğiyle ayrıntı yönetimine o kadar alıştık ki ayrıntı perspektifi dışında düşünmek çok zor hale geldi
Aklıma ilk gelen şey nesnelerin ya da modüllerin arayüzü oldu
Programlama dillerinde bu çok somutken doğal dil konuşmalarında çok daha bulanıktır
Bir başka örnek de C++ generics ile Python generics arasındaki fark. C++'ta bunu çok bilinçli ele almanız gerekirken Python'da type hint'leri görmezden gelirseniz epey örtük biçimde yürür
“Ters Sapir-Whorf, dilin söylenemeyen şeyi sınırlandırması ya da bir şeyi söylememeyi zorlaştırması, hatta bazı şeyleri düşünmemeyi zorlaştırmasıdır” kısmı bana grammar > idioms > standard library > third-party libraries > ecosystem şeklinde bir piramit gibi görünüyor
“Düşünmemeyi zorlaştırır” kısmı, ifade etmesi zor olan ya da önemli kısıtları bulunan sorunlara odaklanıyor gibi
Aşinalık yukarıdan ve aşağıdan içeri doğru işler; insanlar da her katmanda kod yazma biçimleriyle kendi geçmişlerini belli eder
15 yıldan uzun süredir İngilizce okuyup yazıp konuşuyorum ama “I live in London” ile “I'm living in London” arasında fark olduğunu bilmiyordum
Ben Londra'da mı yaşıyorum, yoksa şu anda Londra'da mı yaşıyorum, onu da bilmiyorum 😅
Burada
livingbiçimini sıradan bir sıfatla değiştirip “I am cold” derseniz, bunu şu anda üşüdüğünüz şeklinde anlarız; bir süper kötü gibi kalıcı olarak soğuk olduğunuz şeklinde değilAynı şekilde “I am living in London”, şu anda Londra'da yaşadığınızı ama bunun gelecekte değişebileceğini ima eder
Ayrıca her zaman Londra'da yaşamadığınız nüansını da taşır. Bu, “I am cold” ifadesinin en azından bir kez yeterince sıcak bir durumu deneyimleyip mevcut hâli “normal” değil “soğuk” olarak fark ettiğinizi bir ölçüde ima etmesine benzer