Atama operatörü neden sol tarafa atanıyor?


47

Daha yeni bir arkadaş programlaması öğretmeye başladım (Python kullanıyoruz) ve değişken yaratma ve görevlendirme operatörünü tartışmaya başladığımızda, sağdaki değerin neden soldaki isme atandığını sordu; .

Bunu daha önce pek düşünmemiştim, çünkü bana doğal geldi, ama soldan sağa daha doğal göründüğünü, çünkü çoğumuzun doğal dilleri okuduğumuzu söyledi.

Bunu düşündüm ve kodun okunmasını çok kolaylaştırdığı sonucuna vardım, çünkü atanmış olan isimler (programcının tekrar kullanması gerekir) sola hizalı olarak kolayca görülebilir.

aligned = 2
on = 'foo' + 'bar' + 'foobar'
the = 5.0 / 2
left = 2 + 5

Aksine:

2 = aligned 
'foo' + 'bar' + 'foobar' = on
5.0 / 2 = the 
2 + 5 = right 

# What were the names again...?

Şimdi merak ediyorum bu standart için başka sebepler de var mı. Arkasında bir geçmiş var mı? Yoksa bunun iyi bir seçenek olmasının teknik bir nedeni var mı (derleyiciler hakkında fazla bir şey bilmiyorum)? Ve sağ tarafa atanan herhangi bir programlama dili var mı?


15
R sağ tarafa atayabilir ( value -> variable).
Sen

Belki de bu kötü değişken isimlerinden kaynaklanmaktadır? 'NumAligned 2' ve 'chickensLeft 2 + 5' olur mu?
İş

18
Arkadaşının adı ... Yoda mı?
Adrian,

1
Bu konuda tartışmaya başlarsa, C ++ ve ortaklarını görünce ne yapacağını merak ediyorum.
Blackberry

3
Sadece bir not: Khan Academy'nin Python'da yeni başlayan programcılar için bazı dersleri var: khanacademy.org/#computer-science ve Google'da daha gelişmiş olanlar: code.google.com/edu/languages/google-python-class/set- up.html
lindon fox

Yanıtlar:


56

Aynen @ paxdiablo. İlk programlama dilleri matematikçiler tarafından yazılmıştı - aslında hepsi vardı. Matematikte, kendi ilkesiyle - soldan sağa okuma - çalışma şekli anlamlıdır.

x = 2y - 4.

Matematikte şunu söylersiniz: x, 2y -4'e eşit olsun.

Ayrıca, cebirde bile bunu yaparsınız. Bir değişken için bir denklem çözdüğünüzde, çözmekte olduğunuz değişkeni sol tarafa izole edersiniz. yani, y = mx + b;

Ayrıca, C ailesi gibi bütün bir dil ailesinin belirli bir sözdizimi olduğundan, değişmesi daha maliyetlidir.


19
@FarmBoy: Matematikte atama ve eşitlik Aynı şeydir, çünkü bilgisayarda olduğu gibi bir formülde sıra yoktur. (a eşittir b, aynı zamanda b eşittir a)
Petruza

1
@FB, örneğin Erlang gibi bazı tekli işlevsel diller hariç Atama ve Eşitlik sağlama matematikteki ile aynıdır
Peer Stritzinger

18
@Petruza Hayır, matematikte atama ve eşitlik aynı şey değildir. Eğer 'x = 2y - 3' diyelim, 'Böylece x = 2y - 3' den farklı. Matematik, genellikle bağlam onları farklılaştırır. Bana itiraz eden yorum çok evrensel olarak kabul edildiğinden, doktora derecesine sahip olduğumu söyleyeceğim. matematikte bundan oldukça eminim.
Eric Wilson

2
Bir doktora yakınının hiçbir yerinde matematiği tanımıyorum, sıralı olmadığım için, bir ödevin her iki tarafının da yapılabileceği programlamadan farklı olarak, bir ödevde veya bir eşitlik içerisinde matematikte yürütme sırası bulunmadığıdır. zamanın bir noktasında farklı, zamanın başka bir noktasında eşit olmak zorundalar. Ancak matematikte, let a be...zaman yokmuş gibi bir =
ödevde

