🌍 Global Mirror — Visit original CN site →

Learn X in Y minutes

Where X=Nix

Nix Àr ett enkelt funktionelt sprÄk utvecklat för Nix pakethanteraren och NixOS linuxdistributionen.

Du kan utvÀrdera Nix uttryck genom att anvÀnda nix-instantiate eller 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)


Got a suggestion? A correction, perhaps? Open an Issue on the GitHub Repo, or make a pull request yourself!

Originally contributed by Chris Martin, and updated by 2 contributors.