Programmering Àr mer Àn kodning

Programmering Àr mer Àn kodning

Denna artikel Àr en översÀttning Stanford Seminarium. Men före henne en liten introduktion. Hur bildas zombies? Alla hamnade i en situation dÀr de vill dra upp en vÀn eller kollega till sin nivÄ, men det gÄr inte. Och det Àr inte sÄ mycket med dig som med honom som "det gÄr inte": pÄ ena sidan av skalan finns en normal lön, uppgifter och sÄ vidare, och pÄ den andra, behovet av att tÀnka. Att tÀnka Àr obehagligt och smÀrtsamt. Han ger snabbt upp och fortsÀtter skriva kod utan att slÄ pÄ hjÀrnan alls. Du förestÀller dig hur mycket anstrÀngning det krÀvs för att övervinna barriÀren av inlÀrd hjÀlplöshet, och du gör det bara inte. SÄ hÀr bildas zombies, som, det verkar, kan botas, men det verkar som om ingen kommer att göra det.

NĂ€r jag sĂ„g det Leslie Lamport (ja, samma kamrat frĂ„n lĂ€roböckerna) kommer till Ryssland och gör inte en rapport, utan en frĂ„gestund, var jag lite försiktig. För sĂ€kerhets skull Ă€r Leslie en vĂ€rldsberömd vetenskapsman, författare till grundlĂ€ggande verk inom distribuerad datoranvĂ€ndning, och du kan ocksĂ„ kĂ€nna honom genom bokstĂ€verna La i ordet LaTeX - "Lamport TeX". Den andra alarmerande faktorn Ă€r hans krav: alla som kommer mĂ„ste (helt kostnadsfritt) lyssna pĂ„ ett par av hans rapporter i förvĂ€g, komma med minst en frĂ„ga om dem och först dĂ€refter komma. Jag bestĂ€mde mig för att se vad Lamport sĂ€nde dĂ€r – och det Ă€r fantastiskt! Det Ă€r precis den saken, det magiska lĂ€nkpillret för att bota zombies. Jag varnar dig: frĂ„n texten kan Ă€lskare av superflexibla metoder och de som inte gillar att testa vad som skrivs, sĂ€rskilt brĂ€nna ut.

Efter habrokat börjar faktiskt översÀttningen av seminariet. Njut av att lÀsa!

Vilken uppgift du Àn tar dig an behöver du alltid gÄ igenom tre steg:

  • bestĂ€mma vilket mĂ„l du vill uppnĂ„;
  • bestĂ€mma hur du ska uppnĂ„ ditt mĂ„l;
  • komma till ditt mĂ„l.

Detta gÀller Àven programmering. NÀr vi skriver kod mÄste vi:

  • bestĂ€mma vad programmet ska göra;
  • bestĂ€mma hur den ska utföra sin uppgift;
  • skriv motsvarande kod.

Det sista steget Àr naturligtvis vÀldigt viktigt, men jag ska inte prata om det i dag. IstÀllet kommer vi att diskutera de tvÄ första. Varje programmerare utför dem innan de börjar arbeta. Du sÀtter dig inte ner för att skriva om du inte har bestÀmt dig för om du ska skriva en webblÀsare eller en databas. En viss uppfattning om mÄlet mÄste finnas. Och du funderar definitivt över vad exakt programmet kommer att göra, och skriver inte pÄ nÄgot sÀtt i hopp om att koden pÄ nÄgot sÀtt ska förvandlas till en webblÀsare.

Hur exakt gÄr det hÀr koden för tÀnkande till? Hur mycket anstrÀngning ska vi lÀgga pÄ detta? Allt beror pÄ hur komplext problemet vi löser. Anta att vi vill skriva ett feltolerant distribuerat system. I det hÀr fallet bör vi tÀnka igenom saker noga innan vi sÀtter oss ner för att koda. Vad hÀnder om vi bara behöver öka en heltalsvariabel med 1? Vid första anblicken Àr allt trivialt hÀr, och ingen tanke behövs, men sedan kommer vi ihÄg att ett överflöde kan uppstÄ. DÀrför, Àven för att förstÄ om ett problem Àr enkelt eller komplext, mÄste du först tÀnka.

Om du tÀnker pÄ möjliga lösningar pÄ problemet i förvÀg kan du undvika misstag. Men detta krÀver att ditt tÀnkande Àr tydligt. För att uppnÄ detta mÄste du skriva ner dina tankar. Jag gillar verkligen Dick Guindon-citatet: "NÀr du skriver visar naturen dig hur slarvigt ditt tÀnkande Àr." Om du inte skriver sÄ tror du bara att du tÀnker. Och du behöver skriva ner dina tankar i form av specifikationer.

