Skip to content

English3000/Elixir

Repository files navigation

Debugging Gigalixir:

  1. run locally: MIX_ENV=prod mix phx.server
  2. if still issue, gigalixir logs

Ramp up with the WRAP Stack!

react-native-Web + Relay + Absinthe + PostgreSQL

(+ Jest)

At a bare minimum, I'd go through:

  1. Learn Elixir (free!)
  2. Learn Phoenix ($23, Kindle-compatible)
  3. Learn Absinthe ($18, w/ 30% discount code in the back of any PragProg book)
  4. WRAP Stack Walkthrough (free; how to put all of these technologies together for your first project)
  5. Learn Relay (free; implement with an Absinthe backend; skip to Implementing the Login Mutations for Step 5, and use Ch. 8 of Learn Absinthe for authentication)

Why WRAP?

  1. performance (backend): Absinthe is ~10x faster than NodeJS, Python, Ruby, and (probably even more for) PHP because it can use multiple cores concurrently
  2. performance (API): GraphQL (Relay + Absinthe) allows for more efficient communication between your frontend and backend than REST
  3. productivity (backend): Absinthe is built on top of Phoenix, Elixir's main framework, which provides a Rails-like developer experience for the backend
  4. productivity (frontend): react-native-web will save you time with cross-platform apps and make it easier to reason about your component hierarchy; Relay allows you to put your API with its component--a dramatic timesaver and bug-reducer compared with Redux
  5. platform: Elixir (Absinthe is an implementation of GraphQL written in Elixir) is built on top of the Erlang VM, which allows for fault-tolerant apps using the OTP API and live uploads to your production app; Phoenix's channels make setting up websockets easy--Absinthe leverages this to allow for real-time apps via subscriptions

Love every part of your stack! Try WRAP:

Why Elixir?

Getting Started

Intro

Design patterns

Mix tasks

Phoenix (backend framework)

  • Learn Phoenix
    • Updates to Phoenix (just do ⌘ + f for Creating schema--the rest is dated)

      Because Elixir is a functional programming language, Phoenix uses schemas rather than models. A schema defines a struct's fields, its relationships to other structs, and changeset(s) for it (which handle validations and constraints).

      mix phx.gen.context generates a context which holds the API for all schemas within that context (in an object-oriented language, these functions would be defined within each model). For example, instead of defining functions for user authentication within /lib/<APP>_web/models/user.ex, one should generate an Accounts context and write the functions in /lib/<APP>/accounts/accounts.ex (User will be passed as an argument).

    • Phoenix Presence
    • Hot Module Replacement API & hmr-brunch
    • Mox
    • Property-based testing
    • Testing database interface concurrently

"dependencies are used for direct usage in your codebase, things that usually end up in the production code, or chunks of code

"devDependencies are used for the build process, tools that help you manage how the end code will end up, third party test modules, (ex. webpack stuff)"

react-native-web (cross-platform frontend library)

Absinthe (GraphQL backend)

Relay (GraphQL frontend)

Instead of passing a data prop down the entire component hierarchy (which is why a fragment is a specification of data requirements), you can use React's new Context API. Further, if you don't use Relay, you still don't need to use Redux...!

Deploying Your App

To deploy your frontend and backend separately, deploy your frontend /build to a CDN, and deploy your backend to a Plaform-as-a-Service below, with some configurations.

"I chose to use Gigalixir for hosting my application so that I could get the Heroku-like ease-of-use that it provides, while being able to still learn and use features of Elixir that make it special (like ETS and hot upgrades)."

"Distillery is a release tool. It builds a deployable artifact."

"Ansible isn't meant to be a continuous integration engine."

Advanced

Bleeding Edge

Plugs

Elixir Cheatsheet (in progress)

Note: This material is intended as complementary to the resources above.

Intro

Elixir is built on top of the Erlang VM, which powers something like 50% of the phone system. This means Elixir code is compiled into Erlang VM code, which is then transpiled into assembly code for your machine.

Elixir builds upon the Erlang VM. The Erlang VM supports zero-downtime upgrades, runs isolated processes (so if one crashes, none of the others do and the one that crashed is restarted by a Supervisor process), and--while not the fastest of all programming languages--is an order of magnitude faster than PHP, Python, Ruby, and Node.js because it leverages multicore processors to run processes in parallel. As of the mid-2000s, computers' processing power has remained stagnant and the trend has been to include more cores in computers. As this trend continues, the speed of concurrent languages like Elixir over single-threaded languages will only grow.

Elixir also emerged out of the Rails community. José Valim, the author/creator of the language, was part of the Rails core team. In my view, he took the best of both Erlang and Ruby on Rails to produce Elixir. Same for Chris McCord's Phoenix framework and the whole ecosystem.

It is important to note Elixir is a functional programming language. This means any data stored in memory is immutable. If you no longer use it, it becomes "garbage" to be cleared. Additionally, developers think in terms of steps of functions rather than aspects of objects. Instead of calling a function on a datum, the datum is passed as an argument to the function.

Datatypes

Elixir is a server-side scripting language, meaning it handles requests from the browser and returns responses.

Now let's delve into its datatypes:

Basic

  • integer
  • float
  • boolean
  • atom

Integers are numbers. Floats are numbers with decimal points. Booleans consist of true and false. All expressions of code (which are like clauses in sentences) have a true boolean value, except false (which is a boolean value) and nil which is what some functions return on failure. An atom begins (or, as we'll see later, can end) with :. It is intended for use as a unique value.

Advanced

  • string
  • tuple
  • list
  • keyword list
  • map

You'll notice I did not include strings (words/letters/anything in double-quotes) under Basic.

When code is compiled to assembly (for the machine to understand), everything is converted to binary. Binary means base 2. That means all code is represented as a series of 0s and 1s. Why? Computers work because they have transistors which can store a charge. If a transistor is off (it does not have a charge), this can be represented as 0.

Numbers are simply converted from base 10 to base 2. Booleans are binary. Floats and atoms are more complicated, but each is a single value. By contrast, a series of contiguous values can also be used to represent data. A string is a series of numbers which have been converted into human-readable characters. AKA, all of the characters in a string can be converted into base 10 numbers, which can then be converted to binary (likely implemented with a special leading binary sequence to differentiate them from integers). The series of continguous values can be represented as a tuple or a (linked) list. A tuple is represented as {}. A list is represented as []. Tuples are used to store short series. Lists are for series that are long enough that they may not be stored continguously in a computer's memory. Memory comes in units of bytes, which are 8 bits. A bit is a binary unit (a 0 or a 1). So a short value can fit in a byte. A longer value needs to be split across bytes.

The most common use of tuples in Elixir is pattern-matching. Often, the tuple will have only 2 values. The first is an atom. You set cases for each possible atom where you do something with the second value of the tuple. Linked lists perform the function of arrays in other languages: storing series of values which you can go through or alter via functions.

There is a third data structure called a keyword list, which is a linked list of 2-value tuples: [{}, {}]. The first value of the tuple must be an atom (a key). Additionally, keyword lists can be represented as {key: value, key2: value2}. Keyword lists are often defined as the last argument of a function. Because a keyword list is a set of values, this means you can pass a ranging number of arguments, each of which has a specific use in the function as identified by its key.

Lastly, there are maps, %{}. In a keyword list, the first value of the tuple must be an atom and the list is ordered. A map is unordered and the key of the key-value pair can be any basic datatype (literals) or a string. The value can be any datatype.

The language has additional datatypes but these are generally the most relevant.

Operations

Logic

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published