Tải bản đầy đủ (.doc) (64 trang)

Tìm hiểu về ngôn ngữ lập trình ERLANG

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (687.87 KB, 64 trang )

Tìm hiểu về ngôn ngữ lập trình Erlang
TIỂU LUẬN MÔN HỌC
Đề tài : Tìm hiểu về ngôn ngữ lập trình ERLANG.
[Type text] 1
Tìm hiểu về ngôn ngữ lập trình Erlang
LỜI NÓI ĐẦU 3
ERLANG VÀ HỆ THỐNG HỖ TRỢ LẬP TRÌNH VỚI ERLANG 4
HỆ THỐNG TỪ VỰNG CỦA ERLANG 11
NGỮ NGHĨA CƠ BẢN CỦA ERLANG 12
ĐIỀU KHIỂN LUỒNG TRONG ERLANG 21
MÔI TRƯỜNG THỰC THI CỦA ERLANG 44
KẾT LUẬN 64
[Type text] 2
Tìm hiểu về ngôn ngữ lập trình Erlang
LỜI NÓI ĐẦU
Ngôn ngữ lập trình rất quan trọng trong việc xây dựng nên những ứng dụng chạy
trên máy tính điện tử, những ngôn ngữ lập trình cấp cao hiện nay đều hỗ trợ những
phương pháp lập trình mới giúp cho lập trình viên đơn giản hơn trong việc xây dựng
chương trình. Nhưng không chỉ dừng lại ở đó các ngôn ngữ lập trình cũng ngày càng phát
triển, rất nhiều các ngôn ngữ lập trình mới được ra đời, với nhiều đặc trưng mới phù hợp
hơn với các ứng dụng cụ thể, hỗ trợ những paradigm lập trình khác như parallel, object –
oriented,…
Erlang cũng là một ngôn ngữ cấp cao, được ra đời nhằm mục đích xây dựng những
ứng dụng chạy tốt bằng cách song song hóa các yêu cầu tính toán, hỗ trợ lập trình hàm.
Một đặc điểm quan trọng nhất của Erlang đó là đây là ngôn ngữ xây dựng theo hướng lập
trình tương tranh (Concurrency – Oriented), một hướng khá mới, tiểu luận của chúng em
với mục đích tìm hiểu ngôn ngữ lập trình Erlang với các đặc trưng chính của ngôn ngữ và
làm rõ cách xây dựng chương trình theo hướng lập trình tương tranh của Erlang.
[Type text] 3
Tìm hiểu về ngôn ngữ lập trình Erlang
ERLANG VÀ HỆ THỐNG HỖ TRỢ LẬP


TRÌNH VỚI ERLANG
A. Giới thiệu chung
Erlang là một ngôn ngữ lập trình nhằm mục đích lập trình tương tranh cho phép
thích ứng trên nhiều nền tảng khác nhau (« run foreve »). Với Erlang, sự song song hóa
chỉ phụ thuộc vào ngôn ngữ lập trình chứ không phụ thuộc vào hệ điều hành.
Erlang thực hiện cấu trúc chương trình thành các tiến trình tương tranh (concurrent
process), từ đó khiến cho việc lập trình song song trở nên dễ dàng bằng cách thông qua
các thông điệp được gửi qua lại giữa các tiến trình tương tranh này. Các tiến trình tương
tranh này chạy song song nhưng không dựa trên một quá trình chia sẻ bộ nhớ vì vậy
không gây ra hiện tượng đợi lẫn nhau giữa các tiến trình.Các tiến trình tương tranh này
nhỏ và nhẹ vì vậy mỗi chương trình bao gốm một số lượng lớn các tiến trình tương tranh
(lên đến hàng trăm, hàng nghìn) có thể được thực thi trên một bộ xử lý, một bộ xử lý đa
lõi, hoặc trên một mạng các bộ xử lý khác nhau.
Có 5 lý do mà tác giả của ngôn ngữ khuyên chúng ta nên biết về nó :
Chương trình sẽ chạy nhanh hơn khi được thực thi trên một máy tính đa lõi.
Khả năng xây dựng ứng dụng có chịu lỗi tốt, chúng có thể được chỉnh sửa mà
không cần phải dừng ứng dụng lại.
Ngôn ngữ sử dụng paradigm lập trình hàm (functional programming).
Đây là một ngôn ngữ được kiểm nghiệm thực tế trong hệ thống sản xuất công
nghiệp quy mô lớn.,có các thư viện khổng lồ, và cộng đồng sử dụng rất lớn.
Các ứng dụng được viết lượng lượng dòng lệnh không quá nhiều.
B. Lịch sử của Erlang
Erlang được phát triển tại phòng thí nghiệm Ericsson Computer Science Laboratory
vào những năm 1986. Erlang được thiết kế cho việc lập trình tương tranh, một chương
trình trong erlang được tạo thành bởi hàng nghìn, hàng vạn các tiến trình, các tiến trình
này không chia sẻ bộ nhớ và giao tiếp với nhau qua thông qua các message. Erlang có cơ
chế cho phép chương trình có thể thay đổi code ngay khi chúng đang được thực thi, ta gọi
[Type text] 4
Tìm hiểu về ngôn ngữ lập trình Erlang
đó là cơ chế “on the fly”, chính nhờ cơ chế này ta có thể xây dựng các phần mềm cho các