Specifikationer har mÄnga funktioner, sÀrskilt i stora projekt. Men jag kommer bara att tala om en av dem: de hjÀlper oss att tÀnka klart. Att tÀnka klart Àr vÀldigt viktigt och ganska svÄrt, sÄ hÀr behöver vi all hjÀlp. Vilket sprÄk ska vi skriva specifikationer pÄ? I allmÀnhet Àr detta alltid den första frÄgan för programmerare: vilket sprÄk kommer vi att skriva pÄ. Det finns inget korrekt svar pÄ det: de problem vi löser Àr för olika. För vissa Àr TLA+ ett specifikationssprÄk som jag utvecklat. För andra Àr det bekvÀmare att anvÀnda kinesiska. Allt beror pÄ situationen.

Viktigare Àr en annan frÄga: hur uppnÄr man ett tydligare tÀnkande? Svar: Vi mÄste tÀnka som vetenskapsmÀn. Detta Àr ett sÀtt att tÀnka som har bevisat sig sjÀlvt under de senaste 500 Ären. Inom naturvetenskap bygger vi matematiska modeller av verkligheten. Astronomi var kanske den första vetenskapen i ordets strikta mening. I den matematiska modellen som anvÀnds inom astronomi upptrÀder himlakroppar som punkter med massa, position och fart, Àven om de i verkligheten Àr extremt komplexa objekt med berg och hav, tidvatten och tidvatten. Denna modell, som alla andra, skapades för att lösa vissa problem. Det Àr bra för att avgöra vart du ska rikta teleskopet om du behöver hitta en planet. Men om du vill förutsÀga vÀdret pÄ den hÀr planeten, kommer den hÀr modellen inte att fungera.

Matematik lÄter oss bestÀmma egenskaperna hos en modell. Och vetenskapen visar hur dessa egenskaper relaterar till verkligheten. LÄt oss prata om vÄr vetenskap, datavetenskap. Den verklighet som vi arbetar med Àr datorsystem av olika slag: processorer, spelkonsoler, datorer, exekverande program och sÄ vidare. Jag kommer att prata om att köra ett program pÄ en dator, men i stort sett gÀller alla dessa slutsatser för alla datorsystem. I vÄr vetenskap anvÀnder vi mÄnga olika modeller: Turing-maskinen, delvis bestÀllda uppsÀttningar av hÀndelser och mÄnga andra.

Vad Ă€r ett program? Detta Ă€r vilken kod som helst som kan övervĂ€gas oberoende. Anta att vi behöver skriva en webblĂ€sare. Vi utför tre uppgifter: vi designar anvĂ€ndarens syn pĂ„ programmet, sedan skriver vi programmets högnivĂ„diagram och slutligen skriver vi koden. NĂ€r vi skriver koden inser vi att vi mĂ„ste skriva en textformaterare. HĂ€r mĂ„ste vi Ă„terigen lösa tre problem: bestĂ€mma vilken text detta verktyg kommer att returnera; vĂ€lj en algoritm för formatering; skriva kod. Denna uppgift har sin egen deluppgift: infoga ett bindestreck korrekt i ord. Vi löser Ă€ven denna deluppgift i tre steg – som du kan se upprepas de pĂ„ mĂ„nga nivĂ„er.

LĂ„t oss övervĂ€ga mer i detalj det första steget: vilket problem programmet löser. HĂ€r modellerar vi oftast ett program som en funktion som tar en del input och producerar en del output. I matematik brukar en funktion beskrivas som en ordnad uppsĂ€ttning par. Till exempel beskrivs kvadreringsfunktionen för naturliga tal som mĂ€ngden {<0,0>, <1,1>, <2,4>, <3,9>, 
}. DomĂ€nen för en sĂ„dan funktion Ă€r mĂ€ngden av de första elementen i varje par, det vill sĂ€ga de naturliga talen. För att definiera en funktion mĂ„ste vi specificera dess omfattning och formel.

