diff options
author | Dmitrii Kuznetsov <torgeek@users.noreply.github.com> | 2021-02-22 18:36:35 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-22 18:36:35 +0300 |
commit | bc8bd2646f068cfb402850f7c0f9b1dbfe81e5a0 (patch) | |
tree | 89213fd6afbf9cc9303c1c2fa08dafc840a9d99d /sv-se | |
parent | 363d5281f1e3d5bee6339b5316405b0a4b592c49 (diff) | |
parent | 110511a10110f96b20f107c078f7d5ef4c01b109 (diff) |
Merge pull request #1 from adambard/master
Merge from original adambard
Diffstat (limited to 'sv-se')
-rw-r--r-- | sv-se/brainfuck-sv.html.markdown | 1 | ||||
-rw-r--r-- | sv-se/haskell-sv.html.markdown | 461 | ||||
-rw-r--r-- | sv-se/nix-sv.html.markdown | 368 |
3 files changed, 830 insertions, 0 deletions
diff --git a/sv-se/brainfuck-sv.html.markdown b/sv-se/brainfuck-sv.html.markdown index e9fbc436..57520955 100644 --- a/sv-se/brainfuck-sv.html.markdown +++ b/sv-se/brainfuck-sv.html.markdown @@ -1,5 +1,6 @@ --- language: brainfuck +filename: brainfuck-sv.bf contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] - ["Mathias Bynens", "http://mathiasbynens.be/"] diff --git a/sv-se/haskell-sv.html.markdown b/sv-se/haskell-sv.html.markdown new file mode 100644 index 00000000..da2d6ab0 --- /dev/null +++ b/sv-se/haskell-sv.html.markdown @@ -0,0 +1,461 @@ +--- +language: Haskell +filename: learnhaskell-sv.hs +contributors: + - ["Adit Bhargava", "http://adit.io"] +translators: + - ["Edward Tjörnhammar", "http://edwtjo.me"] +lang: sv-se +--- + +Haskell skapades för att vara ett praktiskt, rent, funktionellt +programmeringsspråk. Det är känt för sin använding av monader och dess +härledande typsystem men anledningen till att jag ständigt återbesöker språket +är på grund av dess elegans. Haskell gör programmering till ett rent nöje. + +```haskell +-- Radkommenterar börjar med två bindestreck. +{- Flerradskommentarer innesluts av vänster/höger måsvinge bindestreck +block på detta vis. +-} + +---------------------------------------------------- +-- 1. Fördefinierade datatyper och operatorer +---------------------------------------------------- + +-- Du har siffror +3 -- 3 + +-- Matte fungerar som förväntat +1 + 1 -- 2 +8 - 1 -- 7 +10 * 2 -- 20 +35 / 5 -- 7.0 + +-- Division är normalt inte heltalsdivision +35 / 4 -- 8.75 + +-- Heltalsdivision, här infix div +35 `div` 4 -- 8 + +-- Boolar (Sant och Falskt) är fördefinierade +True +False + +-- Samt dess operationer +not True -- False +not False -- True +1 == 1 -- True +1 /= 1 -- False +1 < 10 -- True + +-- I ovanstående exempel är `not` en funktion vilken bara tar ett argument. +-- Haskell behöver inte paranteser för sina funktionsanrop... alla argument +-- ges mellanslagsseparerade direkt efter funktionen. Det övergripande mönstret +-- är: +-- func arg1 arg2 arg3... +-- Se sektionen om funktioner för information om hur du skriver dina egna. + +-- Strängar och bokstäver +"Detta är en sträng" +'a' -- bokstav +'Du kan inte använda enkelfnutt för strängar.' -- fel! + +-- Strängar kan konkateneras +"Hej " ++ "världen!" -- "Hej världen!" + +-- En sträng är en lista av bokstäver +['H', 'e', 'j', 's', 'a', 'n'] -- "Hejsan" +"Detta är en sträng" !! 0 -- 'D' + + +---------------------------------------------------- +-- 2. Listor och Tupler +---------------------------------------------------- + +-- Varje element i en lista måste ha samma typ. +-- Dessa listor är ekvivalenta: +[1, 2, 3, 4, 5] +[1..5] + +-- Intervall är mångsidiga. +['A'..'F'] -- "ABCDEF" + +-- Man kan stega intervall. +[0,2..10] -- [0, 2, 4, 6, 8, 10] +[5..1] -- [] (Haskell förutsätter normalt inkrement) +[5,4..1] -- [5, 4, 3, 2, 1] + +-- Indexering in i en lista +[1..10] !! 3 -- 4 (nollindexerat) + +-- Man kan ha oändliga listor i Haskell! +[1..] -- listan över alla naturliga tal + +-- Oändliga listor fungerar enbart för att Haskell har "lat evaluering". +-- Det betyder att Haskell bara evaluerar de uttryck den måste. Du kan alltså +-- fråga efter det 1000:e elementet i en oändlig lista och Haskell kommer då ge +-- dig det: + +[1..] !! 999 -- 1000 + +-- Nu har Haskell evaluerat element 1 till 1000 i denna lista... men resten +-- av medlemmarna i denna oändliga lista existerar inte ännu! Haskell kommer +-- faktiskt inte utvärdera element den inte måste. + +-- Sammanslagning av två listor +[1..5] ++ [6..10] + +-- Lägg till 0 vid listhuvudet +0:[1..5] -- [0, 1, 2, 3, 4, 5] + +-- fler listoperationer som huvud, svans, initiella samt sista +head [1..5] -- 1 +tail [1..5] -- [2, 3, 4, 5] +init [1..5] -- [1, 2, 3, 4] +last [1..5] -- 5 + +-- listomfattningar +[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10] + +-- med bivilkor +[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10] + +-- Varje element i en tupel kan ha olika typ men en tupel kan bara ha en +-- fixerad, eller statisk, längd. +-- En tupel: +("haskell", 1) + +-- För att komma åt element i ett par, alltså en 2-tupel, finns +-- de fördefinierade funktionerna: +fst ("haskell", 1) -- "haskell" +snd ("haskell", 1) -- 1 + +---------------------------------------------------- +-- 3. Funktioner +---------------------------------------------------- +-- En enkel funktion med två parametrar +add a b = a + b + +-- Notera även att om du använder ghci (Haskellinterpretatorn) kommer du behöva +-- använda `let` namnbindning för att synliggöra din funktionsdeklaration, +-- alltså +let add a b = a + b + +-- För att använda funktionen +add 1 2 -- 3 + +-- Man kan även göra funktionsanropet infix, alltså mellan parametersättningen, +-- med hjälp av bakåtfnuttar: +1 `add` 2 -- 3 + +-- Du kan även definiera funktioner vars funktionsnamn avsaknar bokstäver! +-- Med hjälp av parenteser kan du därmed definiera operatorer (normalt infix)! +-- Följande är en operator för heltalsdivision, vilken förlitar sig på div: +(//) a b = a `div` b +35 // 4 -- 8 + +-- Funktionsvakter: ett enkelt sätt att grena ut dina funktioner +fib x + | x < 2 = 1 + | otherwise = fib (x - 1) + fib (x - 2) + +-- Mönstermatchning fungerar på liknande vis. Här ger vi tre olika +-- parametermatchningar för vårat fib-resulat. Haskell kommer automatiskt följa +-- första bästa träff, uppifrån ned, vars vänstra sida om likhetstecknet matchar +-- anroparens parametervärde. +fib 1 = 1 +fib 2 = 2 +fib x = fib (x - 1) + fib (x - 2) + +-- Mönstermatchning på tupler: +foo (x, y) = (x + 1, y + 2) + +-- Mönstermatchning på listor. Här är `x` det första elementet i listan och `xs` +-- är resten av listan. Nu kan vi skriva våran egen map-funktion +minMap func [] = [] +minMap func (x:xs) = func x:(minMap func xs) + +-- Anonyma funktioner, eller lambdauttryck, skapas med hjälp av omvänt +-- snedstreck, följt av parametrarna +minMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7] + +-- Användning av fold (även kallad `inject`, `reduce`, osv.) tillsammans med en +-- anonym funktion. `fold1` är en vänstervikande funktion och använder första +-- värdet i listan som det initiella värdet för ackumulatorn. +foldl1 (\acc x -> acc + x) [1..5] -- 15 + +---------------------------------------------------- +-- 4. Mer funktioner +---------------------------------------------------- + +-- Partiell applikation: +-- Om du inte anropar funktionen med alla sina argument +-- blir den partiellt applicerad. Det betyder att du erhåller en funktion där en +-- delmängd av parametrarna blivit värdesatta men några är fortfarande fria. +add a b = a + b +foo = add 10 -- foo är nu en funktion som tar ett nummer och lägger till 10 till + -- det +foo 5 -- 15 + +-- Ett annat sätt att skriva samma sak +foo = (10+) +foo 5 -- 15 + +-- Funktionskomposition: +-- Operatorn `.` kedjar ihop funktioner +-- Till exempel, nedan är `foo` en funktion som tar ett värde, den adderar 10 +-- till det, multiplicerar det resultatet med 4 och sen ersätts med det värdet. +foo = (4*) . (10+) + +-- 4*(10+5) = 60 +foo 5 -- 60 + +-- Precedensordning: +-- Haskell har en operator `$`. Denna operator applicerar en funktion till en +-- given parameter med dess precedens. I kontrast mot vanlig +-- funktionsapplikation, vilket har den högsta utvärderingsprioriteten 10 och +-- associerar till vänster, har denna prioritetsordning 0 och är +-- högerassociativ. Denna låga prioritet medför att parameteruttrycket till +-- höger om operatorn får det reducerat innan det appliceras till sin vänster. + +-- före +even (fib 7) -- falskt + +-- ekvivalent +even $ fib 7 -- falskt + +-- med funktionskomposition +even . fib $ 7 -- falskt + + +---------------------------------------------------- +-- 5. Typsignaturer +---------------------------------------------------- + +-- Haskell har ett väldigt starkt typsystem, alla giltiga uttryck har en typ. + +-- Några grundläggande typer: +5 :: Integer +"hello" :: String +True :: Bool + +-- Funktioner har också typer, +-- `not` tar en bool och returnerar en bool: +-- not :: Bool -> Bool + +-- Här är ett exempel på en funktionssignatur vilken beskriver en funktion som +-- reducerar två heltal till ett: +-- add :: Integer -> Integer -> Integer + +-- Trots att Haskell härleder typen på icke typsatta uttryck är det bra form att +-- explicit ange dessa för ens deklarerade funktioner: +double :: Integer -> Integer +double x = x * 2 + +---------------------------------------------------- +-- 6. Kontrollflöde och Ifsatser +---------------------------------------------------- + +-- if-sats +haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome" + +-- if-statser kan spridas över rader men indentering har betydelse +haskell = if 1 == 1 + then "awesome" + else "awful" + +-- case uttryck: följande är ett exempel på kommandoradsparsning +case args of + "help" -> printHelp + "start" -> startProgram + _ -> putStrLn "bad args" + +-- Haskell har inte loopar istället används recursion. +-- map applicerar en funktion över varje element i en lista + +map (*2) [1..5] -- [2, 4, 6, 8, 10] + +-- man kan deklarera en for funktion genom att använda map +for array func = map func array + +-- och därefter använda den tillsammans med en anonym funktion för att +-- efterlikna en loop +for [0..5] $ \i -> show i + +-- men vi kunde även ha skrivit på följande vis: +for [0..5] show + +-- Du kan använda foldl eller foldr för att reducera en lista +-- foldl <fn> <initial value> <list> +foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43 + +-- Vilket är samma sak som +(2 * (2 * (2 * 4 + 1) + 2) + 3) + +-- foldl viker från vänster, foldr från höger +foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16 + +-- Vilket alltså är samma sak som +(2 * 1 + (2 * 2 + (2 * 3 + 4))) + +---------------------------------------------------- +-- 7. Datatyper +---------------------------------------------------- + +-- Såhär definierar du din egen datatyp i Haskell +data Color = Red | Blue | Green + +-- När du gjort det kan du använda den i funktionssignaturer och uttryck +say :: Color -> String +say Red = "Du är Rö!" +say Blue = "Du är Blå!" +say Green = "Du är Grön!" + +-- Dina datatyper kan även ta parametrar +data Maybe a = Nothing | Just a + +-- Följande uttryck är alla specialiseringar av typen Maybe +Just "hello" -- har typen `Maybe String` +Just 1 -- har typen `Maybe Int` +Nothing -- har typen `Maybe a` för alla `a` + +---------------------------------------------------- +-- 8. Haskell IO +---------------------------------------------------- + +-- Även om IO inte kan förstås fullt ut utan att först förklara monader är det +-- inte svårt att lära sig tillräckligt för att komma igång + +-- När ett Haskellprogram körs är det topnivåns main som körs. Main måste +-- returnerna ett värde av typen `IO a`, för någon typ `a`. Till exempel: + +main :: IO () +main = putStrLn $ "Hej, himmelen! " ++ (say Blue) +-- putStrLn har typen type String -> IO () + +-- Det är enkelt att göra IO om du kan implementera ditt program som en funktion +-- från String till String. Funktionen +-- interact :: (String -> String) -> IO () +-- tar denna funktion och matar den med strängdata från stdin och skriver ut +-- resultatet som en sträng på stdout + +countLines :: String -> String +countLines = show . length . lines + +main' = interact countLines + +-- Du kan tänka på värden av typen `IO ()` som att representera +-- händelsesekvenser du vill att din dator skall utföra, likt imperativa språk. +-- För att kedja ihop händelsesekvenser använder man ett syntaktiskt socker +-- kallat do-notation. Som exempel: + +sägHej :: IO () +sägHej = do + putStrLn "Vad heter du?" + namn <- getLine -- denna raden läser en rad från stdin och vi binder den till + -- funktionsnamnet `namn` + putStrLn $ "Hejsan, " ++ namn + +-- Övning: Skriv din egen version av interageringsfunktionen `interact` som bara +-- läser en rad från stdin, vanliga `interact` läser till EOF. + +-- Koden i sägHej kommer dock aldrig exekveras. Den enda handlingen som blir det +-- är som bekant utvärderingen av `main`. +-- För att köra `sägHej` kommentera ut definition av `main` ovan och +-- avkommentera nedanstående version: +-- main = sayHello + +-- Låt oss bättre förstå hur funktionen `getLine` vi just använde fungerar. Dess +-- typsignatur är: +-- getLine :: IO String +-- Du kan tänka på typen `IO a` som att representeras av ett datorprogram vilken +-- kommer generera ett värde av typen `a` när det exekveras (utöver allt annat +-- det kan tänkas göra). Vi kan därtill binda detta värde till ett namn för +-- återanvändning genom att använda `<-`. Vi kan även skapa våran egen handling +-- av typen `IO String`: + +handling :: IO String +handling = do + putStrLn "Detta är en rad, tihi" + input1 <- getLine + input2 <- getLine + -- Typen av hela `do` blocket är vad som står på sista raden. Här är även + -- `return` inte ett nyckelord i språket utan en funktion med en typsignatur + return (input1 ++ "\n" ++ input2) -- return :: String -> IO String + +-- Vi kan använda `return` på samma sätt som vi använde `getLine`: + +main'' = do + putStrLn "Jag kommer eka två rader!" + result <- handling + putStrLn result + putStrLn "Tack och hej leverpastej!" + +-- Typen `IO` är ett exempel på en monad. Sättet Haskell utnyttjar monader på är +-- anledningen till hur språket kan bibehålla sin renhet. En funktion vilken +-- interagerar med omvärlden (alltså gör IO) blir markerad med `IO` i sin +-- typsignatur. Detta låter oss enkelt upptäcka vilka funktioner som är "rena" +-- (inte interagerar med omvärlden eller är tillståndsoberoende) and vilka +-- funktioner som inte är det. + +-- Detta är ett mäktigt särdrag eftersom det är enkelt att köra rena funktioner +-- sammanlöpande; Samtidig programmering är enkel att göra i Haskell. + +---------------------------------------------------- +-- 9. Haskell REPL (kodtolk) +---------------------------------------------------- + +-- Efter installation av GHC kan vi starta tolken genom att skriva `ghci`. +-- Nu kan du mata in Haskellkod direkt i den. Nya värden måste introduceras med +-- `let` bindning: + +let foo = 5 + +-- Du kan även se typen av namnbindningen med `:t` + +> :t foo +foo :: Integer + +-- Operatorer, som `+`, `:` och `$` är funktioner. Deras typ kan inspekteras +-- genom att skriva operatorn mellan parenteser: + +> :t (:) +(:) :: a -> [a] -> [a] + +-- Du kan få ytterliggare information om något namn genom att använda `:i` + +> :i (+) +class Num a where + (+) :: a -> a -> a + ... + -- Defined in ‘GHC.Num’ +infixl 6 + + +-- Du kan även köra alla handlingar av typen `IO ()` direkt i tolken + +> sägHej +Vad är ditt namn? +Kompis! +Hello, Kompis! + +``` + +Det finns mycket mer att upptäcka med Haskell, inklusive typklasser och monader. +Vilka är de stora idéerna som gör Haskell till det roliga programmeringsspråket +det är. Jag lämar dig med ett sista exempel; En implementation av quicksort: + +```haskell +qsort [] = [] +qsort (p:xs) = qsort mindre ++ [p] ++ qsort större + where mindre = filter (< p) xs + större = filter (>= p) xs +``` + +Det finns två populära sätt att installera Haskell på: Den traditionella [Cabal sättet](http://www.haskell.org/platform/), eller det nyare [Stack sättet](https://www.stackage.org/install). + +Du kan finna vänligare och/eller djupare introduktioner till Haskell på engelska +från: +[Learn you a Haskell](http://learnyouahaskell.com/), +[Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com/) eller +[Real World Haskell](http://book.realworldhaskell.org/). diff --git a/sv-se/nix-sv.html.markdown b/sv-se/nix-sv.html.markdown new file mode 100644 index 00000000..15d9456b --- /dev/null +++ b/sv-se/nix-sv.html.markdown @@ -0,0 +1,368 @@ +--- +language: nix +filename: learn-sv.nix +contributors: + - ["Chris Martin", "http://chris-martin.org/"] +translators: + - ["Edward Tjörnhammar", "http://edwtjo.me"] +lang: sv-se +--- + +Nix är ett enkelt funktionelt språk utvecklat för +[Nix pakethanteraren](https://nixos.org/nix/) och +[NixOS](https://nixos.org/) linuxdistributionen. + +Du kan utvärdera Nix uttryck genom att använda +[nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate) +eller [`nix-repl`](https://github.com/edolstra/nix-repl). + +``` +with builtins; [ + + # Kommentarer + #========================================= + + # Inlinekommentarer ser ut såhär. + + /* Flerradskommentarer ser ut + såhär. */ + + + # Booleaner + #========================================= + + (true && false) # Och + #=> false + + (true || false) # Eller + #=> true + + (if 3 < 4 then "a" else "b") # Villkorlig + #=> "a" + + + # Heltal + #========================================= + + # Heltal är den enda numeriska typen. + + 1 0 42 (-3) # Några heltal + + (4 + 6 + 12 - 2) # Addition + #=> 20 + + (7 / 2) # Division + #=> 3 + + + # Strängar + #========================================= + + "Stränglitteraler omgärdas av raka citationstecken." + + " + Stränglitteraler kan sträcka sig + över flera rader. + " + + '' + Detta kallas för en indenterad strängliteral, omgärdad av dubbla apostrofer + Den plockar intelligent bort ledande blanktecken. + '' + + '' + a + b + '' + #=> "a\n b" + + ("ab" + "cd") # Strängkonkatenering + #=> "abcd" + + # Antikvotering låter dig bädda in språkvärden i strängar. + ("Din hemkatalog är ${getEnv "HOME"}") + #=> "Din hemkatalog är /home/alice" + + + # Sökvägar + #========================================= + + # Nix har en primitiv, inbyggd, typ för sökvägar. + /tmp/tutorials/learn.nix + + # Relativa sökvägar förenas med sökvägen till dess definerande fils sökväg + # vid tolkningstillfället för att skapa dess absoluta sökväg. + + tutorials/learn.nix + #=> /the-base-path/tutorials/learn.nix + + # En sökväg måste innehålla åtminstonde ett snedstreck, så en relativ sökväg + # till en fil i samma katalog måste ges ett "./" prefix + + ./learn.nix + #=> /the-base-path/learn.nix + + # Divisionsoperatorn / måste omges av blanksteg om man vill att det skall + # tolkas som heltalsdivision + + 7/2 # Detta är en sökväg + (7 / 2) # Detta är heltalsdivision + + + # Importer + #========================================= + + # En nix fil innehåller ett enstaka topnivåuttryck utan fria variabler. + # Ett importuttryck evalueras till värdet på filen som den importerar. + (import /tmp/foo.nix) + + # Importer kan också specificeras med hjälp av strängar. + (import "/tmp/foo.nix") + + # Importsökvägar måste vara absoluta. Sökvägslitteraler härleds vid + # tolkningstillfället så följande är ok. + (import ./foo.nix) + + # Men detta är inte något som sker med strängar. + (import "./foo.nix") + #=> error: string ‘foo.nix’ doesn't represent an absolute path + + + # Let + #========================================= + + # `let` block tillåter oss att binda värden till namn. + (let x = "a"; in + x + x + x) + #=> "aaa" + + # Bindingar kan referera till varandra och deras ordning sinsemellan spelar + # ingen roll. + (let y = x + "b"; + x = "a"; in + y + "c") + #=> "abc" + + # Innre bindningar skuggar utanpåliggande bindingar. + (let a = 1; in + let a = 2; in + a) + #=> 2 + + + # Funktioner + #========================================= + + (n: n + 1) # En lambdafunktion som lägger till 1 + + ((n: n + 1) 5) # Samma funktion applicerad på 5 + #=> 6 + + # Det finns ingen syntax för direkt namngivna funktioner, istället binder man + # dessa med `let` block som andra värden. + (let succ = (n: n + 1); in succ 5) + #=> 6 + + # En funktion är en lambda med en parameter. Flera parameterar kan ges med + # hjälp av currying. + ((x: y: x + "-" + y) "a" "b") + #=> "a-b" + + # Vi kan också ha namngivna funktionsparametrar, vilket vi kommer komma till + # senare, efter att vi introducerat attributset. + + # Listor + #========================================= + + # Listor noteras med hakparenteser. + + (length [1 2 3 "x"]) + #=> 4 + + ([1 2 3] ++ [4 5]) + #=> [1 2 3 4 5] + + (concatLists [[1 2] [3 4] [5]]) + #=> [1 2 3 4 5] + + (head [1 2 3]) + #=> 1 + (tail [1 2 3]) + #=> [2 3] + + (elemAt ["a" "b" "c" "d"] 2) + #=> "c" + + (elem 2 [1 2 3]) + #=> true + (elem 5 [1 2 3]) + #=> false + + (filter (n: n < 3) [1 2 3 4]) + #=> [ 1 2 ] + + + # Mängder + #========================================= + + # Ett attributset är en oordnad mappning av strängnycklar och värden. + { foo = [1 2]; bar = "x"; } + + # Punktoperatorn . väljer ett värde från attributset:et + { a = 1; b = 2; }.a + #=> 1 + + # Frågeoperatorn ? testar om en nyckel är närvarande i ett attributset + ({ a = 1; b = 2; } ? a) + #=> true + ({ a = 1; b = 2; } ? c) + #=> false + + # Snedstrecksoperatorn // slår ihop två attributset:ar. + ({ a = 1; } // { b = 2; }) + #=> { a = 1; b = 2; } + + # Värden på höger skriver över värden till vänster. + ({ a = 1; b = 2; } // { a = 3; c = 4; }) + #=> { a = 3; b = 2; c = 4; } + + # Recursionsnyckelordet rec noterar ett rekursivt attributset (en fixpunkt) + # i vilket attributen kan referera till varandra. + (let a = 1; in { a = 2; b = a; }.b) + #=> 1 + (let a = 1; in rec { a = 2; b = a; }.b) + #=> 2 + + # Nästlade attributset:ar kan definieras bit för bit. + { + a.b = 1; + a.c.d = 2; + a.c.e = 3; + }.a.c + #=> { d = 2; e = 3; } + + # Ett attributsets barn kan inte tilldelas på detta vis om attributsetet + # självt blivit direkt tilldelat. + { + a = { b = 1; }; + a.c = 2; + } + #=> error: attribute ‘a’ already defined + + + # Bindningsintroduktion, `with` + #========================================= + + # Det attributset vilket återfinns i ett `with` uttryck kommer få sina + # värdebindningar introducerade i efterkommande uttryck. + (with { a = 1; b = 2; }; + a + b) + # => 3 + + # Innre bindningar skuggar yttre bindningar. + (with { a = 1; b = 2; }; + (with { a = 5; }; + a + b)) + #=> 7 + + # Första raden av detta exempel börjar med "with builtins;" eftersom builtins + # är ett attributset innehållande alla inbyggda hjälpfunktioner såsom + # (length, head, tail, filter, etc.). Detta sparar oss från att hela tiden + # referera in i det attributset:et , alltså du kan använda bara "length" + # istället för "builtins.length". + + + # Attributsetmönster + #========================================= + + # Attributset är användbara när vi skall skicka med flera värden till en + # funktion. + (args: args.x + "-" + args.y) { x = "a"; y = "b"; } + #=> "a-b" + + # Man kan använda attributsetmönster för ökad tydlighet. + ({x, y}: x + "-" + y) { x = "a"; y = "b"; } + #=> "a-b" + + # Attributmönster misslyckas dock om det medskickade attributmönstret + # innehåller extra nycklar. + ({x, y}: x + "-" + y) { x = "a"; y = "b"; z = "c"; } + #=> error: anonymous function called with unexpected argument ‘z’ + + # Genom att lägga till ", ..." kan vi ignorera ytterliggare nycklar. + ({x, y, ...}: x + "-" + y) { x = "a"; y = "b"; z = "c"; } + #=> "a-b" + + + # Felmeddelanden + #========================================= + + # `throw` gör att programtolken gör abort med dess tillhörande felmeddelande + causes evaluation to abort with an error message. + (2 + (throw "foo")) + #=> error: foo + + # `tryEval` fångar kastade fel `throw`. + (tryEval 42) + #=> { success = true; value = 42; } + (tryEval (2 + (throw "foo"))) + #=> { success = false; value = false; } + + # `abort` fungerar som `throw`, men är kritiskt och kan inte fångas. + (tryEval (abort "foo")) + #=> error: evaluation aborted with the following error message: ‘foo’ + + # `assert` utvärderas till det givna värdet om dess predikat är sant. + # annars skickar den ett fångbart fel. + (assert 1 < 2; 42) + #=> 42 + (assert 1 > 2; 42) + #=> error: assertion failed at (string):1:1 + (tryEval (assert 1 > 2; 42)) + #=> { success = false; value = false; } + + + # Orenhet + #========================================= + + # Eftersom repeterbarhet för byggen är en kritisk egenskap för + # Nix-pakethanteraren betonas funktionell renhet i Nix-programmeringsspråket. + # Men med det sagt existerar det källor till orenhet + + # Man kan referera till miljövariabler. + (getEnv "HOME") + #=> "/home/alice" + + # `trace` funktionen används för att debugga. Den skriver ut första argumentet + # till stderr och reduceras samtidigt till det andra argumentet. + (trace 1 2) + #=> trace: 1 + #=> 2 + + # Man kan skriva filer till Nix-store, lagringsplatsen för alla Nix-uttryck. + # Även om detta är orent beteende är det hyfsat säkert eftersom filens + # lagringsplats är härledd från dess innehåll och beroenden. Man kan läsa + # filer från precis överallt. I nedanstående exempel skriver vi en fil till + # Nix-store och sedan läser tillbaka den. + + (let filename = toFile "foo.txt" "hello!"; in + [filename (builtins.readFile filename)]) + #=> [ "/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt" "hello!" ] + + # Vi kan också ladda ned filer till Nix-store. + (fetchurl "https://example.com/package-1.2.3.tgz") + #=> "/nix/store/2drvlh8r57f19s9il42zg89rdr33m2rm-package-1.2.3.tgz" + +] +``` + +### Vidare Läsning (eng) + +* [Nix Manual - Nix expression language] + (https://nixos.org/nix/manual/#ch-expression-language) + +* [James Fisher - Nix by example - Part 1: The Nix expression language] + (https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55) + +* [Susan Potter - Nix Cookbook - Nix By Example] + (http://funops.co/nix-cookbook/nix-by-example/) |