Kernel 모듈
Kernel 모듈
Kernel은 Elixir의 기본 환경(default environment)이에요. 크게 다음으로 이루어져 있어요.
- 산술 연산자, 프로세스 생성, 데이터 타입 처리 같은 기본 언어 원시 요소
- 제어 흐름과 새 기능 정의(모듈, 함수 등)를 위한 매크로
- 패턴 매칭을 보강하는 가드(guard) 검사
Kernel의 함수와 매크로는 모두 자동으로 import되기 때문에 Kernel. 접두사 없이 Elixir 코드 어디서든 호출할 수 있어요. 예를 들어 IEx에서 이렇게 쓸 수 있죠.
iex> is_number(13)
true
Kernel에서 특정 함수나 매크로를 import하고 싶지 않다면 :except 옵션에 arity와 함께 나열하면 돼요.
import Kernel, except: [if: 2, is_number: 1]
Elixir에는 항상 import되어 건너뛸 수 없는 특수 형식(special forms)도 있어요. 이들은 Kernel.SpecialForms에 설명돼 있어요.
출처: Kernel
본문
Kernel은 Elixir 표준 라이브러리가 그 위에 세워지는 기본 능력을 제공해요. 고급 기능은 표준 라이브러리를 탐색하는 걸 권장해요.
내장 타입
다음 모듈들이 Elixir 내장 데이터 타입을 다룹니다.
Atom— 이름이 있는 리터럴 상수(true,false,nil도 아톰이에요)Float— 부동소수점 정밀도를 가진 숫자Function—fn/1특수 형식으로 만든 코드 청크 참조Integer— 정수List— 가변 개수의 요소를 담는 컬렉션(연결 리스트)Map— 키-값 쌍의 컬렉션Process— 가벼운 실행 스레드Port— 외부 세계와 상호작용하는 메커니즘Tuple— 고정 개수의 요소 컬렉션
전용 모듈이 없는 데이터 타입도 두 가지 있어요.
- Bitstring —
<<>>/1로 만드는 비트의 연속. 비트 수가 8로 나누어떨어지면 binary라고 부르고 Erlang의:binary모듈로 다룰 수 있어요. - Reference —
make_ref/0로 만드는 런타임 시스템의 고유 값
파생 데이터 타입
위 타입 위에 세워진 다른 타입들도 있어요. Date, DateTime, Exception, MapSet, NaiveDateTime, Keyword, Range, Regex, String, Time, URI, Version 등이 대표적이에요.
시스템 모듈
기반 시스템과 연결되는 모듈들이에요. IO(입출력), File(파일시스템), Path(경로 조작), System(시스템 정보 읽기·쓰기) 등이 있어요.
프로토콜
프로토콜은 Elixir에 다형성 디스패치를 더해요. 데이터 타입이 구현할 수 있는 계약(contract)이에요. Elixir 표준 라이브러리는 다음 프로토콜을 제공해요.
Collectable— 데이터를 어떤 타입으로 모아주는 프로토콜Enumerable— Elixir의 컬렉션 처리.Enum모듈은 즉시(eager) 함수,Stream모듈은 지연(lazy) 함수 제공Inspect— 데이터 타입을 프로그래밍 언어 표현으로 변환List.Chars— 데이터 타입을 charlist(비프로그래밍 기반)의 외부 표현으로 변환String.Chars— 데이터 타입을 문자열(비프로그래밍 기반)의 외부 표현으로 변환
프로세스 기반·애플리케이션 중심 기능
프로세스 위에 세워져 동시성·결함 허용 등을 제공하는 모듈들이에요. Agent, Application, GenServer, Registry, Supervisor, Task, Task.Supervisor 등이 있어요.
가드(Guards)
이 모듈에는 Elixir 개발자가 쓰는 내장 가드들이 포함돼요. 패턴 매칭을 보강하는 미리 정의된 함수·매크로 집합으로, 보통 when 연산자 뒤에 옵니다.
def drive(%User{age: age}) when age >= 16 do
...
end
위 절은 사용자 나이가 16 이상일 때만 호출돼요. 가드는 and·or로 여러 조건을 연결할 수도 있어요. 가드 전체는 모든 가드 표현식이 true로 평가될 때 참이에요.
Truthy와 falsy 값
불리언 true·false 외에도 Elixir는 "truthy"/"falsy" 개념이 있어요.
- 값이
false도nil도 아니면 truthy - 값이
false또는nil이면 falsy
Elixir에는 and/2처럼 불리언만 다루는 함수도 있고, &&/2나 !/1처럼 truthy/falsy 값을 다루는 함수도 있어요.
구조적 비교(Structural comparison)
이 모듈의 함수는 구조적 비교를 수행해요. 덕분에 서로 다른 데이터 타입을 비교 연산자로 비교할 수 있어요.
1 < :an_atom
Elixir 개발자가 서로 다른 타입이 섞인 컬렉션(딕셔너리, 정렬된 집합 등)을 만들 수 있게 하려는 거예요. 소프트웨어에는 구조적(structural) 비교와 의미적(semantic) 비교가 있는데, 구조적 비교는 기반 데이터 구조를 비교하는 것으로 최대한 빨라야 해요. 의미적 비교는 각 타입이 무엇을 나타내는지에 신경 써요. 예를 들어 의미적으로 Time을 Date와 비교하는 건 말이 안 되죠.
구조적 비교와 의미적 비교의 차이를 보여주는 예가 문자열이에요. "alien" < "office"이지만 "álien" > "office"예요. 이는 <가 문자열을 이루는 바이트를 비교하기 때문이에요. 알파벳순 나열을 원했다면 "álien"이 "office"보다 앞에 오길 원할 텐데, 그건 의미적 비교의 영역이에요.
즉 Elixir의 비교는 구조적이에요.
주요 함수·매크로
아래는 Kernel에 정의된 대표적인 함수·매크로예요. (전체 목록은 사이드바를 참고하세요.)
산술·비교 연산자
+/2,-/2,*/2,//2,div/2,rem/2— 산술.div/2는 정수 나눗셈,rem/2는 나머지를 돌려줍니다.==/2,!=/2,===/2,!==/2— 동등 비교.===는 엄격 비교(1 === 1.0은 false).</2,>/2,<=/2,>=/2— 순서 비교(구조적).&&/2,||/2,!/1— truthy/falsy 논리 연산.
타입 검사
is_atom/1, is_binary/1, is_boolean/1, is_float/1, is_function/1,
is_integer/1, is_list/1, is_map/1, is_nil/1, is_number/1, is_pid/1,
is_tuple/1, is_bitstring/1, is_map_key/2, is_struct/1
인자 타입을 검사해 불리언을 돌려줘요. 가드에서 자주 쓰여요.
데이터 구조 함수
+/2(리스트 연결),hd/1,tl/1,length/1— 리스트 기본 연산.map_size/1,tuple_size/1— 맵·튜플 크기.put_elem/3,elem/2,tuple_size/1— 튜플 조작.binary_part/3,byte_size/1,bit_size/1— 바이너리·비트열.to_string/1,to_charlist/1— 각각String.Chars,List.Chars호출.inspect/2— term을 사람이 읽는 표현으로 변환.struct/2,struct!/2— 구조체 생성/갱신.
제어 흐름 매크로
if/2,unless/2— 조건 분기.case/2,cond/1— 패턴 매칭 분기, 조건 분기.with/1— 패턴 매칭이 계속 성공하는 동안 클로저 실행.for/1— 컴프리헨션.try/1,rescue/1,catch/1,after/1,else/1— 예외·비로컬 반환 처리.
모듈·함수 정의
def/2,defp/2,defmacro/2,defmacrop/2,defguard/2,defmodule/2,defstruct/1,defimpl/2,defprotocol/2— 모듈·함수·프로토콜 정의.@/1— 모듈 속성.alias/1,import/1,require/1,use/1— 모듈 의존성 지시어.
프로세스·동시성
spawn/1,spawn_link/1,spawn_monitor/1— 프로세스 생성.send/2,receive/1— 메시지 전송·수신.self/0— 현재 프로세스 PID.apply/2,apply/3— 함수 또는 모듈·함수 호출.
그 외
raise/1,raise/2,error/1,exit/1,throw/1— 예외·제어 신호.__MODULE__/0,__DIR__/0,__ENV__/0— 컴파일 환경 정보.make_ref/0— 고유 reference.=>/2,|>/2,../2,<<>>/1,{}/1— 문법 연산자·특수 형식.match?/2— 예외 없이 패턴 매칭 성공 여부 검사.min/2,max/2,abs/1,round/1,trunc/1— 수치 함수.
더 알아보기
Kernel.SpecialForms— import할 수 없는 기본 구성요소(특수 형식)- Patterns and guards — 패턴·가드·확장 소개
- Library guidelines — 라이브러리 작성 지침
- Naming conventions — Elixir 명명 규칙