Men funktioner i matematik Àr inte detsamma som funktioner i programmeringssprÄk. Matematiken Àr mycket lÀttare. Eftersom jag inte har tid för komplexa exempel, lÄt oss övervÀga ett enkelt: en funktion i C eller en statisk metod i Java som returnerar den största gemensamma divisorn av tvÄ heltal. I specifikationen av denna metod kommer vi att skriva: berÀknar GCD(M,N) för argument M О Nvar GCD(M,N) - en funktion vars domÀn Àr uppsÀttningen av par av heltal, och returvÀrdet Àr det största heltal som Àr delbart med M О N. Hur förhÄller sig denna modell till verkligheten? Modellen arbetar pÄ heltal, medan vi i C eller Java har en 32-bitars int. Denna modell lÄter oss avgöra om algoritmen Àr korrekt GCD, men det kommer inte att förhindra överflödesfel. Detta skulle krÀva en mer komplex modell, som det inte finns tid för.

LÄt oss prata om begrÀnsningarna för en funktion som modell. Vissa program (som operativsystem) returnerar inte bara ett visst vÀrde för vissa argument, de kan köras kontinuerligt. Funktionen som modell Àr dessutom inte vÀl lÀmpad för det andra steget: planera hur problemet ska lösas. Snabbsortering och bubbelsortering berÀknar samma funktion, men de Àr helt olika algoritmer. För att beskriva hur mÄlet med programmet uppnÄs anvÀnder jag dÀrför en annan modell, lÄt oss kalla den standardbeteendemodellen. Programmet i det representeras som en uppsÀttning av alla tillÄtna beteenden, som var och en i sin tur Àr en sekvens av tillstÄnd, och tillstÄndet Àr tilldelningen av vÀrden till variabler.

LĂ„t oss se hur det andra steget för euklidalgoritmen skulle se ut. Vi mĂ„ste rĂ€kna GCD(M, N). Vi initierar M ĐșĐ°Đș xOch N ĐșĐ°Đș ysubtrahera sedan upprepade gĂ„nger den minsta av dessa variabler frĂ„n den större tills de Ă€r lika. Till exempel om M = 12Och N = 18, kan vi beskriva följande beteende:

[x = 12, y = 18] → [x = 12, y = 6] → [x = 6, y = 6]

Och om M = 0 О N = 0? Noll Àr delbart med alla tal, sÄ det finns ingen största divisor i detta fall. I den hÀr situationen mÄste vi gÄ tillbaka till det första steget och frÄga: behöver vi verkligen berÀkna GCD för icke-positiva tal? Om detta inte Àr nödvÀndigt behöver du bara Àndra specifikationen.

HÀr bör vi göra en liten avvikelse om produktivitet. Det mÀts ofta i antalet rader kod som skrivs per dag. Men ditt arbete Àr mycket mer anvÀndbart om du blir av med ett visst antal rader, eftersom du har mindre utrymme för buggar. Och det enklaste sÀttet att bli av med koden Àr i första steget. Det Àr fullt möjligt att du helt enkelt inte behöver alla klockor och visselpipor du försöker implementera. Det snabbaste sÀttet att förenkla ett program och spara tid Àr att inte göra saker som inte borde göras. Det andra steget Àr den nÀst mest tidsbesparande potentialen. Om du mÀter produktivitet i termer av skrivna rader kommer du att tÀnka pÄ hur du utför en uppgift mindre produktiv, eftersom du kan lösa samma problem med mindre kod. Jag kan inte ge exakt statistik hÀr, eftersom jag inte har nÄgot sÀtt att rÀkna antalet rader som jag inte skrev pÄ grund av det faktum att jag spenderade tid pÄ specifikationen, det vill sÀga pÄ det första och andra steget. Och experimentet gÄr inte att lÀgga upp hÀr heller, eftersom vi i experimentet inte har rÀtt att genomföra det första steget, uppgiften Àr förutbestÀmd.

Det Ă€r lĂ€tt att förbise mĂ„nga svĂ„righeter i informella specifikationer. Det Ă€r inget svĂ„rt att skriva strikta specifikationer för funktioner, jag kommer inte att diskutera detta. IstĂ€llet kommer vi att prata om att skriva starka specifikationer för standardbeteenden. Det finns ett teorem som sĂ€ger att alla beteenden kan beskrivas med sĂ€kerhetsegenskapen (sĂ€kerhet) och överlevnadsegenskaper (livlighet). SĂ€kerhet innebĂ€r att inget dĂ„ligt kommer att hĂ€nda, programmet kommer inte att ge ett felaktigt svar. ÖverlevnadsförmĂ„ga innebĂ€r att det förr eller senare hĂ€nder nĂ„got bra, det vill sĂ€ga programmet kommer att ge rĂ€tt svar förr eller senare. Som regel Ă€r sĂ€kerhet en viktigare indikator, hĂ€r uppstĂ„r oftast fel. DĂ€rför, för att spara tid, kommer jag inte att prata om överlevnadsförmĂ„ga, Ă€ven om det naturligtvis ocksĂ„ Ă€r viktigt.

