Öz (programlama dili) - Self (programming language)

öz
Logo
paradigma nesne yönelimli ( prototip tabanlı )
Tarafından tasarlandı David Ungar , Randall Smith
geliştirici David Ungar, Randall Smith, Stanford Üniversitesi , Sun Microsystems
İlk ortaya çıktı 1987 ; 34 yıl önce ( 1987 )
kararlı sürüm
Mandarin 2017.1 / 24 Mayıs 2017 ; 4 yıl önce ( 2017-05-24 )
Yazma disiplini dinamik , güçlü
Lisans BSD benzeri lisans
İnternet sitesi www .selflanguage .org
Başlıca uygulamalar
öz
Tarafından etkilenmiş
Küçük konuşma , APL
Etkilenen
NewtonScript , JavaScript , Io , Agora , Squeak , Lua , Factor , REBOL

Self , prototip kavramına dayanan nesne yönelimli bir programlama dilidir . Self, Smalltalk'ın bir lehçesi olarak başladı , dinamik olarak yazıldı ve tam zamanında derleme (JIT) ile nesnelere prototip tabanlı yaklaşımı kullandı: ilk olarak 1980'lerde ve 1990'larda dil tasarımı için deneysel bir test sistemi olarak kullanıldı. . 2006'da Self, tamamen Self ile yazılmış bir Self sanal makinesi olan Klein projesinin bir parçası olarak hala geliştiriliyordu. En son sürüm 2017.1 Mayıs 2017'de yayınlandı.

Çok yüksek düzeyde nesne yönelimli bir dilin optimize edilmiş C'nin yarı hızında çalışmasına izin vermeleri gerektiğinden, Self araştırmasında birkaç tam zamanında derleme tekniğine öncülük edildi ve geliştirildi. Self'in gelişiminin çoğu Sun'da gerçekleşti. Microsystems ve geliştirdikleri teknikler sonrası için konuşlandırılan Java 'nın HotSpot sanal makine .

Bir noktada Self'te Smalltalk'ın bir sürümü uygulandı. JIT'i kullanabildiği için, bu da son derece iyi bir performans verdi.

Tarih

Self, daha çok David Ungar ve Randall Smith tarafından 1986'da Xerox PARC'ta çalışırken tasarlandı . Smalltalk-80 laboratuvarlar tarafından piyasaya sürüldüğünde ve endüstri tarafından ciddiye alınmaya başladığında, amaçları nesne yönelimli programlama dili araştırmalarındaki en son teknolojiyi ilerletmekti . Stanford Üniversitesi'ne taşındılar ve 1987'de ilk çalışan Self derleyicisini kurarak dil üzerinde çalışmaya devam ettiler. Bu noktada odak, sadece dil yerine Self için tüm bir sistemi ortaya koyma girişimine dönüştü.

İlk halka açık sürüm 1990'da yapıldı ve sonraki yıl ekip , dil üzerinde çalışmaya devam ettikleri Sun Microsystems'e taşındı . Birkaç yeni sürüm, 1995'te 4.0 sürümüyle büyük ölçüde uykuda olana kadar izledi. 4.3 sürümü 2006'da piyasaya sürüldü ve Mac OS X ve Solaris'te çalıştı . 2010'da yeni bir sürüm olan sürüm 4.4, bazı orijinal ekip ve bağımsız programcılardan oluşan bir grup tarafından geliştirilmiştir ve sonraki tüm sürümlerde olduğu gibi Mac OS X ve Linux için mevcuttur. 4.5 sürümü Ocak 2014'te yayınlandı ve üç yıl sonra 2017.1 sürümü Mayıs 2017'de yayınlandı.

Self ayrıca kavramlarına dayalı olarak bir dizi dile ilham verdi. Belki de en dikkate değer olanı , Apple Newton için NewtonScript ve tüm modern tarayıcılarda kullanılan JavaScript idi . Diğer örnekler arasında Io , Lisaac ve Agora sayılabilir . IBM Tivoli Çerçeve 1990 yılında geliştirilen 'ın dağıtık nesne sistemi, düşük seviyede, Öz esinlenerek bir prototip tabanlı nesne sisteminde, oldu.

Prototip tabanlı programlama dilleri

Geleneksel sınıf tabanlı OO dilleri, köklü bir ikiliğe dayanır:

  1. Sınıflar , nesnelerin temel niteliklerini ve davranışlarını tanımlar.
  2. Nesne örnekleri , bir sınıfın belirli tezahürleridir.