hệ thống non-stop.
1. Giai đoạn 1985-1988 : Sự ra đời của Erlang:
Vào những năm 1986, Joe Armstrong dự định phát triển một trịnh biên dịch cho
phép lập trình các ứng dụng trên điện thoại một cách hiệu quả. Như chúng ta đã biết, các
ứng dụng trên điện thoại có yêu cầu về khả năng tương tranh cao: một thao tác switch
phải xử lý hàng trăm thậm chí hàng nghìn các giao dịch. Trong quá trình phát triển, ông
bị ảnh hưởng khá nhiều bởi cấu trúc cú pháp của ngôn ngữ Prolog. Trình biên dịch của
ông không những hỗ trợ cho nhiều process cũng lúc mà còn có cơ chế trao đổi thông điệp
giữa các process, cơ chế bắt lỗi … Cùng với Robert Virding, ông đã nghiên cứu và phát
triển ra một ngôn ngữ lập trình, đồng thời phát triển các nguyên lý cho ngôn ngữ này,
ngày này chúng ta gọi ngôn ngữ này là Erlang và nguyên lý mà hai người phát triển là
“Concurrency-Oriented Programming”. Như vậy Erlang là một ngôn ngữ lai giữa ngôn
ngữ lập trình tương tranh và ngôn ngữ lập trình hàm.
Hnh 1. Cấu trúc của ngôn ngữ Erlang
Vào những năm 1987, Erlang lần đầu tiên được sử dụng để thực hiện các ứng dụng
thực tế, erlang được sử dụng để tạo ra một kiến trúc phần mềm mới mang tên là ACS3
được thiết kế cho lập trình các dịch vụ điện thoại trên Ericsson MD110 PABX4, và dự án
mang tên ACS/Dunder đã được triển khai, dựa trên ngôn ngữ erlang để xây dựng kiến
trúc ACS3. Chính nhờ dự án này, ngôn ngứ erlang được phát triển một cách nhanh
chóng, erlang liên tục được cập nhật thêm các tính năng mới, và được áp dụng ngay vào
trong thực tế, những tính năng phù hợp sẽ được giữ lại, còn không chúng sẽ được bỏ đi.
Hầu hết các thay đổi của Erlang đều không được lưu lại, bảng dưới đây là một trong
những mẫu câu lệnh hiếm hoi của erlang trong những ngày đầu phát triển
[Type text] 5
Tìm hiểu về ngôn ngữ lập trình Erlang
Hnh 2. Các mẫu câu lệnh của Erlang trong những ngày đầu
Đến cuối năm 1988, hầu hết mọi ý tưởng trong erlang đã định hình:
Bufered message reception: đây là một trong những ý tưởng được thiết kế đầu tiên
trong erlang, cú pháp gửi nhận tin nhắn được thực hiện theo mẫu sau :
Receive

Patten1 ->
Action1;
Patten2 ->
Action2;
…;
End
Error handling: xử lý lỗi trong erlang khác rất nhiều so với xử lý lỗi trong những
ngôn ngữ lập trình thông thường, cơ chế xử lý lỗi trong erlang được thiết kế để
xây dựng lên một hệ thống chịu lỗi, chúng ta không thể xây dựng một hệ thống
chịu lỗi với một máy tính, điều kiện tiên quyết để xây dựng một hệ thống chịu
lỗi là hệ thống phải có hai máy tính trở lên, quá trình phát hiện lỗi và phục hồi sẽ
được thực hiện trên máy còn lại bởi vì trong trường hợp xấu nhất, máy tính bị lỗi
sẽ bị treo và không thể tính toán được nữa dẫn đến không thể phục hồi. Trong
erlang, mọi thiết bị phần cứng được coi như một đối tượng, và muốn khi muốn
tương tác đến phần cứng thì phải thông qua việc gửi tin nhắn. Điều này khiến
cho mọi việc trở lên dễ dàng trong erlang vì tất cả đều được quy về việc xử lý
các process, và việc trao đổi tin nhắn giữa các process là đồng nhất chứ không
[Type text] 6
Tìm hiểu về ngôn ngữ lập trình Erlang
phân biết xem tin nhắn nào là tin nhắn gửi đến thiết bị phần cứng, tin nhắn nào
là tin nhắn giữa các process với nhau.
Links: links trong erlang dùng để kiểm soát đường truyền lỗi khi xảy ra lỗi giữa các
process. Mô hình xử lý lỗi trong erlang như sau: khi một process trong erlang
“chết”, sẽ có một số các process đóng vai trò “quan sát viên”, chúng theo dõi cái
chết của process đó và sửa những lỗi gây ra cái chết của process kia, tuy nhiên
vậy thi process nào trong hệ thống sẽ được đóng vai trò làm “quan sát viên”
trong số hàng trăm, hàng nghìn process trong một chương trình của erlang.
Chính nhờ links trong erlang mà chúng ta có thể tạo ra một tập các process được
liên kết với nhau, và khi một process thông thường chết thi các process liên kết
với nó sẽ chết theo, tuy nhiên trong số chúng sẽ có những process được gán làm

process hệ thống, khi các process thông thường chết, chúng sẽ có nhiệm vụ khắc
phục lỗi. Ý tưởng này do Mike Williams đề xuất.
Buffers: như ta đã biết các process trong erlang giao tiếp với nhau thông qua việc
gửi thông điệp đến nhau, mỗi một process đều có một “mailbox” để chứa các
thông điệp. Khi một thông điệp được gửi đến nó được đưa vào mailbox, và
process sẽ lên kế hoạch để thực hiện nó. Nếu process thực hiện đối sánh mẫu
thông điệp trong mailbox, nếu thành công thông điệp sẽ được xóa khỏi mailbox
và dữ liệu từ thông điệp sẽ được đưa vào chương trình, nếu không thông điệp sẽ
được đưa vào một hàng đợi. Khi bất cứ một thông điệp nào được process xử lý
tiếp theo, thì những thông điệp được lưu trong hàng đợi sẽ được đưa lại vào
mailbox.
2. Giai đoạn 1989-1997
Trong khoảng thời gian 8 năm này chính là giai đoạn phát triển chính của Erlang, từ
thời gian ban đầu chỉ có hai người phát triển, đến giai đoạn này đã có hàng trăm người
nghiên cứu và sử dụng erlang.
Kết quả của dự án ACS/Dunder: vào tháng 12 năm 1989, báo cáo cuối cùng của dự
án ACS/Dunder được đưa ra, đã có khoảng 25 tính năng của điện thoại đã được thực hiện
thành công, các tính năng này đại diện cho khoảng một phần mười chức năng của
MD110. Báo cáo cũng chỉ ra rằng, Erlang quá chậm để phát triển sản phẩm, để có thể tạo
ra các sản phẩm thực tế thì erlang cần phải nhanh hơn 40 lần so với hiện tại, tuy nhiên
Ericsson vẫn quyết định xây dựng một sản phẩm gọi là “Mobility Server” dựa trên kiến
trúc ACS/Dunder.
[Type text] 7
Tìm hiểu về ngôn ngữ lập trình Erlang
Mở rộng ra thế giới: năm 1989 cũng là lần đầu tiên Erlang có cơ hội được giới thiệu
ra ngoài thế giới thông qua hội nghị SETSS tại Bournemouth. Chính nhờ hội nghị này,
mà các tác giả đã được mởi đến Bellcore để nói về Erlang.
C. Hệ thống hỗ trợ lập trình Erlang
Hệ thống hộ trợ lập trình của Erlang (trình dịch và các thư viện liên quan) được
cung cấp miễn phí tại trang web />Tại đây ta có thể chọn nền hệ điều hành của máy tính thực thi là Linux hay