5
@Petruzza - ama orada olduğunu sıralı yayınlanabilme. Matematiksel belgeler baştan sona yazılır, diğer belgelerle aynıdır. Birinci x = 1bölümde ileri sürdüğümde , ancak ikinci x = 2bölümde ileri sürdüğümde , bu büyük bir çelişki değildir - her iddia sadece belirli bir bağlamda uygulanır. Zorunlu programlamadaki fark, kısmen bir engelin kaldırılması (bağlamsal bir değişikliğe ihtiyacımız yok) ve kısmen uygulama ve kullanışlılıkla ilgilidir.
Steve314

26

BASICen eski bilgisayar dillerinden biri "uygun" biçimine sahipti:

10 LET AREA = HEIGHT * WIDTH

"H nesnenin yüksekliği olsun" gibi bir değişken belirtmenin matematiksel zihniyetiyle eşleşir.

COBOLCOMPUTEifadesiyle de benzerdi . Birçok şeyi yapmanın yollarında olduğu gibi, birçok dilde iletilen keyfi bir karar olabilir.


7
Sanırım bu formlar, program satırları "işlemler" yerine "ifadeler" olarak değerlendirildiğinde daha doğal. Gibi I declare that X must equal THIS, daha doğrusal yerineEvaluate THIS and store it in X
voithos

Bekle, BASIC 'erken' bir bilgisayar dili miydi?
Alex Feinman

2
@Alex 1960'lı yıllardan itibaren zarar gördüğünü düşünürsek, oldukça erken olduğunu söyleyebilirim.
Ben Richards,

1
Öte yandan, COBOL'da yazabildiğiniz MULTIPLY HEIGHT BY WIDTH GIVING AREAiçin sonucu alan değişken ifadenin en sağ tarafındadır.
user281377

25

Aslında, sağ tarafa atanan bir programlama dili var: TI-BASIC ! Sadece bu değil, aynı zamanda atama operatörü olarak '=' kullanmaz, fakat "STO" operatörü olarak bilinen bir ok kullanır.

örnekler:

5→A
(A + 3)→B
(A - B)→C

Yukarıdaki örnekte, üç değişken bildirilmiş ve değerler verilmiştir. A, 5, B, 8 ve C, -3 olacaktır. İlk bildirim / ödev, '5 numaralı mağazayı A' olarak okuyabilir.

Neden TI-BASIC'in atamak için böyle bir sistem kullandığına göre, bunun bir hesap makinesi için bir programlama dili olduğu için onu kullanıyorum. TI hesaplayıcılarındaki "STO" operatörü, bir sayı hesaplandıktan sonra normal hesap makinesi işlemlerinde en sık kullanılandır . Kullanıcının hatırlamak istediği bir sayı olsaydı, "STO" düğmesine basacaktı ve caclulator bir isim isteyecekti (tuş vuruşlarının rakam yerine harfleri üretmesi için otomatik olarak alfa kilidini devreye sokmak için):

Sin(7 + Cos(3))
                    -.26979276
Ans→{variable name}
                    -.26979276

ve kullanıcı, seçtikleri ne olursa olsun değişkeni adlandırabilir. Alfa kilidini açmanız gerekiyorsa, adı yazın, sonra "STO" tuşuna basın ve "Ans" tuşuna basılması normal işlemler için çok hantal olurdu. Tüm hesap makinesi fonksiyonları TI-BASIC'te mevcut olduğundan, diğer dillerin çoğuyla karşılaştırıldığında geriye doğru da olsa, "STO" olarak başka hiçbir atama operatörü eklenmedi.

(Fıkra: TI-BASIC öğrendiğim ilk dillerden biriydi, bu yüzden üniversitede Java'yı ilk öğrendiğimde LEFT'ye atamanın olağandışı ve 'geriye doğru' olduğunu hissettim!)


+1 Bunu tamamen unuttum! TI Basic de benim ilk dilimdi, ama bu ayrıntıyı hatırlamıyorum.
barjak