Örneğin, Vehiclesınıftaki nesnelerin bir ada ve işe gitme ve inşaat malzemeleri teslim etme gibi çeşitli eylemleri gerçekleştirme yeteneğine sahip olduğunu varsayalım . Bob's carsınıfın Vehicle"Bob'un arabası" adlı belirli bir nesnesidir (örneği) . Teorik olarak Bob's car, inşaat malzemelerinin teslim edilmesini söyleyen bir mesaj gönderilebilir .

Bu örnek, bu yaklaşımla ilgili sorunlardan birini göstermektedir: Bob'un bir spor araba olan arabası, inşaat malzemelerini taşıyamaz ve teslim edemez (anlamlı bir anlamda), ancak bu, Vehiclesahip olmak için modellenen bir yetenektir . Daha kullanışlı bir model, aşağıdakilerin uzmanlıklarını oluşturmak için alt sınıflamanın kullanılmasından ortaya çıkar Vehicle; örneğin Sports Carve Flatbed Truck. Yalnızca sınıfın nesnelerinin, inşaat malzemelerinin teslimFlatbed Truck edilmesi için bir mekanizma sağlaması gerekir ; Bu tür işlere uygun olmayan spor arabaların sadece hızlı sürmesi gerekir . Bununla birlikte, bu daha derin model, tasarım sırasında daha fazla içgörü gerektirir; bu, yalnızca sorunlar ortaya çıktıkça ortaya çıkabilecek bir içgörüdür.

Bu konu, prototiplerin arkasındaki motive edici faktörlerden biridir . Uzak gelecekte bir dizi nesnenin ve sınıfın hangi niteliklere sahip olacağını kesin olarak tahmin edemedikçe, bir sınıf hiyerarşisini düzgün bir şekilde tasarlayamazsınız. Çoğu zaman program sonunda ek davranışlara ihtiyaç duyacaktır ve nesneleri farklı bir şekilde ayırmak için sistemin bölümlerinin yeniden tasarlanması (veya yeniden düzenlenmesi ) gerekecektir. Smalltalk gibi erken OO dilleriyle ilgili deneyimler , bu tür sorunların tekrar tekrar ortaya çıktığını gösterdi. Programcı kodunun altındaki temel sınıflar basitçe "yanlış" hale geldiğinden, sistemler bir noktaya kadar büyüme eğiliminde olacak ve daha sonra çok katı hale gelecektir. Orijinal sınıfı kolayca değiştirmenin bir yolu olmadan ciddi sorunlar ortaya çıkabilir.

Smalltalk gibi dinamik diller, sınıflarda iyi bilinen yöntemlerle bu tür değişikliklere izin verdi; sınıfı değiştirerek, ona dayalı nesneler davranışlarını değiştirirdi. Ancak, aynı sınıfa dayalı diğer nesneler bu "yanlış" davranışı bekleyebileceğinden, bu tür değişikliklerin çok dikkatli bir şekilde yapılması gerekiyordu: "yanlış" genellikle bağlama bağlıdır. (Bu, kırılgan temel sınıf sorununun bir biçimidir .) Ayrıca, alt sınıfların üst sınıflardan ayrı olarak derlenebildiği C++ gibi dillerde , bir üst sınıfa yapılan bir değişiklik aslında önceden derlenmiş alt sınıf yöntemlerini bozabilir. (Bu, kırılgan temel sınıf sorununun başka bir biçimi ve ayrıca kırılgan ikili arabirim sorununun bir biçimidir .)

Self ve diğer prototip tabanlı dillerde, sınıflar ve nesne örnekleri arasındaki ikilik ortadan kaldırılmıştır.

Bazı "sınıflara" dayanan bir nesnenin "örneğine" sahip olmak yerine, Self'de kişi mevcut bir nesnenin bir kopyasını yapar ve onu değiştirir. Böylece Bob's car, mevcut bir "Araç" nesnesinin bir kopyası oluşturularak ve ardından hızlı sürüş yöntemi eklenerek, bunun bir Porsche 911 olduğu gerçeği modellenerek oluşturulur . Öncelikle kopya yapmak için kullanılan temel nesneler prototipler olarak bilinir . Bu tekniğin dinamizmi büyük ölçüde basitleştirdiği iddia edilmektedir. Mevcut bir nesnenin (veya nesne kümesinin) yetersiz bir model olduğu ortaya çıkarsa, programcı doğru davranışa sahip değiştirilmiş bir nesne oluşturabilir ve bunun yerine bunu kullanabilir. Mevcut nesneleri kullanan kod değiştirilmez.