Window. Ở đây để tiện cho việc cài đặt và thực thi chương trình em chọn Window.
Ngoài ra chúng ta cần lưu ý đến CEAN (The Comprehensive Erlang Archive
Network) đây là sự tổng hợp tất cả các ứng dụng quan trọng của Erlang vào một bộ cài
đặt duy nhất, điều này giúp cho ta có thể khai thác được một lượng lớn các gói chương
trình được viết bằng Erlang. Để có thể sử dụng CEAN, ta truy cập vào đường dẫn
/>Việc thực hiện cài đặt chương trình khá đơn giản, sau khi cài đặt xong chương trình
ta có thể thấy có hai chương trình thực thi phục vụ cho việc lập trình được gọi là shell
trong thư mục .\erl5.7.3\bin đó là:
erl.exe đây là shell để chạy trên dòng lệnh command line của window để shell
này trước hết ta phải chuyển đến thư mục .\erl5.7.3\bin sau đó thực hiện lệnh erl
werl.exe đây là shell để chạy thông qua cứa sổ của window khi nháy kép vào file
chạy ta sẽ thấy xuất hiện cửa sổ ứng dụng của shell
Dưới đây là shell chạy qua cửa sổ và dòng lệnh chạy thử:
[Type text] 8
Tìm hiểu về ngôn ngữ lập trình Erlang
Hnh 3. Shell cửa sổ của Erlang và lệnh tính biểu thức 2 * (3 + 4)
Từ hình trên ta có thể nhận ra một số thông tin về version của Erlang cũng như
version của Eshell. Shell được thực hiện với dấu nhắc 1>. Để thực hiện biểu thức đã cho
ta gõ trực tiếp biểu thức sau dấu nhắc của hệ thống. Một lỗi khá gặp đối với người mới
lập trình Erlang đó là dấu “.” cuối cùng sau biểu thức. Dấu chấm này đánh dấu kết thúc
một dòng lệnh để chuyển sang lệnh kế tiếp (dấu nhắc hệ thống chuyển thành 2>), nếu
thiếu dấu chấm này câu lệnh sẽ không được thực hiện và nếu ta ấn ENTER dấu nhắc của
hệ thống vẫn là 1> mà không đưa ra được kết quả của biểu thức.
1. Viết code bằng file – module
Để tiện cho quá trình lập trình cũng nhưng thêm các tham số cho quá trình biên dịch
Erlang hỗ trợ xây dựng các Module.
Modules: là đơn vị cơ bản trong Erlang, toàn bộ các functions mà chúng ta viết
được chứa trong modules, các modules được lưu trong các file có phần mở rộng .erl.
Modules cần được biên dịch trước khi chạy. Một file modules đã được biên dịch sẽ có
phần mở rộng là .beam. Xét ví dụ sau:

1>Rectangle = {rectangle, 10, 5}.
{rectangle, 10, 5}.
[Type text] 9
Tìm hiểu về ngôn ngữ lập trình Erlang
2>Circle = {circle, 2.4}.
{circle,2.40000}
3>{rectangle, Width, Ht} = Rectangle.
{rectangle,10,5}
4>Width.
10
5>Ht.
5
6>{circle, R} = Circle.
{circle,2.40000}
7>R.
2.40000
Ta khởi tạo hai tuple đại diện cho hình chữ nhật với các kích thước là 10 và 5, và
hình tròn với bán kính là 2.4. Bây giờ ta sẽ tạo ra một function với tên gọi là area dùng
để tính chu vi của hình chữ nhật và hình tròn. Chúng ta sẽ để function này trong module
mang tên là geometry và được lưu trong file geometry.erl :
-module(geometry).
-export([area/1]).
area({rectangle, Width, Ht}) -> Width * Ht;
area({circle, R}) -> 3.14159 * R * R.
Như vậy, ta thấy rằng phần code của function area bao gồm hai mệnh đề được cách
nhau bằng dẫu “ ; “ và mệnh đề cuối cùng kết thúc bằng dấu chấm. mỗi mệnh đề có phần
đầu và phần thân, phần đầu bao gồm tên function và đi theo nó là pattern (trong ngoặc
đơn), phần thân bao gồm các chuỗi các biểu thức sẽ được tính toán nếu các thông số ở
pattern phù hợp. Để có thể chạy được chương trình trên ta cần biên dịch nó:
1>c(geometry).