Vi uppnÄr sÀkerhet genom att först föreskriva uppsÀttningen av möjliga initiala tillstÄnd. Och för det andra, relationer med alla möjliga nÀsta tillstÄnd för varje stat. LÄt oss agera som vetenskapsmÀn och definiera tillstÄnd matematiskt. UppsÀttningen av initialtillstÄnd beskrivs av en formel, till exempel i fallet med Euklids algoritm: (x = M) ∧ (y = N). För vissa vÀrden M О N det finns bara ett initialtillstÄnd. Sambandet med nÀsta tillstÄnd beskrivs av en formel dÀr variablerna för nÀsta tillstÄnd skrivs med ett primtal och variablerna för det aktuella tillstÄndet skrivs utan ett primtal. NÀr det gÀller Euklids algoritm kommer vi att behandla disjunktionen av tvÄ formler, varav en x Àr det största vÀrdet, och i det andra - y:

Programmering Àr mer Àn kodning

I det första fallet Àr det nya vÀrdet pÄ y lika med det tidigare vÀrdet pÄ y, och vi fÄr det nya vÀrdet pÄ x genom att subtrahera den mindre variabeln frÄn den större variabeln. I det andra fallet gör vi tvÀrtom.

LÄt oss gÄ tillbaka till Euklids algoritm. LÄt oss anta det igen M = 12, N = 18. Detta definierar ett enda initialtillstÄnd, (x = 12) ∧ (y = 18). Vi kopplar sedan in dessa vÀrden till formeln ovan och fÄr:

Programmering Àr mer Àn kodning

HĂ€r Ă€r den enda möjliga lösningen: x' = 18 - 12 ∧ y' = 12och vi fĂ„r beteendet: [x = 12, y = 18]. PĂ„ liknande sĂ€tt kan vi beskriva alla tillstĂ„nd i vĂ„rt beteende: [x = 12, y = 18] → [x = 12, y = 6] → [x = 6, y = 6].

I sista tillstÄndet [x = 6, y = 6] bÄda delarna av uttrycket kommer att vara falskt, sÄ det har inget nÀsta tillstÄnd. SÄ vi har en fullstÀndig specifikation av det andra steget - som du kan se Àr detta ganska vanlig matematik, som hos ingenjörer och vetenskapsmÀn, och inte konstigt, som inom datavetenskap.

Dessa tvÄ formler kan kombineras till en formel för tidslogik. Hon Àr elegant och lÀtt att förklara, men det finns inte tid för henne nu. Vi kanske behöver temporÀr logik bara för livlighetens egendom, den behövs inte för sÀkerheten. Jag gillar inte tidslogik som sÄdan, det Àr inte helt vanlig matematik, men i fallet med livlighet Àr det ett nödvÀndigt ont.

I Euklids algoritm, för varje vÀrde x О y har unika vÀrden x' О y', som gör relationen med nÀsta tillstÄnd sann. Euklids algoritm Àr med andra ord deterministisk. För att modellera en icke-deterministisk algoritm mÄste det aktuella tillstÄndet ha flera möjliga framtida tillstÄnd, och att varje oprimat variabelvÀrde har flera primerade variabelvÀrden sÄ att relationen till nÀsta tillstÄnd Àr sann. Detta Àr lÀtt att göra, men jag ska inte ge nÄgra exempel nu.

För att göra ett arbetsredskap behöver du formell matematik. Hur gör man specifikationen formell? För att göra detta behöver vi ett formellt sprÄk, t.ex. TLA+. Specifikationen för Euclid-algoritmen skulle se ut sÄ hÀr pÄ detta sprÄk:

Programmering Àr mer Àn kodning

En likhetsteckensymbol med en triangel betyder att vÀrdet till vÀnster om tecknet definieras till att vara lika med vÀrdet till höger om tecknet. I huvudsak Àr specifikationen en definition, i vÄrt fall tvÄ definitioner. Till specifikationen i TLA+ behöver du lÀgga till deklarationer och viss syntax, som i bilden ovan. I ASCII skulle det se ut sÄ hÀr:

Programmering Àr mer Àn kodning

