Macarca notasyonu, yetersiz bir şekilde ifade eden statik yazımı olan diller için geçici bir çözüm mü? [kapalı]


28

Eric Lippert'in makalesinde Macar Notasyonu ile Neler Var? Macar Notasyonu’nın (iyi tür) amacının

Depolama temsil bilgisine ek olarak anlamsal bilgileri içerecek şekilde "tip" kavramını da genişletir.

Basit bir örnek, "x" ile bir X koordinatını temsil eden bir değişkeni ve "y" ile bir Y koordinatını temsil eden bir değişkeni (bu değişkenlerin tamsayılar mı yoksa değişkenler mi olduğuna bakılmaksızın "ön") olacaktır. xFoo + yBar, kod açıkça yanlış görünüyor.

Ama aynı zamanda Haskell'in tip sistemi hakkında da okudum ve Haskell'de, derleyicinin sizin için kontrol edeceği gerçek türleri kullanarak Haskell'de, aynı şeyi (yani "anlamsal bilgiyi içine alan tip kavramını genişletmek") başarabilir . Bu nedenle yukarıdaki örnekte xFoo + yBarHaskell'da, programınızı doğru tasarladıysanız, uyumsuz türler olarak bildirildiklerinden derleme başarısız olur. Başka bir deyişle Haskell'in tür sistemi, Macar Notasyonu'na eşdeğer derleme zamanı kontrolünü etkili bir şekilde destekliyor gibi görünüyor.

Yani, Macar Notasyonu sadece tip sistemleri anlamsal bilgiyi kodlayamayan programlama dilleri için bir yardım grubu mu? Veya Macar Notasyonu Haskell'in gibi statik tip bir sistemin sunabileceklerinin ötesinde bir şey sunuyor mu?

