Programming Elixir, Functional |> Concurrent |> Pragmatic |> Fun, Pragmatic 读书笔记

来源:互联网 发布:阿里云免费证书配置 编辑:程序博客网 时间:2024/06/13 11:48

Programming Elixir,  Functional |> Concurrent |> Pragmatic |> Fun, Pragmatic

  1. 安装配置
    1. 又是‘Don't worry about details’!最烦这种写法
      def module Par do
      def pmap(coll, f) do
      coll |> Enum.map(&(Task.async(fn -> f.(&1) end))) |> Enum.map(&Task.await/1)
    2. 调用:result = Par.pmap 1..100, &(&1*&1)
    3. $iex
      1. h(Enum.reverse/1)
    4. $elixir hello.exs
  2. 传统编程
    1. 模式匹配
      1. =不是赋值,而是match操作
      2. var可重新bind到一个subsequent里:a=1, [1,a,3]=[1,2,3] 子作用域名字隐藏?
    2. 所有value不可变
      1. list2 = [ 4 | list1]
      2. 如果process因为heap满而中止,所有数据丢弃,无GC
  3. Basics
    1. 数据类型:Number, Atom(Symbol?:name), Range(s..e)
      1. 正则 ~r{regex}opts(选项:f g i m r s u x)
      2. PID, make-ref
      3. Tuple: {:ok, 42, "abc"}
      4. List: [1,2,3]
        1. 语法糖:[name: "Dave", city: "Dallas"] --> [{:name, "Dave"}, ...]
      5. Map: %{ key => value, ...} Perl风格?
        1. colors[:red] --> colors.red
      6. Binaries
        1. bin = <<1, 2>>
        2. bin = << 3 :: size(2), 5 :: size(4), 1 :: size(2)>>
          1. <<213>>
        3.  :io.format("~-8.2b~n", :binary.bin_to_list(bin2))
          1. 11010101
      7. true, false, nil
  4. 匿名函数
    1. fn arg-list -> body ... end
      1. 注意:1)对命名函数不需要f.()语法 2)由于PM机制, fn内可以有多个子句(多重派发?)
    2. 字符串模板替换(Ruby?):"#{IO.read(file, :line)}"
    3. 函数返回函数(Currying)
    4. 函数作为参数(高阶函数)
      1. &记号:&(Float.round(&1,&2) --> &Float.round/2 (C++11完美转发?)
  5. 模板与命名函数
    1. do ... end居然不是底层的实际语法??def double(n), do: n*2
    2. Guard子句:def f(x) when p(x) do ... end
    3. 默认参数:param \\ defaultValue (编译期的trick?)
    4. defp 宏
    5. |> 管道操作
      1. val |> f(a,b) 基本上相当于f(val, a, b) 插入到第一个参数位置(这有点诡异,对比:F# Java8)
    6. import List, only:[flatten:1]
    7. alias Mix.Tasks.DocTest, as: DocTest (alias指令其实就是内置函数?)
    8. require:引用模块中的宏
    9. 属性(attributes):@name value 主要用于声明常量?那干嘛叫‘属性’
    10. *调用Erlang库函数::io.format
  6. Lists与递归
    1. def sum(l), do: _sum(l,0)
    2. defp _sum([], t), do: t ...
  7. 字典:Maps, HashDicts, Keywords, Sets与Structs
    1. for p = %{height: height} <- people, height>1.5, do: ...
    2. Maps不能bind value到key
      1. new_map = %{ old_map | key => val, ... } 数据结构都是immutable的(对比:Scala)
    3. @derive Access
    4. defstruct name: "...", over_18: false
    5. * put_in, update_in
    6. Set1 = Enum.into 1..5, HashSet.new
  8. Types
  9. 处理集合:Enum与Stream(lazy)
    1. IO.puts File.open("/path/to/file") |> IO.stream(:line) |> Enum.max_by(&String.length/1)
      1. File.stream!
    2. 无限列表:Stream.map
    3. def sleep(sec) do
      receive do
      after sec*1000 -> nil
    4. * Stream.resource
    5. Comprehensions
      1. for x <- [...], x<4, do: x*x
      2. for <<c <- "hello">>, do: >>c>>
  10. Strings 与 Binaries
    1. * Sigils:~-style literals
    2. 类似于Perl的heredoc:~w """ ...
    3. utf-8:String.length/codepoints vs byte_size
  11. 控制流
    1. if ..., do: .. elese: ...
    2. cond do ... -> ... end
    3. case expr do ... -> ... end
    4. raise RuntimerError, message: "!"
  12. demo:获取json并格式化显示
    1. $mix new issues
      1. 习俗:lib/issues/clci.ex OptionParser.parse
    2. defmodules Issues.Mixfile do ...
      1. use Mix.Project
      2. def project do [ ... ] end
      3. defp deps do [ { :httpoison, "~> 0.4"] end
    3. $mix deps.get
    4. $iex -S mix
    5. config.exs
      1. use Mix.Config
      2. import_config "#{Mix.env}.exs"
    6. * Enum.sort l, fn, a, b -> a["t"]<b["t"] end
    7. escript?略
  13. 并发编程
    1. 多进程
      1. spawn(M, :fun, [args])
      2. receive do {sender, msg} -> send sender, {:ok, "Hi"} 这里尾递归
        after 500 -> ... 超时0.5s
      3. * last = Enum.reduce 1..n, self, fn(_, sendto) -> spawn(M, :f, [sendto]) end
      4. $ elixir --erl "+P 1000000" -r chain.exs -e "Chain.run(400_000)"
        用时仅3s?
      5. > Process.flag(:trap_exit, true)
      6. spawn_link(子进程结束将导致父终止)
        1. spawn_monitor (atomic)
      7. Agent?
    2. Nodes
      1. $ iex --sname a1 --cookie secret
    3. OTP:Servers
      1. GenServer 6 callbacks:init, handle_call/cast/info, terminate, code_change
    4. OTP:Supervisors
    5. OTP:Apps(代码+描述)
    6. Tasks and Agents
  14. More Advanced Elixir
    1. Macros
      1. IO.inspect
      2. > quote do: :atom
      3. > Code.eval_quoted( quote do: [1, 2, unquote([3,4])])
      4. 实现if宏
        defmacro myif(cond, clauses) do
        do/else_clause = Keyword.get(clauses, :do/else, nil); 注意,这里是2句话,我笔记缩为1句了
        quote do
        case unquote(cond) do
        val when val in [false, nil] -> unquote(else_clause)
      5. 用Binding注入值
      6. Macros are Hygienic(类似于Scheme)
      7.  ? 操作符重载(略)
  15. Linking Modules
    1. use Behaviour
    2. defcallback ... #声明接口原型?
    3. __using__
      • Trace method calls
  16. Protocols:defprotocol --> defimpl
  17. More Cool Stuff
    1. TypeSpec and Type Checking
0 0
原创粉丝点击