Elixir Language - Riptutorial

1y ago
1.17 MB
97 Pages
Last View : 2m ago
Last Download : 8m ago
Upload by : Jacoby Zeller

Elixir Language#elixir

Table of ContentsAbout1Chapter 1: Getting started with Elixir Language2Remarks2Versions2Examples2Hello World2Hello World from IEx3Chapter 2: Basic .gitignore for elixir program5Chapter 3: Basic .gitignore for elixir program6Remarks6Examples6A basic .gitignore for Elixir6Example6Standalone elixir application6Phoenix application7Auto-generated .gitignore7Chapter 4: basic use of guard clausesExamplesbasic uses of guard clausesChapter 5: BEAMExamplesIntroductionChapter 6: BehavioursExamplesIntroductionChapter 7: Better debugging with IO.inspect and ples12Without labels12

With labelsChapter 8: Built-in types1314Examples14Numbers14Atoms15Binaries and Bitstrings15Chapter 9: Conditionals17Remarks17Examples17case17if and unless17cond18with clause18Chapter 10: Constants20Remarks20Examples20Module-scoped constants20Constants as functions20Constants via macros21Chapter 11: Data es23Chapter 12: Debugging TipsExamples2424Debugging with IEX.pry/024Debugging with IO.inspect/124Debug in pipe25Pry in pipe25Chapter 13: Doctests27

Examples27Introduction27Generating HTML documentation based on doctest27Multiline doctests27Chapter 14: EctoExamples2929Adding a Ecto.Repo in an elixir program29"and" clause in a Repo.get by/329Querying with dynamic fields30Add custom data types to migration and to schema30Chapter 15: ErlangExamples3131Using Erlang31Inspect an Erlang module31Chapter 16: ExDocExamplesIntroductionChapter 17: ExUnitExamplesAsserting ExceptionsChapter 18: Functional programming in educe34Chapter 19: FunctionsExamples3636Anonymous Functions36Using the capture operator36Multiple bodies37Keyword lists as function parameters37

Named Functions & Private Functions37Pattern Matching38Guard clauses38Default Parameters39Capture functions39Chapter 20: Getting help in IEx console41Introduction41Examples41Listing Elixir modules and functionsChapter 21: IEx Console Tips & TricksExamples414242Recompile project with recompile 42See documentation with h 42Get value from last command with v 42Get the value of a previous command with v 42Exit IEx console43See information with i 43Creating PID44Have your aliases ready when you start IEx44Persistent history44When Elixir console is stuck.44break out of incomplete expression45Load a module or script into the IEx session46Chapter 22: InstallationExamples4747Fedora Installation47OSX Installation47Homebrew47Macports47Debian/Ubuntu Installation47Gentoo/Funtoo Installation47Chapter 23: Join Strings49

Examples49Using String Interpolation49Using IO List49Using Enum.join49Chapter 24: Lists50Syntax50Examples50Keyword Lists50Char Lists51Cons Cells52Mapping Lists52List Comprehensions53Combined example53Summary53List difference54List Membership54Converting Lists to a Map54Chapter 25: Maps and Keyword Lists55Syntax55Remarks55Examples55Creating a Map55Creating a Keyword List55Difference between Maps and Keyword Lists56Chapter 26: MetaprogrammingExamplesGenerate tests at compile timeChapter 27: MixExamples5757575858Create a Custom Mix Task58Custom mix task with command line arguments58Aliases58

Get help on available mix tasksChapter 28: Modules5960Remarks60Module Names60Examples60List a module's functions or macros60Using modules60Delegating functions to another module61Chapter 29: NodesExamples6262List all visible nodes in the system62Connecting nodes on the same machine62Connecting nodes on different machines62Chapter 30: OperatorsExamples6464The Pipe Operator64Pipe operator and parentheses64Boolean operators65Comparison operators66Join operators66'In' operator67Chapter 31: OptimizationExamplesAlways measure first!Chapter 32: Pattern matchingExamples6868686969Pattern matching functions69Pattern matching on a map69Pattern matching on a list69Get the sum of a list using pattern matching70Anonymous functions70Tuples71