Som du kan se, inget komplicerat. Specifikationen för TLA+ kan testas, d.v.s. kringgÄ alla möjliga beteenden i en liten modell. I vÄrt fall kommer denna modell att vara vissa vÀrden M О N. Detta Àr en mycket effektiv och enkel verifieringsmetod som Àr helt automatisk. Det gÄr Àven att skriva formella sanningsbevis och kontrollera dem mekaniskt, men detta tar mycket tid, sÄ nÀstan ingen gör detta.

Den största nackdelen med TLA+ Àr att det Àr matematik, och programmerare och datavetare Àr rÀdda för matematik. Vid första anblicken lÄter detta som ett skÀmt, men tyvÀrr menar jag det pÄ fullt allvar. Min kollega berÀttade precis hur han försökte förklara TLA+ för flera utvecklare. SÄ fort formlerna dök upp pÄ skÀrmen blev de genast glasiga ögon. SÄ om TLA+ skrÀmmer dig kan du anvÀnda PlusCal, det Àr ett slags leksaksprogrammeringssprÄk. Ett uttryck i PlusCal kan vara vilket TLA+-uttryck som helst, det vill sÀga i stort sett vilket matematiskt uttryck som helst. PlusCal har dessutom en syntax för icke-deterministiska algoritmer. Eftersom PlusCal kan skriva vilket TLA+-uttryck som helst, Àr PlusCal mycket mer uttrycksfullt Àn nÄgot riktigt programmeringssprÄk. DÀrefter sammanstÀlls PlusCal till en lÀttlÀsbar TLA+-specifikation. Detta betyder naturligtvis inte att den komplexa PlusCal-specifikationen kommer att förvandlas till en enkel sÄdan pÄ TLA + - bara korrespondensen mellan dem Àr uppenbar, det kommer inte att finnas nÄgon ytterligare komplexitet. Slutligen kan denna specifikation verifieras av TLA+-verktyg. Sammantaget kan PlusCal hjÀlpa till att övervinna matematikfobi och Àr lÀtt att förstÄ Àven för programmerare och datavetare. Tidigare publicerade jag algoritmer pÄ det under en tid (cirka 10 Är).

Kanske kommer nĂ„gon att invĂ€nda att TLA + och PlusCal Ă€r matematik, och matematik fungerar bara pĂ„ pĂ„hittade exempel. I praktiken behöver du ett riktigt sprĂ„k med typer, procedurer, objekt och sĂ„ vidare. Detta Ă€r fel. HĂ€r Ă€r vad Chris Newcomb, som arbetade pĂ„ Amazon, skriver: "Vi har anvĂ€nt TLA+ pĂ„ tio stora projekt, och i varje fall har anvĂ€ndningen av det gjort en betydande skillnad för utvecklingen eftersom vi kunde fĂ„nga farliga buggar innan vi började producera, och för att det gav oss den insikt och det förtroende vi behövde för att göra aggressiva prestandaoptimeringar utan att pĂ„verka programmets sanning". Man kan ofta höra att nĂ€r vi anvĂ€nder formella metoder fĂ„r vi ineffektiv kod – i praktiken Ă€r allt precis tvĂ€rtom. Dessutom finns det en Ă„sikt att chefer inte kan övertygas om behovet av formella metoder, Ă€ven om programmerare Ă€r övertygade om deras anvĂ€ndbarhet. Och Newcomb skriver: "Hantera pressar nu hĂ„rt pĂ„ att skriva specifikationer för TLA + och avsĂ€tter specifikt tid för detta". SĂ„ nĂ€r chefer ser att TLA+ fungerar accepterar de det gĂ€rna. Chris Newcomb skrev detta för ungefĂ€r ett halvĂ„r sedan (oktober 2014), men nu, sĂ„ vitt jag vet, anvĂ€nds TLA+ i 14 projekt, inte 10. Ett annat exempel Ă€r designen av XBox 360. En praktikant kom till Charles Thacker och skrev specifikation för minnessystemet. Tack vare denna specifikation hittades en bugg som annars skulle förbli obemĂ€rkt, och pĂ„ grund av vilket varje Xbox 360 skulle krascha efter fyra timmars anvĂ€ndning. IBM-ingenjörer bekrĂ€ftade att deras tester inte skulle ha hittat denna bugg.

Du kan lÀsa mer om TLA + pÄ Internet, men nu ska vi prata om informella specifikationer. Vi behöver sÀllan skriva program som rÀknar ut minsta gemensamma divisor och liknande. Mycket oftare skriver vi program som pretty-printer-verktyget jag skrev för TLA+. Efter den enklaste bearbetningen skulle TLA +-koden se ut sÄ hÀr:

Programmering Àr mer Àn kodning

Men i exemplet ovan ville anvÀndaren sannolikt att konjunktionen och likhetstecknen skulle vara anpassade. SÄ den korrekta formateringen skulle se ut mer sÄ hÀr:

Programmering Àr mer Àn kodning

LÄt oss titta pÄ ett annat exempel:

Programmering Àr mer Àn kodning

HÀr var tvÀrtom anpassningen av likhetstecken, addition och multiplikationstecken i kÀllan slumpmÀssig, sÄ den enklaste bearbetningen rÀcker. I allmÀnhet finns det ingen exakt matematisk definition av korrekt formatering, eftersom "korrekt" i det hÀr fallet betyder "vad anvÀndaren vill ha", och detta kan inte bestÀmmas matematiskt.

Det verkar som att om vi inte har en definition av sanning sĂ„ Ă€r specifikationen vĂ€rdelös. Men det Ă€r inte. Bara för att vi inte vet vad ett program ska göra betyder det inte att vi inte behöver tĂ€nka pĂ„ hur det fungerar – tvĂ€rtom mĂ„ste vi lĂ€gga Ă€nnu mer kraft pĂ„ det. Specifikationen Ă€r sĂ€rskilt viktig hĂ€r. Det Ă€r omöjligt att bestĂ€mma det optimala programmet för strukturerad utskrift, men det betyder inte att vi inte ska ta det alls, och att skriva kod som en ström av medvetande Ă€r inte bra. Till slut skrev jag en specifikation av sex regler med definitioner i form av kommentarer i en java-fil. HĂ€r Ă€r ett exempel pĂ„ en av reglerna: a left-comment token is LeftComment aligned with its covering token. Denna regel Ă€r skriven pĂ„, ska vi sĂ€ga, matematisk engelska: LeftComment aligned, left-comment Đž covering token - termer med definitioner. Det Ă€r sĂ„ matematiker beskriver matematik: de skriver definitioner av termer och, utifrĂ„n dem, regler. Fördelen med en sĂ„dan specifikation Ă€r att sex regler Ă€r mycket lĂ€ttare att förstĂ„ och felsöka Ă€n 850 rader kod. Jag mĂ„ste sĂ€ga att det inte var lĂ€tt att skriva dessa regler, det tog ganska lĂ„ng tid att felsöka dem. Speciellt för detta Ă€ndamĂ„l skrev jag en kod som rapporterade vilken regel som anvĂ€ndes. Tack vare det faktum att jag testade dessa sex regler pĂ„ flera exempel, behövde jag inte felsöka 850 rader kod, och buggar visade sig vara ganska lĂ€tta att hitta. Java har bra verktyg för detta. Om jag bara hade skrivit koden hade det tagit mycket lĂ€ngre tid, och formateringen hade varit av sĂ€mre kvalitet.

Varför kunde inte en formell specifikation anvĂ€ndas? Å ena sidan Ă€r det korrekta utförandet inte alltför viktigt hĂ€r. Strukturella utskrifter Ă€r skyldiga att inte glĂ€dja nĂ„gon, sĂ„ jag behövde inte fĂ„ det att fungera rĂ€tt i alla udda situationer. Ännu viktigare Ă€r det faktum att jag inte hade tillrĂ€ckliga verktyg. TLA+-modellkontrollen Ă€r vĂ€rdelös hĂ€r, sĂ„ jag mĂ„ste skriva exemplen manuellt.

OvanstÄende specifikation har gemensamma egenskaper för alla specifikationer. Det Àr högre nivÄ Àn koden. Det kan implementeras pÄ vilket sprÄk som helst. Alla verktyg eller metoder Àr vÀrdelösa för att skriva det. Ingen programmeringskurs hjÀlper dig att skriva denna specifikation. Och det finns inga verktyg som kan göra den hÀr specifikationen onödig, sÄvida du inte, naturligtvis, skriver ett sprÄk specifikt för att skriva strukturerade utskriftsprogram i TLA+. Slutligen, den hÀr specifikationen sÀger ingenting om exakt hur vi kommer att skriva koden, den anger bara vad den hÀr koden gör. Vi skriver specifikationen för att hjÀlpa oss att tÀnka igenom problemet innan vi börjar tÀnka pÄ koden.

Men den hÀr specifikationen har ocksÄ funktioner som skiljer den frÄn andra specifikationer. 95 % av andra specifikationer Àr betydligt kortare och enklare:

Programmering Àr mer Àn kodning

