Erlang
소개
Erlang은 함수형 병행성 언어
-
병행성
- 가벼운 프로세스를 아주 빠르게 생성
- 각각은 메세지 패싱에 의해 지시 받고 결과 출력
- 공유 메모리 x
-
패턴 매칭
- 함수형 언어의 특징
- Prolog의 것을 함수형으로 고친 것이라 다른 언어들보다 유연
- 자료 형태 선언, 읽는 작업 용이
- 단순 바이너리 데이터 패턴 매칭 가능
-
내장 기능
- 통신 인프라를 위한 언어
- key value 저장소인 ETS, 저장소인 DETS, 등등이 있다
-
장애 허용
- 병행 프로세스 가운데 일부를 감시자로 사용해서 오류가 발생한 프로세스를 깨끗하게 정리하고 재시작
- 실제 Erlang으로 작성된 통신장비 소프트웨어는 가용성 99.9999999%를 찍기도 함
-
성능
- 함수 VS 함수 기반에서 연산 속도, 메모리 사용량이 형편없가 나오는 경우 많음
- Erlang은 기본저긍로 동시성 제어를 위한 언어
- 하나로만 비교하면 느림
- 스케줄러를 완전히 최적화
- 메모리를 아끼기보다 실시간성의 유지를 중요히 여
- 함수 VS 함수 기반에서 연산 속도, 메모리 사용량이 형편없가 나오는 경우 많음
설치
Linux :
sudo apt-get install erlang
MacOS :
brew install erlang
사용
$ erl
Eshell V10.6.4 (abort with ^G)
1> io:fwrite("Hello world~~\n").
Hello world~
ok
2>
Erlang Build Tool
-
rebar3
- Erlang/OTP에서 지원하는 buildtool
- 완전 Erlang 기반
- https://github.com/erlang/rebar3
- 공식사이트 : https://rebar3.org/docs/getting-started/
-
erlang.mk
- Makefile 사용
- 공식사이트 : https://erlang.mk/
-
rebar3 사용 예정
$ git clone https://github.com/erlang/rebar3.git
$ cd rebar3
$ ./bootstrap
$ export PATH=$PATH:~/.cache/rebar3/bin
.
근데 사실 알고리즘 풀 때는 필요 없음
$ erlc (파일명).erl
$ erl -s (모듈명) (함수명)
// 이러면 쉘이 켜진 상태로 멈춤
$ erl -s (모듈명) (함수명) -s init stop
// 이래 하면 함수 출력 후 종료
$ erl -noshell -s (모듈명) (함수명) -s init stop
// 이래 하면 쉘 안켜지고 함수 출력 후 종료
.
helloworld.erl
-module(helloworld). % 모듈명
-export([start/0]). % 함수명
start() ->
io:fwrite("Hello world, samuel!\n").
.
-
Terms
- 어떤 데이터 타입의 데이터는 모두
term
이라 부름
- 어떤 데이터 타입의 데이터는 모두
-
Numbers
- 정수, 부동 소수점
$char
- char의 아스키 값 표기
base#value
- base 는 진수 value 는 진수의 값
2#101
=5
101을 2진수로
-
Atom
- atom 은 리터럴
- 이름이 있는 상수
- 영어 소문자로 시작하며,
_
,@
이외의 문자는'
로 묶어줘야함
hello phone_number 'Monday' 'phone number'
-
Bit Strings and Binaries
- 형식이 지정되지 않은 메모리 영역을 보관할 때 사용
1> <<10, 20>> <<10,20>> 2> <<"ABC">>. <<"ABC">> 3> <<1:1, 0:1>>. <<2:2>>
-
Reference
- Erlang 런타임 시스템의 고유한 term
make_ref/0
호출에 의해 생성
4> Tag = make_ref(). #Ref<0.2589822212.2572943363.197802>
-
Fun
- functional object
fun
은 익명 함수를 만들고, 그 함수 자체를 argument로 다른 함수에 전달
1> Fun1 = fun (X) -> X+1 end.
#Fun<erl_eval.6.128620087>
2> Fun1(2).
3
-
Port Identifier
- Erlang port 식별자
open_port/2
를 이용하여 포트를 생성하면, 이 데이터 타입으로 값이 반환
-
Pid
- 프로세스 식별자
m.erl
이라는 파일을 생성하고 아래의 코드를 입력해주세요.-module(m). -export([loop/0]). loop() -> receive who_are_you -> io:format("I am ~p~n", [self()]), loop() end.
터미널을 열고,
m.erl
이 있는 디렉터리에서 얼랭을 실행합니다.1> c(m). %% 위에서 작성한 m.erl(m 모듈)을 컴파일합니다. {ok,m} 2> P = spawn(m, loop, []). <0.84.0> 3> P ! who_are_you. I am <0.84.0> who_are_you
-
Tuple
- 고정 숫자의 term을 담을 수 있는 데이터 타입
- {Tern, …, TermN}
1> P = {adam, 24, {july, 29}}. {adam,24,{july,29}} 2> element(1, P). adam 3> element(3, P). {july,29} 4> P2 = setelement(2,P,25). {adam,25,{july,29}} 5> tuple_size(P). 3 6> tuple_size({}). 0
-
Map
- Key-Value 조합의 복합 데이터 타입
#{Key1=>Value1,...,KeyN=>ValueN}
1> M1 = #{name=>adam, age=>24, date=>{july,29}}. #{age => 24,date => {july,29},name => adam} 2> maps:get(name, M1). adam 3> maps:get(date, M1). {july,29} 4> M2=maps:update(age,25,M1). #{age => 25,date => {july,29},name => adam} 5> map_size(M2). 3 6> map_size(#{}). 0
-
List
- 가변 개수의 term을 가지는 복합 데이터 타입
[Term1,...,TermN]
1> L1 = [a,2,{c,4}]. [a,2,{c,4}] 2> [H|T] = L1. [a,2,{c,4}] 3> H. a 4> T. [2,{c,4}] 5> L2 = [d|T]. [d,2,{c,4}] 6> length(L1). 3 7> length([]). 0
-
String
- “”로 감싸서 사용하는데 이는 데이터 타입이 아님
- string
"hello"
는[$h,$e,$l,$l,$o]
의 줄임말이며, [104,101,108,108,111]
을 의미
1> "string" "42". "string42"
-
Record
- 고정된 개수의 엘리먼트를 보관하기 위한 데이터 구조
- 실제 데이터 타입이 아님
- 컴파일 동안 Tuple 로 바뀜
-
Boolean
- Boolean 데이터 타입이 존재하지 x
- atom
true
와false
을 Boolean으로 사용
1> 2 =< 3. true 2> true or false. true
-
Escape Sequences
\b
: Backspace\d
: Delete\e
: Escape\f
: Form feed\n
: Newline\r
: Carriage return\s
: Space\t
: Tab\v
: Vertical tab\XYZ
,\YZ
,\Z
: Character with octal representation XYZ, YZ or Z\xXY
: Character with hexadecimal representation XY\x{X...}
Character with hexadecimal representation; X... is one or more hexadecimal characters\^a...\^z
,\^A...\^Z
: Control A to control Z\'
: Single quote\"
: Double quote\\
: Backslash
-
Type Conversions
- 얼랭 매뉴얼 확인
1> atom_to_list(hello). "hello" 2> list_to_atom("hello"). hello 3> binary_to_list(<<"hello">>). "hello" 4> binary_to_list(<<104,101,108,108,111>>). "hello" 5> list_to_binary("hello"). <<"hello">> 6> float_to_list(7.0). "7.00000000000000000000e+00" 7> list_to_float("7.000e+00"). 7.0 8> integer_to_list(77). "77" 9> list_to_integer("77"). 77 10> tuple_to_list({a,b,c}). [a,b,c] 11> list_to_tuple([a,b,c]). {a,b,c} 12> term_to_binary({a,b,c}). <<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>> 13> binary_to_term(<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>). {a,b,c} 14> binary_to_integer(<<"77">>). 77 15> integer_to_binary(77). <<"77">> 16> float_to_binary(7.0). <<"7.00000000000000000000e+00">> 17> binary_to_float(<<"7.000e+00">>). 7.0
Pattern Matching
- 패턴 매칭은 함수의 호출
case
-receive
-try
-표현식- 매칭 연산자(
=
,match operator
)에서 사용
얼랭 변수
- 대문자 or
_
로 시작 - 알파벳, 숫자, _, @ 만 포함 가능
- 할당된 변수는 패턴을 이용해서만 바운드 됨
- 단일 할당!! 한번만 바운드 된다!!!
공식 문서 참고