Tanım

Kendi kendine nesneler, bir "yuva" koleksiyonudur. Yuvalar, değerleri döndüren erişimci yöntemlerdir ve bir yuvanın adından sonra iki nokta üst üste koyarak değeri belirler. Örneğin, "ad" adlı bir yuva için,

myPerson name

adındaki değeri döndürür ve

myPerson name:'foo'

ayarlar.

Self, Smalltalk gibi akış kontrolü ve diğer görevler için bloklar kullanır . Yöntemler, yuvalara ek olarak kod içeren nesnelerdir (bunlar bağımsız değişkenler ve geçici değerler için kullanırlar) ve tıpkı diğer nesneler gibi bir Self yuvasına yerleştirilebilir: örneğin bir sayı. Sözdizimi her iki durumda da aynı kalır.

Self'de alanlar ve yöntemler arasında bir ayrım olmadığını unutmayın: her şey bir yuvadır. Slotlara mesajlar yoluyla erişim Self'deki sözdiziminin çoğunluğunu oluşturduğundan, birçok mesaj "self" e gönderilir ve "self" atlanabilir (dolayısıyla adı).

Temel sözdizimi

Yuvalara erişim sözdizimi Smalltalk'ınkine benzer. Üç tür mesaj mevcuttur:

tekli
receiver slot_name
ikili
receiver + argument
anahtar kelime
receiver keyword: arg1 With: arg2

Tüm mesajlar sonuç döndürür, bu nedenle alıcı (varsa) ve argümanların kendileri diğer mesajların sonucu olabilir. Bir mesajı bir nokta ile takip etmek, Self'in döndürülen değeri atacağı anlamına gelir. Örneğin:

'Hello, World!' print.

Bu, merhaba dünya programının Self versiyonudur . 'Sözdizimi değişmez bir dize nesnesini gösterir. Diğer değişmezler sayıları, blokları ve genel nesneleri içerir.

Gruplandırma parantez kullanılarak zorlanabilir. Açık gruplamanın yokluğunda, tekli mesajların en yüksek önceliğe sahip olduğu, ardından ikili (soldan sağa gruplama) ve en düşük anahtar kelimelerin geldiği kabul edilir. Atama için anahtar sözcüklerin kullanılması, ifadelerin anahtar sözcük mesajlarına da sahip olduğu bazı ekstra parantezlere yol açacaktır, bu nedenle Self'ten kaçınmak için bir anahtar sözcük ileti seçicisinin ilk bölümünün küçük harfle, sonraki bölümlerin büyük harfle başlamasını gerektirir.

valid: base bottom
          between: ligature bottom + height
          And: base top / scale factor.

açık bir şekilde ayrıştırılabilir ve şu anlama gelir:

valid: ((base bottom)
            between: ((ligature bottom) + height)
            And: ((base top) / (scale factor))).

Smalltalk-80'de aynı ifade şu şekilde yazılır:

valid := self base bottom
             between: self ligature bottom + self height
             and: self base top / self scale factor.

base, ligature, heightve öğelerinin örnek değişkenlerscale olmadığını , ancak aslında yöntemler olduğunu varsayarsak . self

Yeni nesneler yapmak

Biraz daha karmaşık bir örnek düşünün:

labelWidget copy label: 'Hello, World!'.

kopya mesajı ile "labelWidget" nesnesinin bir kopyasını yapar (bu sefer kısayol yok), ardından "Merhaba, Dünya"yı "label" adlı yuvaya koymak için bir mesaj gönderir. Şimdi onunla bir şeyler yapmak için:

(desktop activeWindow) draw: (labelWidget copy label: 'Hello, World!').

Bu durumda, (desktop activeWindow)ilk olarak gerçekleştirilir, etkin pencere , masaüstü nesnesinin bildiği pencereler listesinden döndürülür. Sonra (içten dışa, soldan sağa okuyun) daha önce incelediğimiz kod labelWidget'ı döndürür. Son olarak, widget aktif pencerenin çizim yuvasına gönderilir.

heyet