Aslında STO operatörü, makinenin nasıl çalıştığına ve herhangi bir dilin nasıl çalıştığına daha yakın. Değer önce hesaplanır ve sonra hafızaya kaydedilir.
Kratz

15

Sezgisel 1: Dil tasarlarken bir şeyi yapmanın birden fazla yolu ile karşılaşıldığında, en yaygın, en sezgisel olanı seçin, yoksa Perl + ile bitirdiniz.

Şimdi, nasıl daha doğal (en azından İngilizce konuşanlar için)? Nasıl İngilizce şeyler yazdığımızı / söylediğimize bir bakalım:

Steven şimdi 10 yaşında (şu anda 10 yaşında Steven'ın aksine). 190 kilonun üzerinde ağırlıktayım (tartığım 190 kilonun aksine).

Kodunda:

steven = 10
i > 190

Aşağıdakiler ayrıca daha doğal geliyor:

"Mary 18 yaşındaysa, o zaman bir şeker alabilir". "Eğer 21 yaşından küçüksem, erkek kardeşimden yanımda tekila isteyeceğim".

if (mary == 18) { ... }
if (i < 21) { ... }

daha:

"Eğer 18 yo Mary ise ..." "21 yaşımdan büyükse ..."

Şimdi kod:

if (18 == mary) { ... }
if (21 > i) { ... }

Bunun programcılar veya İngilizce konuşanlar için doğal olmadığını unutmayın. Cümleler yoda-speak gibi ses çıkarır ve kod takma yoda-koşuludur. Bunlar C ++ 'da yardımcı olabilir, ancak çoğu insanın hemfikir olacağından eminim: bir derleyici ağır kaldırma işlemini yapabilir ve yoda koşullarına olan ihtiyacı azaltabilirse, yaşam biraz daha kolay olacaktır.

Tabii ki, biri her şeye alışabilir. Örnek olarak, 81 sayısı şöyle yazılmıştır:

Seksen Bir (İngilizce) Seksen ve bir (İspanyolca) Bir ve Seksen (Almanca).

Sonunda 4 var! = 24 "Rusça yeşil elma masasında yatıyor" demenin geçerli yolları - sıra (neredeyse) farketmez, 'on' ile 'table' ile birlikte gelmesi dışında. Yani, eğer anadili bir Rus konuşmacıysanız (örneğin), o zaman birinin yazıp yazmamasından a = 10ya da 10 = aher ikisinin de aynı derecede doğal görünmesinden dolayı umursamayabilirsiniz .

Dilbilim büyüleyici bir konu olsa da, resmen hiç okumamıştım ve pek fazla dil bilmiyorum. Umarım yine de yeterince karşı örnek verdim.


4
... ve Fransızca, 81 "dört kez yirmi bir" olarak söylenir ... :)
Martin Sojka

1
@ Martin, ingilizcenin çok benzer olduğuna inanıyorum.
bir CVn

7
@Martin Bu gerçekten garip, çünkü dört kez yirmi biri 84.
Peter Olson

6
@Peter: parantezinizi yanlış (four times twenty) one
yaptınız

4
@Job: "18 yaşında bir Mary ise ..." kitabını okumak, kaçınılmaz olarak Yoda'ya "Dokuz yüz yaşındayken ulaşamayacağın kadar iyi görünüyorsun, değil mi?" Demişti. Jedi'nin
Dönüşünde

11

1950'lerde FORTRAN ile başladı. FORTRAN'ın FORmula TRANslasyonunun bir kısaltması olduğu zaman - söz konusu formüller, geleneksel olarak her zaman sola atayan basit cebirsel denklemlerdir.

Öte yandan, yakın çağdaş COBOL, İngiliz gibiydi ve sağa tayin edildi (çoğunlukla!).

MOVE 1 TO COUNTER.
ADD +1 TO LINE-CNT.
MULTIPLY QTY BY PRICE GIVING ITEM-PRICE.

