`
simohayha
  • 浏览: 1395732 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

programming erlang前三章记要

阅读更多
今天花了2各种头,看了一下programming erlang的前三章,由于自己对scheme和haskell都有一些了解,因此觉得语法方面,erlang和他们挺相似的.

顺便发下牢骚,emacs实在是用不习惯,可是vi的erlang插件实在是烂,郁闷..

这边只是一个简要的描述.

1整数
erlang里面的整数和scheme里面的是一样的都是允许任意长度的(只要不超出机器字长的限制):
3> 123456789 * 987654321 * 112233445566778899 * 998877665544332211.

如果你想指定一个数字的进制,你可以这样做:

4> 16#cafe * 32#sugar.
1577682511434

2变量

在erlang里面变量的命名必须第一个字母是大写的,而且由于erlang是纯粹的FP,因此他的变量是不可变的(scheme就不是纯粹的FP):
2> X=123456789.
123456789

4> X = 1234.
=ERROR REPORT==== 11-Sep-2006::20:32:49 ===
Error in process <0.31.0> with exit value:
  {{badmatch,1234},[{erl_eval,expr,3}]}
** exited: {{badmatch,1234},[{erl_eval,expr,3}]} **


这边可以看到重复赋值会报错.
在这里要注意,在erlang中"="号并不是一般语言中的赋值的意思,而是模式匹配(pattern matching)的操作.当一个变量被赋值之后,erlang会将这个变量绑定到这个值上.

我们再看下面的例子:
2> X=1234.
1234
4> X =1234.
1234
5> Y=1234.
1234
6>X=Y.
1234
7> X=123456.
出错...


这边我猜测,X,Y其实共享1234.

3 浮点数

1> 5/3.
1.66667
2> 4/2.
2.00000
3> 5 div 3.
1
4> 5 rem 3.
2
5> 4 div 2.
2
6> Pi = 3.14159.
3.14159
7> R = 5.
5
8> Pi * R * R.
78.5397

这边注意一下div和 /的区别就行了.

4 atom
erlang中,atom的定义以小写字母开头,他经常被用来表示非字符的常量,他还可以用单引号括起来,这样就能使用大写字母开头的atom了.

1> hello.
hello


5 tuple

tuple主要是将一些元素分组,它和c中的结构体有些类似,不过他里面的域是没有名字的。因此为了更容易让人理解你的代码,建议在tuple的第一个元素使用atom来描述你的tuple:

1> Person = {person,
                 {name, joe},
                 {height, 1.82},
                 {footsize, 42},
                 {eyecolour, brown}}.


这边要注意"_"符号,他其实也就是一个占位符了:

1>Person={person,{name,{first,joe},{last,armstrong}},{footsize,42}}.
{person,{name,{first,joe},{last,armstrong}},{footsize,42}}
2> {_,{_,{_,Who},_},_} = Person.
{person,{name,{first,joe},{last,armstrong}},{footsize,42}}


6 list

其实list也就是scheme中的列表了,换了个名字而已...
list是用中括号,将一些元素括起来,中间用逗号隔开:

1> ThingsToBuy = [{apples,10},{pears,6},{milk,3}].
[{apples,10},{pears,6},{milk,3}]


假设我们有个list L,那么通过表达式[H|T]=L,H,T都没有被绑定,H将会是L的第一个元素,T则将是除去第一个元素外的list:
4> [Buy1|ThingsToBuy2] = ThingsToBuy1.
[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]


7 string

在erlang中,其实字符串也就是一个整数list了,虽然他看起来也是用双引号括起来的:

3> [83,117,114,112,114,105,115,101].
"Surprise"


我们可以这样创建一个字符串:
6> [I-32,$u,$r,$p,$r,$i,$s,$e].
"Surprise"


如果有一个数字不能打印,那么就是直接打印出整个数字list:

4> [1,83,117,114,112,114,105,115,101].
[1,83,117,114,112,114,105,115,101].


在上面的代码里,1不是一个可打印的字符.

8 moudle

模块是erlang的基本单元,所有的函数都写在模块里,而模块都被存储在.erl文件里面,模块必须被编译成.beam文件后才能被运行.

-module(geometry).
-export([area/1]).
area({rectangle, Width, Ht}) -> Width * Ht;
area({circle, R})            -> 3.14159 * R * R.


这边函数的定义的话,其实也就类似oo里面的多态了.不过这边是函数的多态罢了.这边要注意要用;来隔开,如果你用"."的话,就要重载了.


-module代表模块的名字,-export表示这个模块中的那个方法能被外面的模块所使用,area/1说明外部模块可以使用的是area的只有一个参数的方法。-import则是导入外部模块的方法.
这就是一个简单的模块.可以这样的使用他:
1> c(geometry).
{ok,geometry}
2> geometry:area({rectangle, 10, 5}).
50
3> geometry:area({circle, 1.4}).
6.15752


9 fun 函数

其实也就是lambda了,换个名字而已:

5> Hypot = fun(X, Y) -> math:sqrt(X*X + Y*Y) end.
#Fun<erl_eval.12.115169474>
6> Hypot(3,4).
5.00000

通过fun我们可以轻松的对函数curry化:

1> Fruit = [apple,pear,orange].
[apple,pear,orange]
2> MakeTest = fun(L) -> (fun(X) -> lists:member(X, L) end) end.
#Fun<erl_eval.6.56006484>
3> IsFruit = MakeTest(Fruit).
#Fun<erl_eval.6.56006484>
4> IsFruit(pear).
true
5> IsFruit(apple).
true


10 高阶函数

比如map,filter之类的高阶函数,erlang也都是有的:

12> L = [1,2,3,4].
[1,2,3,4]
17> lists:map(Even, [1,2,3,4,5,6,8]).
[false,true,false,true,false,true,true]
18> lists:filter(Even, [1,2,3,4,5,6,8]).
[2,4,6,8]


11 List Comprehensions

也就是python里面的差不多了,不过语法差些而已:
1> L = [1,2,3,4,5].
[1,2,3,4,5]
4> [2*X || X <- L ].
[2,4,6,8,10]


看个快速排序:

qsort([]) -> [];
qsort([Pivot|T]) ->
        qsort([X || X <- T, X < Pivot])
        ++ [Pivot] ++
        qsort([X || X <- T, X >= Pivot]).
1> L=[23,6,2,9,27,400,78,45,61,82,14].
[23,6,2,9,27,400,78,45,61,82,14]


12 guard

guard是一种我们能够增强我们的模式匹配的一种结构,假设我们想写一个max(X,Y).我们可以用guard来这样写:

max(X, Y) when X > Y -> X;
max(X, Y) -> Y.


Guard Sequence是一个或多个Guard,他们都用;来隔开,就是或的意思了,也就是说,有一个为真,整个就为真.我们还可以用oralso来替代.
is_atom(L) orelse (is_list(L) andalso length(L) > 2)

而guard则是一个或者多个表达式,他们用,隔开,就是与的意思,也就是说,如果有一个为假,则整个就为假.去我们还可以用andalso来替代.
A >= -1.0 andalso A+1 > B


13 record

定义一个record:

-record(todo, {status=reminder,who=joe,text}).


我们能够在erl里面使用rr来读取这个record:

1> rr("records.hrl").
[todo]


创建和修改record:

2> X=#todo{}.
#todo{status = reminder,who = joe,text = undefined}
3> X1 = #todo{status=urgent, text="Fix errata in book"}.
#todo{status = urgent,who = joe,text = "Fix errata in book"}
4> X2 = X1#todo{status=done}.
#todo{status = done,who = joe,text = "Fix errata in book"}


这边要注意,当使用X1#todo...时,他会先复制一个record然后再进行更新操作,因此此时X1,并不会改变.

得到一个record中的域的值:
8> X2#todo.text.
"Fix errata in book"



一个record其实也就是一个有名字的tuple:

11> X2.
#todo{status = done,who = joe,text = "Fix errata in book" }
12> rf(todo).
ok
13> X2.
{todo,done,joe,"Fix errata in book" }



14 其他的表达式

case :

 filter(P, [H|T]) ->
    case P(H) of
        true -> [H|filter(P, T)];
        false -> filter(P, T)
    end;
filter(P, []) ->
    [].


if :

  if
   Guard1 ->
     Expr_seq1;
   Guard2 ->
     Expr_seq2;
   ...
end



最后看一段将一个list分为计数和偶数两个组的更高效的写法(相比较使用List Comprehensions:

使用List Comprehensions:

odds_and_evens(L) ->
    Odds = [X || X <- L, (X rem 2) =:= 1],
    Evens = [X || X <- L, (X rem 2) =:= 0],
    {Odds, Evens}.
5> lib_misc:odds_and_evens([1,2,3,4,5,6]).
{[1,3,5],[2,4,6]}


更高效的写法:

odds_and_evens_acc(L) ->
    odds_and_evens_acc(L, [], []).
odds_and_evens_acc([H|T], Odds, Evens) ->
    case (H rem 2) of
        1 -> odds_and_evens_acc(T, [H|Odds], Evens);
        0 -> odds_and_evens_acc(T, Odds, [H|Evens])
    end;
odds_and_evens_acc([], Odds, Evens) ->
    {Odds, Evens}.




































7
1
分享到:
评论
5 楼 simohayha 2008-11-27  
coolspeed 写道

随便问下,后面部分是没看呢还是没写记要呢?
偶像译的书耶,译本现在出来了,不看也弄来收藏?:D纯属瞎扯。


没看呢,要学的东西太多,总要先放弃一些。。

哈哈,最好能弄到签名版。。
4 楼 coolspeed 2008-11-27  
随便问下,后面部分是没看呢还是没写记要呢?
偶像译的书耶,译本现在出来了,不看也弄来收藏?:D纯属瞎扯。
3 楼 simohayha 2008-01-08  
哈哈,小狗和我心有戚戚焉..
2 楼 笨笨狗 2008-01-08  
俺跟楼主一样,属于“博爱”人群,喜欢动态语言,Python、Ruby、Groovy、Javascript、List……哈哈哈哈
1 楼 lighter 2008-01-08  
楼主这个家伙, erlang学,ruby也学,scheme和haskel了解一些,python也知道不少。
别无他意,只是随便说说而已。
对我而言,首先学工作首先用到的东西;有空的话,我现在已经比较喜欢看一些计算机原理和数据的东西,以前的基础差了一些。前一段日子,单单看Spring Ioc方面的源码就看的有点喜欢。
可能我们在同一幢办公楼上班的,呵呵,猜的

相关推荐

    Concurrent Programming in ERLANG (P1-90)

    **并发编程在Erlang中的应用(Concurrent Programming in ERLANG)** 本标题及描述明确指出了文档的主要内容是关于如何在Erlang语言中进行并发编程。Erlang是一种通用、并发、强类型、垃圾回收的编程语言,特别适用...

    Erlang - Structured Programming Using Processes

    ### Erlang - 结构化编程使用进程 #### 摘要与背景介绍 本文档探讨了如何在Erlang环境中应用结构化编程技术,并通过一个个人会计软件的应用案例来展示进程作为设计构建的重要作用。作者Jay Nelson从多个角度讨论了...

    erlang 设计指南

    "Programming Erlang: Software for a Concurrent World"是Joe Armstrong编写的经典书籍,深入探讨了Erlang的设计哲学和技术细节。 在Erlang中,并发是核心特性之一。通过轻量级进程(Lightweight Processes, LWP)...

    数据:Erlang的纯函数式和泛型编程

    这些概念在 Erlang 中可能需要通过第三方库或自定义实现来实现,因为它们是函数式编程中常见的抽象,但在Erlang的标准库中并不直接提供。 总的来说,Erlang 的纯函数式编程和泛型编程特性使得它成为构建高并发、...

    高清彩版 Concepts of Programming Languages 11th Edition

    3. **面向对象语言**:基于对象的概念,对象可以包含数据和操作这些数据的方法。Java、C++等是典型的面向对象语言。 4. **逻辑式语言**:使用逻辑规则来描述问题,Prolog是最具代表性的逻辑式语言之一。 5. **并行与...

    Programming-Paradigms-DD1361.Inet:实验室网络

    要在实验室获得批准,您的程序必须有效、满足某些要求并记录在案。 该实验室的目的是研究面向 Internet 的编程,然后特别是通过套接字进行通信(有一个关于套接字的官方教程供感兴趣的人阅读)。 您可以描述通信的...

    编程牛人采访,Coders at Work

    3. **Joe Armstrong**:Erlang语言的发明者之一。 4. **Simon Peyton Jones**:Haskell社区的重要成员,微软研究院研究员。 5. **Peter Norvig**:Google研究总监,人工智能领域专家。 6. **Jamie Zawinski**:X ...

    如何成为一个编程高手

    要成为一个编程高手,首先要具备扎实的IT工程师技能。这些技能包括高效编码能力、丰富的实战经验以及深厚的理论基础。编码不仅仅是写程序,更重要的是能够在有限时间内编写出高质量的代码,这需要对语言特性和最佳...

    Coders_at_Work

    《Coders at Work:Reflections on the Craft of Programming》是一本由Peter Seibel撰写的书籍,于2009年出版。本书通过一系列深入访谈的方式,揭示了多位顶尖程序员的工作方式、思考过程和技术见解,为读者提供了...

    点文件:我的(半)识字的点文件,用于Nix,Emacs,鱼等,由家庭经理和GNU Stow管理

    11. **Rebar3**:Rebar3 是Erlang的构建工具,用于自动化编译、测试和打包过程。如果你在Erlang环境中工作,可能需要配置相关的点文件来定制Rebar3的行为。 12. **Starship**:Starship 是一个快速且可高度定制的...

    short_api_tutorial::link:如何使用Elixir,Phoenix和Mnesia制作链接缩短器

    **Elixir** 是一种基于Erlang VM的函数式编程语言,它提供了并发性、分布式和容错能力。Elixir的语法简洁,易于阅读,适合构建高可用性的系统。 **Phoenix框架** 是Elixir的Web开发框架,它受到了Ruby on Rails的...

    coinbase_ex:Coinbase V2 API包装器

    Elixir是一种函数式编程语言,它运行在Erlang虚拟机上,以其并发性、容错性和高可扩展性著称。Coinbase Ex利用Elixir的强大特性,为Coinbase API提供了一个优雅的封装,使得Elixir开发者能以Elixir风格进行API调用。...

    rummage_ecto:用于ecto查询的搜索,排序和分页

    - **Elixir 编程语言**:`rummage_ecto` 是基于 Elixir 语言的,Elixir 是一种运行在 Erlang VM(BEAM)上的函数式编程语言,以其并发性能和稳定性而著称。 - **Phoenix 框架**:虽然 `rummage_ecto` 不限于 ...

Global site tag (gtag.js) - Google Analytics