{ok,geometry}
2>geometry:area({rectangle, 10, 5}).
50
3> geometry:area({circle, 1.4}).
6.15752
Ở câu lệnh thứ 1 c(geometry) dùng để biên dịch mã code trong file
geometry.erl, trình biên dịch trả lại kết quả thành công {ok, geometry}, ở câu lệnh
thứ 2 và 3 ta gọi functiong trong module geometry. Khi ta gọi câu lệnh
geometry:area({rectangle, 10, 5}), thì việc đầu tiên đó là gán giá trị
Width = 10 và Ht = 5, sau đó phần code sau dấu -> được thực hiện đó là lấy
Width*Ht.
[Type text] 10
Tìm hiểu về ngôn ngữ lập trình Erlang
HỆ THỐNG TỪ VỰNG CỦA ERLANG
D. Hệ thống ký tự của ngôn ngữ Erlang
Trong Erlang hệ thống ký tự rất đa dạng Erlang có thể nhận được khá nhiều ký tự
(tất cả ký tự của bảng ISO-8859-1 (Latin-1).
Các ký tự được phân loại như dưới bảng sau:
Mã cơ số 8 Mã thập phân Ký tự Thuộc lớp
200 - 237 128 - 159 Các ký tự điều khiển
240 - 277 160 - 191 - ¿ Dấu câu
300 - 326 192 - 214 À - Ö Chữ in hoa
327 215 × Dấu câu
330 - 336 216 - 222 Ø - Þ Chữ in hoa
337 - 366 223 - 246 ß - ö Chữ thường
367 247 ÷ Dấu câu
370 - 377 248 - 255 ø - ÿ Chữ thường
E. Các từ khóa của Erlang (reserved word):
after and andalso band begin bnot bor bsl bsr bxor case catch cond
div end fun if let not of or orelse query receive rem try when xor

F. Biến và các atom hợp lệ
Các cụm ký tự được bắt đầu bởi chữ cái in hoa được coi là một biến, mỗi biến được
bắt đầu bằng _ là một biến có thể đại diện cho bất kỳ giá trị nào (ta không quan tâm và
không tác động đến biến dạng này).
Các cụm ký tự mà không bắt đầu được coi như một atom, nếu muốn có atom bắt
đầu bằng chữ cái in hoa ta để trong dấu nháy đơn (‘’).
G. Dấu phân cách
Hằng ký tự nằm trong cặp nháy kép (“”)
Dấu « . » là thể hiện kết thúc lệnh sau dấu này ấn Enter sẽ thực hiện
Dấu « , » là dấu thể hiện phân tách giữa các phần tử trong 1 list, 1 danh sách tham
số, …
Dầu « ; » là dấu thể hiện các vế của một câu lệnh.
[Type text] 11
Tìm hiểu về ngôn ngữ lập trình Erlang
Đằng sau dấu % là một câu chú thích, toàn bộ những kí tự đằng sau dấu % cho đến
cuối dòng đều được coi là câu chú thích và sẽ không được dịch bởi Erlang
compiler.
NGỮ NGHĨA CƠ BẢN CỦA ERLANG
H. Biến đối với ngôn ngữ - Variable
Đối với một ngôn ngữ lập trình thì biến là một thành phần rất quan trọng của ngôn
ngữ nó là nơi thể hiện cách xử lý đối với vùng nhớ của một ngôn ngữ lập trình, tùy từng
ngôn ngữ mà các biến có thể được xử lý khác nhau, chúng được gán cho một tập các kiểu
tương ứng ở từng ngôn ngữ lập trình. Mỗi biến được gán cho một tên để người lập trình
có thể thao tác với biến thông qua tên
Trong Erlang thì tên của biến được thể hiện bằng một cụm các ký tự bắt đầu bằng
một chữ cái in hoa. Khi thực thi chương trình chạy trên shell mỗi thành phần đều được
gán với một biến cụ thể.
Biễn số thường được khai báo dưới dạng bắt đầu bằng chữ cái in hoa hay là dấu
gạch dưới và có thể bao gồm các ký tự số và chữ, gạch chân và @. Ví dụ:
X

Name1
PhoneNumber
Phone_number
_
_Height
Các biến số được ràng buộc tới giá trị đang sử dụng. Erlang chỉ cho phép 1 biến số
chỉ đuợc ràng buộc 1 lần.
Những biến số bất định được biểu diễn bởi dấu gạch dưới (_) và có thể được sử
dụng khi một biến được sử dụng, nhưng giá trị của nó bị bỏ qua. Ví dụ:
[H | _] = [1, 2, 3]
Các biến số bắt đầu với dấu gạch chân (_Height) là các biến số ở dưới dang thường,
không phải là dạng bất định, Tuy nhiên chúng được bỏ qua bởi chương trình dịch, chúng
sẽ không sinh ra bất kỳ các cảnh bảo nào cho nhưng biến không được sử dụng. Ví dụ:
member(_,[]) -> [].
Có thể được viết để dễ dàng đọc hơn:
member(Elem, []) -> [].
[Type text] 12
Tìm hiểu về ngôn ngữ lập trình Erlang
Tuy nhiên điều này sẽ gây nên nhưng cảnh báo cho các biến số không đuợc sử dụng
Elem, nếu code được biên dịch với cờ warn_usused_vars. Chúng ta có thể viết lại dưới
dạng sau:
Member(_Elem,[]) -> [].
Chú ý ràng các biến số bất đầu với dấu gạch chấn sẽ phù hợp (match) với:
{_, _} = {1, 2}
Nhưng sẽ gây lỗi:
{_N, _N} = {1, 2}
Phạm vi của biến này là trong mệnh để function của nó (function clause). Các biến
được ràng buộ trong một nhánh của các lệnh if, case, hay các biểu thức nhận về phải
được ràng buộc trong tất các các nhánh để có thể nhần được giá trị bên ngoài biểu thức,
học không chúng sẽ được lưu ý dưới dạng unsafe (không an toàn) bên ngoài biểu thức.

Mỗi biến trong Erlang được dùng một phép gán (“=”) một lần duy nhất khi muốn
biết giá trị của biến nào thì chỉ cần gõ tên biến ra. Một khi X đã có giá trị cố định ta có
thể sử dụng nó, tuy nhiên khi ta có ý định gán lại cho X một giá trị khác thì shell sẽ báo
lỗi, bởi vì thứ nhất biến trong Erlang không phải là một biến như ta vẫn quan niệm như
trong các ngôn ngữ lập trình khác như Java hay C, thứ hai dấu “=” không phải là toán tử
gán. Các biến trong Erlang có giá trị không thay đổi, ta gọi chúng là các “single
assignment variables”, các biến này chỉ nhận giá trị một lần duy nhất, các biến đã được
nhận giá trị thì được gọi là “bound variable” còn các biến chưa được nhận giá trị thì được
gọi là “unbound variable”, tất cả các biến ban đầu đều thuộc dạng “unbound variable”.
Khi Erlang nhận được một câu lệnh X=1234 thì nó sẽ liên kết biến X với giá trị
1234, và trước khi được gán trị 1234 thì biến X có thể nhận bất cứ giá trị nào, tuy nhiên
khi đã được gán thì nó sẽ giữ giá trị đó mãi mãi.
Trong Erlang thì phép gán “=” được thực hiện là một phép “pattern matching
operation”, ta có thể gọi tắt là phép bound. Mỗi khi thực hiện phép bound Lhs = Rhs,
thì Rhs sẽ được thực hiện tính toán trước, sau đó kết quả này được đối sánh với Lhs, nếu
không thực hiện được lỗi sẽ được đưa ra
Ví dụ:
1> X.
** 1: variable 'X' is unbound **
2> X = 2.
2
3> X + 1.
3
4> {X, Y} = {1, 2}.
[Type text] 13
Tìm hiểu về ngôn ngữ lập trình Erlang
** exception error: no match of right hand side value {1,2}
5> {X, Y} = {2, 3}.
{2,3}
6> Y.

3
Trong khi thực hiện Shell ta có thể dùng lênh f() để cho phép shell quên đi các phép
bound trước đó đến các biến khi đó ta có thể thực hiện bound lại một tên biến đã sử dụng.
I. DataType của Erlang
1. Số và biểu diễn số trong Erlang
Các số được cung cấp các cách viết thông thường với các số nguyên và các số thực
(các số thực được viết dưới dạng dấu chấm tĩnh, chấm động: 3.123453E12)
Ngoài ra Erlang còn cung cấp các cách viết khác:
• $char – trong đó char là các ký tự ASCII.
• Base#value – trong đó base là hệ cơ số của số được biểu diễn, value là cách ghi số
đã cho trong hệ cơ số base, trong đó base là các số từ 2 đến 36.
2. Atom
Trong Erlang chúng ta sử dụng các atom để định nghĩa các hằng số kí tự, khác với
trong C, để sử dụng các hằng số kí tự thì ta phải khai báo chúng ở phần đầu của chương
trình ví dụ như khai báo marco, hoặc khai báo trong một file header ví dụ như gobal.h, và
để sử dụng file này, ngay ở đầu chương trình chính ta phải có lệnh “#include gobal.h”.
Trong Erlang thì các hằng số kí tự là toàn cục, ta không cần phải sử dụng các định nghĩa
marco hoặc gọi các hàm include như trong C.
Đây là kiểu dữ liệu dạng chữ, dạng một hằng số tên. Như đã nói ở phần trước Atom
cần phải để trong dấu ngoặc đơn, nếu nó được bắt đầu bằng một chữ cái in hoa hoặc chứa
thêm các ký tự khác ngoài các chữ cái và số ra như dấu cách (space), dấu « _ » hoặc dấu
« @ ».
Ví dụ :
hello
phone_number
'Monday'
'phone number'
Giá trị của atom chính là atom, có nghĩa là giá trị của một atom chính là hằng số kí
tự, vì erlang là một ngôn ngữ lập trình hàm nên mọi biến đều phải có giá trị, và giá trị đó
có thể là số hay atom (hằng số kí tự).

[Type text] 14
Tìm hiểu về ngôn ngữ lập trình Erlang
3. Funciton một kiểu dữ liệu khá đặc biệt.
Đây là một kiểu dữ liệu khá đặc biệt của các ngôn ngữ hỗ trợ lập trình hàm như các
ngôn ngữ Standard ML (SML) hay OCaml, … .Nếu như ở các ngôn ngữ không hỗ trợ lập
trình hàm thì kiểu dữ liệu mảng có thể được coi như một kiểu dữ liệu hàm nhưng khá hạn
chế và không hiệu quả.
Ngôn ngữ Erlang hỗ hợ kiểu dữ liệu hàm bằng khai báo như ví dụ sau:
1> Fun1 = fun (X) -> X+1 end.
#Fun<erl_eval.6.39074546>
2> Fun1(2).
3
Như trong đoạn code trên ta cũng thấy được việc tính giá trị của hàm trở nên rất đơn
giản chỉ cần viết TenHam(GiaTriCuaThamSo) là ta có thể tính được giá trị của hàm.
Tham số vào của một hàm, hay kết quả trả về của hàm có thể là một hàm khác. Nhờ
hỗ trợ như vậy nên ta có thể xây dựng các hàm cấp cao (high-order function), như ví dụ
dưới đây:
1> Double = fun(Fun, X) -> Fun(Fun(X)) end.
#Fun<erl_eval.12.113037538>
2> Nhanhai = fun(X) -> X*2 end.
#Fun<erl_eval.6.13229925>
3> Double(Nhanhai, 3).
12
Ta thấy hàm Double nhận đầu vào là một hàm với biến là X, kết quả trả ra là một
hàm thực hiện bằng cách thực hiện hai lần hàm đã cho.
4. Tuple và Record
Đây là kiểu dữ liệu tích Đề-Các của ngôn ngữ Erlang, là một tập hợp gồm các thành
phần dữ liệu có các kiểu khác nhau.
Nếu như trong C ta sử dụng cấu trúc struct để tạo nên kiểu dữ liệu có cấu trúc thể
hiện tích Đề Các của các kiểu dữ liệu đơn giản, bằng cách khai báo một struct như sau:

struct point {
Int x;
Int y;
} P;
Với Erlang kiểu dữ liệu Tuple được hai báo như sau:
{Term1, ,TermN}
[Type text] 15
Tìm hiểu về ngôn ngữ lập trình Erlang
Như ta thấy các thành phần của Tuple nằm trong cặp ngoặc nhọn {} và ngăn cách
nhau bởi dấu “,” . Các thành phần của một Tuple có thể là bất ký kiểu dữ liệu nào kể cả
kiểu Tupble (nested Tupble) giống trong C các struct có thể lồng nhau. Ví dụ:
Person = {person, {name, joe}, {height, 1.82}, {footside, 42},
{eyecolour, brown}}.
Trong C, khi muốn khởi tạo giá trịc các trường x và trường y ta sử dụng dấu chấm,
Ví dụ: P.x = 10;
Erlang thì không khai báo theo cách đó, để tạo ra một cấu trúc như trên đơn giản ta
chỉ cần viết
P = {10, 45}.
Câu lệnh trên tạo ra một tuple và gán nó cho biến P. Không giống như C, trường
của Tuple không có tên, do đó tuple P chỉ chứa duy nhất hai giá trị số nguyên, chúng ta
buộc phải nhớ xem ta tạo ra tuple này dùng để làm gì. Một cách đơn giản để làm chương
trình dễ hiểu hơn đó là ta sử dụng một atom làm biến đầu tiên trong tuple để nhắc chúng
ta nhớ tuple này làm gì, vậy thay vì viết P = {10, 45} ta sẽ khai báo P = {point, 10, 45}.
Tuple được tạo ra tự động khi chúng ta khai báo chúng, và chúng sẽ được hủy đi khi
không được sử dụng đến nữa, Erlang sẽ sử dụng garbage collector để thu hồi tất cả các bộ
nhớ không sử dụng nữa vì vậy chúng ta không phải quan tâm quá nhiều đến việc cấp phát
bộ nhớ như trong C. Chúng ta có thể tạo ra các Tuple mới từ các Tuple cũ thông qua biến
được gán cho Tuple đó:
2>F = {firstName, joe}.
{firstName,joe}

3> L = {lastName, armstrong}.
{lastName,armstrong}
4> P = {person, F, L}.
{person,{firstName,joe},{lastName,armstrong}}
Các trường trong tuple của erlang không có tên, vậy làm thế nào để ta có thể lấy giá
trị trong tuple. Như ta đã biết, dấu “=” trong erlang được sử dụng như một toán tử gán
trong C, nhưng thực chất nó là một toán tử pattern matching, nó được erlang sử dụng
trong nhiều chức năng khác nhau, trong đó có việc lấy dữ liệu từ tuple. Để lấy dữ liệu từ
tuple, đơn giản như sau:
1>Point = {point, 10, 45}.
{point, 10, 45}.
2>{point, X, Y} = Point.
{point,10,45}
3>X.
10
4>Y.
45
[Type text] 16
Tìm hiểu về ngôn ngữ lập trình Erlang
Ở câu lệnh thứ 1, ta khởi tạo một tuple và gán vào biến Point, ở câu lệnh thứ hai ta
thực hiện toán tử pattern matching “=” khi đó Lhs = Rhs và được gán bởi Rhs, lúc đó X
sẽ được gán giá trị 1, và Y sẽ được gán giá trị 45. Như vậy để có thể lấy dữ liệu từ tuple
thì tuple ở cả hai phía phải có cùng số lượng thành phần và cùng kiểu biến. Nếu muốn lấy
giá trị từ một tuple phức tạp, như tuple chứa các biền miêu tả con người, thì ta sử dụng
một tuple có cùng cấu trúc với tuple đó, và thay thế một biến chưa được gán tại giá trị mà
ta muốn lấy:
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}}
3>Who.
joe
Để ý thấy rằng ta sử dụng ( _ ) để thay thế các biến mà ta không quan tâm, và kí tự (
_ ) được gọi là biến vô danh, không giống như các biến bình thường, ta không cần phải
quan tâm đến giá trị của biến ( _ ) trong câu lệnh nên nó có thể xuất hiện nhiều lần trong
câu lệnh.
Ngoài cách làm trên khi làm việc với Tuple ta có thể sử dụng một số hàm được xây
dựng sẵn như:
• element(ViTri,Tuple) cho biết giá trị của phần tử thứ ViTri của Tuple.
• setelement(ViTri, Tuple, GiaTri) thêm vào Tuple phần tử GiaTri tại
vị trí ViTri.
• tupble_size(Tuple) cho biết số phần tử của Tuple.
Ví dụ:
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
Tuple làm việc khá thuận lợi nhờ tính đơn giản của nó nhưng nó lại có một mặt yếu
đó là tên của các trường không có vì vậy ta sẽ có thể gặp rắc rối khi làm việc với những
[Type text] 17
Tìm hiểu về ngôn ngữ lập trình Erlang

