Yanıtlar:
Güçlü yazılan bir dil ile statik olarak yazılan bir dil arasındaki fark nedir?
Statik olarak yazılan bir dilde, uygulama (derleyici veya yorumlayıcı) tarafından derleme zamanında denetlenen bir tür sistemi vardır. Tür denetimi bazı programları reddeder ve denetimi geçen programlar genellikle bazı garantilerle birlikte gelir; örneğin, derleyici kayan noktalı sayılarda tamsayı aritmetik komutlarının kullanılmamasını garanti eder.
Mesleki literatürde en yaygın kullanılan tanım "güçlü yazılan" bir dilde, programcının yazım sistemi tarafından getirilen kısıtlamalar üzerinde çalışmasının mümkün olmaması olmasına rağmen, "güçlü yazılan" ne anlama geldiğine dair gerçek bir anlaşma yoktur. . Bu terim neredeyse her zaman statik olarak yazılan dilleri tanımlamak için kullanılır.
Statik olarak yazılanın tersi "dinamik olarak yazılır", yani
Örneğin, dinamik olarak yazılan bir dil olan Lua , diğerlerinin yanı sıra bir dize türüne, bir sayı türüne ve bir Boole türüne sahiptir. Lua'da her değer tam olarak bir türe aittir , ancak bu dinamik olarak yazılan tüm diller için bir gereklilik değildir. Lua'da iki dizeyi birleştirmeye izin verilir, ancak bir dizeyi ve bir Boolean'ı birleştirmeye izin verilmez.
"Güçlü yazılan" ın tersi "zayıf yazılan" dır, yani yazım sistemi çevresinde çalışabilirsiniz. Herhangi bir işaretçi türü, yalnızca döküm yoluyla başka bir işaretçi türüne dönüştürülebildiğinden, C, kötü bir şekilde zayıf yazılmıştır. Pascal'ın güçlü bir şekilde yazılması amaçlanmıştı, ancak tasarımdaki bir gözetim (etiketsiz varyant kayıtları) tür sistemine bir boşluk getirdi, bu yüzden teknik olarak zayıf yazılmıştır. Gerçekten güçlü yazılan dillere örnek olarak CLU, Standard ML ve Haskell verilebilir. Standart ML, aslında, dil yaygın bir şekilde dağıtıldıktan sonra keşfedilen tür sistemindeki boşlukları kaldırmak için birkaç revizyondan geçti.
Genel olarak, "güçlü" ve "zayıf" hakkında konuşmak o kadar kullanışlı değil. Bir tip sistemin boşluk deliği olup olmadığı boşluk deliklerinin tam sayısı ve doğasından, uygulamada ortaya çıkma olasılıklarından ve bir boşluktan yararlanmanın sonuçları nelerden daha az önemlidir. Uygulamada, "güçlü" ve "zayıf" terimlerini tamamen kullanmaktan kaçınmak en iyisidir , çünkü
Amatörler genellikle onları "statik" ve "dinamik" ile birleştirir.
Görünüşe göre "zayıf yazma" bazı kişiler tarafından örtük dönüşümlerin göreceli yaygınlığı veya yokluğu hakkında konuşmak için kullanılmaktadır.
Profesyoneller terimlerin ne anlama geldiğini tam olarak kabul edemezler.
Genel olarak, kitlenizi bilgilendirme veya aydınlatma olasılığı düşüktür.
Üzücü gerçek şu ki, tip sistemler söz konusu olduğunda, "güçlü" ve "zayıf" teknik anlam üzerinde evrensel olarak kabul edilmiş bir şey değildir. Tip sistemlerinin göreceli gücünü tartışmak istiyorsanız, garantilerin tam olarak ne olduğunu ve sağlanmadığını tartışmak daha iyidir. Örneğin, sorulması gereken iyi bir soru şudur: "belirli bir türün (veya sınıfın) her değerinin, bu türün kurucularından biri çağrılarak oluşturulduğu garanti ediliyor mu?" C'de cevap hayır. CLU, F # ve Haskell'de evet. C ++ için emin değilim - bilmek istiyorum.
Aksine, statik yazma , programların yürütülmeden önce kontrol edildiği ve bir programın başlatılmadan önce reddedilebileceği anlamına gelir . Dinamik yazma , değer türlerinin yürütme sırasında denetlendiği ve kötü yazılan bir işlemin programın durmasına veya çalışma zamanında bir hataya neden olabileceği anlamına gelir . Statik yazmanın birincil nedeni, bu tür "dinamik tür hataları" olabilecek programları devre dışı bırakmaktır.
Biri diğerini ima ediyor mu?
Bilgiçlik düzeyinde, hayır, çünkü "güçlü" kelimesi gerçekten hiçbir şey ifade etmez. Ancak pratikte insanlar neredeyse her zaman iki şeyden birini yaparlar:
Onlar (yanlış) "statik" ve "dinamik" anlamında "güçlü" ve "zayıf" kullanırlar, bu durumda (yanlış) "güçlü yazılır" ve "statik olarak yazılır" dönüşümlü olarak kullanırlar.
Statik tip sistemlerin özelliklerini karşılaştırmak için "güçlü" ve "zayıf" kullanırlar. Birisinin "güçlü" veya "zayıf" dinamik tip sistemden bahsettiğini duymak çok nadirdir. Gerçekten herhangi bir tür sistemi olmayan FORTH dışında, tip sisteminin altüst edilebildiği dinamik olarak yazılmış bir dil düşünemiyorum. Tanıma göre, bu kontroller yürütme motoruna yüklenir ve her işlem yürütülmeden önce akıl sağlığı için kontrol edilir.
Her iki durumda da, bir kişi "güçlü bir şekilde yazılmış" bir dil çağırırsa, o kişinin statik olarak yazılmış bir dil hakkında konuşması muhtemeldir.
Bu genellikle yanlış anlaşılır, bu yüzden temizlememe izin verin.
Statik yazma , türün değişkene bağlı olduğu yerdir . Türler derleme zamanında kontrol edilir.
Dinamik yazma , türün değere bağlı olduğu yerdir . Türler çalışma zamanında kontrol edilir.
Yani Java'da:
String s = "abcd";
s
"sonsuza dek" olacak bir String
. Yaşamı boyunca farklı String
s'leri gösterebilir (çünkü s
Java'da bir referanstır). Bir null
değeri olabilir ama asla Integer
a ya da a'yı göstermez List
. Bu statik yazımdır.
PHP dilinde:
$s = "abcd"; // $s is a string
$s = 123; // $s is now an integer
$s = array(1, 2, 3); // $s is now an array
$s = new DOMDocument; // $s is an instance of the DOMDocument class
Dinamik yazım.
(Uyarıyı düzenleyin!)
Güçlü yazım , yaygın olarak kabul edilmiş bir anlamı olmayan bir ifadedir. Bu terimi statik yazım dışında bir şey ifade etmek için kullanan çoğu programcı, derleyici tarafından uygulanan bir tür disiplin olduğunu ima etmek için kullanır. Örneğin, CLU, tür tarafından sağlanan yapıcıları kullanmak dışında, istemci kodunun soyut türde bir değer oluşturmasına izin vermeyen güçlü bir tür sistemine sahiptir. C'nin biraz güçlü bir tür sistemi vardır, ancak bir program her zaman bir işaretçi türünün değerini başka bir işaretçi türünün değerine atabildiği için bir dereceye kadar "alt" olabilir. Örneğin, C'de döndürülen bir değeri alabilir malloc()
ve neşeyle üzerine dökebilirsiniz FILE*
ve derleyici sizi durdurmaya çalışmaz - hatta tehlikeli bir şey yaptığınızı bile uyarmaz.
(Orijinal cevap "çalışma zamanında türü değiştirmiyorum" değeri hakkında bir şey söyledi. Birçok dil tasarımcıları ve derleyici yazarları biliyorum ve muhtemelen bazı çok gelişmiş araştırma dışında, çalışma zamanında tür değiştiren değerleri hakkında konuşan bir bilmiyorum "güçlü güncelleme sorunu" olarak bilinen sistemler.)
Zayıf yazma , derleyicinin yazma disiplinini zorlamadığını veya belki de zorlamanın kolayca alt edilebileceğini gösterir.
Bu cevabın orijinali, zayıf yazmayı örtük dönüşümle (bazen "örtük tanıtım" olarak da adlandırılır) sınırladı. Örneğin, Java'da:
String s = "abc" + 123; // "abc123";
Bu, örtük tanıtımın bir örneğidir: 123, birleştirilmeden önce örtük olarak bir dizeye dönüştürülür "abc"
. Java derleyicisinin bu kodu yeniden yazdığı söylenebilir:
String s = "abc" + new Integer(123).toString();
Klasik bir PHP "ile başlar" problemini düşünün:
if (strpos('abcdef', 'abc') == false) {
// not found
}
Buradaki hata strpos()
, 0 değerinin eşleşmenin dizinini döndürmesidir. 0, boole'ye zorlanır false
ve bu nedenle durum aslında doğrudur. Çözelti kullanmaktır ===
yerine ==
örtülü dönüşüm önlemek için.
Bu örnek, örtük dönüşüm ve dinamik yazmanın bir kombinasyonunun programcıları nasıl saptırabileceğini gösterir.
Bunu Ruby ile karşılaştırın:
val = "abc" + 123
hangi Ruby çünkü bir çalışma zamanı hatasıdır nesne 123 olduğu değil örtük bir geçirilecek olur sırf dönüştürülen +
yöntemle. Ruby'de programcı dönüşümü açık yapmalıdır:
val = "abc" + 123.to_s
PHP ve Ruby karşılaştırması burada iyi bir örnek. Her ikisi de dinamik olarak yazılan dillerdir, ancak PHP'nin çok fazla örtük dönüşümü vardır ve Ruby (belki de bilmiyorsanız şaşırtıcı olabilir).
Buradaki nokta, statik / dinamik eksenin güçlü / zayıf eksenden bağımsız olmasıdır. İnsanlar muhtemelen kısmen karıştırırlar çünkü güçlü ve zayıf yazım sadece daha az net olarak tanımlanmakla kalmaz, aynı zamanda güçlü ve zayıf olanın tam olarak ne anlama geldiğine dair gerçek bir fikir birliği yoktur. Bu nedenle güçlü / zayıf yazım, siyah veya beyazdan çok gri tonudur.
Olduğunu bu bakmak için başka bir yol: Yani soruyu cevaplamak için çoğunlukla bu statik yazarak derleme zamanı tip emniyet ve güçlü yazarak olan zamanı tür güvenliğidir söylemek doğru olduğunu.
Bunun nedeni, statik olarak yazılan bir dildeki değişkenlerin bildirilmesi gereken bir türü olması ve derleme zamanında denetlenebilmesidir. Güçlü yazılan bir dilin çalışma zamanında türü olan değerleri vardır ve programcının dinamik bir denetim yapmadan tür sistemini bozması zordur.
Ancak bir dilin Statik / Güçlü, Statik / Zayıf, Dinamik / Güçlü veya Dinamik / Zayıf olabileceğini anlamak önemlidir.
"abc" + 123
bir çalışma zamanı hatasıdır, ruby'de derleme hatası değildir. Derleme hatası olsaydı, ruby statik olarak yazılır.
Her ikisi de iki farklı eksende kutuplardır:
Güçlü yazım , a'nın bir türden diğerine otomatik olarak dönüştürülmeyeceği anlamına gelir. Zayıf yazılan tersidir: Perl, "123"
otomatik olarak int biçimine dönüştürerek sayısal bağlamda olduğu gibi bir dize kullanabilir 123
. Python gibi kuvvetle yazılmış bir dil bunu yapmaz.
Statik olarak yazılan araçlar, derleyici derleme zamanında her değişkenin türünü bulur. Dinamik olarak yazılan diller yalnızca çalışma zamanında değişken türlerini belirler.
Güçlü yazılan, türler arasında dönüşümler arasında kısıtlamalar olduğu anlamına gelir. Statik olarak yazılan, türlerin dinamik olmadığı anlamına gelir - oluşturulduktan sonra bir değişkenin türünü değiştiremezsiniz.
Veri Zorlaması mutlaka zayıf yazılan anlamına gelmez, çünkü bazen sözdizimi şekeri:
Java'nın yukarıdaki örneği,
String s = "abc" + 123;
Zayıf yazılan bir örnek değil çünkü gerçekten yapıyor:
String s = "abc" + new Integer(123).toString()
Yeni bir nesne oluşturuyorsanız veri baskısı da zayıf yazılmaz. Java, zayıf yazılan çok kötü bir örnektir (ve iyi yansıması olan herhangi bir dil büyük olasılıkla zayıf yazılmayacaktır). Çünkü dilin çalışma zamanı her zaman türün ne olduğunu bilir (istisna yerel türler olabilir).
Bu C'den farklıdır. C, zayıf yazılan en iyi örneklerden biridir. 4 bayt bir tam sayı, bir yapı, bir işaretçi veya 4 karakter ise çalışma zamanının hiçbir fikri yoktur.
Dilin çalışma zamanı, zayıf yazılıp yazılmadığını gerçekten tanımlar, aksi takdirde gerçekten sadece düşüncesi.
DÜZENLEME: Çalışma zamanının Güçlü Türlü bir sistem olması için çalışma zamanı sisteminde tüm türlerin yeniden yapılandırılması gerekmediği için, bu durum mutlaka doğru değildir. Haskell ve ML o kadar eksiksiz statik analize sahiptirler ki, çalışma zamanından potansiyel ommit tipi bilgileri alabilirler.
Cevap zaten yukarıda verilmiştir. Güçlü ve haftalık ve statik ve dinamik kavramları birbirinden ayırmaya çalışmak.
Güçlü Yazma: Bir türden diğerine otomatik olarak dönüştürülmez
Go veya Python'da güçlü bir şekilde yazılan diller gibi "2" + 8, "tür zorlamasına" izin vermedikleri için bir tür hatası oluşturur.
Zayıf (gevşek) Yazılan: Otomatik olarak bir türe diğerine dönüştürülecek: JavaScript veya Perl gibi zayıf yazılan diller hata vermeyecek ve bu durumda JavaScript '28' ile sonuçlanacak ve perl 10 ile sonuçlanacaktır.
Perl Örneği:
my $a = "2" + 8;
print $a,"\n";
Main.pl dosyasına kaydedin ve çalıştırın perl main.pl
ve çıkış 10'u alacaksınız.
Programlamada, programcı değişken tiplerin kontrol edildiği noktaya göre statik yazmayı ve dinamik yazmayı tanımlar. Statik yazılan diller, tür denetiminin derleme zamanında yapıldığı, dinamik yazılan diller ise tür denetiminin çalışma zamanında yapıldığı dillerdir.
Bu ne anlama geliyor?
Git'te çalışma zamanından önce yazılan kontrolleri yapar (statik kontrol). Bu, yalnızca yürüttüğü kodu çevirip yazmakla kalmaz, aynı zamanda kod çalıştırılmadan önce tüm kodu ve tür hatasını atar. Örneğin,
package main
import "fmt"
func foo(a int) {
if (a > 0) {
fmt.Println("I am feeling lucky (maybe).")
} else {
fmt.Println("2" + 8)
}
}
func main() {
foo(2)
}
Bu dosyayı main.go dosyasına kaydedin ve çalıştırın, bunun için derleme başarısız mesajı alacaksınız.
go run main.go
# command-line-arguments
./main.go:9:25: cannot convert "2" (type untyped string) to type int
./main.go:9:25: invalid operation: "2" + 8 (mismatched types string and int)
Ancak bu durum Python için geçerli değildir. Örneğin, aşağıdaki kod bloğu ilk foo (2) çağrısı için yürütülür ve ikinci foo (0) çağrısı için başarısız olur. Çünkü Python dinamik olarak yazılmıştır, sadece üzerinde çalıştığı kodu çevirir ve tip kontrol eder. Başka blok asla foo (2) için çalıştırılmaz, bu nedenle "2" + 8'e hiç bakılmaz ve foo (0) çağrısı için bu bloğu yürütmeye çalışır ve başarısız olur.
def foo(a):
if a > 0:
print 'I am feeling lucky.'
else:
print "2" + 8
foo(2)
foo(0)
Aşağıdaki çıktıyı göreceksiniz
python main.py
I am feeling lucky.
Traceback (most recent call last):
File "pyth.py", line 7, in <module>
foo(0)
File "pyth.py", line 5, in foo
print "2" + 8
TypeError: cannot concatenate 'str' and 'int' objects
Biri diğerini ima etmez. Bir dilin statik olarak yazılması, tüm değişkenlerin türlerinin derleme zamanında bilindiği veya çıkartıldığı anlamına gelir.
Bir kuvvetle yazılan dil başka şekilde bir tür kullanmasına izin vermez. C, zayıf yazılan bir dildir ve güçlü yazılan dillerin izin vermediğine iyi bir örnektir. C'de yanlış tipte bir veri elemanı geçirebilirsiniz ve şikayet etmeyecektir. Güçlü yazılan dillerde yapamazsınız.
Güçlü yazma muhtemelen değişkenlerin iyi tanımlanmış bir türe sahip olduğu ve farklı türdeki değişkenlerin ifadelerde birleştirilmesine ilişkin katı kurallar olduğu anlamına gelir. Örneğin, A bir tamsayı ve B bir şamandıra ise, A + B ile ilgili katı kural A'nın bir şamandıra dökülmesi ve sonucun bir şamandıra olarak döndürülmesi olabilir. A bir tam sayı ve B bir dize ise, katı kural A + B'nin geçerli olmaması olabilir.
Statik yazım muhtemelen türlerin derleme zamanında (veya derlenmemiş diller için eşdeğeri) atandığı ve program yürütülürken değişemediği anlamına gelir.
Bu sınıflandırmaların birbirini dışlamadığını unutmayın, gerçekten sık sık birlikte olmalarını beklerim. Güçlü yazılan birçok dil de statik olarak yazılmıştır.
Ve 'muhtemelen' kelimesini kullandığımda bunun, bu terimlerin evrensel olarak kabul edilmiş bir tanımı olmadığı için olduğuna dikkat edin. Şimdiye kadar cevaplardan zaten göreceğiniz gibi.