(Tabii ki, Haskell'i örnek olarak kullanıyorum. Benzer ifade edici (rich? Strong?) Tip sistemlere sahip başka diller olduğundan eminim, ancak hiçbirine rastlamadım.)


Açık olmak gerekirse, ben değilim değil değişken isimleri annotating bahsediyor veri türü değil, hakkında bilgi anlam programı çerçevesinde değişkenin. Örneğin, bir değişken bir tamsayı ya da değişken ya da çift ya da uzun ya da her neyse olabilir, ama belki de değişkenin anlamı , inç cinsinden ölçülen göreceli bir x koordinatı olmasıdır. Bu, Macar Notasyonu (ve Haskell tipleri) aracılığıyla kodlamaktan bahsettiğim bilgi türüdür.


Pascal - Pascal'da tanımladığınız bir XCood ve YCoord tipini denemek ve eklemek isteseniz de, sadece bir derleyici uyarısı alacaksınız IIRC
mcottle

1
blog.moertel.com/articles/2006/10/18/… , Haskell'deki tip sistemindeki "macarca uygulamalar" a çok benzer bir şey yapma hakkında bir makaledir.
Logan Capaldo

1
F # da bu stil özelliğine sahiptir.
Rangoric

Bu gerçekten güzel bir makale bağlantısı (moertel.com bir) tam olarak düşündüğüm şeyi gösteriyor: string sistemini kullanarak telsiz enterpolasyon güvenlik açıklarını ve derleme zamanı hatalarına dönüşüyor. Bağlantı için teşekkürler.
Ryan C. Thompson

Bence pek çok OO, anlambilim için Macar gösterimini yakaladı, çünkü bugün muhtemelen şöyle yazacaksınız: Foo.Position.X + Bar.Position.Y.
Pieter B

Yanıtlar:


27

Evet derim".

Dediğiniz gibi, Macar Notasyonu, türünde kodlanamayan addaki bilgileri kodlamaktır. Ancak, temelde iki durum vardır:

  1. Bu bilgi önemlidir.
  2. Bu bilgi önemli değil.

İlk önce durum 2 ile başlayalım: eğer bu bilgi önemli değilse, o zaman Macar Notasyonu sadece gereksiz gürültüdür.

Daha ilginç olan durum 1 numaradır, ancak eğer bilgi önemli ise kontrol edilmeli, yani ismin değil türün bir parçası olması gerektiğini savunuyorum .

Bu da bizi Eric Lippert'in teklifine geri getiriyor:

Depolama temsil bilgisine ek olarak anlamsal bilgileri içerecek şekilde "tip" kavramını da genişletir.

Aslında bu, "tip kavramını uzanan" değil ise tip kavramı! Tüm amacı tiplerinin (bir tasarım aracı olarak) semantik bilgi kodlamak etmektir! Depo temsili, genellikle türe hiç ait olmayan bir uygulama detayıdır . (Ve özellikle bir OO dilinde türe ait olamaz , çünkü temsil bağımsızlığı OO için ön koşullardan biridir.)


Macar gösteriminin en çok kullanılan AFAIK olduğu C, yine de bir OO dili değildir.
Péter Török,

4
@ PéterTörök: OO, bir dilin özelliği olmayan bir tasarım deseni, modern diller ise C'yi değilken kolaylaştıracak şekilde tasarlandı.
Jan Hudec

3
@ PéterTörök: C düzleminde oldukça fazla sayıda nesne yönelimli kod yazdım. Ne dediğimi biliyorum.
Jan Hudec

1
Önemli bilgilerin adından ziyade bir değişkenin türüne gömülmesi gerektiği doğru olsa da, söylenmesi gereken ancak hangi tür sistemlerin ifade edemediği birçok önemli şey vardır. Örneğin S1, evrendeki herhangi bir yerde tek referansı varsa , char[]sahibi istediği zaman değiştirebilecek ve değiştirebilecek, ancak asla dış koda maruz bırakılmayacak ve kimsenin asla değişmemesi gereken fakat paylaşılabilecek S2bir referanstır. char[]değiştirmeyeceğine söz veren nesnelerle, anlamsal olarak aynı "tür şey" olarak mı kabul edilmeli S1ve S2kabul edilmeli ?
supercat

1
@supercat - Teklik türlerini açıklıyorsunuz.
Jack

9

Türlerin tüm amacı (bir tasarım aracı olarak) anlamsal bilgiyi kodlamaktır!

Bu cevabı beğendim ve bu cevabı takip etmek istedim ...

Haskell hakkında hiçbir şey bilmiyorum, ancak xFoo + yBarC, C ++ veya Java gibi bir tür güvenlik türünü destekleyen herhangi bir dilde olduğu gibi bir şeyi başarabilirsiniz . C ++ 'da XDir ve YDir sınıflarını, yalnızca kendi tipindeki nesneleri alan aşırı yüklenen' + 'operatörleriyle tanımlayabilirsiniz. C veya Java'da, '+' operatörü yerine add () işlevini / yöntemini kullanarak eklemenizi yapmanız gerekir.

Her zaman anlambilim için değil, anlam bilgisi için kullanılan Macar Notasyonunu da gördüm (anlamsallığın türe göre gösterilebildiği durumlar hariç). Değişkenin türünü, sizin için türü bir ya da başka bir durumda editörde görüntüleyen "akıllı" programlama editörlerinden önceki günlerde hatırlamanın kolay bir yolu.


Nesne yönelimli olmak xFoo + yBar, kullanıcı tarafından tanımlanmış türlere izin verecek bir dil için ne gerekli ne de ne de bu örneğin çalışması için C ++ 'nın OO yönü değildir.
Luc Danton

Haklısın O O değil, güvenlik türü. Cevabımı düzenledim.
BHS

Hmm. xFoo + yBarDerleme hatası (veya en azından çalışma zamanı hatası) hemen hemen her dilde yapabileceğiniz iyi bir nokta . Ancak, XDir ve YDir sınıfları ile matematik, örneğin Java veya C ++, ham sayılarla matematikten daha yavaş olur mu? Anladığım kadarıyla Haskell'de, türler derleme zamanında kontrol edilir ve daha sonra çalışma zamanında, sadece tür kontrolü olmadan ham matematik olur ve bu nedenle normal sayılar eklemekten daha yavaş olmaz.
Ryan C. Thompson

C ++ 'da, tip kontrolü derleme zamanında da yapılır ve çoğu durumda dönüştürme ve benzeri işlemler en iyi duruma getirilir. Java bunu da yapmaz, çünkü operatörün aşırı yüklenmesine izin vermez ve böyle bir şey yapar - XCoordinateörneğin normal bir int gibi davranamazsınız.
cHao

5

"Macar Notasyonu" ifadesinin aslından farklı bir şey ifade ettiği anlaşılıyor , ancak soruya "hayır" cevabını vereceğim. Değişkenleri semantik veya hesaplamalı türlerle adlandırmak SML veya Haskell tarzı yazarak aynı şeyi yapmaz. Bandaj bile değil. C'yi bir örnek olarak alarak, bir gpszTitle değişkenini adlandırabilirsiniz, ancak bu değişkenin global kapsamı olmayabilir, hatta boş sonlandırılmış bir dizeye bir nokta bile oluşturmayabilir.

Daha modern Macar notasyonlarının güçlü bir türden kesinti sisteminden daha büyük bir sapma olduğunu düşünüyorum, çünkü "anlamsal" bilgileri (global için "g" veya bayrak için "f" gibi) hesaplama tipiyle ("p" pointer ") karıştırıyorlar. i "integer, etc vs.) Değişken isimlerinin sadece hesaplama türlerine (zaman içinde değişen) belirsiz benzerlik gösterdiği ve zamanla değişen" hepsi bir sonraki maç "kullanamayacak kadar benzer göründüğü, acımasız bir karışıklık olarak sona erer. Belirli bir fonksiyonda bir değişken bulmak - hepsi aynıdır.


4

Macar notasyonu BCPL için yazılmış, hiç türü olmayan bir dil icat edildi. Veya daha doğrusu, kelimenin tam olarak bir veri türü vardı. Bir kelime bir işaretçi olabilir veya nasıl kullandığınıza bağlı olarak bir karakter veya boolean veya düz bir tam sayı olabilir. Açıkçası bu, bir karakterin düzenlemesini kaldırma gibi korkunç hatalar yapmayı çok kolaylaştırdı. Böylece Macar notasyonu icat edildi, böylece programcının en azından koda bakarak manuel tip kontrolü yapabildi.

BCPL'nin soyundan gelen C, tamsayılar, işaretçiler, karakterler vb. İçin farklı türlere sahiptir. ancak bu seviyenin ötesindeki anlambilim hala tür olarak ifade edilememiştir. Bu, "Sistemler" denilen ile Macarca "Uygulamalar" olarak adlandırılanlar arasındaki farka neden olur. Bir değişkenin int olduğunu ifade etmenize gerek yoktu, ancak int'in bir x veya y koordinatı mı yoksa bir dizin mi olduğunu belirtmek için kod harfleri kullanabilirsiniz.

Daha modern diller, özel tür tanımlarına izin verir; bu, türlerdeki anlamsal kısıtlamaları değil, değişken adlarını kodlayabileceğiniz anlamına gelir. Örneğin, tipik bir OO dili koordinat çiftleri ve alanlar için belirli tiplere sahip olacaktır, bu nedenle bir y koordinatına x koordinatı eklemekten kaçınırsınız.

Örneğin, Joels'ın Apps Macarca'yı öven ünlü makalesinde , HTML enjeksiyonunu önlemek için usgüvenli olmayan bir dize ve sgüvenli (html kodlu) bir dize için önek örneğini kullanır . Geliştirici, HTML-enjeksiyon hatalarını basitçe dikkatlice inceleyerek kodu önleyebilir ve değişken öneklerin eşleşmesini sağlayabilir. Örneği, başlangıçta özel sınıflara izin vermeyen eski bir dil olan VBScript'te. Modern bir dilde sorun özel bir türle çözülebilir ve aslında Asp.net'in HtmlStringsınıfla yaptığı şey budur . Bu şekilde derleyici otomatik olarak hatayı bulacaktır, bu da insan göz küresine dayanmaktan daha güvenlidir. Bu yüzden açıkça, özel tiplere sahip bir dil, bu durumda "Apps Macarca" ihtiyacını ortadan kaldırır.


2

Evet, yeteri kadar güçlü tipte sistemleri olan birçok dilde hala problem var - mevcut tiplere dayanan / benzer yeni tiplerin anlaşılabilirliği.

Örneğin, yazım sistemini daha fazla kullanabileceğimiz birçok dilde kullanmıyoruz çünkü temelde ad dışında mevcut bir tür ile aynı olan yeni bir tür ek yükü ve birkaç dönüşüm işlevi çok büyük.

Temel olarak, bu dillerde iyice macarca notasyonu öldürmek için bir nevi yazılan tip tanımlarına ihtiyacımız var (F # stili UoM de yapabilir)


2

Unutmayın, IDE'lerin ne tür bir değişken olduğunu size söyleyen açılır pencere ipuçlarına sahip olmadığı bir zaman vardı. IDE'lerin düzenlemekte oldukları kodu anlamadıkları bir zamandı, bu yüzden kullanımdan kolayca bildirime geçemezsiniz. Ayrıca, kod tabanının tamamını el ile geçmeden, el ile değişiklik yaparak bir tanesini kaçırmadan umudunuzu değiştirmeden bir değişken adını yeniden adlandıramayacağınız bir zaman vardı. Arama ve değiştirme özelliğini kullanamazsınız, çünkü Müşteri’de arama yapmak MüşteriName’yi de alır ...

O karanlık günlerde, hangi tip bir değişkenin kullanıldığını bilmek yardımcı oldu. Düzgün bir şekilde bakımı yapılırsa (yeniden düzenleme araçlarının bulunmaması nedeniyle BÜYÜK ise) Macar notasyonu size bunu verdi.

Ürettiği korkunç isimlerin bu günlerde maliyeti çok yüksek ama bu nispeten yeni bir şey. Açıkladığım IDE gelişmelerinden önce bir sürü kod var.


1
Yanılmıyorsam, bu OP'nin sorduğu dilden farklı türde bir Macar gösterimini ele alan başka bir cevap.
MatrixFrog 11:11

2
Bu cevap, önek dil düzeyinde "tür" anlamına gelen "Sistem Macarcası" olarak adlandırılan şeyi açıklar. Soru, "tip" kelimesinin yanlış anlaşılmadığı ve anlamsal tip anlamına geldiği "Uygulamalar Macarca" hakkında soruyor . Macarca Sistemler bugünlerde neredeyse evrensel olarak kınandı (ve haklı olarak; Macar noterinin asıl amacının temelini oluşturuyor). Uygulamalar Macarca, ancak, iyi bir şey olabilir.
cHao

SCustomerName seçmeden sCustomer'ı arayabilen editörler (vi ve emacs 2 örnektir) 70'lerden beri var.
Larry Coleman

@Larry, belki, ama onları 80'lerde programladığım sistemlerde çalıştırmalarını
sağlayamadın

@chao, hayır değil - amacım insanların neden ekstra bilgileri genellikle değişken isimlerine koyduğunu açıklamaya çalışıyordu. Macar gösteriminin herhangi bir versiyonundan bahsetmeden dikkatli bir şekilde kaçtım. Belki de neden "ara ve değiştir kaynak kodunda çalışmıyor" bölümünde verdiğim örnek "Systems Hungarian" adlı bölüme benziyor, ancak bunun anlamı değildi. Karışıklığı önlemek için önde gelen "ler" i sildim.
mcottle

0

Doğru!

Assembler gibi tamamen yazılmamış dillerin dışında, Macar notasyonu gereksiz ve can sıkıcıdır. Kuşkusuz, çoğu IDE'nin tür güvenliğini kontrol ederken, türünü seçtiğinizi düşünün.

"İ" "d" ve "?" önekler sadece kodu daha az okunabilir hale getirir ve gerçekten de yanıltıcı olabilir - bir "inek-orker" iaSumsItems türünü Tamsayı'dan Uzun'a değiştirir ancak alan adını değiştirmeyi zahmet etmez.


9
Yanıtınız, orijinal, akıllı "Uygulamalar" Macarca ile Macarca "Sistemler" denilen aptal bastarizasyon arasındaki farkı anlamadığınızı gösteriyor. Okuma joelonsoftware.com/articles/Wrong.html
Ryan Culpepper
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.