Tuple có số lượng thành phần lớn và phức tạp. Trong Erlang một kiểu dữ lieuj mới cũng
được cung cấp nhằm thực hiện điểm yếu này đó là Record.
Record cũng là một dạng tuple nhưng có số lượng thành phần là cố định, và các
trường của nó không như tuple, được đặt tên giống như struct trong ngôn ngữ C. Để sử
dụng được record ta cần phải thêm –record() vào phần đầu của module sử dụng Record.
Như trong ví dụ sau:
-module(person).
-export([new/2]).
-record(person, {name, age}).
new(Name, Age) ->
#person{name=Name, age=Age}.
1> person:new(ernie, 44).
{person,ernie,44}
Hoặc ta cũng có thể định nghĩa riêng record trong file có đuôi mở rộng là .hrl. File
này sẽ được include vào file nguồn sử dụng tương ứng. Nếu muốn shell hiểu được record
này ta cần gọi hàm rr(). Ví dụ:
Trong file records.hrl ta có định nghĩa record như sau:
-record(todo, {status=reminder,who=joe,text}).
Khi đó trong shell ta thực hiện lệnh gọi:
1> rr("records.hrl").
[todo]
Để lấy các thành phần dữ liệu trong Record ngoài cách lấy dữ liệu như đối với
Tuple ta có thể thực hiện như sau:
8> X2#todo.text.
"Fix errata in book"
5. List và hằng xâu trong Erlang
List là kiểu dữ liệu tập hợp của ngôn ngữ Erlang, cũng giống trong C, list trong
erlang cũng dùng để liệt kê các biến, kiểu dữ liệu tập hợp này có kể thứ tự của các phần
tử. Kiểu dữ liệu này có thể được khai báo như sau :
[Term1, ,TermN]