Teoride, her Self nesnesi bağımsız bir varlıktır. Self'in ne sınıfları ne de meta-sınıfları vardır. Belirli bir nesnede yapılan değişiklikler diğerlerini etkilemez, ancak bazı durumlarda etki etmesi istenir. Normalde bir nesne yalnızca yerel yuvalarına karşılık gelen mesajları anlayabilir, ancak ana nesneleri gösteren bir veya daha fazla yuvaya sahip olarak , bir nesne kendisini anlamadığı herhangi bir mesajı ana nesneye devredebilir . Herhangi bir yuva, bir sonek olarak bir yıldız işareti eklenerek bir üst işaretçi yapılabilir. Bu şekilde Self , sınıf tabanlı dillerde kalıtımı kullanacak görevleri yerine getirir . Yetkilendirme, ad alanları ve sözcüksel kapsam belirleme gibi özellikleri uygulamak için de kullanılabilir .

Örneğin, basit bir muhasebe uygulamasında kullanılan "banka hesabı" adlı bir nesnenin tanımlandığını varsayalım. Genellikle, bu nesne, içindeki yöntemlerle, belki de "para yatırma" ve "çekme" ile ve bunların ihtiyaç duyduğu herhangi bir veri yuvasıyla oluşturulur. Bu, tamamen işlevsel bir banka hesabı olduğu için yalnızca kullanım şekliyle özel olan bir prototiptir.

Özellikler

"Bob'un hesabı" için bu nesnenin bir klonunu yapmak, tam olarak prototip gibi başlayan yeni bir nesne yaratacaktır. Bu durumda, yöntemleri ve tüm verileri içeren yuvaları kopyaladık. Bununla birlikte, daha yaygın bir çözüm, ilk önce , normalde bir sınıfla ilişkilendirilecek öğeleri içeren, özellikler nesnesi adı verilen daha basit bir nesne yapmaktır .

Bu örnekte, "banka hesabı" nesnesi para yatırma ve çekme yöntemine sahip olmayacak, ancak ebeveyn olarak bunu yapan bir nesneye sahip olacaktır. Bu şekilde banka hesabı nesnesinin birçok kopyası yapılabilir, ancak yine de o kök nesnedeki yuvaları değiştirerek hepsinin davranışını değiştirebiliriz.

Bunun geleneksel bir sınıftan farkı ne? Şunun anlamını iyi düşünün:

myObject parent: someOtherObject.

Bu alıntı, çalışma zamanında 'ana*' yuvayla ilişkili değeri değiştirerek myObject'in "sınıfını" değiştirir (yıldız işareti, yuva adının bir parçasıdır, ancak karşılık gelen iletiler değildir). Devralma veya sözcüksel kapsam belirlemeden farklı olarak, temsilci nesnesi çalışma zamanında değiştirilebilir.

Slot ekleme

Self içindeki nesneler, ek yuvalar içerecek şekilde değiştirilebilir. Bu, grafiksel programlama ortamı kullanılarak veya ilkel '_AddSlots:' ile yapılabilir. Bir ilkel normal anahtar kelime mesajı olarak aynı sözdizimi vardır, ancak alt çizgi karakteri ile adından başlar. _AddSlots ilkel öğesinden kaçınılmalıdır, çünkü bu, ilk uygulamalardan kalmadır. Ancak kodu kısalttığı için aşağıdaki örnekte göstereceğiz.

Daha önceki bir örnek, arabalar ve kamyonlar arasındaki davranışı ayırt edebilmek için Vehicle adlı basit bir sınıfı yeniden düzenlemekle ilgiliydi. Öz'de kişi bunu şöyle bir şeyle başarabilir:

_AddSlots: (| vehicle <- (|parent* = traits clonable|) |).

'_AddSlots:' primitifinin alıcısı belirtilmediği için "self"dir. Komut isteminde yazılan ifadelerde bu, "lobi" adı verilen bir nesnedir. '_AddSlots:' argümanı, yuvaları alıcıya kopyalanacak olan nesnedir. Bu durumda, tam olarak bir yuvaya sahip gerçek bir nesnedir. Yuvanın adı 'araç' ve değeri başka bir değişmez nesnedir. "<-" notasyonu, ilk slotun değerini değiştirmek için kullanılabilecek 'araç:' adlı ikinci bir slotu ifade eder.

"=" sabit bir yuvayı belirtir, bu nedenle karşılık gelen 'ebeveyn:' yoktur. 'Araç'ın başlangıç ​​değeri olan gerçek nesne, klonlama ile ilgili mesajları anlayabilmesi için tek bir yuva içerir. (| |) veya daha basit olarak () olarak gösterilen gerçekten boş bir nesne hiçbir mesaj alamaz.