Vidare Àr denna specifikation en uppsÀttning regler. Som regel Àr detta ett tecken pÄ dÄlig specifikation. Att förstÄ konsekvenserna av en uppsÀttning regler Àr ganska svÄrt, varför jag var tvungen att lÀgga mycket tid pÄ att felsöka dem. Men i det hÀr fallet kunde jag inte hitta ett bÀttre sÀtt.

Det Àr vÀrt att sÀga nÄgra ord om program som körs kontinuerligt. Som regel arbetar de parallellt, till exempel operativsystem eller distribuerade system. VÀldigt fÄ mÀnniskor kan förstÄ dem mentalt eller pÄ papper, och jag Àr inte en av dem, Àven om jag en gÄng kunde göra det. DÀrför behöver vi verktyg som kontrollerar vÄrt arbete - till exempel TLA + eller PlusCal.

Varför var det nödvÀndigt att skriva en specifikation om jag redan visste vad exakt koden skulle göra? Jag trodde faktiskt att jag visste det. Dessutom, med en specifikation, behöver en utomstÄende inte lÀngre komma in i koden för att förstÄ exakt vad han gör. Jag har en regel: det ska inte finnas nÄgra allmÀnna regler. Det finns ett undantag frÄn denna regel, naturligtvis, det Àr den enda allmÀnna regeln jag följer: specifikationen av vad koden gör ska berÀtta för folk allt de behöver veta nÀr de anvÀnder koden.

SĂ„ vad exakt behöver programmerare veta om att tĂ€nka? Till att börja med samma sak som alla andra: om du inte skriver sĂ„ verkar det bara för dig som du tĂ€nker. Dessutom mĂ„ste du tĂ€nka innan du kodar, vilket betyder att du mĂ„ste skriva innan du kodar. Specifikationen Ă€r vad vi skriver innan vi börjar koda. En specifikation behövs för alla koder som kan anvĂ€ndas eller modifieras av vem som helst. Och denna "nĂ„gon" kan vara författaren till koden sjĂ€lv en mĂ„nad efter att den skrevs. En specifikation behövs för stora program och system, för klasser, för metoder och ibland Ă€ven för komplexa delar av en enskild metod. Vad exakt ska skrivas om koden? Du mĂ„ste beskriva vad den gör, det vill sĂ€ga vad som kan vara anvĂ€ndbart för alla som anvĂ€nder den hĂ€r koden. Ibland kan det ocksĂ„ vara nödvĂ€ndigt att specificera hur koden uppnĂ„r sitt syfte. Om vi ​​gick igenom denna metod under algoritmer, sĂ„ kallar vi det en algoritm. Om det Ă€r nĂ„got mer speciellt och nytt, sĂ„ kallar vi det design pĂ„ hög nivĂ„. Det finns ingen formell skillnad hĂ€r: bĂ„da Ă€r en abstrakt modell av ett program.

Hur exakt ska man skriva en kodspecifikation? Huvudsaken: den ska vara en nivÄ högre Àn sjÀlva koden. Den ska beskriva tillstÄnd och beteenden. Det ska vara sÄ strikt som uppgiften krÀver. Om du skriver en specifikation för hur en uppgift ska implementeras kan du skriva den i pseudokod eller med PlusCal. Du mÄste lÀra dig hur man skriver specifikationer pÄ formella specifikationer. Detta kommer att ge dig de nödvÀndiga fÀrdigheterna som ocksÄ hjÀlper dig med informella sÄdana. Hur lÀr man sig att skriva formella specifikationer? NÀr vi lÀrde oss att programmera skrev vi program och debuggade dem sedan. Det Àr samma sak hÀr: skriv specen, kontrollera den med modellkontrollen och fixa felen. TLA+ kanske inte Àr det bÀsta sprÄket för en formell specifikation, och ett annat sprÄk Àr troligen bÀttre för dina specifika behov. Fördelen med TLA+ Àr att det lÀr ut matematiskt tÀnkande vÀldigt bra.

Hur lÀnkar man specifikation och kod? Med hjÀlp av kommentarer som kopplar samman matematiska begrepp och deras genomförande. Om du arbetar med grafer kommer du pÄ programnivÄ att ha arrayer av noder och arrayer av lÀnkar. DÀrför mÄste du skriva exakt hur grafen implementeras av dessa programmeringsstrukturer.