Như trên ta thấy List trong Erlang được khởi tạo trong các dấu ngoặc vuông [], các
phần tử được cách nhau bằng dẫu “,“ thành phần có thể là một tuple, hay atom, hoặc một
biến số bình thường thông thường:
1>ThingsToBuy = [{apples,10},{pears,6},{milk,3}].
[{apples,10},{pears,6},{milk,3}]
Hoặc ta có thể khai bảo theo cách sau:
[Type text] 18
Tìm hiểu về ngôn ngữ lập trình Erlang
2>[1+7,hello,2-2,{cost, apple, 30-20},3].
[8,hello,0,{cost,apple,10},3]
Mỗi thành phần của List được gọi là một element và mỗi list đều có một độ dài
bằng số lượng các element có trong list đó.
List có thể là một List rỗng ([]) hay là một List được cấu tạo từ hai thành phần Head
và Tail, ở đây Head là chỉ thành phần đầu tiên của List còn Tail là phần còn lại của List
ngoài Head ra, như vậy Tail cũng là một danh sách, kí tự “|“ dùng để phân biệt phần đầu
với phần đuôi của một list. Như vậy List có thể được biểu diễn thành [Head|Tail].
Cách viết List như trên ([Term1, ,TermN]) là cách viết ngắn gọn của [Term1|[ |
[TermN|[]]]].
Một List mà có thành phần Tail cũng là List thường được gọi là một List chuẩn. Ở
Erlang cũng cho phép tạo ra những List mà thành phần Tail của nó không phải là một
List ví dụ như List [a|b], nhưng những loại List như vậy thường rất ít khi được sử dụng.
Chúng ta có thể tạo thêm nhiều thành phần hơn trong list mới bằng cách viết
[E1,E2…,En|T]:
3>ThingsToBuy1 = [{oranges,4},{newspaper,1}|ThingsToBuy].
[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]
Cũng giống như tuple, muốn lấy giá trị từ list ta sử dụng toán tử pattern matching “
= “. Nếu T không phải là một list rỗng thì biểu thức [X|Y] = T (với X, Y là những
biến “unbound variable”) sẽ gán phần đầu của T cho X và phần đuôi của T cho Y:
4>[Buy1|ThingsToBuy2] = ThingsToBuy1.
[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}

Như vậy, biến Buy1 sẽ được gán {oranges, 4} và ThingsToBuy2 sẽ là phần list còn
lại. Điều tương tự xảy ra khi ta sử dụng câu lệnh:
5>[Buy2,Buy3|ThingsToBuy3Z = ThingsToBuy2.
{newspaper,1},{apples,10},{pears,6},{milk,3}]
Ví dụ một đoạn chương trình về List:
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
[Type text] 19
Tìm hiểu về ngôn ngữ lập trình Erlang
7> length([]).
0
Tập hợp các hàm làm việc với List được để trong thư viện lists.
String là một chuỗi ký tự trong Erlang được biểu diễn bằng cách để trong dấu nháy
kép (“”), nhưng chuỗi ký tự không phải là một kiểu dữ liệu trong Erlang nó là một cách
viết ngắn của một list. Ví dụ như chuỗi “Hello” là viết tắt của list [$h,$e,$l,$l,$o] hoặc
list [104,101,108,108,111].
Các chuỗi ký tự sẽ được nối vào nhau một cách tự động nếu viết liền nhau. Ví dụ :
1>"string" "42".
"string42"
6. Binary

