又要开始一门新的语言的学习了

还记得上一家公司也是学习的一门古老的语言delphi,现在又要学一门新的古早语言erlang,一门不可以修改变量,没有可变状态,没有共享内存,也没有锁的语言,一门if,for,while等语句都需要自己编写的语言。erlang的诞生只比c晚4年,整个语言似乎都充斥着“过时”二字,不过等到我真的深入学习了才明白,嗯,是真的过时了。不过也不是没有值得学习的地方,毕竟自己连个半吊子都算不上


erlang是专门为需要并发式,分布式,高容错,可扩展的系统所设计的,比较适合作为游戏或者有大规模用户交互系统如聊天系统的服务器,语法也比较奇葩,许多规则颠覆了我对编程语言的传统认知,也了解到函数式语言和命令式语言的区别,函数式语言变量的值不能改变,命令式语言可以改变,(虽然不知道为什么不能改变还要叫变量,书中是这么写的)
1.它们是变量,但它们的值只能被改变一次(也就是说,它们从未绑定改变为具有一个值)
2.它们看上去像是传统编程语言里的变量
3.“=”不是赋值,是一个模式匹配符操作,当“变量”未绑定值时,“=”表现为类似赋值的效果
参考
Erlang程序设计(第二版)
【瑞典】Joe Armstrong著
幽蓝鹰 牛华成译

以下将随意记录我的学习内容

% 规则记录
% %为注释符号
% 每句话结尾(每行)必须加上.
% 变量首字符必须大写
% /运算符结果一定为浮点数
% div操作符为整除,向下取整
% rem操作符为取余数
% 对于“=”操作符的理解是,若两边没有任何未绑定的变量,则直接进行判等,否则会想办法在不违背原则的情况下给变量绑定值,使两边相等
% 匿名变量“_”可以用作占位符,可以绑定多个不同的值
% 列表表头指第一个元素,表尾指其他元素
% [A|B] = C,将C的表头数据绑定到A上面,表尾绑定到B上面,或[A,B|C] = D
% 所有绑定均为深拷贝(我是这么理解的,反正原变量也不会发生变化)
% 字符串必须用双引号",实际上一个列表的简写
% 对于一个函数有多个定义,使用分号隔开
% fun函数类似于python中的lambda
% 列表推导[fun(X)||X <- L] 与python中[lambda X:fun(X) for X in L]一致
% 特别需要注意的是,[fun(X,Y)||X<-L,Y<-M]中,是一个嵌套循环,且顺序从前往后,会执行len(L)*len(M)次数的fun
% X -- [Y] 列表里移除一个元素Y返回剩下的元素
% 一般来说内置函数都是小写,如is_integer,网上的东西真的太不靠谱了,搜出来好多版本,就是没有正确答案
% 最开始搜的Is_integer,后来搜发现应该是Is_Integer,还是不对,又搜到了一个is_Integer,总之就是没有搜出is_interger
-module(test).
-export([start/1]).

start(arg1) -> ...

-moudle(test).用于指定本文件的代码为test模块,即定义模块名称,一般与文件名字相同
-export([start/1]).用于导出模块内的函数供别的模块使用,类似于c++内的public作用,未导出的函数将只能在本模块内使用,如被本模块函数调用,数字1代表start这个函数接收一个参数,如需要导出多个函数,则形如-export([func1/n1,func2/n2,...]).
start(arg1)-> 指定义该函数,后面跟着函数的具体内容,有点像es6的箭头函数,函数内容不需要加花括号

pythag(N)->
    [ {A,B,C} ||
        A <- lists:seq(1,N),
        B <- lists:seq(1,N),
        C <- lists:seq(1,N),
        A+B+C =< N,
        A*A+B*B =:= C*C
].
def pythag(N):
    return [{A,B,C} for A in range(1,N) for B in range(1,N) for C in range(1,N) if A+B+C <= N and A*A+B*B == C*C]
def pythag(N):
    res = []
    for i in range(1,N):
        for j in range(1,N):
            for k in range(1,N):
                if A+B+C <= N and A*A+B*B == C*C:
                        res.append({A,B,C})
    return res

上面三段代码功能类似

% 终极无敌重要的if标点总结
% erlang对格式卡的太死了,针对if,经过大量实践,总结出如下规律
% 1.每一个if分支末尾必须加上“;”,除了最后一句
% 2.最后一个分支必须什么都不加
% 3.end后面是根据代码处于的位置加符号,一定要加,但是“,”“;”“.”都有可能加
% 以下代码符号但凡加错一个都编译不了
even(X) -> 
    if
        is_integer(X) ->
            if
                X rem 2 =:= 0 -> 
                    true;
                true -> 
                    false
            end;
        true ->
            false
    end.

% 于是乎,为了更好的理解,我将代码的缩进改成这样
even(X) -> 
    if is_integer(X) ->
        if X rem 2 =:= 0 ->
            true;
        true -> 
            false end;
    true ->
        false end.
% 于是现在的规则就变成了,除非末尾是>,否则必须加符号
% 从最外层的if语句往内看,最外层的所有分支除了最后一个分支末尾,其余末尾全加上分号
% 在往内依次执行,加过标点符号就不需要再加
% 所以,从今往后的所有的if都不在另起一行,所有的end也不再另起一行,所有的->当没有嵌套且返回值较为简单可不换行,否则必换行
最后修改:2023 年 06 月 07 日
来过的证明就是打钱