Güçlü yazılan bir dil ile statik olarak yazılan bir dil arasındaki fark nedir?


Yanıtlar:


543

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 ve dinamik

Statik olarak yazılanın tersi "dinamik olarak yazılır", yani

  1. Çalışma zamanında kullanılan değerler tiplere ayrılmıştır.
  2. Bu tür değerlerin nasıl kullanılabileceği konusunda kısıtlamalar vardır.
  3. Bu kısıtlamalar ihlal edildiğinde, ihlal (dinamik) tür hatası olarak bildirilir.

Ö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ü ve zayıf

"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.

Burada gerçekten neler oluyor?

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.


3
@Adam: Açıkçası açılacak kadar doğru değil :) Cletus'un cevabı çok fazla yanlış anlama içerdiğinden (en kötüsünü düzenlediğim halde), her şeyi bir hece kelimesiyle hecelemek zorunda hissettim ...
Norman Ramsey

1
Peki seni destekledim :) "Derleme" kelimesi bile günümüzün sanal dillerinde dinamik diller çalıştıran bir kelime değil. Teknik olarak Java ve C # iki kez derlenir (JIT) ve her ikisi de bir tür analiz yapar. .NET vm'de çalışan Javascript gibi bir dil, VM nedeniyle daha tipik olabilir.
Adam Gent

2
Şimdi çok kafam karıştı! Tamam, sevgili arena gladyatörleri, benim gibi fakir bir ruh aşağıdaki basit anlayışla gidebilir mi? 1.Statik: Değerler, derleme zamanı sırasında türle ilişkilendirilir ve çalışma süresi ile ilişkilendirilmez.2.Dinamik: Değerler, çalışma zamanı sırasında türle ilişkilidir, bu nedenle, değerin türü, çalışma zamanı sırasında değişebilir ~ dökümle ilgili sorunlara daha yatkın çalışma sırasında. 3. Güçlü / zayıf: Unutun! Bunlar teknik terimler değil, sadece kötü isimlendirme. Kişinin hangi bağlamdan bahsettiğine bağlıdır. Bu basit anlayışla hayatımı sürdürebilir miyim? :(
Saurabh Patil

"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. Birisi bunun C'de meydana geldiği örnek bir durum sağlayabilir mi? Sanırım bu yapılara işaretçiler döküm içerir?
corazza

Güçlü ve Zayıf Yazma: böyle bir sınıflandırma yok.
Raúl

248

Bu genellikle yanlış anlaşılır, bu yüzden temizlememe izin verin.

Statik / Dinamik Yazma

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ı Strings'leri gösterebilir (çünkü sJava'da bir referanstır). Bir nulldeğeri olabilir ama asla Integera 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.

Güçlü / Zayıf Yazma

(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 falseve 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).

Statik / Dinamik ve Güçlü / Zayıf

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.


$ S bir tam sayı veya dize olduğunu söylemek yerine, türün "abcd" ile ilişkili olduğunu veya $ s değişkeniyle değil 1234 olduğunu söylerseniz daha iyi olurdu.
Srinivas Reddy Thatiparthy

Açık örneklerle mükemmel cevap. Bununla birlikte, insanların neden çift kavram olarak güçlü / statik hakkında sorular sorduğu konusundaki karışıklığa tamamen değinmediğini düşünüyorum. Örneğin, OP'nin "statik yazım IMPLY güçlü yazım mı?" Cevabınız onların bağımsızlığını vurgular. Güçlü olanın neden statik ile eşleştirildiğini açıklamaya devam etmek için Norman Ramsey'in önceki cevabı çok iyi: stackoverflow.com/questions/376611/…
JasDev

1
"abc" + 123bir çalışma zamanı hatasıdır, ruby'de derleme hatası değildir. Derleme hatası olsaydı, ruby ​​statik olarak yazılır.
sepp2k

Zayıf yazım örneklerinin iyileştirilmesi (cevabımı görmek) gerekir, ancak başka türlü güzel biçimlendirmeler gerekir.
Adam Gent

Benim opion güçlü vs zayıf typgin şudur: Strong: "c" + True = çalışma zamanı hatası veya derleme zamanı hatası. Zayıf: "c" + True = "b" veya "d" çünkü her şey ham bayt olarak kabul edilir. Güçlü: C #, Yakut, C ++ Zayıf: Montaj, C (örtük geçersiz işaretçiler nedeniyle)
Jonathan Allen

17

Her ikisi de iki farklı eksende kutuplardır:

  • güçlü yazım yerine zayıf yazım
  • statik olarak yazılırken dinamik olarak yazılı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.


6
Katılmam gerekiyor. Güçlü yazılan bir dil, çalışma zamanında türlerin ne olduğunu bilen bir dildir. Zayıf yazılan bir dil, Assembly'den hoşlanmayan bir dildir. Örneğin üçüncü bir eksende, "örtük ve açık dönüşümler".
Jonathan Allen

1
Aslında normal Jonathan kabul ediyorum ama tam statik analiz yaparsanız ve döküm izin vermiyorsa çalışma zamanında mevcut türleri güçlü bir şekilde yazmak zorunda değilsiniz. (düzenlenmiş cevabıma bakın).
Adam Gent

1
Python, dinamik olarak yazılmış ve güçlü bir şekilde yazılmış bir dile
örnektir

13

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.


Bunu göstermek için: Güçlü yazılan bir dilde, "5" == 5 değerini karşılaştıramaz ve doğru olmasını sağlayamazsınız: Dizeler tamsayı değildir. Belleğim hizmet veriyorsa, modern komut dosyası dillerinin çoğu dinamik olarak yazılmıştır. Tcl / Tk, ancak zayıf yazılır - Her şey bir dize olarak ele alınabilir.
Little Bobby Tables

Bobby, zayıf yazılan bir dilde "5" == 5 0x35 == 0x05 olarak okunur. Başka bir deyişle, her şey ham bayt olarak kabul edilir.
Jonathan Allen

İkinize de katılmıyorum. Lua al; "5" == 5 ile karşılaştırabilirsiniz ve yanlış döndürür, ancak "5" + 0'a giderek hızlı bir dönüştürme yapılabilir.
RCIX

12

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.


B muhtemelen daha iyi, eğer biraz daha az biliniyorsa, örnek.
Tom Hawtin - tackline

Javascript de oldukça zayıf yazılmıştır, ancak çok az tür olduğundan ve gerçekten yeni türler oluşturamadığınız için.
Adam Gent

10

Cevap zaten yukarıda verilmiştir. Güçlü ve haftalık ve statik ve dinamik kavramları birbirinden ayırmaya çalışmak.

Güçlü yazılan nedir VS Zayıf yazılan?

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.plve çıkış 10'u alacaksınız.

Statik VS Dinamik tipi nedir?

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.

  • Statik: Çalışma zamanından önce kontrol edilen türler
  • Dinamik: Çalıştırma sırasında anında kontrol edilen türler

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

8

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.


7

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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.