Bunun en iyi örnek olduğunu düşünüyorum çünkü ortak bir İngilizce konuşmacının okunabileceği bir dilde bir bağlamı mükemmel bir şekilde gösteriyor; Bunun önemli olduğunu inanıyorum ki, çok sayıda insan ingilizce olarak sadece ödevin anlam kazanması için soldan sağa okunacağını söylüyor, bu kesinlikle doğru değil.
Joshua Hedges

5

@ Diceguyd30'un işaret ettiği gibi, her ikisi de işarettedir.

  • <Identifier> = <Value>vasıta "let Tanıtıcı olmak Değeri ". Ya da genişletmek için: değişken tanımlayın (veya yeniden tanımlama) Tanıtıcı için Değer .
  • <Value> -> <Identifier>vasıta "mağaza Değer için Tanımlayıcısı'nın ". Put: Ya da genişletmek için Değerini tarafından belirlenen konuma Tanımlayıcısı'nın .

Elbette, genel olarak Tanımlayıcıyı konuşmak aslında herhangi bir L-değeri olabilir.

İlk yaklaşım, değişkenlerin soyut kavramını onurlandırırken, ikinci yaklaşım gerçek depolama hakkındadır.

İlk yaklaşımın, ataması olmayan dillerde de yaygın olduğunu unutmayın. Ayrıca değişken tanımı ve atama nispeten yakın olduklarını unutmayın <Type> <Identifier> = <Value>vs <Identifier> = <Value>.


3

Daha önce de belirtildiği gibi, oldukça eski tüm bilgisayar dilleri bu şekilde çalıştı. BASIC'den yıllar önce gelen FORTRAN.

Atama değişkeninin atama ifadesinin solunda olması gerçekten mantıklı geliyor. Bazı dillerde, SAME NAME ile birlikte farklı sonuç türlerine neden olan birkaç farklı aşırı rutine sahip olabilirsiniz. Derleyiciye önce atanan değişkenin türünü görmesine izin vererek, hangi aşırı yüklü rutinin çağrılacağını veya (örneğin) bir tamsayıdan bir şamandıraya dönüştürürken ne tür bir döküm oluşturulacağını bilir. Bu biraz basit bir açıklama, ama umarım fikri anlarsın.


2
Açıklamanızı anlıyorum, ancak derleyici ifadenin sonuna kadar sadece ileriye bakamaz mıydı?
voithos

Bu, lexer'ı günümüz dillerinde daha basit hale getirebilir, ancak kaç tane programlama dili bile bu tür bir sözdizimi yeniyken, yöntem aşırı yüklense bile, adlandırılmış yöntemleri bile kaç programlama dili destekleyebilir?
bir CVn

2
Merhaba @voithos. Evet - derleyici ileriye bakabilirdi, ancak bu muhtemelen derleyici yazmanın ilk günlerinde kabul edilemez bir karmaşıklık düzeyi olurdu - genellikle elle kodlanmış bir montajcıydı! Atanan değişkeni sola koymanın pragmatik bir seçim olduğunu düşünüyorum: hem insanın hem de makinenin ayrıştırması daha kolay.
Dave Jewell

Bir görevin sağa atamasının önemsiz olacağını düşünüyorum. 3 + 4 == 6 + 7 gibi bir ifade kullanıldığında, her iki taraf operatörden önce değerlendirilir, çünkü dil özyinelemeli olarak tanımlanır. 'Değişken = expression' dil öğesi kolayca 'expression = değişken' olarak değiştirilebilir. Bunun belirsiz durumlara yol açıp açmadığı dilin geri kalanına bağlıdır.
Kratz

@Kratz - şimdi derleyiciler için kesinlikle doğru, ancak tokenize edilmiş kaynaklarla çalışan çok eski yorumlanmış diller için küçük bir sorun olabilir. Soldaki değişken yerine sağdaki değişkeni tercih etmiş olabilecek OTOH.
Steve314

3

Erken ayrıştırma algoritmalarının bir kalıntısı olabilir. LR ayrıştırma işleminin yalnızca 1965'te icat edildiğini ve LL ayrıştırıcılarının (o sırada makinelerin zaman ve mekan sınırlamaları dahilinde) tersine gitmekte zorlanabileceğini unutmayın. Düşünmek:

