[Java] is C with range checking and garbage collection
John Carmack, (Twitter, 2012-04-30)
seen from T1
seen from T1

seen from Saudi Arabia
seen from Argentina
seen from Qatar

seen from Australia
seen from United States
seen from Malaysia

seen from Japan
seen from United States
seen from China
seen from China

seen from United States
seen from Indonesia

seen from United States

seen from Malaysia
seen from Malaysia
seen from United States

seen from Saudi Arabia
seen from United States
[Java] is C with range checking and garbage collection
John Carmack, (Twitter, 2012-04-30)

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch âą No registration required âą HD streaming
Gratislunchen Àr över; parallellismen gör entré (del 3)
SÄ tvÄ processer kan inte försöka anvÀnda samma variabel samtidigt. Det ger problem. En naiv lösning Àr ju att bara förhindra dem frÄn att anvÀnda samma variabel samtidigt. Det brukar kallas lÄs eller mutexes (mutex stÄr för mutual exclusion och betyder att flera saker inte fÄr komma Ät en variabel samtidigt.)
Process 1 sÀtter ett lÄs pÄ variabeln den anvÀnder, gör sitt med den, och lÄser sen upp lÄset. Process 2 fÄr dÄ sÀtta sitt lÄs pÄ den. Det Àr faktiskt sÄ hÀr man oftast gör i dag nÀr man gör nÄgot parallellt. Man lÄser variabler eller delar av minnet. TyvÀrr Àr det inte utan problem.
TÀnk dig att Erika och Jonas gÄr pÄ dagis bÄda tvÄ. Det finns tvÄ lÄdor med lego som man behöver för att bygga en tuff borg. BÄde Erika och Jonas vill bygga den dÀr borgen, men de pratar inte med varandra sÄ de vet inte om att den andra vill det.
Erika gÄr fram till en av lÄdorna och sÀtter sitt lÄs pÄ den för att han kommer att anvÀnda den. Erika gÄr vidare till den andra lÄdan och upptÀcker att Jonas har satt sitt lÄs pÄ den. Erika stÀller dig dÀr och vÀntar pÄ att Jonas ska bli klar med lÄdan och lÄsa upp sitt lÄs, men det hÀnder aldrig. Erika stÄr dÀr natt efter natt och dag efter dag men aldrig lÄser Jonas upp sin lÄda.
Har du listat ut vad som har hÀnt? Jonas ville ocksÄ bygga den tuffa borgen, sÄ han lÄste lÄdan som var nÀrmast honom och gick till lÄdan som Erika just hade lÄst. DÀr vÀntar Jonas pÄ att Erika ska lÄsa upp sin lÄda, men det hÀnder aldrig. BÄda vÀntar pÄ varandras lÄs och det hÀr kallas för en deadlock.
Det finns naturligtvis strategier för att undvika deadlocks, som till exempel att alla mÄste lÄsa lÄdorna i samma ordning, men i nÄgorlunda komplicerade system sÄ kommer deadlocks uppstÄ ÀndÄ.
Deadlocks Àr inte heller det enda problemet med lÄs. LÄs kan vara ineffektiva ocksÄ. TÀnk dig om en process behöver 57 variabler för nÄgon lÄng utrÀkning, medan en annan process bara behöver en av de dÀr variablerna för att skriva ut nÄgot. Om den lÄnga processen hinner lÄsa variablerna först mÄste den lilla, snabba vÀnta lÀnge pÄ att fÄ göra den dÀr viktiga utskriften som den skulle kunna göra bara den fick.
DÄ kan man börja prata om lÄs som hindrar andra frÄn att skriva, men de fortfarande fÄr lÀsa. I vissa fall fungerar det, i andra Àr det vÀldigt dumt; tÀnk dig ett kÀrnkraftverk eller sjukhus dÀr programmet inte fÄr lÀsa en variabel som Àr halvskriven.
LÄs Àr lÄngt ifrÄn perfekta. Faktum Àr att de som arbetar med dem brukar avsky dem, för de Àr svÄra att debugga, de Àr instabila, de ger jÀtteful kod och sÄ vidare. De Àr visserligen lite bÀttre Àn att inte ha nÄgot skydd alls, men de Àr vÀldigt omstÀndliga.
Gratislunchen Àr över; parallellismen gör entré (del 2)
SĂ„ nu nĂ€r gratislunchen Ă€r över mĂ„ste vi göra program snabbare pĂ„ nĂ„got annat sĂ€tt. Parallellism betyder att göra flera saker samtidigt. Med flera kĂ€rnor kan man göra flera saker samtidigt. ĂndĂ„ verkar det som att de allra flesta program som skrivs i dag bara kör pĂ„ en kĂ€rna. De Ă€r skrivna för att bara göra en sak i taget.
Trots allt Àr det sÄ vi Àr vana vid att programmera saker. Vi Àr vana att skriva kod pÄ formen
gör det hÀr
sen gör det hÀr
sen gör det hÀr
om det hÀr Àr pÄ nÄgot visst sÀtt
gör det hÀr
annars
gör det hÀr
och det hÀr
och det hÀr istÀllet
nÀr du Àr klar med det, gör det hÀr
och gör sen det hÀr
och sÄ vidare. Det hÀr Àr en lista pÄ instruktioner som mÄste göras uppifrÄn och ned, annars blir det problem. Det gÄr inte att köra nÄgot samtidigt dÀr inte.
Den största boven hÀr Àr variabler. TÀnk dig följande kodsnutt i assembler.
li $t0, 0x03fb6c78 # stoppa in adressen 0x03fb6c78 till t0 lw $t1, 0($t0) # ladda in innehÄllet i adressen till t1 addi $t1, $t1, 1 # lÀgg till 1 pÄ vÀrdet i t1 sw $t1 0($t0) # stoppa tillbaks nya t1 till gamla adressen
Först hÀmtar man innehÄllet nÄgonstans i minnet, sen ökar man pÄ det med ett, och sen stoppar man tillbaks det. Det dÀr Àr vad som i C skrivs
variabel++;
Ser du hur det Àr komponerat av fyra olika instruktioner egentligen? DÀr kommer problemet in. TÀnk om det Àr tvÄ processer som körs pÄ olika kÀrnor som ska göra det dÀr. Om variabeln börjar med vÀrdet fyra kan man vÀnta sig att efter att tvÄ processer har ökat den sÄ blir vÀrdet sex. Inte om de försöker öka samtidigt.
Process 1 hÀmtar variabel som har vÀrde fyra
Process 1 lÀgger till 1 till variabel, som fÄr vÀrde fem lokalt i process 1
Process 2 hÀmtar variabel som har vÀrde fyra i minnet fortfarande
Process 1 skriver tillbaks sin lokala variabel med vÀrde fem till minnet
Process 2 lÀgger till 1 till sin variabel, som fÄr vÀrde fem lokalt i process 2
Process 2 skriver tillbaks sin lokala variabel med vÀrde fem till minnet.
I slutÀndan har variabeln vÀrdet fem i minnet, trots att vi vÀntade oss sex. Kaos! Det hÀr Àr problemet med flera processer som kör samtidigt. De kan förstöra för varandra nÀr de delar pÄ minne och sÄnt.
Du kan sÀkert redan tÀnka dig en lösning, eller hur? Du kan sÀkert förestÀlla dig att "Men om process 2 inte fÄr röra minnet medan process 1 anvÀnder det?" Du har helt rÀtt! Det kommer i nÀsta del.
Gratislunchen Àr över; parallellismen gör entré (del 1)
Ănda sen datorer började bli anvĂ€ndbara pĂ„ 50- och 60-talet har de alltid blivit snabbare, snabbare och Ă„ter snabbare. En dator i början av 80-talet var lite grovt 50 gĂ„nger snabbare Ă€n en i början av sjuttitalet. PĂ„ ett Ă„r hann datorerna bli lite grovt 1.6 gĂ„nger snabbare.
Det hÀr Àr vad som kallas för en gratis lunch. NÀr man pÄ 90-talet programmerade nÄgot, sÄ kunde man medvetet göra programmet lite lÄngsamt pÄ dagens datorer, för nÀr programmet slÀpps ett Är senare, kommer det gÄ ungefÀr 1.6 gÄnger snabbare. Utan att programmeraren behöver göra nÄgonting. Det sparar massa utvecklingstid. Programmeraren behöver inte bry sig om ifall programmet Àr lite lÄngsamt, för hÄrdvaran kommer att komma ikapp.
Men nÄgot har hÀnt. Vi nÄdde omrÄdet omkring 4 GHz vid 2005 eller 2006. Vi borde ju nu i 2012 ha allra minst 50 GHz. Varför har vi inte det? Det har hÀnt nÄgot. Det har hÀnt nÄgot stort.
NÀr vi slog i 4 GHz-grÀnsen sÄ blev vÀrmen för mycket. Vi kan inte lÀngre ha snabbare processorer, för de blir alldeles för varma. De som överklockar en bra bit över 4 GHz skaffar vattenkylning. Det rÀcker inte med luft dÄ lÀngre. Industrin tÀnker inte tvinga alla att vattenkyla sina datorer. Industrin har gett upp jakten pÄ fler GHz.
SÄ vad kan man göra om man inte har snabbare processorer? Var tar utvecklingen vÀgen? Vi fÄr fler kÀrnor istÀllet. Nu har antalet kÀrnor börjat vÀxa lika snabbt som processorhastigheten gjorde förut.
Nu, Är 2012, tillverkas det vÀldigt fÄ datorer eller datorliknande enheter med bara en kÀrna. Samtliga nya, hÀftiga mobiltelefoner har flera kÀrnor (oftast fyra.) SÄ vitt jag vet har alla spelkonsoler flera kÀrnor. Laptops och stationÀra datorer Àr flerkÀrniga. Surfplattor Àr flerkÀrniga.
Man kan inte lÀngre utveckla lÄngsamma program och vÀnta pÄ att hÄrdvaran ska komma ikapp.
Gratislunchen Àr över. Vad kan vi utvecklare göra?
Ibland stöter jag pÄ blogginlÀgg som jag egentligen inte Àr intresserad av, men jag lÀser ÀndÄ för att författaren skriver sÄ bra. Det hÀr Àr ett av dem.
Och det Àr ju bra, för nu vet jag hur man kan dela upp load mellan cache-servrar pÄ ett skalbart och relativt tryggt sÀtt.

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch âą No registration required âą HD streaming
Re: Ăr nĂ„got tal summan av de övriga talen?
Men... sÀger du, Jag gillade ju den första funktionen, som tog tre argument. Det blir ju jÀttekrÄngligt om man ska göra en lista varje gÄng.
Ăverlagring, sĂ€ger jag, Ăverlagring, min vĂ€n.
Förutsatt att du har den funktionen vi kom fram till i ursprungliga inlÀgget sÄ kan du ju lÀtt skapa en funktion som tar tre argument istÀllet, like so:
def isSum(a: Int, b: Int, c: Int): Boolean = isSum(Vector(a, b, c))
Det dÀr Àr Scala för att sÀga det som pÄ svenska heter, "Att kolla om tre heltal Àr en summering Àr samma sak som att kolla om en lista av samma tre heltal Àr en summering."
Och allt var gott igen. Och det blev natt och morgon igen. Det var den andra dagen.
Tidskomplexitet förklarad (lite)
TÀnk dig att du ska leta upp ett speciellt namn i en telefonkatalog. Det finns tvÄ sjÀlvklara sÀtt att göra det pÄ.
Du kan börja pÄ Aab-Ericsson Sara, konstatera att "det var inte det hÀr namnet jag ville ha," gÄ vidare till nÀsta namn, som kanske rÄkar vara Aalto Catharina och konstantera "inte det hÀr heller." SÄ fortsÀtter du till nÀsta, nÀsta och nÀsta namn tills du hittar det du vill ha.
Att söka igenom en telefonkatalog pÄ det sÀttet tar tid. VÀldigt lÄng tid. Om namnet man letar efter Àr det sista namnet i katalogen mÄste man söka igenom lika mÄnga namn som det finns namn i katalogen. Man brukar kalla det för att sökningsmetoden man anvÀnder har en tidskomplexitet pÄ $$\\mbox{O}(n)$$, eller att metoden Àr linjÀr i sin tidskomplexitet.
$$\\mbox{O}(n)$$ betyder att "Om telefonkatalogen har $$n$$ namn, sÄ mÄste man i vÀrsta fall söka igenom $$n$$ namn för att hitta det man vill."
Som du sÀkert kÀnner till finns det andra metoder för att hitta namn i telefonkatalogen. Om du Àr smart kan du slÄ upp telefonkatalogen pÄ precis mitten, titta pÄ namnet som Àr pÄ mitten av sidan, och frÄga dig sjÀlv, "Namnet jag söker, ligger det före eller efter det namnet jag tittar pÄ nu?"
PÄ det sÀttet kan du fortsÀtta dela in telefonkatalogen i hÀlfter, och till slut har du bara ett eller inget namn kvar, beroende pÄ om det du söker finns eller inte finns i katalogen. DÄ har du utnyttjat att telefonkatalogen faktiskt Àr sorterad.
Det hÀftiga med den metoden Àr att den krÀver inte alls att man kollar igenom lika mÄnga namn som den förra. Om telefonkatalogen skulle ha 3 000 namn sÄ skulle du med förra metoden behöva lÀsa 3 000 namn. Det Àr sjukt mycket. Med den hÀr nya metoden behöver du bara lÀsa 12 namn. Bara tolv namn.
Den andra metoden kallas för en binÀr sökning och har en tidskomplexitet pÄ $$\mbox{O}(\\log{n})$$. Om telefonkatalogen innehÄller $$n$$ namn, sÄ behöver man i vÀrsta fall bara söka igenom $$\\log_2{n}$$ namn innan man hittar det man letar efter. (Bry dig inte om vad det hÀr $$\\log$$ betyder, det enda du behöver veta Àr att $$\\log{n}$$ Àr mycket mindre Àn $$n$$.)
TillÄt mig illustrera hur stor skillnaden Àr mellan $$\mbox{O}(\\log{n})$$ och $$\\mbox{O}(n)$$. TÀnk dig att det flyttar in massa mÀnniskor i omrÄdet, sÄ telefonkatalogens storlek dubbleras. Telefonkatalogen blir dubbelt sÄ tjock. Telefonkatalogen gÄr frÄn att vara kanske fyra centimeter tjock till att bli Ätta centimeter. Det Àr mÄnga, mÄnga fler namn.
Med den linjÀra sökningen behöver du nu söka igenom dubbelt sÄ mÄnga namn. Om det tog en halvtimme frÄn början, sÄ kommer det ta en timme nu att leta igenom alla namn.
Med den binÀra sökningen behöver du bara leta igenom ett namn till. NÀr telefonkatalogens tjocklek dubbleras behöver du bara leta igenom ett enda ynka litet namn till.
Det Àr dÀrför man, nÀr man programmerar, hellre anvÀnder metoder som gÄr i $$\mbox{O}(\\log{n})$$ Àn $$\\mbox{O}(n)$$.
GrundlÀggande lambdakalkyl
Lambdakalkyl lÄter fÄnigt (jag tÀnker pÄ professor Kalkyl i Tintin) men Àr i sjÀlva verket riktigt lÀckert. Lambdakalkyl formar grunden för all funktionell programmering, och det Àr sÄ simpelt.
Du kÀnner förmodligen till funktioner frÄn matematiken eller programmeringen. SÄ hÀr kan till exempel en funktione inom matematiken se ut.
$$$f(x) = 2x$$$
Funktionen $$f$$ tar ett $$x$$ som argument, och returnerar det dubbla vÀrdet (tvÄ gÄnger $$x$$.) LÄt mig visa precis samma sak i lambdakalkylen.
$$$\\lambda x \\rightarrow 2x$$$
Detta Àr en funktion som dubblerar invÀrdet. Först skriver man $$\\lambda$$ för att ange att det Àr en lambdafunktion, sen skriver man parameterns namn (bara en parameter!) som funktionen ska ta emot som argument, sen har jag valt att anvÀnda en pil (Àven om det inte Àr helt korrekt) och sen funktionskroppen. Du kan se följande omvandling:
$$$\\mbox{funktionsnamn}(\\mbox{parameter}) = \\mbox{funktionskropp}$$$
Ă€r samma sak som
$$$\\lambda \\mbox{parameter} \\rightarrow \\mbox{funktionskropp}$$$
Att ha en pil dÀr Àr mitt pÄfund. Egentligen ska det vara en punkt, men punkt Àr sÄ sjukt otydligt sÄ jag lÄter gÀrna bli det. Lambdafunktioner har inget namn, Àr en första iakttagelse. Man kan identifiera dem med deras parameternamn istÀllet. (Det innebÀr att parameternamnet mÄste vara unikt! Jag Äterkommer till det.)
SÄ. Right. En lambdafunktion Àr liksom en helt insluten enhet. Du kan plocka ut en lambdafunktion frÄn var som helst och den betyder fortfarande samma sak, oavsett var den sitter. SÄ hÀr applicerar man lambdafunktioner till nÄgot argument:
$$$(\\lambda x \\rightarrow 2x)\\ 5$$$
Vi innesluter lambdafunktionen i parenteser för att visa att det Àr en enhet, och sen sÀtter vi nÄgot argument till höger om den. Det som Àr direkt till höger om funktionen kommer att stoppas in istÀllet för $$x$$ i funktionen. I det hÀr fallet fÄr vi $$$2 \\times 5$$$ som i sin tur blir 10, det vet vi alla. Men grejen Àr att nÀr man stoppar in ett argument i en lambdafunktion, sÄ tar man bort allt fancy $$\\lambda x \\rightarrow$$, om det inte behövs lÀngre. Kvar Àr bara funktionskroppen, med alla $$x$$ ersatta med argumentet.
HÀr fÄr du nÄgra till lambdafunktioner att trÀna pÄ.
$$$(\\lambda y \\rightarrow 5y)\\ 7$$$ $$$(\\lambda z \\rightarrow z^2)\\ 8$$$ $$$(\\lambda k \\rightarrow 3k + 9)\\ 3$$$
SÄ, jag tror du fattar. Dags att gÄ vidare till HÀftigt #1. Man kan anvÀnda vilka vÀrden som helst som argument, inklusive andra lambdafunktioner! HÀr Àr en funktion som tar en funktion som argument.
$$$\\lambda f \\rightarrow f\\ 4$$$
Den hÀr kan ta emot en funktion i $$f$$, och sen stoppar den in den funktionen i 4. SÄ den hÀr funktionen gör nÄgot med fyra. Vad nÄgot Àr beror pÄ vilken funktion man stoppar in. Till exempel kan man göra sÄ hÀr:
$$$(\\lambda f \\rightarrow f\\ 4)\\ (\\lambda x \\rightarrow 2x)$$$
För att ta reda pÄ vad det hÀr blir fÄr vi börja med att stoppa in $$\\lambda x$$ i $$\\lambda f$$, och dÄ fÄr vi $$$(\\lambda x \\rightarrow 2x)\\ 4$$$
Vi har bara gjort vÄr vanliga ersÀttning och vi bytte ut alla $$f$$ i funktionskroppen mot argumentet. Den hÀr resulterande funktionen vet vi ju hur man rÀknar ut. SÄ, det dÀr Àr ju flexibelt. Nu kommer HÀftigt #2.
Lambdafunktioner kan returnera vilka vÀrden som helst, Àven andra lambdafunktioner. Nyss anvÀnde vi lambdafunktioner som argument, nu kan vi ocksÄ returnera dem.
Detta Àr en lambdafunktion som returnerar en annan lambdafunktion.
$$$\\lambda b \\rightarrow (\\lambda a \\rightarrow a + b)\\ 3$$$
För att veta vad funktionen $$\\lambda b$$ returnerar, mÄste vi först veta vad dess kropp blir. Men vi vet ju redan att $$(\\lambda a \\rightarrow a + b) 3$$ kommer att ge resultatet av att ersÀtta alla $$a$$ med 3. SÄ, om vi gör det fÄr vi $$$\\lambda b \\rightarrow 3 + b$$$
Och wham! En lambdafunktion returnerade en annan lambdafunktion! Den hÀr funktionen kan vi nu ge ett argument för att plussa nÄgot med tre.
$$$(\\lambda b \\rightarrow 3 + b)\\ 4$$$
Och vi fÄr $$3 + 4$$. Nu kommer the interesting part. Vi skulle kunna skrivit allt pÄ en rad istÀllet, like so:
$$$(\\lambda b \\rightarrow (\\lambda a \\rightarrow a + b)\\ 3)\\ 4$$$
Det hÀr betyder "Jag vill ha $$a+b$$ dÀr $$a = 3$$ och $$b = 4$$." Ser du hur det kan tolkas som en funktion med tvÄ argument, fast det egentligen Àr tvÄ funktioner med ett argument var? SÄ hÀr skulle man kunna skriva:
$$$(\\lambda b \\rightarrow (\\lambda a \\rightarrow a + b)\\ b)\\ 3\\ 4$$$
Ser du!! Det Àr en funktion i en funktion, sÄ det Àr visserligen tvÄ funktioner, men till det yttre tar den tvÄ argument. Om du skulle kunna stoppa in lambdorna i en lÄda, sÄ hÀr,
$$$\\mbox{sum} = \\lambda b \\rightarrow (\\lambda a \\rightarrow a + b)\\ b$$$
sÄ skulle du ocksÄ kunna anropa den sÄ hÀr:
$$$\mbox{sum}\\ 3\\ 4$$$
En funktion som tar emot tvÄ argument! Trots att den Àr uppbyggd av lambdor som bara kan ta ett argument. VÀnta nu, hur gick det dÀr till? Vi ÄtergÄr till den ursprungliga lambdan som vi döpte om till $$\\mbox{sum}$$.
$$$(\\lambda b \\rightarrow (\\lambda a \\rightarrow a + b)\\ b)\\ 3\\ 4$$$
Vi börjar med att göra vad vi kan. Trean Àr ett argument till $$\\lambda b$$, sÄ vi kan börja med att stoppa in den:
$$$(\\lambda b \\rightarrow (\\lambda a \\rightarrow a + b)\\ 3)\\ 4$$$
Notera tvÄ saker hÀr.
Vi kan inte stoppa in trean istÀllet för $$b$$ inuti $$\\lambda a$$, för vi kan inte se in i andra lambdafunktioner. Det hade varit smidigt om vi kunde, men vi kan inte. Det Àr bra med strikta regler för vad man fÄr och inte fÄr göra.
Vi har inte tagit bort $$\\lambda b \\rightarrow$$. Eftersom det finns en lambdafunktion kvar inuti $$\\lambda b$$:s funktionskropp kan vi inte sÀkert veta att $$\\lambda b$$ osv inte lÀngre behövs. (Vi kan inte se in i andra lambdafunktioner, som sagt.) Vi behÄller det tills vi vet sÀkert att det inte behövs lÀngre.
SÄ, nu har vi ett nytt uttryck, och det vet vi vad vi kan göra med det. Stoppa in trean som argument till $$\\lambda a$$.
$$$(\\lambda b \\rightarrow 3 + b)\\ 4$$$
DÀr fick vi ta bort $$\\lambda a \\rightarrow$$, för vi vet sÀkert att det inte behövs mer. Nu har vi ett nytt uttryck, som vi ocksÄ vet vad man gör med. Stoppa in fyran som argument till $$\lambda b$$.
$$$3 + 4$$$
Och sÄ har vi lyckats följa hur en funktion som tar emot tvÄ argument fungerar, nÀr den faktiskt Àr uppbyggd av flera funktioner som tar ett argument var. Att bygga upp en funktion som tar flera argument utav flera funktioner som bara tar ett argument kallas förresten för currying.
Nu ringer mitt sÀllskap pÄ dörren, men lite senare kanske jag kan visa hur man faktiskt kan programmera i lambdakalkyl.