Reading a FilePattern matching anonymous functionsChapter 33: Polymorphism in orphism with ProtocolsChapter 34: ProcessesExamples737575Spawning a Simple Process75Sending and Receiving Messages75Recursion and Receive75Chapter 35: r 36: Sigils78Examples78Build a list of strings78Build a list of atoms78Custom sigils78Chapter 37: State Handling in ElixirExamplesManaging a piece of state with an AgentChapter 38: Stream79797980Remarks80Examples80Chaining multiple operationsChapter 39: Strings8081Remarks81Examples81

Convert to string81Get a substring81Split a string81String Interpolation81Check if String contains Substring81Join Strings82Chapter 40: Task83Syntax83Parameters83Examples83Doing work in the background83Parallel processing83Chapter 41: Tips and Tricks84Introduction84Examples84Creating Custom Sigils and Documenting84Multiple [ OR ]84iex Custom Configuration - iex Decoration84Credits86

AboutYou can share this PDF with anyone you feel could benefit from it, downloaded the latest versionfrom: elixir-languageIt is an unofficial and free Elixir Language ebook created for educational purposes. All the contentis extracted from Stack Overflow Documentation, which is written by many hardworking individualsat Stack Overflow. It is neither affiliated with Stack Overflow nor official Elixir Language.The content is released under Creative Commons BY-SA, and the list of contributors to eachchapter are provided in the credits section at the end of this book. Images may be copyright oftheir respective owners unless otherwise specified. All trademarks and registered trademarks arethe property of their respective company owners.Use the content presented in this book at your own risk; it is not guaranteed to be correct noraccurate, please send your feedback and corrections to info@zzzprojects.comhttps://riptutorial.com/1

Chapter 1: Getting started with ElixirLanguageRemarksElixir is a dynamic, functional language designed for building scalable and maintainableapplications.Elixir leverages the Erlang VM, known for running low-latency, distributed and fault-tolerantsystems, while also being successfully used in web development and the embedded softwaredomain.VersionsVersionRelease -01-031.32016-06-211.42017-01-05ExamplesHello WorldFor installation instructions on elixir check here, it describes instructions related to differentplatforms.Elixir is a programming language that is created using erlang, and uses erlang's BEAM runtime (likeJVM for java).We can use elixir in two modes: interactive shell iex or directly running using elixir command.Place the following in a file named hello.exs:IO.puts "Hello world!"https://riptutorial.com/2

From the command line, type the following command to execute the Elixir source file: elixir hello.exsThis should output:Hello world!This is known as the scripted mode of Elixir. In fact, Elixir programs can also be compiled (andgenerally, they are) into bytecode for the BEAM virtual machine.You can also use iex for interactive elixir shell (recommended), run the command you will get aprompt like this:Interactive Elixir (1.3.4) - press Ctrl C to exit (type h() ENTER for help)iex(1) Here you can try your elixir helloworldexamples:iex(1) IO.puts "hello, world"hello, world:okiex(2) You can also compile and run your modules through iex. For example, if you have a helloworld.exthat contains:defmodule Hello dodef sample doIO.puts "Hello World!"endendThrough iex, do:iex(1) c("helloworld.ex")[Hello]iex(2) Hello.sampleHello World!Hello World from IExYou can also use the IEx (Interactive Elixir) shell to evaluate expressions and execute code.If you are on Linux or Mac, just type iex on your bash and press enter: iexIf you are on a Windows machine, type:https://riptutorial.com/3

C:\ iex.batThen you will enter into the IEx REPL (Read, Evaluate, Print, Loop), and you can just typesomething like:iex(1) "Hello World""Hello World"If you want to load a script while opening an IEx REPL, you can do this: iex script.exsGiven script.exs is your script. You can now call functions from the script in the console.Read Getting started with Elixir Language online: 4

Chapter 2: Basic .gitignore for elixir programRead Basic .gitignore for elixir program online: 5

Chapter 3: Basic .gitignore for elixir programRemarksNote that the /rel folder may not be needed in your .gitignore file. This is generated if you areusing a release management tool such as exrmExamplesA basic .gitignore for Elixir/ build/cover/depserl crash.dump*.ez# Common additions for various operating systems:# MacOS.DS Store# Common additions for various editors:# JetBrains IDEA, IntelliJ, PyCharm, RubyMine etc.ideaExample### Elixir ###/ build/cover/depserl crash.dump*.ez### Erlang ###.eunitdeps*.beam*.pltebinrel/example project.concrete/DEV MODE.rebarStandalone elixir application/ build/cover/depserl crash.dump*.ezhttps://riptutorial.com/6