vehicle _AddSlots: (| name <- 'automobile'|).

Burada alıcı, artık 'ana*'ya ek olarak 'ad' ve 'ad:' yuvalarını içerecek olan önceki nesnedir.

_AddSlots: (| sportsCar <- vehicle copy |).
sportsCar _AddSlots: (| driveToWork = (''some code, this is a method'') |).

Önceden 'araç' ve 'sportsCar' tamamen aynı olsa da, şimdi ikincisi orijinalinde olmayan bir yöntemle yeni bir slot içeriyor. Yöntemler yalnızca sabit yuvalara dahil edilebilir.

_AddSlots: (| porsche911 <- sportsCar copy |).
porsche911 name:'Bobs Porsche'.

Yeni nesne 'porsche911' tam olarak 'spor Araba' gibi başladı, ancak son mesaj 'ad' yuvasının değerini değiştirdi. Biri farklı bir değere sahip olsa bile her ikisinin de tamamen aynı yuvalara sahip olduğunu unutmayın.

Çevre

Self'in bir özelliği, daha önceki Smalltalk sistemlerinin kullandığı aynı tür sanal makine sistemine dayanmasıdır . Yani programlar, C gibi dillerde olduğu gibi bağımsız varlıklar değildir , ancak çalışabilmeleri için tüm bellek ortamlarına ihtiyaç duyarlar. Bu, uygulamaların anlık görüntüler veya görüntüler olarak bilinen kayıtlı bellek parçaları halinde gönderilmesini gerektirir . Bu yaklaşımın bir dezavantajı, görüntülerin bazen büyük ve hantal olmasıdır; ancak, çalışma zamanı durumunun incelenmesi ve değiştirilmesi daha kolay olduğundan, bir görüntünün hatalarını ayıklamak genellikle geleneksel programların hatalarını ayıklamaktan daha basittir. (Kaynak tabanlı ve görüntü tabanlı geliştirme arasındaki fark, sınıf tabanlı ve prototipik nesne yönelimli programlama arasındaki farka benzer.)

Ayrıca ortam, sistemdeki nesnelerin hızlı ve sürekli değişimine göre uyarlanmıştır. Bir "sınıf" tasarımını yeniden düzenlemek, yöntemleri mevcut atalardan yenilerine sürüklemek kadar basittir. Test yöntemleri gibi basit görevler, bir kopya oluşturularak, yöntemi kopyaya sürükleyip ardından değiştirerek gerçekleştirilebilir. Geleneksel sistemlerden farklı olarak, yalnızca değiştirilen nesne yeni koda sahiptir ve test etmek için hiçbir şeyin yeniden oluşturulması gerekmez. Yöntem işe yararsa, basitçe ataya geri sürüklenebilir.

Verim

Kendi kendine VM'ler, bazı kıyaslamalarda optimize edilmiş C hızının yaklaşık yarısı kadar bir performans elde etti.

Bu, yüksek seviyeli bir dilin bunu iyi bir şekilde gerçekleştirmesini sağlamak için Öz araştırma alanında öncülük edilen ve geliştirilen tam zamanında derleme teknikleri ile sağlandı .

Çöp toplama

Çöp toplayıcı Öz için kullandığı kuşak çöp toplama yaşa göre nesneleri segregates. Sayfa yazmalarını kaydetmek için bellek yönetim sistemini kullanarak bir yazma engeli korunabilir. Bu teknik mükemmel performans sağlar, ancak bir süre çalıştıktan sonra önemli ölçüde zaman alan tam bir çöp toplama işlemi gerçekleşebilir.

Optimizasyonlar

Çalışma zamanı sistemi, çağrı yapılarını seçici olarak düzleştirir. Bu, kendi içinde mütevazı bir hızlanma sağlar, ancak farklı arayan türleri için tür bilgilerinin ve birden çok kod sürümünün kapsamlı bir şekilde önbelleğe alınmasına izin verir. Bu, birçok yöntem araması yapma ihtiyacını ortadan kaldırır ve koşullu dal ifadelerinin ve sabit kodlanmış çağrıların eklenmesine izin verir - genellikle dil düzeyinde genellik kaybı olmadan, ancak tamamen çöp toplanmış bir sistemde C benzeri performans verir.

Ayrıca bakınız

Referanslar

daha fazla okuma

Dış bağlantılar