identifier = function();
function();

İkisi açıkça ikinci belirteçten ayrılıyor. Diğer yandan,

function() = identifier;
function();

Eğlenceli değil. Atama ifadelerini yuvalamaya başladığınızda bu daha da kötüleşir.

function(prev_identifier = expression) = identifier;
function(prev_identifier = expression);

Tabii ki, makineler için netleştirilmesinin daha kolay olması aynı zamanda insanlar için netleştirilmesinin daha kolay olması anlamına da gelir. Başka bir kolay örnek verilen herhangi bir tanımlayıcının başlatılmasının araştırılmasıdır.

identifier1 = expressionOfAnArbitraryLength;
identifier2 = expressionOfAReallyReallyReallyArbitraryLength;
identifier3 = expression;
identifier4 = AlongLineExpressionWithAFunctionCallWithAssignment(
    identifier = expr);

Kolay, sadece sol tarafa bak. Diğer taraftan sağ taraf

expressionOfAnArbitraryLength = identifier1;
expressionOfAReallyReallyReallyArbitraryLength = identifier2;
expression = identifier3;
AlongLineExpressionWithAFunctionCallWithAssignment(expr = identifier
    ) = identifier4;

Özellikle de grepkartlara yumruk atamazsanız, istediğiniz tanımlayıcıyı bulmak daha zordur.


Tam olarak düşündüğüm nokta, evet.
voithos,

2

Montaj dilleri , hedefin sol taraftaki kodunun bir parçası olarak var. Daha yüksek seviyeli diller, önceki dillerin sözleşmelerini takip etme eğilimindeydi.

Gördüğünüz zaman =(ya da :=Pascalish lehçeleri için), bunları sorabilirsiniz is assigned the value, o zaman soldan sağa doğru bir anlam ifade eder (çünkü çoğu dilde soldan sağa okuduk). Programlama dilleri ağırlıklı olarak soldan sağa okuyan insanlar tarafından geliştirildiğinden, sözleşmeler sıkışmış.

Bu bir çeşit yol bağımlılığıdır . Sanırım bilgisayar programlaması İbranice ya da Arapça konuşanlar (ya da başka bir sağdan sola) konuşan kişilerce icat edilmişse, o zaman hedefi sağa koyacağımızdan şüpheleniyorum.


Evet, ama editörlerin içindeki metnin de aynı hizada olacağından şüpheliyim ...
voithos

8
Assembly dilleri hakkında böyle genelleme yapamazsınız. Hedef işlenenin nerede olduğuna göre değişir.
Çabuk_şimdi

2
@quickly_now: doğru; Aslında, ilkel makine dillerinin çoğu (bugünün standartlarına göre montajcılar bile), genellikle sadece bir ya da iki genel amaçlı akümülatör olduğundan, hedefi bile yoktu. işlemlerin çoğu, yalnızca bellek adresini belirten ve kaynağın (akümülatör olan) değil, yalnızca bellek adresini belirten 'mağaza' kodları dışında, akümülatörü hedef olarak ima etti. ALGOL benzeri diller için atama sözdizimi üzerinde herhangi bir etkisinin olduğunu sanmıyorum.
Javier,

3
@Tangurena - Bazı assembler dilleri solda kalmıştır. Opcode'dan değil (birleştirilmiş nesne kodu), ancak anımsatıcı komutu için argümanlar listesinin solunda. Ancak, diğerlerinde sağdaki hedef var. 68000 assembler’da, mov.b #255, d0örneğin, d0atanacak kaydın nerede olduğunu yazarsınız . Daha eski montajcılar talimat başına yalnızca tek bir argümana sahiptir. 6502'de LDA #255(Load Accumulator), Asolda olduğunu iddia edebilirsiniz , fakat solda da STA wherever(Store Accumulator).
Steve314