/relPhoenix application/ build/db/deps/*.ezerl crash.dump/node o-generated .gitignoreBy default, mixfor Elixir.new projectname will generate a .gitignore file in the project root that is suitable# The directory Mix will write compiled artifacts to./ build# If you run "mix test --cover", coverage assets end up here./cover# The directory Mix downloads your dependencies sources to./deps# Where 3rd-party dependencies like ExDoc output generated docs./doc# If the VM crashes, it generates a dump, let's ignore it too.erl crash.dump# Also ignore archive artifacts (built via "mix archive.build").*.ezRead Basic .gitignore for elixir program online: 7

Chapter 4: basic use of guard clausesExamplesbasic uses of guard clausesIn Elixir, one can create multiple implementations of a function with the same name, and specifyrules which will be applied to the parameters of the function before calling the function in order todetermine which implementation to run.These rules are marked by the keyword when, and they go between the defand the do in the function definition. A trivial example:function name(params)defmodule Math dodef is even(num) when num 1 dofalseenddef is even(num) when num 2 dotrueenddef is odd(num) when num 1 dotrueenddef is odd(num) when num 2 dofalseendendSay I run Math.is even(2) with this example. There are two implementations of is even, withdiffering guard clauses. The system will look at them in order, and run the first implementationwhere the parameters satisfy the guard clause. The first one specifies that num 1 which is nottrue, so it moves on to the next one. The second one specifies that num 2, which is true, so thisis the implementation that is used, and the return value will be true.What if I run Math.is odd(1)? The system looks at the first implementation, and sees that since numis 1 the guard clause of the first implementation is satisfied. It will then use that implementationand return true, and not bother looking at any other implementations.Guards are limited in the types of operations they can run. The Elixir documentation lists everyallowed operation; in a nutshell they allow comparisons, math, binary operations, type-checking(e.g. is atom), and a handful of small convenience functions (e.g. length). It is possible to definecustom guard clauses, but it requires creating macros and is best left for a more advanced guide.Note that guards do not throw errors; they are treated as normal failures of the guard clause, andthe system moves on to look at the next implementation. If you find that you're getting(FunctionClauseError) no function clause matching when calling a guarded function with paramshttps://riptutorial.com/8

you expect to work, it may be that a guard clause which you expect to work is throwing an errorwhich is being swallowed up.To see this for yourself, create and then call a function with a guard which makes no sense, suchas this which tries to divide by zero:defmodule BadMath dodef divide(a) when a / 0 :foo do:barendendCalling BadMath.divide("anything") will provide the somewhat-unhelpful error (FunctionClauseError)no function clause matching in BadMath.divide/1 — whereas if you had tried to run "anything" / 0directly, you would get a more helpful error: (ArithmeticError) bad argument in arithmeticexpression.Read basic use of guard clauses online: e-of-guardclauseshttps://riptutorial.com/9

Chapter 5: BEAMExamplesIntroductioniex :observer.start:okopens the GUI observer interface, showing you CPU breakdown, memory usage,and other information critical to understanding the usage patterns of your applications.:observer.startRead BEAM online: s://riptutorial.com/10

Chapter 6: BehavioursExamplesIntroductionBehaviours are a list of functions specifications that another module can implement. They aresimilar to interfaces in other languages.Here’s an example behaviour:defmodule Parser do@callback parse(String.t) :: any@callback extensions() :: [String.t]endAnd a module that implements it:defmodule JSONParser do@behaviour Parserdef parse(str), do: # . parse JSONdef extensions, do: ["json"]endThe @behaviour module attribute above indicates that this module is expected to define everyfunction defined in the Parser module. Missing functions will result in undefined behaviour functioncompilation errors.Modules can have multiple @behaviour attributes.Read Behaviours online: rshttps://riptutorial.com/11

Chapter 7: Better debugging with IO.inspectand labelsIntroductionis very useful when you try to debug your chains of method calling. It can get messythough if you use it too often.IO.inspectSince Elixir 1.4.0 the label option of IO.inspect can helpRemarksOnly works with Elixir 1.4 , but I can't tag that yet.ExamplesWithout labelsurl .inspectPoison.decode!IO.inspectThis will result in a lot of output with no s/1"%HTTPoison.Response{body: "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"sunt aut facererepellat provident occaecati excepturi optio reprehenderit\",\n \"body\": \"quia etsuscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderit molestiae ut utquas totam\\nnostrum rerum est autem sunt rem eveniet architecto\"\n}",headers: [{"Date", "Thu, 05 Jan 2017 14:29:59 GMT"},{"Content-Type", "application/json; charset utf-8"},{"Content-Length", "292"}, {"Connection", "keep-alive"},{"Set-Cookie"," cfduid d56d1be0a544fcbdbb262fee9477600c51483626599; expires Fri, 05-Jan-18 14:29:59 GMT;path /; domain .typicode.com; HttpOnly"},{"X-Powered-By", "Express"}, {"Vary", "Origin, ls", "true"},{"Cache-Control", "public, max-age 14400"}, {"Pragma", "no-cache"},{"Expires", "Thu, 05 Jan 2017 18:29:59 GMT"},{"X-Content-Type-Options", "nosniff"},{"Etag", "W/\"124-yv65LoT2uMHrpn06wNpAcQ\""}, {"Via", "1.1 vegur"},{"CF-Cache-Status", "HIT"}, {"Server", "cloudflare-nginx"},{"CF-RAY", "31c7a025e94e2d41-TXL"}], status code: 200}"{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"sunt aut facere repellat providenthttps://riptutorial.com/12

occaecati excepturi optio reprehenderit\",\n \"body\": \"quia et suscipit\\nsuscipitrecusandae consequuntur expedita et cum\\nreprehenderit molestiae ut ut quas totam\\nnostrumrerum est autem sunt rem eveniet architecto\"\n}"%{"body" "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderitmolestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto","id" 1,"title" "sunt aut facere repellat provident occaecati excepturi optio reprehenderit","userId" 1}With labelsusing the label option to add context can help a lot:url ect(label:"url")"raw http resonse")"raw body")"parsed body")url: "https://jsonplaceholder.typicode.com/posts/1"raw http resonse: %HTTPoison.Response{body: "{\n \"userId\": 1,\n \"id\": 1,\n \"title\":\"sunt aut facere repellat provident occaecati excepturi optio reprehenderit\",\n \"body\":\"quia et suscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderitmolestiae ut ut quas totam\\nnostrum rerum est autem sunt rem eveniet architecto\"\n}",headers: [{"Date", "Thu, 05 Jan 2017 14:33:06 GMT"},{"Content-Type", "application/json; charset utf-8"},{"Content-Length", "292"}, {"Connection", "keep-alive"},{"Set-Cookie"," cfduid d22d817e48828169296605d27270af7e81483626786; expires Fri, 05-Jan-18 14:33:06 GMT;path /; domain .typicode.com; HttpOnly"},{"X-Powered-By", "Express"}, {"Vary", "Origin, ls", "true"},{"Cache-Control", "public, max-age 14400"}, {"Pragma", "no-cache"},{"Expires", "Thu, 05 Jan 2017 18:33:06 GMT"},{"X-Content-Type-Options", "nosniff"},{"Etag", "W/\"124-yv65LoT2uMHrpn06wNpAcQ\""}, {"Via", "1.1 vegur"},{"CF-Cache-Status", "HIT"}, {"Server", "cloudflare-nginx"},{"CF-RAY", "31c7a4b8ae042d77-TXL"}], status code: 200}raw body: "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"sunt aut facere repellatprovident occaecati excepturi optio reprehenderit\",\n \"body\": \"quia etsuscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderit molestiae ut utquas totam\\nnostrum rerum est autem sunt rem eveniet architecto\"\n}"parsed body: %{"body" "quia et suscipit\nsuscipit recusandae consequuntur expedita etcum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem evenietarchitecto","id" 1,"title" "sunt aut facere repellat provident occaecati excepturi optio reprehenderit","userId" 1}Read Better debugging with IO.inspect and labels riptutorial.com/13

Chapter 8: Built-in typesExamplesNumbersElixir comes with integers and floating point numbers. An integer literal can be written indecimal, binary, octal and hexadecimal formats.iex x 291291iex x 0b100100011291iex x 0o443291iex x 0x123291As Elixir uses bignum arithmetic, the range of integer is only limited by the available memoryon the system.Floating point numbers are double precision and follows IEEE-754 specification.iex x 6.86.8iex x 1.23e-111.23e-11Note that Elixir also supports exponent form for floats.iex 1 12iex 1.0 1.02.0First we added two integers numbers, and the result is an integer. Later we added two floatingpoint numbers, and the result is a floating point number.Dividing in Elixir always returns a floating point number:iex 10 / 25.0In the same way, if you add, subtract or multiply an integer by a floating point number the resultwill be floating point:https://riptutorial.com/14

iex 40.0 242.0iex 10 - 5.05.0iex 3 * 3.09.0For integer division, one can use the div/2 function:iex div(10, 2)5AtomsAtoms are constants that represent a name of some thing. The value of an atom is it's name. Anatom name starts with a colon.:atom# that's how we define an atomAn atom's name is unique. Two atoms with the same names always are equal.iex(1) a :atom:atomiex(2) b :atom:atomiex(3) a btrueiex(4) a btrueBooleans true and false, actually are atoms.iex(1) true :truetrueiex(2) true :truetrueAtoms are stored in special atoms table. It's very important to know that this table is not garbagecollected. So, if you want (or accidentally it is a fact) constantly create atoms - it is a bad idea.Binaries and BitstringsBinaries in elixir are created using the Kernel.SpecialForms construct .They are a powerful tool which makes Elixir very useful for working with binary protocols andencodings.https://riptutorial.com/15

Binaries and bitstrings are specified using a comma delimited list of integers or variable values,bookended by " " and " ". They are composed of 'units', either a grouping of bits or a groupingof bytes. The default grouping is a single byte (8 bits), specified using an integer: 222,173,190, 239 # 0xDEADBEEFElixir strings also convert directly to binaries:iex 0, "foo" 0, 102, 111, 111 You can add "specifiers" to each "segment" of a binary, allowing you to encode: Data Type Size EndiannessThese specifiers are encoded by following each value or variable with the "::" operator: 102::integer-native 102::native-integer # Same as above 102::unsigned-big-integer 102::unsigned-big-integer-size(8) 102::unsigned-big-integer-8 # Same as above 102::8-integer-big-unsigned -102::signed-little-float-64 # -102 as a little-endian Float64 -102::native-little-float-64 # -102 as a Float64 for the current machineThe available data types you can use are: integerfloatbits (alias for bitstring)bitstringbinarybytes (alias for binary)utf8utf16utf32Be aware that when specifying the 'size' of the binary segment, it varies according to the 'type'chosen in the segment specifier: integer (default) 1 bit float 1 bit binary 8 bitsRead Built-in types online: -typeshttps://riptutorial.com/16

Chapter 9: ConditionalsRemarksNote that the do.end syntax is syntactic sugar for regular keyword lists, so you can actually dothis:unless false, do: IO.puts("Condition is false")# Outputs "Condition is false"# With an else :if false, do: IO.puts("Condition is true"), else: IO.puts("Condition is false")# Outputs "Condition is false"Examplescasecase {1, 2} do{3, 4} - "This clause won't match."{1, x} - "This clause will match and bind x to 2 in this clause."- "This clause would match any value."endis only used to match the given pattern of the particular data. Here , {1,2} is matching withdifferent case pattern that is given in the code example.caseif and unlessif true do"Will be seen since condition is true."endif false do"Won't be seen since condition is false."else"Will be seen.endunless false do"Will be seen."endunless true do"Won't be seen."else"Will be seen."endhttps://riptutorial.com/17

condcond023enddo 1 - IO.puts "0 1" 1 1 - IO.puts "1 1 2" 1 2 - IO.puts "1 2 3"# Outputs "1 1 2" (first condition evaluating to true)condwill raise a CondClauseError if no conditions are true.cond do1 2 - "Hmmm""foo" "bar" - "What?"end# ErrorThis can be avoided by adding a condition that will always be true.cond do. other conditionstrue - "Default value"endUnless it is never expected to reach the default case, and the program should in fact crash at thatpoint.with clauseclause is used to combine matching clauses. It looks like we combine anonymous functionsor handle function with multiple bodies (matching clauses). Consider the case: we create a user,insert it into DB, then create greet email and then send it to the user.withWithout the with clause we might write something like this (I omitted functions implementations):case create user(user params) do{:ok, user} - case Mailer.compose email(user) do{:ok, email} - Mailer.send email(email){:error, reason} - handle errorend{:error, changeset} - handle errorendHere we handle our business process's flow with case (it could be cond or if). That leads us to socalled 'pyramid of doom', because we have to deal with possible conditions and decide: whethermove further or not. It would be much nicer to rewrite this code with with statement:https://riptutorial.com/18

with {:ok, user} - create user(user params),{:ok, email} - Mailer.compose email(user) do{:ok, Mailer.send email}else{:error, reason} - handle errorendIn the code snippet above we've rewrite nested case clauses with with. Within with we invoke somefunctions (either anonymous or named) and pattern match on their outputs. If all matched, withreturn do block result, or else block result otherwise.We can omit else so with will return either do block result or the first fail result.So, the value of with statement is its do block result.Read Conditionals online: nalshttps://riptutorial.com/19

Chapter 10: ConstantsRemarksSo this is a summary analysis I've done based on the methods listed at How do you defineconstants in Elixir modules?. I'm posting it for a couple reasons: Most Elixir documentation is quite thorough, but I found this key architectural decisionlacking guidance - so I would have requested it as a topic. I wanted to get a little visibility and comments from others about the topic. I also wanted to test out the new SO Documentation workflow. ;)I've also uploaded the entire code to the GitHub repo elixir-constants-concept.ExamplesModule-scoped constantsdefmodule MyModule do@my favorite number 13@use snake case "This is a string (use double-quotes)"endThese are only accessible from within this module.Constants as functionsDeclare:defmodule MyApp.ViaFunctions.Constants dodef app version, do: "0.0.1"def app author, do: "Felix Orr"def app info, do: [app version, app author]def bar, do: "barrific constant in function"endConsume with require:defmodule MyApp.ViaFunctions.ConsumeWithRequire dorequire MyApp.ViaFunctions.Constantsdef Constants.app versionMyApp.ViaFunctions.Constants.app authorinspect MyApp.ViaFunctions.Constants.app info# This generates a compiler error, cannot invoke bar/0 inside a guard.# def foo( bar) when is bitstring(bar) dohttps://riptutorial.com/20

#IO.puts "We just used bar in a guard: #{bar}"# endendConsume with import:defmodule MyApp.ViaFunctions.ConsumeWithImport doimport MyApp.ViaFunctions.Constantsdef foo()IO.putsIO.putsIO.putsendenddoapp versionapp authorinspect app infoThis method allows for reuse of constants across projects, but they will not be usable within guardfunctions that require compile-time constants.Constants via macrosDeclare:defmodule MyApp.ViaMacros.Constants do@moduledoc """Apply with use MyApp.ViaMacros.Constants, :app or import MyApp.ViaMacros.Constants,:app .Each constant is private to avoid ambiguity when importing multiple modulesthat each have their own copies of these constants."""def app doquote do# This method allows sharing module constants which can be used in guards.@bar "barrific module constant"defp app version, do: "0.0.1"defp app author, do: "Felix Orr"defp app info, do: [app version, app author]endenddefmacro using (which) when is atom(which) doapply( MODULE , which, [])endendConsume with use:defmodule MyApp.ViaMacros.ConsumeWithUse douse MyApp.ViaMacros.Constants, :appdef foo()IO.putsIO.putsIO.putsdoapp versionapp authorinspect app infohttps://riptutorial.com/21

enddef foo( bar) when is bitstring(@bar) doIO.puts "We just used bar in a guard: #{@bar}"endendThis method allows you to use the @some constant inside guards. I'm not even sure that thefunctions would be strictly necessary.Read Constants online: shttps://riptutorial.com/22

Chapter 11: Data StructuresSyntax [head tail] [1, 2, 3, true] # one can use pattern matching to break up cons cells. Thisassigns head to 1 and tail to [2, 3, true] %{d: val} %{d: 1, e: true} # this assigns val to 1; no variable d is created because the d onthe lhs is really just a symbol that is used to create the pattern %{:d } (note that hashrocket notation allows one to have non-symbols as keys for maps just like in ruby)RemarksAs for which data structure to us here are some brief remarks.If you need an array data structure if you're going to be doing a lot of writing use lists. If insteadyou are going to be doing a lot of read you should use tuples.As for maps they are just simply how you do key value stores.ExamplesListsa [1, 2, 3, true]Note that these are stored in memory as linked lists. Id est this is a series of cons cells where thehead (List.hd/1) is the value of first item of the list and the tail (List.tail/1) is the value of the rest ofthe list.List.hd(a) 1List.tl(a) [2, 3, true]Tuplesb {:ok, 1, 2}Tuples are the equivalent of arrays in other languages. They are stored contiguously in memory.Read Data Structures online: uctureshttps://riptutorial.com/23

Chapter 12: Debugging TipsExamplesDebugging with IEX.pry/0Debugging with IEx.pry/0 is quite simple.1. require IEx in your module2. Find the line of code you want to inspect3. Add IEx.pry after the lineNow start your project (e.g. iex-S mix).When the line with IEx.pry/0 is reached the program will stop and you have the chance to inspect.It is like a breakpoint in a traditional debugger.When you are finished just type respawn into the console.require IEx;defmodule Example dodef double sum(x, y) doIEx.pryhard work(x, y)enddefp hard work(x, y) do2 * (x y)endendDebugging with IO.inspect/1It is possible to use IO.inspect/1 as a tool to debug an elixir program.defmodule MyModule dodef myfunction(argument 1, argument 2) doIO.inspect(argument 1)IO.inspect(argument 2)endendIt will print out argument 1 and argument 2 to the console. Since IO.inspect/1 returns itsargument it is very easy to include it in function calls or pipelines without breaking the flow:do something(a, b) do something else(c)# can be adorned with IO.inspect, with no change in functionality:https://riptutorial.com/24

do something(IO.inspect(a), IO.inspect(b)) IO.inspectdo something(IO.inspect(c))Debug in piped

Elixir is a dynamic, functional language designed for building scalable and maintainable applications. Elixir leverages the Erlang VM, known for running low-latency, distributed and fault-tolerant systems, while also being successfully

Related Documents:

Early praise for Programming Elixir Dave Thomas has done it again. Programming Elixir is what every programming book aspires to be. It goes beyond the basics of simply teaching syntax and mechanical examples. It teaches you how to think Elixir. Bruce Tate CTO, icanmakeitbetter.com. Author.

Elixir 9 only - First, depress the lever blade and use a 2 mm hex to remove the set screw. Elixir 9 & 7 - Open a vise 1/2 inch and place a clean rag over the jaws of the vise. Position the pivot pin over the opening of the vise. Use a rubb

Alchemy) transitioned to Neidan (Daoist Internal Alchemy) and the "elixir" became the “inner elixir” sought to be created, or developed, or simply re-discovered (in the version of Liu Yiming, which stated that we already had it in ourselves). The Elixir now becomes

- 1 PHYTO Elixir Shampoo - 1 PHYTO Elixir Mask - 1 PHYTO Elixir Cream - 1 PHYTO Elixir Oil VALUE: 175 STARTING BID 100 BUY NOW 300. ITEM # 13 LA CHATELAINE Luxurious hand cream gift set composed of 12 -1oz tubes from the South of

Elixir 1 - Remove the grip and shifter from the handlebar according to your manufacturer's instructions. Use a 4 mm hex to loosen the brake clamp bolt and slide the brake lever off the end of the handlebar. Pull the hose

ELIXIR - Distributed infrastructure for life science. 20 members Implemented through National ELIXIR Nodes. Build on: local bioinformatics on national strengths and priorities Consolidates Europe’s natio

Elixir Data Designer for extracting, merging and processing data from a variety of datasources, either to generate direct data output (for example, Excel files or database records), or to feed data into Elixir

Literary Theory and Schools of Criticism Introduction A very basic way of thinking about literary theory is that these ideas act as different lenses critics use to view and talk about art, literature, and even culture. These different lenses allow critics to consider works of art based on certain assumptions within that school of theory. The different lenses also allow critics to focus on .