Niçin orada olduğunu (öğrendiğim tüm programlama dillerinde, C ++, Java, Python gibi) stdlib gibi standart kütüphanelerin, benzer "işlevlerin" dilin kendisinin ilkeli olması yerine olduğunu düşündüm.
Niçin orada olduğunu (öğrendiğim tüm programlama dillerinde, C ++, Java, Python gibi) stdlib gibi standart kütüphanelerin, benzer "işlevlerin" dilin kendisinin ilkeli olması yerine olduğunu düşündüm.
Yanıtlar:
Vincent'ın (+1) iyi cevabını biraz genişletmeme izin ver :
Derleyici neden bir işlev çağrısını bir dizi talimata çeviremiyor?
En az iki mekanizma aracılığıyla bunu yapabilir ve yapar:
bir işlev çağrısının satır içi olarak yapılması - çeviri sırasında, derleyici, bir kaynak kod çağrısını, işlevi gerçek bir çağrı yapmak yerine, doğrudan satır içi ile değiştirebilir. Yine de işlevin bir yerde tanımlanmış ve standart kütüphanede olabilecek bir uygulamaya sahip olması gerekir.
içsel işlev - içsel işlev, derleyicinin, işlevi bir kütüphanede mutlaka işlevi bulamadan bilgilendirildiği işlevlerdir. Bunlar genellikle herhangi bir şekilde pratik olarak erişilemeyen donanım özellikleri için ayrılmıştır, o kadar basit ki, assembly dili kitaplığı çağrısının ek yükü bile yüksek sayılır. (Derleyici genellikle kaynak kodunu kendi dilinde otomatik olarak satır içi yapabilir, ancak içsel mekanizmanın geldiği montaj işlevlerini bulamaz.)
Yine de bunlar söyleniyor, en iyi seçenek bazen derleyicinin kaynak dilde bir işlev çağrısını makine kodunda bir işlev çağrısına çevirmesidir. Özyineleme, sanal yöntemler ve büyük boyutta satır içi her zaman mümkün / pratik olmamak bazı nedenlerdir. (Başka bir neden, derleme (nesne modülleri), ayrı yük birimleri (örn. DLL'ler) gibi derlemenin amacıdır).
Standart kütüphane işlevlerinin çoğunun da içsel olmasını sağlamanın gerçek bir avantajı yoktur (bu, derleyiciye gerçek bir avantaj sağlamazsa daha fazla bilgi zorlaştırır), bu nedenle bir makine kodu tekrar çağırması çoğu zaman en uygunudur.
C, standart kütüphane işlevlerini destekleyen diğer açık dil ifadelerini tartışmasız bırakan dikkat çekici bir dildir. Kütüphaneler önceden var olmasına rağmen, bu dil, standart kütüphane işlevlerinden daha fazla iş yapmaya ve dilin gramerindeki açık ifadelerden daha az çalışmasına yöneldi. Örneğin, diğer dillerde IO sık sık çeşitli ifadeler biçiminde kendi sözdizimine sahipken, C dilbilgisi herhangi bir IO ifadesi tanımlamamaktadır, bunun yerine sadece standart kütüphaneye ertelemek yerine, tüm işlev çağrıları yoluyla erişilebilir derleyici zaten nasıl yapılacağını bilir.
Bu sadece dilin kendisini olabildiğince basit tutmasıdır. Bir döngü türü veya parametreleri işlevlere vb. Geçirme yolları gibi dilin bir özelliği ile çoğu uygulamanın ihtiyaç duyduğu ortak işlevsellik arasında ayrım yapmanız gerekir.
Kütüphaneler, birçok programcı için faydalı olabilecek fonksiyonlardır, bu nedenle paylaşılabilen yeniden kullanılabilir kodlar olarak yaratılırlar. Standart kütüphaneler, programcıların tipik olarak ihtiyaç duyduğu yaygın işlevler olarak tasarlanmıştır. Bu şekilde programlama dili daha geniş bir programcı yelpazesi için hemen kullanışlıdır. Kütüphaneler, dilin temel özelliklerini değiştirmeden güncellenebilir ve genişletilebilir.
PHP
Örnek olarak, geniş dil işlevleri ile dilin kendisi arasında hiçbir fark yoktur.
include
, require
ve require_once
, eğer / için / iken (yapısal programlama), istisnalar, zayıf yazarak kuralları karmaşık 'hatası değerlerinin' ayrı bir sistem, karmaşık operatör öncelik kuralları ve uzayıp . Forth Smalltalk Şema, Prolog, vb, diyelim ki, basitliği ile karşılaştırın;)
Diğer cevapların söylediklerine ek olarak, standart fonksiyonları bir kütüphaneye koymak endişelerin ayrılmasıdır :
Dili ayrıştırmak ve bunun için kod oluşturmak derleyicinin işidir. Derleyicinin işi, o dilde yazılmış ve bir kütüphane olarak verilmiş olan herhangi bir şeyi içermek değildir.
Neredeyse tüm programların ihtiyaç duyduğu temel işlevleri sağlamak, standart kütüphanenin (her zaman dolaylı olarak kullanılabilir olan) işidir . Yararlı olabilecek tüm fonksiyonları içermesi standart kütüphanenin işi değildir.
Birçok programın yapmadan yapabileceği, ancak birçok uygulamanın standart ortamlarda gönderilmesini garanti altına almak için hala temel olan ve aynı zamanda gerekli olan yardımcı işlevsellik sağlamak isteğe bağlı standart kitaplıkların işidir. Bu isteğe bağlı kitaplıkların işi, şimdiye kadar yazılmış tüm yeniden kullanılabilir kodları içermesidir.
Yararlı yeniden kullanılabilir fonksiyonların koleksiyonlarını sağlamak kullanıcı kütüphanelerinin işidir. Yazılan tüm kodu içeren kullanıcı kütüphanelerinin işi değildir.
Bir uygulamanın kaynak kodunun işi, geriye kalan kod parçalarını yalnızca o uygulamayla gerçekten alakalı olarak sağlamaktır.
Her bedene uyan tek bir yazılım istiyorsanız, delice karmaşık bir şey elde edersiniz. Karmaşıklığı yönetilebilir seviyelere indirmek için modüler hale getirmeniz gerekir. Kısmi uygulamalara izin vermek için modüler hale getirmeniz gerekir :
Iş parçacığı kitaplığı, tek çekirdekli yerleşik denetleyicisinde değersizdir. Bu gömülü denetleyicinin dil uygulamasının yalnızca pthread
kitaplığı içermesini sağlamak, yapılacak en doğru şeydir.
Matematik kütüphanesi bir FPU'su olmayan mikro denetleyicide değersizdir. Yine, bu gibi işlevler sağlamaya zorlanmamak sin()
, yaşamı, o mikro denetleyici için kendi dil uygulayıcıları için kolaylaştırır.
Çekirdek programlarken çekirdek standart kütüphanesi bile değersizdir. Sen uygulayamaz write()
çekirdeğin içine bir sistem çağrısı olmadan ve siz uygulayamaz printf()
olmadan write()
. Bir çekirdek programcısı olarak, sistemi write()
çağırmak sizin işinizdir , orada olmasını bekleyemezsiniz.
Standart kütüphanelerden bu tür ihmallere izin vermeyen bir dil, birçok görev için uygun değildir . Dilinizin alışılmadık ortamlarda esnek bir şekilde kullanılabilir olmasını istiyorsanız, hangi standart kitaplıkların dahil edilmesinde esnek olması gerekir. Diliniz standart kitaplıklara ne kadar güvenirse, yürütme ortamında o kadar fazla varsayım yapar ve bu nedenle bu ön koşulları sağlayan ortamlarda kullanımını kısıtlar.
Tabii ki, python ve java gibi yüksek seviyeli diller , çevreleri hakkında birçok varsayım yapabilir . Ve standart kütüphanelerine pek çok şey ekleme eğilimindedirler. C gibi daha düşük seviyeli diller standart kütüphanelerinde çok daha az sağlar ve çekirdek standart kütüphanesini çok daha küçük tutar. Bu nedenle, hemen hemen her mimari için çalışan bir C derleyicisi bulursunuz, ancak üzerinde hiçbir python komut dosyası çalıştıramayabilirsiniz.
Derleyicilerin ve standart kitaplıkların ayrı olmasının büyük bir nedeni, iki farklı amaca hizmet etmeleridir (her ikisi de aynı dil spesifikasyonuyla tanımlanmış olsalar bile): derleyici daha üst düzey kodları makine talimatlarına çevirir ve standart kitaplık önceden test edilmiş sınama sağlar Yaygın olarak ihtiyaç duyulan işlevselliğin uygulamaları. Derleyici yazarları, diğer yazılım geliştiricilerin yaptığı gibi modülerliğe de değer verir. Aslında, ilk C derleyicilerinden bazıları, derleyiciyi ön işleme, derleme ve bağlantı için ayrı programlara böler.
Bu modülerlik size birçok avantaj sağlar:
Tarihsel olarak konuşursak (en azından C'nin bakış açısından), dilin orijinal, standartlaştırma öncesi sürümlerinin standart bir kütüphanesi yoktu. İşletim sistemi satıcıları ve üçüncü taraflar, sıklıkla kullanılan işlevselliklerle dolu kitaplıklar sunacaklardır, ancak farklı uygulamalar farklı şeyler içeriyordu ve bunlar büyük ölçüde birbiriyle uyumlu değildi. C standartlaştırıldığında, bu farklı uygulamaları uyumlu hale getirmek ve taşınabilirliği geliştirmek için bir "standart kütüphane" tanımladılar. C standart kütüphanesi, Boost kütüphanelerinin C ++ 'a sahip olduğu gibi dilden ayrı olarak geliştirildi, ancak daha sonra dil spesifikasyonuna entegre edildi.
Ek köşe-cevap: Fikri mülkiyet yönetimi
Dikkate değer bir örnek, Microsoft tarafından Intel'den satın alınan ve çerçeve açık kaynaklı olsa bile açıklanmayan şekilde kaldığı .NET Framework'te Math.Pow uygulamasının (çift, çift) uygulanmasıdır . (Kesin olmak gerekirse, yukarıdaki durumda bu bir kütüphane yerine dahili bir çağrıdır ancak fikir saklanır.) Dilin kendisinden ayrılmış bir kütüphane (teorik olarak standart kütüphanelerin bir alt kümesi), dilin destekçilerini çizim konusunda daha fazla esneklik sağlayabilir. şeffaflığı koruyacak olanlar ile açıklanamayanlar arasındaki sınır (üçüncü taraflarla yapılan sözleşmeler veya IP ile ilgili diğer nedenlerle).
Math.Pow
, herhangi bir satın alma işleminden veya Intel ile ilgili herhangi bir şeyden bahsetmiyor ve işlevin uygulanmasının kaynak kodunu okuyan kişilerden bahsediyor.
Hatalar ve hata ayıklama.
Hatalar: Tüm yazılımlarda hatalar, standart kütüphanenizde hatalar ve derleyicinizde hatalar var. Dilin bir kullanıcısı olarak, derleyicinin aksine standart kütüphanedeyken bu tür hataları bulmak ve çözmek çok daha kolaydır.
Hata ayıklama: Standart bir kütüphanenin yığın izini görmem ve bana nelerin yanlış olabileceği konusunda bir fikir vermem çok daha kolay. Çünkü o yığın izlemede anladığım bir kod var. Elbette daha derine inebilir ve kendi içsel işlevlerinizi takip edebilirsiniz, ancak günden güne her zaman kullandığınız bir dilde ise çok daha kolaydır.
Bu mükemmel bir soru!
Örneğin, C ++ Standardı derleyicide veya standart kütüphanede ne yapılması gerektiğini asla belirtmez: sadece uygulamaya atıfta bulunur . Örneğin, ayrılmış semboller hem derleyici (içsel olarak) hem de standart kütüphane tarafından birbirinin yerine kullanılabilir.
Yine de, bildiğim tüm C ++ uygulamaları, derleyici tarafından sağlanan asgari sayıda özgün ve standart kütüphane tarafından sağlanan mümkün olacaktır.
Bu nedenle, standart kütüphaneyi derleyicideki gerçek işlevsellik olarak tanımlamak teknik olarak mümkün olsa da pratikte nadiren kullanılmaktadır.
Bazı işlevsellik parçasını standart kütüphaneden derleyiciye taşıma fikrini düşünelim.
Avantajları:
Dezavantajları:
std
denemenin yalnızca küçük bir kütüphane oluşturmasını zorlaştırır .Bu, bir şeyi derleyiciye taşımanın şimdi ve gelecekte pahalı olduğu ve bu nedenle sağlam bir vaka gerektirdiği anlamına gelir . Bazı işlevsellik parçaları için gereklidir (normal kod olarak yazılamazlar), ancak o zaman bile derleyiciye taşınmak ve üzerlerine standart kitaplıkta inşa etmek için asgari ve genel parçaları çıkarmak gerekir.
Kendim bir dil tasarımcısı olarak, buradaki diğer cevapların bazılarını tekrar etmek istiyorum, ancak bunu bir dil inşa eden birinin gözünden sağlamak istiyorum.
Yapabileceğiniz her şeyi eklemeyi tamamladığınızda bir API bitmez. Yapabileceğiniz her şeyi almayı tamamladığınızda bir API biter.
Bazı dilleri kullanarak bir programlama dili belirtilmelidir. Kendi dilinizde yazılmış herhangi bir programın arkasındaki anlamı aktarabilmelisiniz. Bu dili yazmak çok zordur ve iyi yazmak bile zordur. Genel olarak, bilgisayara değil, diğer geliştiricilere, özellikle de diliniz için derleyiciler veya tercümanlar yazan geliştiricilere anlam vermek için kullanılan çok kesin ve iyi yapılandırılmış bir İngilizce biçimi olma eğilimindedir. İşte C ++ 11 spec, [intro.multithread / 14] 'den bir örnek:
Bir atomik nesne M üzerindeki B değeri hesaplamasına göre görünür yan etki dizisi, M'nin modifikasyon sırasındaki en büyük bitişik yan etki dizisidir, burada birinci yan etki B'ye göre görülebilir ve her yan etki için, B'nin kendisinden önce olduğu durum böyle değildir. B değerlendirmesiyle belirlenen bir M atomik objesinin değeri, B'ye göre M'nin görünür sırasındaki bazı işlemler tarafından kaydedilen değer olacaktır. hesaplama aşağıdaki tutarlılık gereklilikleri göz önüne alındığında benzersizdir. — Notu yaz]
Blek! C ++ 11'in çoklu okuyucuyu nasıl idare ettiğini kavramaya başlamış olan herkes, ifadelerin neden bu kadar sımsıkı olmak zorunda olduğunu takdir edebilir, ancak bu, onun ... gerçekten de ... opak olduğu gerçeğini affetmez!
Kontrast bu tanımı ile std::shared_ptr<T>::reset
standart kütüphane bölümünde:
template <class Y> void reset(Y* p);
Etkileri: Eşdeğeri
shared_ptr(p).swap(*this)
Öyleyse fark nedir? Dil tanımı bölümünde, yazarlar okuyucunun dil ilkellerini anladığını varsayamazlar. Her şey İngilizce nesirinde dikkatlice belirtilmelidir. Kütüphane tanımı bölümüne girince, davranışı belirtmek için dili kullanabiliriz. Bu genellikle çok daha kolaydır!
Prensip olarak, bir kişi ilk belgenin başlangıcında ilkellerden, “ilkel ilkeler” ile bir çizgi çizmeye gerek kalmadan “standart kütüphane özellikleri” olarak ne düşüneceğimizi tanımlayarak pürüzsüz bir birikime sahip olabilir. "standart kütüphane" özellikleri. Uygulamada, bu çizgi çizilmesi çok değerlidir çünkü dilin en karmaşık bölümlerinden bazılarını (algoritmaları uygulaması gerekenler gibi) onları ifade etmek için tasarlanmış bir dil kullanarak yazmanıza izin verir.
Ve biz gerçekten bulanık çizgiler görüyoruz:
java.lang.ref.Reference<T>
olabilir sadece standart kütüphane sınıfları tarafından alt sınıflanamayacağını java.lang.ref.WeakReference<T>
java.lang.ref.SoftReference<T>
ve java.lang.ref.PhantomReference<T>
çünkü davranışları Reference
öylesine derinden onlar "standart kitaplığı" sınıfları olarak uygulanan bu sürecin bölümüne bazı kısıtlamalar koymak için gerekli Java dili spesifikasyonu ile dolaşık vardır.Bu, mevcut cevaplara bir ek olarak verilmiştir (ve yorum için çok uzun).
Standart bir kütüphane için en az iki neden var:
Belirli bir dil özelliği bir kütüphane işlevindeyse ve nasıl çalıştığını bilmek istersem, bu işlev için yalnızca kaynağı okuyabilirim. Bir hata raporu / yama / çekme isteği göndermek istersem, bir düzeltme ve test senaryoları düzenlemek için genellikle zor değildir. Derleyicideyse, iç kısımlara girebilirim. Aynı dilde olsa bile (ve öyle olmalı, kendine saygı duyan herhangi bir derleyici kendi kendine barındırılmalıdır) derleyici kodu uygulama koduna benzemez. Doğru dosyaları bulmak bile sonsuza kadar sürebilir.
O rotaya giderseniz, kendinizi potansiyel bir katkıda bulunanlardan kesiyorsunuz.
Birçok dil bu özelliği bir dereceye kadar sunar, ancak sıcak yüklemeyi yapan kodu sıcak olarak yeniden yüklemek oldukça karmaşık olacaktır. SL çalışma zamanından ayrıysa yeniden yüklenebilir.
Bu ilginç bir soru ama daha önce verilmiş çok sayıda iyi cevap var, bu yüzden tam bir cevap almayacağım.
Ancak, sanmadığım iki şey yeterince dikkat çekti:
İlk olarak, her şeyin süper net bir kesim olmadığı. Bu tam olarak bir spektrum biraz çünkü işleri farklı yapmak için sebepler var. Örnek olarak, derleyiciler genellikle standart kütüphaneleri ve işlevlerini bilir. Örnek olarak: C'nin "Merhaba Dünya" fonksiyonu - printf - aklıma gelen en iyisi. Bu bir kütüphane işlevidir, bir tür olması gerekir, çünkü çok platform bağımlıdır. Ancak programcının kötü çağrılar hakkında uyarılması için davranışının (uygulama tarafından tanımlanmış) derleyici tarafından bilinmesi gerekir. Bu özellikle temiz değil, ancak iyi bir uzlaşma olarak görülüyordu. Bu arada, bu "neden bu tasarımın" sorularının çoğunun gerçek cevabı: çok fazla uzlaşma ve "o zaman iyi bir fikir gibi göründü". Her zaman değil, "bunu yapmanın net yoluydu" ya da "
İkincisi, standart kütüphanenin bu kadar standart olmamasını sağlamasıdır. Bir dilin arzulandığı birçok durum vardır ancak genellikle onlara eşlik eden standart kütüphaneler hem pratik hem de arzu edilebilir değildir. Bu genellikle standart olmayan platformlarda C gibi programlama dilleri olan sistemlerde geçerlidir. Örneğin, işletim sistemi veya zamanlayıcı olmayan bir sisteminiz varsa: iş parçacığınız olmayacak.
Standart bir kütüphane modelinde (ve içinde iş parçacığı destekleniyorsa) bu, temiz bir şekilde işlenebilir: derleyici hemen hemen aynıdır, geçerli kitaplıkların bitlerini yeniden kullanabilirsiniz ve kaldırmayacağınız herhangi bir şey. Bu derleyici içine pişmiş ise işler karışmaya başlar.
Örneğin:
Uyumlu bir derleyici olamazsınız.
Standarttan sapmanızı nasıl belirtirsiniz? Genellikle, başarısız olabileceğiniz bazı ithalat / içerme sözdizimlerinin bir biçimi olduğunu unutmayın; örneğin, standart kütüphane modelinde eksik olan herhangi bir şey varsa, pitonların ithalatı veya C'leri sorunu kolayca işaret eder.
Ayrıca 'kütüphane' işlevini değiştirmek veya uzatmak istiyorsanız da benzer sorunlar uygulanır. Bu düşündüğünden çok daha yaygın. Sadece diş açmaya devam etmek için: pencereler, linux ve bazı egzotik ağ işleme üniteleri hepsi farklı şekilde diş açıyor. Linux / windows bitleri oldukça statik olabilir ve aynı bir API kullanabilse de, NPU işleri haftanın günleri ve onunla birlikte API ile değişecektir. Derleyiciler, bu tür bir şeyi ayırmanın bir yolu olmadığında, hangi bitleri hızlı bir şekilde desteklemeleri / yapabilecekleri konusunda karar vermeleri gerektiğine karar verdiklerinde derhal sapma yaparlar.