Erlang sử dụng một cấu trúc dữ liệu đặt tên là binary để lưu giữ một lượng lớn dữ
liệu một cách hiệu quả hơn so với lưu trữ bằng list hay tuple, và nhờ đó chương trình sẽ
chạy nhanh hơn, tối ưu hơn với đầu vào và đầu ra là các mã nhị phân. Binaries được viết
và in ra dưới dạng một chuỗi các số nguyên hay strings nằm hai dấu nhỏ hơn và hai dấu
lớn hơn. Ví dụ:
1> <<5,10,20>>.
<<5,10,20>>
2> <<"hello">>. <<"hello">>
Giá trị số nguyên được sử dụng trong binary chỉ được nằm trong khoảng 0 đên
255. Cồn đối với string thì <<”cat”>> là viết tắt của <<99, 97, 116>> chính
là mã ASCII của kí tự, nếu dãy số trong binary đều đại diện cho mã ASCII của một
kí tự nào đó thì shell sẽ in ra chuỗi số như một string, còn không shell chỉ in ra một chuỗi
các số nguyên. Chúng ta có thể tạo một binary hoặc lấy các thành phần trong một binary
bằng cách sử dụng các hàm trong BIF hoặc có thể dùng cấu trúc bit (Bit Syntax)
Các hàm BIF thao tác trên binary:
@spec list_to_binary(loList) -> binary(): trả lại một binary được tạo
thành từ các số nguyên và binary trong loList. loList ở đây là một list mà các
thành phần là các số nguyên trong khoảng 0 255, hoặc là các binaries:
1>Bin1 = <<1,2,3>>.
<<1,2,3>>
2>Bin2 = <<4,5>>.
<<4,5>>
3>Bin3 = <<6>>.
<<6>>
4>list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).
<<1,2,3,1,2,3,4,5,4,6>>
[Type text] 20
Tìm hiểu về ngôn ngữ lập trình Erlang
@spec split_binary(Bin, Pos) -> {Bin1, Bin2}: chia một binary Bin thành
hai phần tại vị trí phần tử thứ Pos:

1> split_binary(<<1,2,3,4,5,6,7,8,9,10>>, 3).
{<<1,2,3>>,<<4,5,6,7,8,9,10>>}
@spec term_to_binary(Term) -> Bin : chuyển đổi bất cứ mẫu dữ liệu nào của
Erlang thành một binary. Term được sử dụng để chuyển đổi thành binary bằng
câu lệnh term_to_binary có thể được lấy từ trong file, được lấy từ các thông điệp
truyền trên mạng, và tất nhiên các Term này có thể được tái tạo lại sau này. Câu
lệnh này rất hữu dụng cho việc lưu trữ các cấu trúc dữ liệu phức tạp trong file
hoặc gửi các cấu trúc dữ liệu phức tạp đến các máy trạm.
@spec binary_to_term(Bin) -> : đây là hàm ngược của hàm term_to_binary:
1>B = term_to_binary({binaries,"are", useful}).
<<131,104,3,100,0,8,98,105,110,97,114,105,101,115,107,0,3,97,114,1
01,100,0,6,117,115,101,102,117,108>>
2>binary_to_term(B).
{binaries,"are",useful}
@spec size(Bin)-> Int : trả lại số byte trong một binary:
1> size(<<1,2,3,4,5>>).
5
ĐIỀU KHIỂN LUỒNG TRONG
ERLANG
J. Biểu thức (Expression)
Trong phần này, chúng ta sẽ tìm hiểu tất các các loại biểu thức đuợc sử dụng trong
Erlang. Chương trình bằng Erlang cho phép chúng ta sử dụng các macro và biểu thức
theo kiểu bản ghi. Tuy nhiên, những biểu thức này được mở rộng trong suốt lúc biên
dịch, và nó không thực sự đúng là biểu thức Erlang.
1. Biểu diễn biểu thức:
Tất cả các biểu thức con được biểu diễn trước khi bản thân nó được biểu diễn, trừ
khi nó đuợc biểu diễn một cách rõ ràng. Ta có thể xem xét ví dụ sau:
Expr1 + Expr2
Trong đó, Expr1 và Expr2 cũng là biểu thức, cần phải được biểu diễn trước,
trong bất cứ thứ tự nào, trước khi các thông tin thêm vào được thực hiện.

[Type text] 21
Tìm hiểu về ngôn ngữ lập trình Erlang
Rất nhiều các toán tử chỉ có thể được sử dụng như là tham số của một kiểu phù hợp.
Ví dụ, các toán tử số học chỉ có thể sử dụng tới các kiểu số. Các tham số của các kiểu
không phù hợp sẽ gây nên lỗi badarg run-time.
2. Số hạng (Term)
Dạng đơn giản nhất của các biểu thức là một số hạng (term), đó là số nguyên, số
thức, atom, kiểu chuỗi, danh sách hay là tuple. Giả trị trả về cũng thuộc kiểu dữ liệu đó.
3. Biến số (Variables)
Một biến số là một biểu thức. Nếu một biến số trỏ đến một giá trị, đó chính là giá trị
trả vể. Các biến số không bị ràng buộc chỉ được cho phép trong các biểu mẫu (patterns).
Một biểu mẫu có cũng cấu trúc như một kiểu dữ liệu, nhưng có thể bao gồm
các biến không ràng buộc. Ví dụ
Name1
[H | T]
{error, Reason}
Patterns – mẫu được cho phép trên đầu mỗi mệnh đề, biểu thức case and receive, và
biểu thức so khớp (match expression).
Toán tử so khớp ( = ): Nếu Pattern1 và Pattern2 là biểu mẫu hợp lệ, thì biểu thức
sau đây cũng là biểu thức hợp lệ:
Pattern1 = Pattern2
Khi số khớp với các số hạng, cả Pattern1 và Pattern2, sẽ đuợc so khớp với số hạng
này. Ở đây chúng ta nên ẩn sau các đặc trưng này để tránh xa việc biểu diễn lại các số
hạng. Ví dụ:
f({connect,From,To,Number,Options}, To) ->
Signal = {connect,From,To,Number,Options},
;
f(Signal, To) ->
ignore.
Có thể được viết lại như sau:

f({connect,_,To,_,_} = Signal, To) ->
;
f(Signal, To) ->
ignore.
Tiền tố xâu dữ liệu trong biểu mẫu:
Khi so khớp các xâu dữ liệu, biểu mẫu sau đây là hợp lệ:
f("prefix" ++ Str) ->
[Type text] 22
Tìm hiểu về ngôn ngữ lập trình Erlang
Cú pháp sau đây được coi là tương đương nhưng khó có thể đọc được hơn:
f([$p,$r,$e,$f,$i,$x | Str]) ->
Biểu thức trong biểu mẫu:
Nếu chỉ sử dụng toán hạng số và toán hạng biểu diễn bit, và nếu giá trị của nó có thể
được biểu diễn là một hằng số trong thời gian dịch, các biểu thức số học có thể được sử
dụng trong các pattern. Ví dụ:
case {Value, Result} of
{?THRESHOLD+1, ok} ->
4. So khớp:
Exp1 = Exp2
So khớp Exp1, một biểu thức với Exp2. Nếu việc so khớp thành công, bất kỳ một
biến số không ràng buộc trong biểu mẫu trở nên ra buộc và giá trị của Exp2 được trả về.
Nếu việc so khớp bị lỗi, lỗi badmatch run-time sẽ được ném ra:
Ví dụ:
1> {A, B} = {answer, 42}.
{answer,42}
2> A.
answer
3> {C, D} = [1, 2].
** exception error: no match of right hand side value [1,2]
5. Cách gọi hàm – function calls:

ExprF(Expr1, ,ExprN)
ExprM:ExprF(Expr1, ,ExprN)
Trong dạng đầu tiên của việc gọi hàm, ExprM: ExprF(Expr1, …, ExprN),
mỗi ExprM và ExpF phải là atom hay là một biểu thức mà biểu diễn dưới dạng atom.
Hàm này được gọi bằng cách sử dụng tên đầy đủ chức năng (fully qualified function
name), thườn được nhắc đến như là một remote hay là external function call – gọi chức
năng ngoài. Ví dụ:
lists:keysearch(Name, 1, List)
Trong dạng thứ 2, ExprF(Expr1, …, ExprN), ExprF phải là một atom hay
được biểu diễn dưới dạng fun.
Nếu ExprF là một atom, thì hàm này gọi băng việc sử dụng tên đầy đủ chức năng ẩn
– implicitly qualified function name. Nếu ExprF/N là tên của một chức năng rõ ràng hay
tự động nhập từ module M, thì việc gọi là được gọi là rut gọn
M:ExprF(Expr1, …, ExprN).
[Type text] 23
Tìm hiểu về ngôn ngữ lập trình Erlang
Mặt khác, ExprF/N phải là chức nàng được định nghĩa một cách cục bộ. Ví
dụ:
handle(Msg, State)
spawn(m, init, [])
Ví dụ khi ExprF là một fun:
Fun1 = fun(X) -> X+1 end
Fun1(3)
=> 4
Fun2 = {lists,append}
Fun2([1,2], [3,4])
=> [1,2,3,4]
fun lists:append/2([1,2], [3,4])
=> [1,2,3,4]
Để tránh được sự nhập nhằng có thể xảy ra, thì tên gọi đầy đủ chức năng phải được

sử dụng khi gọi một hàm với cùng một tên như là một BIF, và trình dịch không cho phép
định nghĩa một hàm với cùng một tên như là hàm được nhận vào một cách rõ ràng.
Chú ý rằng việc gọi một hàm cục bộ có sự khác nhau giữa việc sử dụng tên hàm
đầy đủ chức năng hay là ẩn, nó sẽ được tham chiếu đến phiên bản muộn nhất của module.
6. If – rẽ nhánh có điều kiện:
if
GuardSeq1 ->
Body1;
;
GuardSeqN ->
BodyN
end
Các nhánh điều kiện của biểu thức IF được check một cách tuần tự cho tới khi
GuardSeq (biểu thức điều kiện ) nhận giá trị true. Sau đó phân thân – body tương ứng của
lệnh IF được thực hiện (các biểu thức được phân cách bởi dấu , ).
Giá trị trả vể của body là giá trị trả về của biểu thức
Nếu GuardSeq không phải là true, thì mệnh để if sẽ gây nên lỗi if_clause. Nếu cần
thiết biểu thức guard mang giá trị true có thể được sử dụng như là nhánh cuối cùng (luôn
luôn trả về giá trị true).
Ví dụ:
is_greater_than(X, Y) ->
if
X>Y ->
true;
true -> % works as an 'else' branch
false
[Type text] 24
Tìm hiểu về ngôn ngữ lập trình Erlang
end
7. Case:

case Expr of
Pattern1 [when GuardSeq1] ->
Body1;
;
PatternN [when GuardSeqN] ->
BodyN
end
Biểu thức Expr được biểu diễn và biểu mẫu Pattern được so khớp một cách tuần tự
với kết quả. Nếu việc so khớp thành công và GuardSeq là true, thì Body tương ứng được
biểu diễn.
Giá trị trả về của Body là giá trị trả về của biểu thức case.
Nếu không có biểu mẫu so khớp nào với GuardSeq là true, lỗi case_clause (mệnh đề
case) sẽ xảy ra.
Ví dụ:
is_valid_signal(Signal) ->
case Signal of
{signal, _What, _From, _To} ->
true;
{signal, _What, _To} ->
true;
_Else ->
false
end.
8. Send – toán tử gửi:
Gửi giá trị của Expr2 như một thông điệp tới một quá trình được đặc tả bởi Expr1.
Giá trị của biểu thức Expr2 cũng là giá trị trả về.
Expr1 phải biểu diễn là một PID (processing identify), tên đăng ký – atom hày là
một tuple {Name, Node}, ở đây Name là một ation và Node là một tên Node, cũng là một
atom
Nếu Expr1 biểu diễn một tên, nhưng tên này không được đăng ký, lỗi badarg run-

time sẽ xảy ra.
Gửi một thông điệp tới một PID không bao giờ bị lỗi thậm chí nếu PID trỏ tới một
process không tồn tại.
Gửi thông điệp phân tán: nếu Expr1 biểu diễn một tuple {Name, Node} (hay một
PID được đặt tại một Node khác), cũng không bao giờ lỗi.
[Type text] 25

×