Skillnaden mellan en kompilator och en tolk
On december 31, 2021 by adminSkillnaden mellan en kompilator och en tolk verkar tillräckligt tydlig enligt definitionerna:
- Tolk är ett program som direkt utför instruktioner som är skrivna i ett programmeringsspråk
- Kompilator är ett program som omvandlar källkod i ett språk på låg(er)nivå
Om man gräver djupare finner man dock en viss otydlighet mellan de två.
En tolk kan faktiskt översätta källspråket i en mellanform för att påskynda utförandet. Det är vad som vanligtvis händer med ett språk som är beroende av en virtuell maskin. Detta leder naturligtvis till vissa frågor:
Är alla språk som använder en virtuell maskin tolkade?
Är alla faktiskt kompilerade?
Man kan säga både och: ett språk kompileras först i en mellanform/språk och sedan tolkas denna mellanform/språk vid körningen. Detta leder också till en annan fråga: en kompilator och en tolk bör inte betraktas som ett program, utan mer som en grupp av program, ett system. Det som du som användare anser vara en kompilator kan i själva verket innehålla mer än ett program. Det kan till exempel innehålla en länkare: ett program som kombinerar olika objektfiler i en fil, så att den kan användas lättare. Något liknande kan sägas om en tolk.
Kan du berätta allt om kompilatorer & tolkar?
Så, vilka är alla de delar som utgör en kompilator eller en tolk? Du kan leta efter ett exakt och tekniskt svar på sådana frågor i den akademiska världen. Eller så kan du hitta diskussioner om dessa frågor på StackOverflow.
Det som verkligen är viktigt för oss som utvecklare, eller till och med för oss som skapare av ett språk, är vilka skillnaderna är när vi arbetar med dem. Båda har fördelar och nackdelar, och faktum är att vissa språk kan ha både en tolk och en kompilator, eller mer än en. Det är vad vi kommer att se.
Huvudpunkten kvarstår fortfarande: en tolk utför koden nu, en kompilator förbereder källkoden för en exekvering som kommer senare. Alla praktiska skillnader härstammar från dessa olika mål.
Hur distribuerar man ett program
I praktiska termer är en viktig skillnad att en kompilator genererar ett fristående program, medan ett tolkat program alltid behöver tolken för att kunna köras.
När du väl har ett kompilerat program kan du köra det utan att behöva installera något annat. Detta förenklar distributionen. Å andra sidan fungerar det körbara programmet på en specifik plattform: olika operativsystem och olika processorer behöver olika kompilerade versioner. Ett kompilerat C++-program kan till exempel fungera på en dator med en x86-processor, men inte på en dator med ett ARM-chip. Eller det kan fungera på ett Linux-system, men inte på ett Windows-system.
Om du ska tolka ett program kan du distribuera samma kopia till användare på olika plattformar. De kommer dock att behöva en tolk som körs på deras specifika plattform. Du kan antingen distribuera den ursprungliga källkoden eller en mellanform. Ett intuitivt sätt att se på en tolk är detta: den är som eval
-funktionen i JavaScript. Den fungerar överallt där JavaScript fungerar, men den behöver en JavaScript-tolkare för den plattformen för att kunna köras.
Stöd för flera plattformar
Detta är en teknisk skillnad som leder till viktiga reella konsekvenser: det är lättare att göra plattformsoberoende program med ett tolkat programmeringsspråk.
Det beror på att du för det mesta bara skapar ett program för tolkplattformen. Det är tolken själv som översätter det till rätt form för den verkliga plattformen (t.ex. Windows/Linux och x86/ARM). Naturligtvis finns det fortfarande vissa skillnader i varje plattform som du måste vara medveten om. Ett vanligt exempel är teckenet för katalogseparator.
När du kompilerar ett program måste du istället själv ta hand om alla de små skillnaderna mellan varje plattform. Detta sker delvis på grund av att kompilerade språk tenderar att vara språk på låg(er) nivå, t.ex. C++, så de ger dig lägre tillgång till systemet och därmed mer ansvar. Men en annan orsak är att alla bibliotek som du använder måste själva ha stöd för olika plattformar. Så om de inte stöder Windows kan du inte stödja Windows.
Snabbhet har flera ansikten
När det gäller snabbhet har vi återigen ett slags paradox: en kompilator är både snabbare och långsammare än en tolk. Många vet att ett kompilerat program är mycket snabbare än ett tolkat, men detta är inte hela bilden. Ett kompilerat program är snabbare att köra än ett tolkat program, men det tar mer tid att kompilera och köra ett program än att bara tolka det.
En kompilator producerar verkligen snabbare program. Det sker i grunden därför att den måste analysera varje uttalande bara en gång, medan en tolkare måste analysera det varje gång. Dessutom kan en kompilator optimera den körbara kod som den producerar. Det beror både på att den vet exakt var den ska köras och på att det tar tid att optimera koden. Tid som skulle göra tolkningen för långsam.
Runtime Speed Versus Development Speed
Man kan tycka att detta är pyttegris: om man kompilerar ett program så körs det snabbare, tiden som det tar att kompilera spelar ingen roll. Detta är vanligtvis den gamla skolans åsikt. Och utan tvekan körs det resulterande programmet fler gånger än det kompileras. Så vem bryr sig om att utvecklingen tar längre tid? Ja, det krävs förvisso en ”ta med smärtan” attityd till utveckling som är något beundransvärd. Men vad händer om vinsterna i körtid inte är relevanta, medan förlusterna i utvecklingsproduktivitet är betydande?
Det är en sak om man skapar ett operativsystem och en annan om man gör en selfie-app. Till och med dina användare kanske föredrar en inte ens märkbar förlust i körtidshastighet i utbyte mot att de får funktioner snabbare. Det finns inget universellt svar: i vissa sammanhang är produktivitet viktigare än snabbhet, i andra är det tvärtom.
The Mysteries Of Debugging
Det finns en annan aspekt som är mer osäker än vad man skulle kunna tro: debugging. På pappret är felsökning lättare när man använder en tolk än när man använder en kompilator. Det stämmer av flera skäl:
- Med tolken finns det en version av den körbara filen; Du behöver inte en felsökningsversion för utveckling och en releaseversion för slutanvändaren
- Det finns färre plattformsspecifika buggar när du använder en tolk
- eftersom tolken omvandlar koden i farten, är informationen från källkoden fortfarande tillgänglig
- Då tolken utför ett uttalande i taget är det lättare att hitta ett fel
Den skillnad som utvecklingsverktygen gör
Och även om allt detta är sant i praktiken kan det vara mindre relevant än vad det verkar. Faktum är att om du tänker på din erfarenhet skulle du förmodligen upptäcka att det är svårare att felsöka JavaScript än att felsöka C++. Varför är det så? Det beror delvis på utformningen av själva språken. JavaScript använder dynamisk typning, medan C++ använder statisk typning. Det senare gör det lättare att upptäcka misstag tidigt. Men i slutändan handlar det om utvecklingsverktygen. Det är svårt att kompilera C++ för hand, så de flesta använder IDE för att utveckla med det. Å andra sidan kan man lätt använda textredigerare och kommandoradsverktyg för att utveckla i JavaScript.
Detta innebär i praktiken att om man utvecklar med C++ kan man också felsöka C++. I stället kan man utveckla med JavaScript utan att veta hur man gör korrekt felsökning i JavaScript.
Med detta sagt, om vi placerar dem i samma sammanhang, var och en med ett bra IDE och stödverktyg, återgår situationen till det normala. Många tolkade miljöer används faktiskt av personer som vill lära sig att använda ett nytt språk. Det är lättare att testa, och hitta vad som är rätt och fel, genom att titta på vad som händer rad för rad och i realtid.
Sammanfattning
Vi har sett de viktigaste skillnaderna som spelar roll mellan en kompilator och en tolk. Ännu viktigare är att vi har sett att konsekvenserna av olika filosofier är viktigare än de tekniska konsekvenserna. Kort sagt finns det kulturer som följer med vissa tekniska val som i slutändan är relevanta i sig själva. Om man vill ha snabbhet och enkel utveckling kommer man att välja alla tekniker för snabbhet och inte bara en. Och dina användare kommer att följa dig.
Detta är en viktig aspekt att tänka igenom, särskilt om du vill skapa ett eget programmeringsspråk. Rasmus Lerdorf skapade PHP för att det skulle vara lätt att använda. Och det var verkligen otroligt lätt att använda jämfört med alternativen, åtminstone när det skapades. Men det började mer som ett bibliotek än som ett språk. Och även om det har förbättrats mycket lider det fortfarande av sin början. Du kan fortfarande skapa bra PHP-kod, men färre av dess användare än vanligt gör det. För om du bara behöver något som fungerar, säkerhet, underhåll osv. så kommer allt annat senare.
Om du vill veta hur du praktiskt kan bygga en tolk eller en kompilator för ditt språk kan du ta en titt på resurserna för att skapa ett programmeringsspråk. Om du vill lära dig det, och allt du behöver för att skapa ditt eget språk, behöver du bara välja en bra bok, älskad av både barn och vuxna, om hur man skapar pragmatiska, lätta språk.
5 saker att göra rätt när man bygger ett språk
Få checklistan via e-post och få fler tips om hur man bygger språk
.
Lämna ett svar