Det bör noteras att inget av ovanstĂ„ende gĂ€ller sjĂ€lva processen att skriva kod. NĂ€r du skriver koden, det vill sĂ€ga du utför det tredje steget, behöver du ocksĂ„ tĂ€nka och tĂ€nka igenom programmet. Om en deluppgift visar sig vara komplex eller icke-uppenbar mĂ„ste du skriva en specifikation för den. Men jag pratar inte om sjĂ€lva koden hĂ€r. Du kan anvĂ€nda vilket programmeringssprĂ„k som helst, vilken metod som helst, det handlar inte om dem. Dessutom eliminerar inget av ovanstĂ„ende behovet av att testa och felsöka kod. Även om den abstrakta modellen Ă€r korrekt skriven kan det finnas buggar i dess implementering.

Att skriva specifikationer Ă€r ett ytterligare steg i kodningsprocessen. Tack vare det kan mĂ„nga fel fĂ„ngas med mindre anstrĂ€ngning - vi vet detta frĂ„n erfarenheten frĂ„n programmerare frĂ„n Amazon. Med specifikationer blir kvaliteten pĂ„ programmen högre. SĂ„ varför gĂ„r vi sĂ„ ofta utan dem? För att skriva Ă€r svĂ„rt. Och att skriva Ă€r svĂ„rt, för för detta behöver du tĂ€nka, och att tĂ€nka Ă€r ocksĂ„ svĂ„rt. Det Ă€r alltid lĂ€ttare att lĂ„tsas som man tycker. HĂ€r kan du dra en analogi med löpning – ju mindre du springer, desto lĂ„ngsammare springer du. Du mĂ„ste trĂ€na dina muskler och trĂ€na pĂ„ att skriva. Behöver övning.

Specifikationen kan vara felaktig. Du kanske har gjort ett misstag nÄgonstans, eller kraven kan ha Àndrats eller en förbÀttring kan behöva göras. Alla koder som nÄgon anvÀnder mÄste Àndras, sÄ förr eller senare kommer specifikationen inte lÀngre att matcha programmet. Helst, i det hÀr fallet, mÄste du skriva en ny specifikation och helt skriva om koden. Vi vet mycket vÀl att ingen gör det. I praktiken patchar vi koden och uppdaterar eventuellt specifikationen. Om detta mÄste hÀnda förr eller senare, varför skriva specifikationer överhuvudtaget? För det första, för den som ska redigera din kod kommer varje extra ord i specifikationen att vara guld vÀrt, och den hÀr personen kan mycket vÀl vara du sjÀlv. Jag kritiserar ofta mig sjÀlv för att jag inte fÄr tillrÀckligt med specifikationer nÀr jag redigerar min kod. Och jag skriver fler specifikationer Àn kod. DÀrför mÄste specifikationen alltid uppdateras nÀr du redigerar koden. För det andra, för varje revision blir koden sÀmre, den blir svÄrare och svÄrare att lÀsa och underhÄlla. Detta Àr en ökning av entropin. Men om du inte börjar med en spec, sÄ kommer varje rad du skriver att vara en redigering, och koden kommer att vara svÄrhanterlig och svÄr att lÀsa frÄn början.

Som sagt Eisenhower, ingen strid vanns med plan, och ingen strid vanns utan en plan. Och han visste ett och annat om strider. Det finns en Äsikt att skriva specifikationer Àr ett slöseri med tid. Ibland Àr detta sant, och uppgiften Àr sÄ enkel att det inte finns nÄgot att tÀnka igenom. Men du ska alltid komma ihÄg att nÀr du blir tillsagd att inte skriva specifikationer, blir du tillsagd att inte tÀnka. Och du bör tÀnka pÄ det varje gÄng. Att tÀnka igenom uppgiften garanterar inte att du inte kommer att göra misstag. Som vi vet var det ingen som uppfann trollstaven, och programmering Àr en svÄr uppgift. Men om du inte tÀnker igenom problemet kommer du garanterat att göra misstag.

Du kan lĂ€sa mer om TLA + och PlusCal pĂ„ en speciell hemsida, du kan gĂ„ dit frĂ„n min hemsida ĐżĐŸ ссылĐșĐ”. Det var allt för mig, tack för din uppmĂ€rksamhet.

Observera att detta Àr en översÀttning. NÀr du skriver kommentarer, kom ihÄg att författaren inte kommer att lÀsa dem. Om du verkligen vill chatta med författaren, dÄ kommer han att vara med pÄ Hydra 2019-konferensen, som kommer att hÄllas 11-12 juli 2019 i St. Petersburg. Biljetter kan köpas pÄ den officiella webbplatsen.

KĂ€lla: will.com

LĂ€gg en kommentar