2
Üstelik, Intel 4004 (8086 ailesinin 4 bitlik nihai atası, aralarında 8008 ve 8080) bile , yüksek seviyeli dillere atandıktan sonra geliştirildi . 8086 serisinin montajcıların 50'li ve daha önceki yıllarda ne yaptığını temsil ettiğini varsayarsanız, bunun doğru olduğundan çok şüpheliyim.
Steve314

2

İki işlenen gibi, son ilk adlandırılmış ve hedef alındı yüzden, soldan sağa doğru ne anlama yetmeyecek için, COBOL en ifadeleri okuyun: multiply salary by rate giving tax.

Ancak, bu kadar alçakgönüllü, tatsız bir tatsız yorum yapmak için (oldukça haklı olarak) işaretleneceğim korkusundan dolayı öğrencinize COBOL'u tercih edebileceğini söyleyemem! :-)


1

Soldan sağa daha doğal göründüğünü, çünkü çoğumuzun doğal dilleri okuduğunu söyledi.

Bence bu bir hata. Bir yandan, "10'a x atayın" veya "10'a x'e taşı" diyebilirsiniz. Öte yandan, "x'i 10'a ayarla" veya "x 10 olur" diyebilirsiniz.

Başka bir deyişle, seçtiğiniz fiile bağlı olarak, atanan değişken özne olabilir veya olmayabilir veya solda olabilir veya olmayabilir. Bu yüzden, "doğal olan", tamamen ödevi temsil etmek için alışılmış ifadeler seçiminize bağlıdır.


0

Sahte kodda atama operatörü sağda çok sık yazılır. Örneğin

2*sqrt(x)/(3+y) -> z

Casio hesap makinelerinde, programlanamayan değişkenlerde bile, atama değişkeni sağda da görüntülenir.

A+2B → C

Forth'da değişken de sağdadır

expression variable !

X86'da, Intel sözdizimi solda bir hedefe sahip, ancak GAS sözdizimi sırayı tersine çevirerek birçok insan için, özellikle de çıkarma veya karşılaştırma gibi parametrelerin sırası ile ilgili talimatlarda karışıklık yaratıyor. Bu talimatlar 2 farklı lehçede aynıdır

mov rax, rbx    ; Intel syntax
movq %rbx, %rax ; GAS syntax

İkisi de rbx'deki değeri rax'e taşır. Başka hiçbir montaj dili bilmiyorum GAS gibi sağdaki hedefi yaz.

Bazı platformlar ifadeyi sola ve değişkeni sağa koyar:

MOVE expression TO variable      COBOL
expression → variable            TI-BASIC, Casio BASIC
expression -> variable           BETA, R
put expression into variable     LiveCode

https://en.wikipedia.org/wiki/Assignment_%28computer_science%29#Notation

Çoğu dil soldaki değeri atar, operatörlerin hizalanmasının kolay olmasının nedenlerinden biri, atanan operatörlerin ve değişkenlerin konumlarının satırlar arasında çılgınca değişmeyeceği ve değişkenleri çılgınca değişmediği için, değeri sola atar. msgstr "değişken biraz değer olsun".

Ancak bazı insanlar "x değerini y ye taşı" demeyi ve değişkeni sağa yazmayı tercih ederler.


-1

Bence mantıklı bir düşünme şekli izliyor.
Önce bir kutu (değişken) olmalı, sonra içine bir nesne (değer) koymalısınız.
Nesneyi havaya kaldırmaz ve etrafına bir kutu koyarsın.


2
Evet yaparsın. Çoğu dilde sağ taraf soldakinden önce değerlendirilir.
Javier,

3
Onun bir "yolun sağ tarafında sürüş" bir şey. Mantıklı görünüyor, ancak sadece her zaman yaptığınız gibi. Üstün ülkeler soldan ilerliyor.
James Anderson,

1
@JamesAnderson üstün ülkeler? : o
nawfal

Haklısın, soldan sağa yazma sisteminin, hepsi olmasa da hemen hemen her programlama dili tarafından kullanıldığı sanırım roma alfabesi olarak kullanılması mantıklı.
Petruza
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.