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