Tiếng AnhTiếng PhápTiếng Tây Ban Nha

Ad


Biểu tượng yêu thích OnWorks

hy - Trực tuyến trên đám mây

Chạy hy trong nhà cung cấp dịch vụ lưu trữ miễn phí OnWorks qua Ubuntu Online, Fedora Online, trình giả lập trực tuyến Windows hoặc trình mô phỏng trực tuyến MAC OS

Đây là lệnh hy có thể được chạy trong nhà cung cấp dịch vụ lưu trữ miễn phí OnWorks bằng cách sử dụng một trong nhiều máy trạm trực tuyến miễn phí của chúng tôi như Ubuntu Online, Fedora Online, trình giả lập trực tuyến Windows hoặc trình giả lập trực tuyến MAC OS

CHƯƠNG TRÌNH:

TÊN


hy - hy Tài liệu [image: Hy] [image]

Thử Hy https://try-hy.appspot.com

PyPI https://pypi.python.org/pypi/hy

nguồn https://github.com/hylang/hy

Danh sách hylang-thảo luận

IRC #hy trên Freenode

Xây dựng tình trạng
Travis CI.UNINDENT

Hy là một phương ngữ tuyệt vời của Lisp được nhúng trong Python.

Vì Hy chuyển đổi mã Lisp của nó thành Cây cú pháp trừu tượng Python, bạn có
toàn bộ thế giới Python tuyệt đẹp trong tầm tay bạn, ở dạng Lisp!

Nội dung:

BẮT ĐẦU NHANH


[hình ảnh: Karen Rustard's Cuddles] [hình ảnh]

(Cảm ơn Karen Rustad vì Cuddles!)

LÀM THẾ NÀO ĐẾN GET HY CÓ THẬT NHANH:

1. Tạo một ảo Python Môi trường.

2. Kích hoạt Môi trường Python ảo của bạn.

3. Đặt hy từ PyPI với đánh rớt cài đặt, dựng lên hy.

4. Bắt đầu REPL với hy.

5. Nhập nội dung trong REPL:

=> (in "Hy!")
Hy!
=> (defn salutationsnm [name] (print (+ "Hy" name "!")))
=> (salutationsnm "YourName")
Hy tên của bạn!

vv

6. Nhấn CTRL-D khi bạn hoàn tất.

CHÚA ƠI! Đó là kinh ngạc! I muốn đến viết a Hy chương trình.

7. Mở một trình soạn thảo lập trình ưu tú và nhập:

(print "Tôi đã định viết mã theo cú pháp Python, nhưng sau đó tôi nhận được Hy.")

8. Lưu dưới dạng tuyệt vời..

9. Và chạy chương trình Hy đầu tiên của bạn:

thật tuyệt vời.

10.
Hít thở sâu để không bị tăng thông khí.

11.
Hãy mỉm cười một cách độc ác và lẻn đến thủy cung của bạn và làm những điều không thể nói ra.

Tutorial


Chào mừng bạn đến với hướng dẫn Hy!

Tóm lại, Hy là một phương ngữ Lisp, nhưng một phương ngữ chuyển đổi cấu trúc của nó thành Python ...
nghĩa đen là một chuyển đổi thành cây cú pháp trừu tượng của Python! (Hoặc nói thô thiển hơn
điều khoản, Hy là người nói ngọng trên Python!)

Điều này khá tuyệt vì nó có nghĩa là Hy bao gồm một số điều:

· Một Lisp cảm thấy rất giống Pythonic

· Đối với Lispers, một cách tuyệt vời để sử dụng sức mạnh điên rồ của Lisp nhưng trong thế giới rộng lớn của Python
thư viện (tại sao có, bây giờ bạn có thể viết một ứng dụng Django trong Lisp!)

· Đối với Pythonistas, một cách tuyệt vời để bắt đầu khám phá Lisp, từ sự thoải mái của Python!

· Đối với tất cả mọi người: một ngôn ngữ dễ chịu có rất nhiều ý tưởng gọn gàng!

Cơ bản intro đến nói ngọng cho Pythonistas
Được rồi, có thể bạn chưa bao giờ sử dụng Lisp trước đây, nhưng bạn đã sử dụng Python!

Một chương trình "chào thế giới" ở Hy thực ra siêu đơn giản. Hãy thử nó:

(in "hello world")

Nhìn thấy? Dễ dàng! Như bạn có thể đã đoán, điều này giống với phiên bản Python của:

in "hello world"

Để cộng một số phép toán siêu đơn giản, chúng ta có thể làm:

(+1 3)

Mà sẽ trả về 4 và sẽ tương đương với:

1 + 3

Những gì bạn sẽ nhận thấy là mục đầu tiên trong danh sách là hàm đang được gọi và
phần còn lại của các đối số là các đối số được chuyển vào. Trên thực tế, trong Hy (như với hầu hết
Lisps) chúng ta có thể chuyển nhiều đối số cho toán tử cộng:

(+ 1 3 55)

Mà sẽ trả về 59.

Có thể bạn đã nghe nói về Lisp trước đây nhưng không biết nhiều về nó. Lisp không khó như bạn
có thể nghĩ, và Hy kế thừa từ Python, vì vậy Hy là một cách tuyệt vời để bắt đầu học Lisp.
Điều chính rõ ràng về Lisp là có rất nhiều dấu ngoặc đơn. Điều này có thể
Thoạt nghe có vẻ khó hiểu, nhưng nó không quá khó. Hãy xem một số phép toán đơn giản
được gói trong một loạt các dấu ngoặc đơn mà chúng ta có thể nhập vào trình thông dịch Hy:

(kết quả setv (- (/ (+ 1 3 88) 2) 8))

Điều này sẽ trả về 38. Nhưng tại sao? Chà, chúng ta có thể xem xét biểu thức tương đương trong
con trăn:

kết quả = ((1 + 3 + 88) / 2) - 8

Nếu bạn đang cố gắng tìm ra cách hoạt động của những điều trên trong python, tất nhiên bạn
tìm ra kết quả bằng cách giải từng dấu ngoặc đơn bên trong. Đó là cùng một ý tưởng cơ bản trong
Hy. Hãy thử bài tập này trước bằng Python:

kết quả = ((1 + 3 + 88) / 2) - 8
# được đơn giản hóa thành ...
kết quả = (92/2) - 8
# được đơn giản hóa thành ...
kết quả = 46 - 8
# được đơn giản hóa thành ...
kết quả = 38

Bây giờ chúng ta hãy thử điều tương tự trong Hy:

(kết quả setv (- (/ (+ 1 3 88) 2) 8))
; được đơn giản hóa thành ...
(kết quả setv (- (/ 92 2) 8))
; được đơn giản hóa thành ...
(kết quả setv (- 46 8))
; được đơn giản hóa thành ...
(kết quả setv 38)

Như bạn có thể đoán, biểu thức cuối cùng này với setv nghĩa là gán biến
"kết quả" thành 38.

Nhìn thấy? Không quá khó!

Đây là tiền đề cơ bản của Lisp. Lisp là viết tắt của "danh sách xử lý"; điều này có nghĩa là
cấu trúc của chương trình thực sự là danh sách các danh sách. (Nếu bạn đã quen với Python
danh sách, hãy tưởng tượng toàn bộ cấu trúc tương tự như trên nhưng thay vào đó là dấu ngoặc vuông, bất kỳ
bạn sẽ có thể thấy cấu trúc ở trên vừa là một chương trình vừa là một cấu trúc cơ sở dữ liệu.) Đây là
dễ hiểu hơn với nhiều ví dụ hơn, vì vậy hãy viết một chương trình Python đơn giản, kiểm tra nó,
và sau đó hiển thị chương trình Hy tương đương:

def simple_conversation ():
print "Xin chào! Tôi muốn làm quen với bạn. Hãy kể cho tôi nghe về bản thân bạn!"
name = raw_input ("Tên của bạn là gì?")
age = raw_input ("Tuổi của bạn là bao nhiêu?")
in "Xin chào" + tên + "! Tôi thấy bạn là" + tuổi + "tuổi."

simple_conversation ()

Nếu chúng tôi chạy chương trình này, nó có thể như sau:

Xin chào! Tôi muốn làm quen với bạn. Cho tôi biết về bản thân của bạn!
Tên của bạn là gì? Gary
Bạn bao nhiêu tuổi? 38
Xin chào Gary! Tôi thấy bạn đã 38 tuổi.

Bây giờ chúng ta hãy xem xét chương trình Hy tương đương:

(định nghĩa cuộc trò chuyện đơn giản []
(in "Xin chào! Tôi muốn làm quen với bạn. Hãy kể cho tôi nghe về bản thân bạn!")
(tên setv (đầu vào thô "Tên bạn là gì?"))
(setv age (raw-input "Bạn đang ở độ tuổi nào?"))
(print (+ "Xin chào" tên "! Tôi thấy bạn là"
tuổi "tuổi.")))

(cuộc trò chuyện đơn giản)

Nếu bạn nhìn vào chương trình trên, miễn là bạn nhớ rằng phần tử đầu tiên trong mỗi
danh sách của chương trình là hàm (hoặc macro ... chúng ta sẽ nói đến những cái đó sau) được gọi
và phần còn lại là các đối số, khá dễ dàng để tìm ra tất cả điều này có nghĩa là gì.
(Như bạn có thể cũng đoán, định nghĩa là phương pháp xác định phương pháp Hy.)

Tuy nhiên, ban đầu nhiều người cảm thấy điều này khó hiểu vì có quá nhiều dấu ngoặc đơn,
nhưng có rất nhiều thứ có thể giúp làm điều này dễ dàng hơn: giữ cho thụt lề đẹp và
sử dụng một trình chỉnh sửa có đối sánh dấu ngoặc đơn (điều này sẽ giúp bạn tìm ra những gì mỗi
dấu ngoặc đơn kết hợp với) và mọi thứ sẽ bắt đầu dễ chịu.

Có một số lợi thế khi có một cấu trúc mã thực sự là một dữ liệu rất đơn giản
dựa trên cấu trúc cốt lõi của Lisp. Đối với một điều, điều đó có nghĩa là các chương trình của bạn
dễ phân tích cú pháp và toàn bộ cấu trúc thực tế của chương trình được hiển thị rất rõ ràng
cho bạn. (Có một bước bổ sung trong đó cấu trúc bạn thấy được chuyển đổi thành Python
đại diện riêng ... trong các Lisp "thuần túy" hơn như Common Lisp hoặc Emacs Lisp, dữ liệu
cấu trúc bạn thấy trong mã và cấu trúc dữ liệu được thực thi còn nhiều hơn thế nữa
gần đúng nghĩa đen.)

Một hàm ý khác của điều này là macro: nếu cấu trúc của chương trình là một dữ liệu đơn giản
cấu trúc, điều đó có nghĩa là bạn có thể viết mã có thể viết mã rất dễ dàng, nghĩa là
việc triển khai các tính năng ngôn ngữ hoàn toàn mới có thể rất nhanh. Trước Hy, đây không phải
rất có thể cho các lập trình viên Python ... bây giờ bạn cũng có thể sử dụng các macro 'đáng kinh ngạc
quyền lực (chỉ cần cẩn thận để không hướng chúng về phía trước)!

Hy is a Lisp có hương vị Python
Hy chuyển đổi sang cây cú pháp trừu tượng của riêng Python, vì vậy bạn sẽ sớm bắt đầu thấy rằng tất cả
sức mạnh quen thuộc của python nằm trong tầm tay bạn.

Bạn có toàn quyền truy cập vào các kiểu dữ liệu và thư viện tiêu chuẩn của Python trong Hy. Hãy thử nghiệm
với điều này trong trình thông dịch hy:

=> [1 2 3]
[1, 2, 3]
=> {"con chó" "sủa"
... "con mèo" "meo meo"}
hữu ích. Cảm ơn !
{'dog': 'sủa', 'cat': 'meo'}
=> (, 1 2 3)
(1, 2, 3)

Nếu bạn đã quen với các Lisps khác, bạn có thể quan tâm rằng Hy hỗ trợ Common
Phương pháp trích dẫn Lisp:

=> '(1 2 3)
(1L 2L 3L)

Bạn cũng có quyền truy cập vào tất cả các phương pháp hay của các loại được tích hợp sẵn:

=> (.strip "fooooo")
"fooooo"

Đây là gì? Đúng vậy, điều này chính xác giống như:

"fooooo" .strip ()

Đúng vậy --- Lisp với ký hiệu dấu chấm! Nếu chúng tôi có chuỗi này được chỉ định dưới dạng một biến, chúng tôi
cũng có thể làm như sau:

(setv this-string "fooooo")
(chuỗi này. dải)

Điều kiện thì sao ?:

(nếu (thử một điều gì đó)
(in "đây là nếu đúng")
(in "this is if false"))

Như bạn có thể nói ở trên, đối số đầu tiên if là một bài kiểm tra sự thật, lập luận thứ hai là
phần thân nếu đúng và đối số thứ ba (tùy chọn!) là nếu sai (tức là. khác).

Nếu bạn cần thực hiện các điều kiện phức tạp hơn, bạn sẽ thấy rằng bạn không có elif
có sẵn tại Hy. Thay vào đó, bạn nên sử dụng một cái gì đó được gọi là chung cư. Trong Python, bạn có thể làm
cái gì đó như:

một sốvar = 33
nếu somevar> 50:
print "Biến đó quá lớn!"
elif somevar <10:
print "Biến đó quá nhỏ!"
khác:
print "Biến đó đúng là jussssst!"

Trong Hy, bạn sẽ làm:

(chung cư
[(> somevar 50)
(print "Biến đó quá lớn!")]
[(<somevar 10)
(print "Biến đó quá nhỏ!")]
[thật
(print "Biến đó đúng là jussssst!")])

Điều bạn sẽ nhận thấy là chung cư tắt giữa một số câu lệnh được thực thi và
được kiểm tra có điều kiện để biết đúng hay sai và sau đó sẽ thực thi một đoạn mã nếu nó quay
ra là sự thật. Bạn cũng sẽ nhận thấy rằng khác được thực hiện ở cuối đơn giản bởi
đang kiểm tra để mà đúng -- đó là bởi vì đúng sẽ luôn đúng, vì vậy nếu chúng ta đi được xa đến mức này, chúng ta sẽ
luôn chạy cái đó!

Bạn có thể nhận thấy ở trên rằng nếu bạn có mã như:

(nếu một số điều kiện
(cơ thể-nếu-đúng)
(nội dung nếu sai))

Nhưng đợi đã! Điều gì xảy ra nếu bạn muốn thực thi nhiều hơn một câu lệnh trong phần nội dung của một trong các câu lệnh
này?

Bạn có thể làm như sau:

(nếu (thử một điều gì đó)
(làm
(in "đây là nếu đúng")
(print "và tại sao không, chúng ta hãy tiếp tục nói về sự thật của nó!))
(in "cái này vẫn chỉ đơn giản là sai"))

Bạn có thể thấy rằng chúng tôi đã sử dụng do để bọc nhiều câu lệnh. Nếu bạn quen thuộc với
Lisps, cái này tương đương với tiên tri nơi khác

Nhận xét bắt đầu bằng dấu chấm phẩy:

(in "cái này sẽ chạy")
; (in "nhưng điều này sẽ không")
(+ 1 2 3); chúng tôi sẽ thực hiện việc bổ sung, nhưng không phải nhận xét này!

Vòng lặp không cứng nhưng có một loại cấu trúc đặc biệt. Trong Python, chúng ta có thể làm:

cho tôi trong phạm vi(10):
print "'i' hiện tại" + str (i)

Tương đương trong chữ Hy sẽ là:

(cho [i (phạm vi 10)]
(print (+ "'i' hiện tại" (str i))))

Bạn cũng có thể nhập và sử dụng các thư viện Python khác nhau. Ví dụ:

(nhập hệ điều hành)

(nếu (os.path.isdir "/ tmp / somedir")
(os.mkdir "/ tmp / somedir / anotherdir")
(in "Này, con đường đó không có!"))

Trình quản lý ngữ cảnh của Python (với câu lệnh) được sử dụng như thế này:

(với [[f (open "/tmp/data.in")]]
(in (.đọc f)))

tương đương với:

với open ("/ tmp / data.in") là f:
print f.read ()

Và vâng, chúng tôi có khả năng hiểu Danh sách! Trong Python, bạn có thể làm:

Tỷ lệ cược_squared = [
pow (num, 2)
cho num trong phạm vi(100)
nếu num% 2 == 1]

Trong Hy, bạn có thể làm như sau:

(tỷ lệ cược setv bình phương
(danh sách-comp
(pow số 2)
(num (phạm vi 100))
(= (%số 2) 1)))

; Và, một ví dụ bị đánh cắp một cách đáng xấu hổ từ trang Clojure:
; Hãy liệt kê tất cả các khối của Bàn cờ:

(danh sách-comp
(, xy)
(x (phạm vi 8)
y "ABCDEFGH"))

; [(0, 'A'), (0, 'B'), (0, 'C'), (0, 'D'), (0, 'E'), (0, 'F'), ( 0, 'G'), (0, 'H'),
; (1, 'A'), (1, 'B'), (1, 'C'), (1, 'D'), (1, 'E'), (1, 'F'), (1 , 'G'), (1, 'H'),
; (2, 'A'), (2, 'B'), (2, 'C'), (2, 'D'), (2, 'E'), (2, 'F'), (2 , 'G'), (2, 'H'),
; (3, 'A'), (3, 'B'), (3, 'C'), (3, 'D'), (3, 'E'), (3, 'F'), (3 , 'G'), (3, 'H'),
; (4, 'A'), (4, 'B'), (4, 'C'), (4, 'D'), (4, 'E'), (4, 'F'), (4 , 'G'), (4, 'H'),
; (5, 'A'), (5, 'B'), (5, 'C'), (5, 'D'), (5, 'E'), (5, 'F'), (5 , 'G'), (5, 'H'),
; (6, 'A'), (6, 'B'), (6, 'C'), (6, 'D'), (6, 'E'), (6, 'F'), (6 , 'G'), (6, 'H'),
; (7, 'A'), (7, 'B'), (7, 'C'), (7, 'D'), (7, 'E'), (7, 'F'), (7 , 'G'), (7, 'H')]

Python có hỗ trợ cho các đối số từ khóa và đối số lạ mắt khác nhau. Trong Python, chúng ta có thể
xem:

>>> def option_arg (pos1, pos2, keyword1 = None, keyword2 = 42):
... trả lại [pos1, pos2, từ khóa1, từ khóa2]
hữu ích. Cảm ơn !
>>> option_arg (1, 2)
[1, 2, Không có, 42]
>>> option_arg (1, 2, 3, 4)
[1, 2, 3, 4]
>>> option_arg (keyword1 = 1, pos2 = 2, pos1 = 3, keyword2 = 4)
[3, 2, 1, 4]

Điều tương tự ở Hy:

=> (defn option-arg [pos1 pos2 & option keyword1 [keyword2 42]]
... [pos1 pos2 từ khóa1 từ khóa2])
=> (tùy chọn-đối số 1 2)
[1 2 Không có 42]
=> (tùy chọn-đối số 1 2 3 4)
[1 2 3 4]

Nếu bạn đang chạy phiên bản Hy trước đây 0.10.1 (ví dụ: git master), cũng có một phiên bản mới rất hay
cú pháp đối số từ khóa:

=> (tùy chọn-arg: từ khóa1 1
...: pos2 2
...: pos1 3
...: keyword2 4)
[3, 2, 1, 4]

Nếu không, bạn luôn có thể sử dụng ứng dụng. Nhưng những gì ứng dụng?

Bạn có quen với việc đi qua không * args** kwargs bằng Python ?:

>>> args = [1 2]
>>> kwargs = {"keyword2": 3
... "keyword1": 4}
>>> option_arg (* args, ** kwargs)

Chúng tôi có thể tái tạo điều này với ứng dụng:

=> (setv args [1 2])
=> (setv kwargs {"keyword2" 3
... "keyword1" 4})
=> (áp dụng kwargs-arg args tùy chọn)
[1, 2, 4, 3]

Ngoài ra còn có cấu trúc đối số từ khóa kiểu từ điển giống như sau:

(định nghĩa kiểu khác [& key {"key1" "val1" "key2" "val2"}]
[phím1phím2])

Sự khác biệt ở đây là vì nó là một từ điển, bạn không thể dựa vào bất kỳ
sắp xếp thứ tự cho các đối số.

Hy cũng ủng hộ * args** kwargs. Trong Python:

def some_func (foo, bar, * args, ** kwargs):
nhập bản in
pprint.pprint ((foo, bar, args, kwargs))

The Hy tương đương:

(defn some-func [foo bar & rest args & kwargs kwargs]
(nhập pprint)
(pprint.pprint (, foo bar args kwargs)))

Cuối cùng, tất nhiên chúng ta cần các lớp học! Trong Python, chúng ta có thể có một lớp như:

lớp FooBar (đối tượng):
"" "
Tuy nhiên, một lớp mẫu khác
"" "
def __init __ (self, x):
tự.x = x

def get_x (tự):
"" "
Trả lại bản sao của chúng tôi về x
"" "
trả về self.x

Trong Hy:

(khử lớp FooBar [đối tượng]
"Tuy nhiên, một lớp mẫu khác"
[[--trong đó--
(fn [tự x]
(setv self.xx)
; Hiện cần cho --init-- vì __init__ cần Không
; Hy vọng rằng điều này sẽ biến mất :)
Không có)]

[get-x
(fn [bản thân]
"Trả lại bản sao x của chúng tôi"
tự.x)]])

Bạn cũng có thể thực hiện các thuộc tính cấp độ lớp. Trong Python:

khách hàng lớp (mô hình.Model):
name = models.CharField (max_length = 255)
address = models.TextField ()
note = models.TextField ()

Trong Hy:

(loại bỏ phân loại Khách hàng [models.Model]
[[name (models.CharField: max-length 255})]
[địa chỉ (models.TextField)]
[ghi chú (mô hình.TextField)]])

Hy <-> Python tương tác
Bằng cách nhập Hy, bạn có thể sử dụng Hy trực tiếp từ Python!

Nếu bạn lưu những thứ sau vào lời chào.:

(xin chào từ biệt [tên] (in "xin chào từ hy," tên))

Sau đó, bạn có thể sử dụng nó trực tiếp từ python, bằng cách nhập hy trước khi nhập mô-đun. Trong
con trăn:

nhập khẩu hy
nhập lời chào

Welcome.greet ("Foo")

Bạn cũng có thể khai báo một hàm trong python (hoặc thậm chí là một lớp!) Và sử dụng nó trong Hy!

Nếu bạn lưu những thứ sau vào Greeting.py bằng Python:

chào def (tên):
print ("xin chào,% s"% (name))

Bạn có thể sử dụng nó trong Hy:

(nhập lời chào)
(.greet lời chào "foo")

Để sử dụng các đối số từ khóa, bạn có thể sử dụng trong Greeting.py:

chào def (name, title = "Sir"):
print ("Lời chào,% s% s"% (tiêu đề, tên))

(nhập lời chào)
(Lời chào .greet "Foo")
(Lời chào .greet "Foo" "Darth")
(áp dụng (. lời chào, lời chào) ["Foo"] {"title" "Lord"})

Cái nào sẽ xuất ra:

Xin chào, Sir Foo

Xin chào, Darth Foo

Xin chào, Lord Foo

Lời khuyên!
Hy cũng có một cái gì đó được gọi là "macro phân luồng", một tính năng thực sự gọn gàng của
Của Clojure. "Macro phân luồng" (được viết là ->) được sử dụng để tránh làm tổ sâu
biểu thức.

Macro phân luồng sẽ chèn từng biểu thức vào đối số đầu tiên của biểu thức tiếp theo
thay thế.

Hãy lấy cổ điển:

(vòng lặp (in (eval (đọc))))

Thay vì viết nó như vậy, chúng ta có thể viết nó như sau:

(-> (đọc) (eval) (in) (vòng lặp))

Bây giờ, sử dụng trăn-sh, chúng tôi có thể chỉ ra cách macro phân luồng (do thiết lập của python-sh)
có thể được sử dụng như một đường ống:

=> (nhập [sh [cat grep wc]])
=> (-> (cat "/ usr / share / dict / words") (grep "-E" "^ hy") (wc "-l"))
210

Tất nhiên, mở rộng ra:

(wc (grep (cat "/ usr / share / dict / words") "-E" "^ hy") "-l")

Có thể đọc được nhiều hơn, phải không? Sử dụng macro phân luồng!

HY STYLE HƯỚNG DẪN


“Bạn biết đấy, thưa Bộ trưởng, tôi không đồng ý với cụ Dumbledore về nhiều mặt… nhưng bạn không thể phủ nhận ông ấy
có phong cách… ”- Phineas Nigellus Black, Harry Potter các trật tự of các Phoenix

Hướng dẫn phong cách Hy dự định là một bộ quy tắc cơ bản cho Hyve (vâng, cộng đồng Hy
tự hào về việc phụ Hy vào mọi việc) viết mã Hy thành ngữ. Hy phát xuất rất nhiều
từ Clojure & Common Lisp, trong khi luôn duy trì khả năng tương tác của Python.

Dạo thử
Sản phẩm Tao of Hy
Ummon hỏi sư trưởng: "Ngài đang giảng kinh gì vậy?"
"Kinh Niết Bàn."
"Kinh Niết Bàn có Tứ đức, phải không?"
"Nó có."
Uất Noãn Tâm cầm một cái chén lên hỏi: "Cái này có bao nhiêu đạo?"
"Không có gì cả," nhà sư nói.
"Nhưng cổ nhân nói là có, phải không?" Ummon nói.
"Bạn nghĩ gì về những gì họ nói?"
Ummon đập cốc và hỏi, "Bạn hiểu không?"
"Không," nhà sư nói.
“Sau đó,” Ummon nói, “Tốt hơn là bạn nên tiếp tục với các bài giảng của mình về kinh.
- macro (công án)

Sau đây minh họa một danh sách ngắn gọn về các quyết định thiết kế dẫn đến việc
Hy.

· Trông giống như một Lisp; DTRT với nó (ví dụ: dấu gạch ngang chuyển thành dấu gạch dưới, bịt tai chuyển sang
viết hoa toàn bộ).

· Chúng tôi vẫn là Python. Hầu hết nội bộ dịch 1: 1 sang nội bộ Python.

· Sử dụng Unicode ở mọi nơi.

· Khắc phục các quyết định sai trong Python 2 khi chúng ta có thể (xem true_divisi).

· Khi nghi ngờ, hãy chuyển sang Python.

· Nếu bạn vẫn không chắc chắn, hãy hoãn lại Clojure.

· Nếu bạn thậm chí không chắc chắn hơn, hãy chuyển sang Common Lisp.

· Hãy nhớ rằng chúng tôi không phải là Clojure. Chúng tôi không phải Lisp chung. Chúng tôi là Homoiconic Python, với
các bit bổ sung có ý nghĩa.

Bố trí & Thụt đầu dòng
· Tránh các khoảng trống ở cuối. Chúng thật tệ!

· Thụt lề phải là 2 khoảng trắng (không có tab cứng), ngoại trừ khi khớp với thụt lề của
dòng trước đó.

;; Tốt (và được ưu tiên)
(định nghĩa fib [n]
(nếu (<= n 2)
n
(+ (sợi (- n 1)) (sợi (- n 2)))))

;; Vẫn ổn
(định nghĩa fib [n]
(nếu (<= n 2) n (+ (fib (- n 1)) (fib (- n 2)))))

;; Vẫn ổn
(định nghĩa fib [n]
(nếu (<= n 2)
n
(+ (sợi (- n 1)) (sợi (- n 2)))))

;; Kỳ cục một cách lố bịch
(định nghĩa fib [n]
(nếu (<= n 2)
n ;; vâng, tôi thích nhấn phím cách một cách ngẫu nhiên
(+ (sợi (- n 1)) (sợi (- n 2)))))

· Dấu ngoặc đơn phải không bao giờ bị bỏ lại một mình, buồn và cô đơn trên dòng riêng của họ.

;; Tốt (và được ưu tiên)
(định nghĩa fib [n]
(nếu (<= n 2)
n
(+ (sợi (- n 1)) (sợi (- n 2)))))

;; Kỳ cục một cách lố bịch
(định nghĩa fib [n]
(nếu (<= n 2)
n
(+ (xơ (- n 1)) (xơ (- n 2)))
)
); GAH, BẮT NÓ BẰNG LỬA

· Căn chỉnh theo chiều dọc cho phép khối.

(hãy để [[foo (thanh)]
[qux (baz)]]
(foo qux))

· Nhận xét nội tuyến sẽ có hai khoảng trắng từ cuối mã; họ luôn phải có một
khoảng trắng giữa ký tự bình luận và phần bắt đầu bình luận. Ngoài ra, cố gắng không
bình luận rõ ràng.

;; Tốt
(setv ind (dec x)); lập chỉ mục bắt đầu từ 0

;; Phù hợp với phong cách nhưng chỉ nêu rõ ràng
(setv ind (dec x)); đặt chỉ mục thành x-1

;; Tồi tệ
(setv ind (dec x)); gõ các từ cho vui

Lập trình Phong cách
· Theo quy ước, cố gắng không sử dụng def cho bất kỳ thứ gì khác ngoài các biến toàn cục; sử dụng setv
bên trong các hàm, vòng lặp, v.v.

;; Tốt (và được ưu tiên)
(def * giới hạn * 400000)

(xác định fibs [ab]
(trong khi đúng
(nhường a)
(setv (, ab) (, b (+ ab)))))

;; Xấu (và không được ưa thích)
(xác định fibs [ab]
(trong khi đúng
(nhường a)
(def (, ab) (, b (+ ab)))))

· Không sử dụng cú pháp biểu thức s khi cú pháp vectơ được dự định. Ví dụ, thực tế
rằng ví dụ trước đây của hai ví dụ này hoạt động chỉ là do trình biên dịch không quá
nghiêm khắc. Trong thực tế, cú pháp chính xác ở những nơi chẳng hạn như đây là cú pháp sau.

;; Xấu (và ác)
(định nghĩa foo (x) (in x))
(ảnh 1)

;; Tốt (và được ưu tiên)
(định nghĩa foo [x] (in x))
(ảnh 1)

· Sử dụng macro luồng hoặc macro đuôi luồng khi gặp phải lồng ghép sâu
biểu thức s. Tuy nhiên, hãy thận trọng khi sử dụng chúng. Sử dụng chúng khi rõ ràng và
khả năng đọc được cải thiện; không xây dựng các biểu thức phức tạp, khó hiểu.

;; Được ưu tiên
(def * tên *
(với [f (open "names.txt")]
(-> (.read f) (.strip) (.replace "\" "" ") (.split", ") (đã sắp xếp))))

;; Không tốt lắm
(def * tên *
(với [f (open "names.txt")]
(đã sắp xếp (.split "," (.replace "\" "" "(.strip (.read f)))))))

;; Có lẽ không phải là một ý kiến ​​hay
(hình vuông xác định? [x]
(- >> 2 (pow (int (sqrt x))) (= x)))

· Ký hiệu dấu chấm kiểu clojure được ưu tiên hơn cách gọi trực tiếp phương thức của đối tượng,
mặc dù cả hai sẽ tiếp tục được hỗ trợ.

;; Tốt
(với [fd (open "/ etc / passwd")]
(in (.readlines fd)))

;; Không tốt lắm
(với [fd (open "/ etc / passwd")]
(in (fd.readlines)))

Kết luận
“Thời trang phai nhạt, phong cách là vĩnh cửu” —Có Saint Laurent

Hướng dẫn này chỉ là một tập hợp các nguyên tắc cộng đồng và rõ ràng, các nguyên tắc cộng đồng làm
không có ý nghĩa nếu không có một cộng đồng tích cực. Đóng góp được hoan nghênh. Tham gia với chúng tôi tại #hy in
freenode, viết blog về nó, tweet về nó, và quan trọng nhất, hãy vui vẻ với Hy.

Cảm ơn
· Hướng dẫn này được lấy cảm hứng từ @paultag bài đăng trên blog của Hy Survival Hướng dẫn

· Các Clojure Phong cách Hướng dẫn

TÀI LIỆU INDEX


Nội dung:

Lệnh Dòng Giao thức
hy
Lệnh Dòng Các lựa chọn
-c
Thực thi mã Hy trong lệnh.

$ hy -c "(print (+ 2 2))"
4

-i
Thực thi mã Hy trong lệnh, sau đó ở lại REPL.

-m
Thực thi mã Hy trong mô-đun, Bao gồm cả xoa dịu nếu được xác định.

Sản phẩm -m cờ kết thúc danh sách tùy chọn để tất cả các đối số sau mô-đun tên
được chuyển đến mô-đun trong sys.argv.

Mới trong phiên bản 0.10.2.

--gián điệp In mã Python tương đương trước khi thực thi. Ví dụ:

=> (defn salutationsnm [name] (print (+ "Hy" name "!")))
def salutationsnm (tên):
return print (((u'Hy '+ name) + u'! '))
=> (salutationsnm "YourName")
salutationsnm (u'YourName ')
Hy tên của bạn!
=>

Mới trong phiên bản 0.9.11.

--show-tracebacks
In các truy nguyên mở rộng cho các trường hợp ngoại lệ Hy.

Mới trong phiên bản 0.9.12.

-v In số phiên bản Hy và thoát.

hyc
Lệnh Dòng Các lựa chọn
tập tin[, tệpN]
Biên dịch mã Hy sang mã byte Python. Ví dụ: lưu mã sau dưới dạng
hyname.hy:

(defn hy-hy [tên]
(print (+ tên "Hy" "!")))

(hy-hy "Afroman")

Sau đó chạy:

$ hyc hyname.hy
$ python hyname.pyc
Hy Afroman!

hy2py
Mới trong phiên bản 0.10.1.

Lệnh Dòng Các lựa chọn
-s

--có nguồn
Hiển thị cấu trúc nguồn được phân tích cú pháp.

-a

--với-ast
Hiển thị AST đã tạo.

-np

--không-trăn
Không hiển thị mã Python được tạo từ AST.

Hy (Các ngôn ngữ)
Chú ý:
Điều này là không đầy đủ; vui lòng xem xét đóng góp vào nỗ lực tài liệu.

Lý thuyết of Hy
Hy duy trì, trên mọi thứ khác, khả năng tương thích 100% theo cả hai hướng với Python
chinh no. Tất cả mã Hy tuân theo một vài quy tắc đơn giản. Hãy ghi nhớ điều này, vì nó sẽ đến
tiện dụng.

Các quy tắc này giúp đảm bảo rằng mã Hy là thành ngữ và có thể giao tiếp được bằng cả hai ngôn ngữ.

· Các ký hiệu trong bịt tai sẽ được dịch sang phiên bản viết hoa của chuỗi đó. Vì
thí dụ, foo sẽ trở thành FOO.

· Các thực thể UTF-8 sẽ được mã hóa bằng cách sử dụng mã trừng phạt và bắt đầu bằng hy_. Ví dụ,
sẽ trở thành hy_w7h, sẽ trở thành hy_g6htôi ♥ bạn sẽ trở thành hy_iu_t0x.

· Các ký hiệu chứa dấu gạch ngang sẽ được thay thế bằng dấu gạch dưới. Ví dụ,
kết xuất mẫu sẽ trở thành kết xuất_mẫu. Điều này có nghĩa là các ký hiệu có dấu gạch ngang sẽ
phủ bóng các điểm tương đương gạch dưới của chúng và ngược lại.

Tích hợp sẵn
Hy có một số biểu mẫu đặc biệt được sử dụng để giúp tạo AST trong Python chính xác.
Sau đây là các biểu mẫu "đặc biệt", có thể có hành vi hơi bất ngờ trong
một số tình huống.

.
Mới trong phiên bản 0.10.0.

. được sử dụng để thực hiện truy cập thuộc tính trên các đối tượng. Nó sử dụng một DSL nhỏ để cho phép nhanh chóng
truy cập vào các thuộc tính và mục trong cấu trúc dữ liệu lồng nhau.

Ví dụ,

(. foo bar baz [(+ 1 2)] đông lạnh)

Biên dịch xuống:

foo.bar.baz [1 + 2] .frob

. biên dịch đối số đầu tiên của nó (trong ví dụ, foo) là đối tượng để thực hiện
tham chiếu thuộc tính. Nó sử dụng các ký hiệu trần làm thuộc tính để truy cập (trong ví dụ, thanh,
căn cứ, tê cóng), và biên dịch nội dung của danh sách (trong ví dụ, [(+ 1 2)]) để lập chỉ mục.
Các đối số khác gây ra lỗi biên dịch.

Quyền truy cập vào các thuộc tính không xác định sẽ ném một Lỗi thuộc tính. Quyền truy cập vào các khóa không xác định sẽ ném một
Chỉ mụcLỗi (trên danh sách và bộ giá trị) hoặc Lỗi chính (trên từ điển).

->
-> (Hoặc luồng vĩ mô) được sử dụng để tránh lồng các biểu thức. Macro phân luồng
chèn mỗi biểu thức vào vị trí đối số đầu tiên của biểu thức tiếp theo. Sau
mã chứng minh điều này:

=> (đầu ra định nghĩa [ab] (in ab))
=> (-> (+ 4 6) (đầu ra 5))
10 5

- >>
- >> (Hoặc luồng đuôi vĩ mô) tương tự như luồng vĩ mô, nhưng thay vì
khi chèn mỗi biểu thức vào đối số đầu tiên của biểu thức tiếp theo, nó sẽ thêm nó vào
đối số cuối cùng. Đoạn mã sau minh họa điều này:

=> (đầu ra định nghĩa [ab] (in ab))
=> (- >> (+ 4 6) (đầu ra 5))
5 10

ứng dụng
ứng dụng được sử dụng để áp dụng danh sách đối số tùy chọn và từ điển kwargs tùy chọn
vào một chức năng.

Cách sử dụng: (nộp đơn tên fn [tranh luận] [kwargs])

Ví dụ:

(defn thunk []
"hy there")

(áp dụng thunk)
; => "hy there"

(xác định tổng giá trị mua [số lượng giá và tùy chọn [phí 1.05] [vat 1.1]]
(* phí số lượng giá vat))

(áp dụng tổng giá trị mua [10 15])
; => 173.25

(áp dụng tổng giá trị mua [10 15] {"vat" 1.05})
; => 165.375

(áp dụng tổng giá trị mua [] {"price" 10 "số lượng" 15 "vat" 1.05})
; => 165.375


được sử dụng trong các biểu thức logic. Nó có ít nhất hai tham số. Nếu tất cả các thông số
đánh giá Thật, tham số cuối cùng được trả về. Trong bất kỳ trường hợp nào khác, giá trị sai đầu tiên
sẽ được trả lại. Cách sử dụng ví dụ:

=> (và Đúng Sai)
Sai

=> (và True True)
Thật

=> (và Đúng 1)
1

=> (và Đúng [] Sai Đúng)
[]

LƯU Ý:
đoản mạch và ngừng đánh giá các thông số ngay khi sai đầu tiên là
đã gặp.

=> (và Sai (in "xin chào"))
Sai

khẳng định
khẳng định được sử dụng để xác minh các điều kiện trong khi chương trình đang chạy. Nếu điều kiện không
đã gặp, một Khẳng địnhLỗi được nuôi dưỡng. khẳng định có thể nhận một hoặc hai tham số. Người đầu tiên
tham số là điều kiện để kiểm tra và nó sẽ đánh giá một trong hai Thật or Sai. Các
tham số thứ hai, tùy chọn, là nhãn cho xác nhận và là chuỗi sẽ là
lớn lên với Khẳng địnhLỗi. Ví dụ:

(khẳng định (= giá trị kỳ vọng biến))

(khẳng định Sai)
; Khẳng địnhLỗi

(khẳng định (= 1 2) "một nên bằng hai")
; AssertionError: một phải bằng hai

PGS
PGS được sử dụng để liên kết khóa với một giá trị trong từ điển hoặc để đặt chỉ mục của danh sách
thành một giá trị. Nó có ít nhất ba tham số: dữ liệu cấu trúc được sửa đổi, một chính
or chỉ sốgiá trị. Nếu nhiều hơn ba tham số được sử dụng, nó sẽ liên kết thành từng cặp.

Ví dụ về cách sử dụng:

=> (để [[bộ sưu tập {}]]
... (bộ sưu tập assoc "Dog" "Bark")
... (sưu tầm in ấn))
{u'Dog ': u'Bark'}

=> (để [[bộ sưu tập {}]]
... (bộ sưu tập assoc "Chó" "Vỏ cây" "Mèo" "Meo meo")
... (sưu tầm in ấn))
{u'Cat ': u'Meow', u'Dog ': u'Bark'}

=> (để [[bộ sưu tập [1 2 3 4]]]
... (assoc collection 2 Không có)
... (sưu tầm in ấn))
[1, 2, Không có, 4]

LƯU Ý:
PGS sửa đổi cơ cấu dữ liệu tại chỗ và trả về Không áp dụng.

phá vỡ
phá vỡ được sử dụng để thoát ra khỏi một vòng lặp. Nó kết thúc vòng lặp ngay lập tức. Sau
ví dụ có vô hạn trong khi vòng lặp được kết thúc ngay sau khi người dùng nhập k.

(while True (if (= "k" (raw-input "?"))
(nghỉ)
(in "Thử lại")))

chung cư
chung cư có thể được sử dụng để xây dựng lồng nhau if các câu lệnh. Ví dụ sau đây cho thấy
mối quan hệ giữa macro và sự mở rộng của nó:

(điều kiện [điều kiện-1 kết quả-1]
[điều kiện-2 kết quả-2])

(nếu điều kiện-1 kết quả-1
(nếu điều kiện-2 kết quả-2))

Như được hiển thị bên dưới, chỉ khối kết quả phù hợp đầu tiên được thực thi.

=> (xác định giá trị kiểm tra [giá trị]
... (cond [(<giá trị 5) (in "giá trị nhỏ hơn 5")]
... [(= giá trị 5) (in "giá trị bằng 5")]
... [(> giá trị 5) (in "giá trị lớn hơn 5")]
... [True (in "giá trị không nên là")]))

=> (giá trị kiểm tra 6)
giá trị lớn hơn 5

tiếp tục
tiếp tục trả về quá trình thực thi để bắt đầu một vòng lặp. Trong ví dụ sau,
(tác dụng phụ1) được gọi cho mỗi lần lặp. (tác dụng phụ2), tuy nhiên, chỉ được gọi trên
mọi giá trị khác trong danh sách.

;; giả sử rằng (side-effect1) và (side-effect2) là các hàm và
;; bộ sưu tập là một danh sách các giá trị số

(cho [x bộ sưu tập]
(làm
(hiệu ứng phụ1 x)
(nếu (% x 2)
(tiếp tục))
(hiệu ứng phụ2 x)))

dict-comp
dict-comp được sử dụng để tạo từ điển. Nó có ba hoặc bốn tham số. Người đầu tiên
hai tham số là để kiểm soát giá trị trả về (cặp khóa-giá trị) trong khi tham số thứ ba là
được sử dụng để chọn các mục từ một chuỗi. Tham số thứ tư và tham số tùy chọn có thể được sử dụng để
lọc ra một số mục trong chuỗi dựa trên biểu thức điều kiện.

=> (dict-comp x (* x 2) [x (phạm vi 10)] (lẻ? x))
{1:2, 3:6, 9:18, 5:10, 7:14}

do / tiên tri
dotiên tri được sử dụng để đánh giá từng đối số của chúng và trả về đối số cuối cùng. Trở lại
các giá trị từ mọi đối số khác với đối số cuối cùng bị loại bỏ. Nó có thể được sử dụng trong lambda or
danh sách-comp để thực hiện logic phức tạp hơn như thể hiện trong một trong các ví dụ sau.

Một số ví dụ sử dụng:

=> (nếu đúng
... (do (in "Nhạc rock hiệu ứng phụ!")
... (in "Yeah, thật!")))
Đá phản ứng phụ!
Thật đấy!

;; giả sử rằng (hiệu ứng phụ) là một hàm mà chúng ta muốn gọi cho mỗi
;; và mọi giá trị trong danh sách, nhưng giá trị trả về của chúng mà chúng tôi không quan tâm
=> (list-comp (do (side-effect x)
... (nếu (<x 5) (* 2 x)
... (*4 x)))
... (x (phạm vi 10)))
[0, 2, 4, 6, 8, 20, 24, 28, 32, 36]

do có thể chấp nhận bất kỳ số đối số nào, từ 1 đến n.

def / setv
defsetv được sử dụng để liên kết một giá trị, đối tượng hoặc chức năng với một biểu tượng. Ví dụ:

=> (định danh ["Alice" "Bob" "Charlie"])
=> (in tên)
[u'Alice ', u'Bob', u'Charlie ']

=> (bộ đếm setv (fn [mục bộ sưu tập] (mục bộ sưu tập .count)))
=> (bộ đếm [1 2 3 4 5 2 3] 2)
2

phân loại
Các lớp mới được khai báo với phân loại. Nó có thể nhận hai tham số tùy chọn: một vectơ
xác định một siêu lớp có thể có và một vectơ khác chứa các thuộc tính của lớp mới
lớp dưới dạng hai vectơ mục.

(khử lớp tên lớp [siêu lớp-1 siêu lớp-2]
[[giá trị thuộc tính]])

Cả giá trị và hàm đều có thể được ràng buộc trên lớp mới như được minh họa trong ví dụ bên dưới:

=> (khử lớp Cat []
... [[tuổi Không có]
... [màu "trắng"]
... [speak (fn [self] (in "Meo"))]])

=> (điểm xác định (Mèo))
=> (setv spot.colour "Đen")
'Màu đen'
=> (.speak spot)
meo

định nghĩa / làm xấu
định nghĩalàm xấu macro được sử dụng để xác định các chức năng. Chúng lấy ba tham số: tên
của hàm để xác định, một vectơ của thông số, và thân hình của hàm:

(tên định nghĩa [params] body)

Các tham số có thể có các từ khóa sau:

&không bắt buộc
Tham số là tùy chọn. Tham số có thể được cung cấp dưới dạng danh sách hai mục, trong đó
phần tử đầu tiên là tên tham số và phần tử thứ hai là giá trị mặc định. Thông số
cũng có thể được cung cấp dưới dạng một mục duy nhất, trong trường hợp đó, giá trị mặc định là Không áp dụng.

=> (xác định tổng giá trị [giá trị và tùy chọn [giá trị gia tăng-thuế 10]]
... (+ (/ (* giá trị gia tăng-thuế) 100) giá trị))

=> (tổng-giá trị 100)
110.0

=> (tổng-giá trị 100 1)
101.0

&Chìa khóa

& kwargs
Tham số sẽ chứa 0 hoặc nhiều đối số từ khóa.

Các ví dụ mã sau đây xác định một hàm sẽ in tất cả từ khóa
đối số và giá trị của chúng.

=> (định nghĩa thông số in [& kwargs kwargs]
... (cho [(, kv) (.items kwargs)] (in kv)))

=> (áp dụng tham số in [] {"tham số-1" 1 "tham số-2" 2})
tham số-2 2
tham số-1 1

&còn lại Tham số sẽ chứa 0 hoặc nhiều đối số vị trí. Không có vị trí khác
các đối số có thể được chỉ định sau cái này.

Ví dụ mã sau đây xác định một hàm có thể cho từ 0 đến n số
thông số. Sau đó, nó tính tổng mọi số lẻ và trừ mọi số chẵn.

=> (định nghĩa zig-zag-sum [& số còn lại]
(let [[số lẻ (danh sách tổng hợp x [số số x] (số lẻ? x))]
[số chẵn (list-comp x [x số] (chẵn? x))]]
(- (tổng các số lẻ) (tổng các số chẵn))))

=> (zig-zag-sum)
0
=> (zig-zag-sum 3 9 4)
8
=> (zig-zag-sum 1 2 3 4 5 6)
-3

bí danh xác định / bí danh defun
Mới trong phiên bản 0.10.0.

Sản phẩm bí danh xác địnhbí danh defun macro rất giống định nghĩa, với sự khác biệt rằng
thay vì xác định một hàm với một tên duy nhất, chúng cũng có thể xác định bí danh. Khác
hơn là lấy danh sách các ký hiệu cho tên hàm làm tham số đầu tiên, bí danh xác định
bí danh defun không khác gì định nghĩalàm xấu.

=> (defn-alias [bí danh tên chính] []
... (in "Xin chào!"))
=> (tên chính)
"Xin chào!"
=> (bí danh)
"Xin chào!"

xoa dịu
Mới trong phiên bản 0.10.1.

Sản phẩm xoa dịu macro xác định một hàm chính được gọi ngay lập tức với sys.argv as
đối số nếu và chỉ khi tệp này đang được thực thi dưới dạng tập lệnh. Nói cách khác, điều này:

(xác định [& phần còn lại args]
(làm gì đó với args))

tương đương với:

def main (* args):
do_something_with (args)
trả lại 0

nếu __name__ == "__main__":
nhập khẩu hệ thống
retval = main (* sys.arg)

if isinstance (retval, int):
sys.exit (retval)

Lưu ý rằng như bạn có thể thấy ở trên, nếu bạn trả về một số nguyên từ hàm này, đây sẽ là
được sử dụng làm trạng thái thoát cho tập lệnh của bạn. (Python mặc định thoát trạng thái 0 nếu không,
có nghĩa là mọi thứ đều ổn!)

(Từ (sys.exit 0) không được chạy rõ ràng trong trường hợp trả về không phải là số nguyên từ
xoa dịu, đó là một ý tưởng hay để đặt (xoa dịu) là đoạn mã cuối cùng trong tệp của bạn.)

rã đông
rã đông được sử dụng để xác định macro. Định dạng chung là (defmacro tên [thông số]
kinh nghiệm).

Ví dụ sau định nghĩa một macro có thể được sử dụng để hoán đổi thứ tự của các phần tử trong mã,
cho phép người dùng viết mã bằng ký hiệu infix, trong đó toán tử ở giữa
Toán hạng.

=> (tiền tố defmacro [mã]
... (trích dẫn (
... (bỏ trích dẫn (lấy mã 1))
... (bỏ trích dẫn (lấy mã 0))
... (bỏ trích dẫn (lấy mã 2)))))

=> (infix (1 + 1))
2

bí danh defmacro
bí danh defmacro được sử dụng để xác định macro với nhiều tên (bí danh). Định dạng chung
is (defmacro-bí danh [tên] [thông số] kinh nghiệm). Nó tạo ra nhiều macro với cùng một
danh sách tham số và nội dung, trong danh sách tên được chỉ định.

Ví dụ sau xác định hai macro, cả hai macro đều cho phép người dùng viết mã vào
ký hiệu infix.

=> (defmacro-alias [infix infi] [code]
... (trích dẫn (
... (bỏ trích dẫn (lấy mã 1))
... (bỏ trích dẫn (lấy mã 0))
... (bỏ trích dẫn (lấy mã 2)))))

=> (infix (1 + 1))
2
=> (infi (1 + 1))
2

defmacro / g!
Mới trong phiên bản 0.9.12.

defmacro / g! là một phiên bản đặc biệt của rã đông được sử dụng để tự động tạo gensym
cho bất kỳ ký hiệu nào bắt đầu bằng g!.

Ví dụ, g! a sẽ trở thành (gensym "Một").

XEM CŨNG THẾ:
Phần sử dụng gensym

người sửa lỗi
Mới trong phiên bản 0.9.12.

người sửa lỗi xác định macro trình đọc, cho phép bạn cấu trúc lại hoặc sửa đổi cú pháp.

=> (trình duyệt ^ [expr] (print expr))
=> # ^ (1 2 3 4)
(1 2 3)
=> # ^ "Xin chào"
"Xin chào"

XEM CŨNG THẾ:
Macro trình đọc phần

các
Mới trong phiên bản 0.9.12.

các loại bỏ một đối tượng khỏi không gian tên hiện tại.

=> (setv foo 42)
=> (del foo)
=> foo
Traceback (cuộc gọi gần đây nhất cuối cùng):
Tập tin " ", dòng 1, trong
NameError: tên 'foo' không được xác định

các cũng có thể xóa các đối tượng khỏi ánh xạ, danh sách và hơn thế nữa.

=> (kiểm tra setv (danh sách (phạm vi 10)))
=> kiểm tra
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
=> (del (kiểm tra lát cắt 2 4)) ;; loại bỏ các mục từ 2 đến 4 bị loại trừ
=> kiểm tra
[0, 1, 4, 5, 6, 7, 8, 9]
=> (setv dic {"foo" "bar"})
=> dic
{"foo": "bar"}
=> (del (lấy dic "foo"))
=> dic
{}

làm để
Mới trong phiên bản 0.10.1.

làm để được sử dụng để đơn giản hóa một chuỗi các lệnh gọi phương thức tới một đối tượng.

=> (doto [] (.append 1) (.append 2) .reverse)
[2 1]

=> (bộ sưu tập setv [])
=> (.append bộ sưu tập 1)
=> (.append bộ sưu tập 2)
=> (bộ sưu tập .reverse)
=> bộ sưu tập
[2 1]

đánh giá
đánh giá đánh giá một biểu thức được trích dẫn và trả về giá trị.

=> (eval '(in "Hello World"))
"Chào thế giới"

đánh giá và biên dịch
eval-khi-biên dịch
Thành phố điện khí hóa phía tây dãy núi Rocky đầu tiên / xe hơi
Thành phố điện khí hóa phía tây dãy núi Rocky đầu tiênxe hơi là các macro để truy cập phần tử đầu tiên của một tập hợp:

=> (đầu tiên (phạm vi 10))
0

cho
cho được sử dụng để gọi một hàm cho mỗi phần tử trong danh sách hoặc vectơ. Kết quả của mỗi
cuộc gọi bị hủy và cho biểu thức trả về Không áp dụng thay thế. Mã ví dụ lặp lại
kết thúc bộ sưu tập và cho mỗi thành phần in bộ sưu tập gọi tác dụng phụ chức năng với
thành phần như đối số của nó:

;; giả sử rằng (hiệu ứng phụ) là một hàm nhận một tham số duy nhất
(cho [bộ sưu tập phần tử] (phần tử hiệu ứng phụ))

;; vì có thể có một khối khác tùy chọn
(đối với [bộ sưu tập phần tử] (phần tử hiệu ứng phụ)
(khác (hiệu ứng phụ-2)))

Tùy chọn khác khối chỉ được thực thi nếu cho vòng lặp kết thúc bình thường. Nếu
việc thực thi bị tạm dừng với phá vỡ, Các khác khối không thực thi.

=> (cho [phần tử [1 2 3]] (nếu (<phần tử 3)
... (phần tử in)
... (nghỉ))
... (else (in "vòng lặp đã kết thúc")))
1
2

=> (cho [phần tử [1 2 3]] (nếu (<phần tử 4)
... (phần tử in)
... (nghỉ))
... (else (in "vòng lặp đã kết thúc")))
1
2
3
vòng lặp kết thúc

genexpr
genexpr được sử dụng để tạo biểu thức trình tạo. Nó có hai hoặc ba tham số. Các
tham số đầu tiên là biểu thức kiểm soát giá trị trả về, trong khi tham số thứ hai được sử dụng
để chọn các mục từ danh sách. Tham số thứ ba và tham số tùy chọn có thể được sử dụng để lọc ra
một số mục trong danh sách dựa trên biểu thức điều kiện. genexpr tương tự như
danh sách-comp, ngoại trừ nó trả về một giá trị có thể lặp lại đánh giá từng giá trị một thay vì
đánh giá chúng ngay lập tức.

=> (tập hợp def (phạm vi 10))
=> (lọc def (genxpr x [x bộ sưu tập] (chẵn? x)))
=> (danh sách được lọc)
[0, 2, 4, 6, 8]

gensym
Mới trong phiên bản 0.9.12.

gensym được sử dụng để tạo một biểu tượng duy nhất cho phép viết macro mà không cần
xung đột tên biến tình cờ.

=> (gensym)
u ': G_1235'

=> (gensym "x")
u ': x_1236'

XEM CŨNG THẾ:
Phần sử dụng gensym

được
được được sử dụng để truy cập các phần tử đơn lẻ trong danh sách và từ điển. được có hai tham số:
các dữ liệu cấu trúcchỉ số or chính của mặt hàng. Sau đó nó sẽ trả về
giá trị từ từ điển hoặc danh sách. Cách sử dụng ví dụ:

=> (để [[động vật {"chó" "sủa" "mèo" "meo meo"}]
... [số ["không" "một" "hai" "ba"]]]
... (in (lấy động vật "chó"))
... (in (lấy số 2)))
vỏ cây
hai

LƯU Ý:
được gây ra lỗi KeyError nếu từ điển được truy vấn cho một khóa không tồn tại.

LƯU Ý:
được gây ra lỗi IndexError nếu một danh sách hoặc một bộ được truy vấn cho một chỉ mục nằm ngoài
giới hạn.

toàn cầu
toàn cầu có thể được sử dụng để đánh dấu một biểu tượng là toàn cục. Điều này cho phép lập trình viên chỉ định một
giá trị của một biểu tượng toàn cầu. Đọc một ký hiệu toàn cục không yêu cầu toàn cầu từ khóa -
chỉ gán nó không.

Ví dụ sau đây cho thấy cách ký hiệu chung a được gán một giá trị trong một hàm và
sau đó được in trong một chức năng khác. Không có toàn cầu từ khóa, chức năng thứ hai
sẽ ném một TênLỗi.

(định nghĩa set-a [giá trị]
(toàn cầu a)
(setv một giá trị))

(định nghĩa print-a []
(in a))

(bộ-a 5)
(in-a)

if / nếu không
Mới trong phiên bản 0.10.0: if-not

if được sử dụng để chọn mã được thực thi có điều kiện. Nó phải chứa một điều kiện
khối và khối sẽ được thực thi nếu khối điều kiện đánh giá là Thật. Tùy ý,
nó có thể chứa một khối cuối cùng được thực thi trong trường hợp đánh giá điều kiện là
Sai.

nếu không tương tự, nhưng khối thứ hai sẽ được thực thi khi điều kiện không thành công trong khi
khối thứ ba và khối cuối cùng được thực thi khi kiểm tra thành công - thứ tự ngược lại của if.

Ví dụ sử dụng:

(nếu (tài khoản còn tiền?)
(in "chúng ta hãy đi mua sắm")
(in "hãy bắt đầu và làm việc"))

(nếu-không (tiền còn lại? tài khoản)
(in "hãy bắt đầu và làm việc")
(in "chúng ta hãy đi mua sắm"))

Tính trung thực của Python được tôn trọng. Không áp dụng, Sai, không thuộc bất kỳ kiểu số nào, một chuỗi trống,
và một từ điển trống được coi là Sai; mọi thứ khác được xem xét Thật.

ngọng-nếu / sợi ngọng-nếu-không / sự sống-không
Mới trong phiên bản 0.10.0.

Tính năng mới trong phiên bản 0.10.2: lisp-if-not / life-not

Đối với những người thích một Lispy hơn if mệnh đề, chúng tôi có ngọng-nếu, hoặc là sợi. Điều này có thể xem xét
Không áp dụng / hư không là sai! Tất cả các giá trị Python "false-ish" khác được coi là đúng.
Ngược lại, chúng ta có ngọng-nếu-khôngsự sống-không song song với ifnếu không cái nào đảo ngược
sự so sánh.

=> (lisp-if True "true" "false")
"thật"
=> (lisp-if False "true" "false")
"thật"
=> (lisp-if 0 "true" "false")
"thật"
=> (lisp-if nil "true" "false")
"sai"
=> (lisp-if Không có "true" "false")
"sai"
=> (lisp-if-not nil "true" "false")
"thật"
=> (lisp-if-not Không có "true" "false")
"thật"
=> (lisp-if-not False "true" "false")
"sai"

; Tương đương nhưng ngắn hơn
=> (life True "true" "false")
"thật"
=> (life nil "true" "false")
"sai"
=> (life-not Không có "true" "false")
"thật"

nhập khẩu
nhập khẩu được sử dụng để nhập các mô-đun, như trong Python. Có một số cách nhập khẩu có thể
được dùng.

;; Nhập từng mô-đun này
;;
;; Trăn:
;; nhập hệ thống
;; nhập os.path
(nhập sys os.path)

;; Nhập từ một mô-đun
;;
;; Python: từ nhập os.path tồn tại, isdir, isfile
(nhập [os.path [tồn tại isdir isfile]])

;; Nhập bằng bí danh
;;
;; Python: nhập sys dưới dạng systest
(nhập [sys: as systest])

;; Bạn có thể liệt kê nhiều loại hàng nhập khẩu khác nhau tùy thích.
(nhập [tests.resources [kwtest function-with-a-dash]]
[os.path [tồn tại isdir isfile]]
[sys: as systest])

;; Nhập tất cả các chức năng mô-đun vào không gian tên hiện tại
(nhập [sys [*]])

lambda / fn
lambdafn có thể được sử dụng để xác định một chức năng ẩn danh. Các thông số tương tự như
định nghĩa: tham số đầu tiên là vectơ của các tham số và phần còn lại là phần thân của
chức năng. lambda trả về một chức năng mới. Trong ví dụ sau, một hàm ẩn danh
được định nghĩa và chuyển cho một hàm khác để lọc đầu ra.

=> (def people [{: name "Alice": age 20}
... {: name "Bob": 25 tuổi}
... {: tên "Charlie": tuổi 50}
... {: name "Dave": 5} tuổi])

=> (định nghĩa hiển thị người [bộ lọc người]
... (cho [người người] (nếu (người lọc) (in (: tên người)))))

=> (những người hiển thị (fn [person] (<(: age person) 25)))
Alice
Dave

Cũng giống như trong các định nghĩa hàm thông thường, nếu phần tử đầu tiên của phần thân là một chuỗi, nó
phục vụ như một chuỗi tài liệu. Điều này rất hữu ích cho việc cung cấp các phương thức docstrings của lớp.

=> (setv lần-ba
... (fn [x]
... "Nhân đầu vào với ba và trả về kết quả."
... (* x 3)))

Điều này có thể được xác nhận thông qua tích hợp sẵn của Python giúp đỡ chức năng:

=> (trợ giúp lần-ba)
Trợ giúp về hàm times_three:

times_three (x)
Nhân đầu vào với ba và trả về kết quả
(KẾT THÚC)

cuối cùng
Mới trong phiên bản 0.10.2.

cuối cùng có thể được sử dụng để truy cập phần tử cuối cùng của tập hợp:

=> ([2 4 6] cuối cùng)
6

cho phép
cho phép được sử dụng để tạo các biến phạm vi từ vựng. Chúng được tạo ở đầu
cho phép biểu mẫu và không còn tồn tại sau biểu mẫu. Ví dụ sau đây giới thiệu điều này
hành vi:

=> (let [[x 5]] (in x)
... (hãy để [[x 6]] (in x))
... (in x))
5
6
5

Sản phẩm cho phép macro nhận hai tham số: một vectơ xác định biếnthân hình cái nào được
Thực thi. biến là một vectơ trong đó mỗi phần tử là một biến đơn hoặc một vectơ
xác định một cặp giá trị biến. Trong trường hợp của một biến duy nhất, nó được gán giá trị
Không áp dụng; nếu không, giá trị đã cung cấp sẽ được sử dụng.

=> (let [x [y 5]] (in xy))
Không có 5

danh sách-comp
danh sách-comp thực hiện hiểu danh sách. Nó có hai hoặc ba tham số. Người đầu tiên
tham số là biểu thức kiểm soát giá trị trả về, trong khi biểu thức thứ hai được sử dụng để
chọn các mục từ một danh sách. Tham số thứ ba và tham số tùy chọn có thể được sử dụng để lọc ra một số
của các mục trong danh sách dựa trên biểu thức điều kiện. Vài ví dụ:

=> (tập hợp def (phạm vi 10))
=> (list-comp x [x collection])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

=> (list-comp (* x 2) [x collection])
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

=> (list-comp (* x 2) [x collection] (<x 5))
[0, 2, 4, 6, 8]

không
không được sử dụng trong các biểu thức logic. Nó nhận một tham số duy nhất và trả về một
giá trị sự thật. Nếu như Thật được cung cấp dưới dạng một tham số, Sai sẽ được trả lại và ngược lại.
Ví dụ sử dụng:

=> (không đúng)
Sai

=> (không Sai)
Thật

=> (không phải Không có)
Thật

or
or được sử dụng trong các biểu thức logic. Nó có ít nhất hai tham số. Nó sẽ trả về
tham số không sai đầu tiên. Nếu không có giá trị nào như vậy tồn tại, tham số cuối cùng sẽ được trả về.

=> (hoặc Đúng Sai)
Thật

=> (và Sai Sai)
Sai

=> (và Sai 1 Đúng Sai)
1

LƯU Ý:
or ngắn mạch và dừng đánh giá các thông số ngay khi giá trị thực đầu tiên là
đã gặp.

=> (hoặc True (in "xin chào"))
Thật

in
in được sử dụng để xuất trên màn hình. Cách sử dụng ví dụ:

(in "Hello world!")

LƯU Ý:
in luôn luôn trở lại Không áp dụng.

trích dẫn gần đúng
trích dẫn gần đúng cho phép bạn trích dẫn một biểu mẫu, nhưng cũng đánh giá một cách có chọn lọc các biểu thức.
Các biểu hiện bên trong một trích dẫn gần đúng có thể được đánh giá một cách chọn lọc bằng cách sử dụng unquote (~). Các
biểu mẫu đã đánh giá cũng có thể được nối bằng cách sử dụng bỏ dấu ngoặc kép (~@). Trích dẫn cũng có thể được
được viết bằng backquote (`) Biểu tượng.

;; hãy để `qux 'là một biến có giá trị (bar baz)
`(foo ~ qux)
; tương đương với '(foo (bar baz))
`(foo ~ @ qux)
; tương đương với '(foo bar baz)

trích dẫn
trích dẫn trả về biểu mẫu được chuyển cho nó mà không đánh giá nó. trích dẫn cách khác có thể là
được viết bằng dấu nháy đơn (') Biểu tượng.

=> (setv x '(in "Hello World"))
; biến x được đặt thành biểu thức & không được đánh giá
=> x
(u'print 'u'Hello World')
=> (eval x)
Xin chào thế giới

yêu cầu
yêu cầu được sử dụng để nhập macro từ một mô-đun nhất định. Nó có ít nhất một tham số
chỉ định mô-đun mà macro sẽ được nhập. Nhiều mô-đun có thể được nhập
với một yêu cầu.

Ví dụ sau sẽ nhập macro từ mô-đun-1mô-đun-2:

(yêu cầu mô-đun-1 mô-đun-2)

phần còn lại / cdr
phần còn lạicdr trả về tập hợp được truyền dưới dạng đối số không có phần tử đầu tiên:

=> (còn lại (phạm vi 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

set-comp
set-comp được sử dụng để tạo bộ. Nó có hai hoặc ba tham số. Tham số đầu tiên là
để kiểm soát giá trị trả về, trong khi giá trị thứ hai được sử dụng để chọn các mục từ
sự nối tiếp. Tham số thứ ba và tham số tùy chọn có thể được sử dụng để lọc ra một số mục trong
trình tự dựa trên một biểu thức điều kiện.

=> (dữ liệu setv [1 2 3 4 5 2 3 4 5 3 4 5])
=> (set-comp x [x data] (lẻ? x))
{1, 3, 5}

lát
lát có thể được sử dụng để lấy một tập hợp con của một danh sách và tạo một danh sách mới từ nó. Hình thức
lấy ít nhất một tham số xác định danh sách để cắt. Hai tham số tùy chọn có thể là
được sử dụng để cung cấp vị trí bắt đầu và kết thúc của tập hợp con. Nếu chúng không được cung cấp,
giá trị mặc định của Không áp dụng sẽ được sử dụng thay thế. Tham số tùy chọn thứ ba được sử dụng để
bước kiểm soát giữa các phần tử.

lát tuân theo các quy tắc tương tự như đối tác Python của nó. Các chỉ số phủ định được tính
bắt đầu từ cuối danh sách. Một số ví dụ sử dụng:

=> (tập hợp def (phạm vi 10))

=> (bộ sưu tập lát cắt)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

=> (bộ sưu tập lát 5)
[5, 6, 7, 8, 9]

=> (tuyển tập lát 2 8)
[2, 3, 4, 5, 6, 7]

=> (tuyển tập lát cắt 2 8 2)
[2, 4, 6]

=> (tập hợp lát -4 -2)
[6, 7]

quăng / nâng cao
Sản phẩm quăng or nâng cao các biểu mẫu có thể được sử dụng để nâng cao Ngoại lệ trong thời gian chạy. Cách sử dụng ví dụ:

(phi)
; đọc lại ngoại lệ cuối cùng

(ném IOError)
; Ném lỗi IOError

(ném (IOError "foobar"))
; Ném lỗi IOError ("foobar")

quăng có thể chấp nhận một đối số duy nhất (một Ngoại lệ lớp hoặc phiên bản) hoặc không có đối số với
nâng cao lại lần cuối cùng Ngoại lệ.

thử
Sản phẩm thử biểu mẫu được sử dụng để bắt đầu một thử / bắt khối. Biểu mẫu được sử dụng như sau:

(cố gắng
(chức năng dễ xảy ra lỗi)
(catch [e ZeroDivisionError] (in "Chia cho XNUMX"))
(else (in "không có lỗi"))
(cuối cùng (in "tất cả đã xong")))

thử phải chứa ít nhất một bắt khối, và có thể tùy ý bao gồm một khác or cuối cùng
khối. Nếu lỗi xuất hiện với một khối bắt phù hợp trong quá trình thực thi
chức năng dễ xảy ra lỗi, Đó bắt khối sẽ được thực thi. Nếu không có lỗi nào được nêu ra, khác
khối được thực thi. Các cuối cùng khối sẽ được thực thi cuối cùng bất kể có hay không
lỗi đã được nêu ra.

trừ khi
Sản phẩm trừ khi macro là cách viết tắt để viết một if câu lệnh kiểm tra nếu đã cho
có điều kiện là Sai. Phần sau cho thấy sự mở rộng của macro này.

(trừ khi câu lệnh điều kiện)

(nếu có điều kiện
Không áp dụng
(làm câu lệnh))

unquote
Trong một biểu mẫu gần như được trích dẫn, unquote lực lượng đánh giá của một biểu tượng. unquote được bí danh là
dấu ngã (~) Biểu tượng.

(tên def "Cuddles")
(quasiquote (= name (tên bỏ trích dẫn)))
; => (u '=' u'name 'u'Cuddles')

`(= tên ~ tên)
; => (u '=' u'name 'u'Cuddles')

bỏ dấu ngoặc kép
bỏ dấu ngoặc kép buộc đánh giá một biểu tượng trong một dạng gần như được trích dẫn, giống như
unquote. bỏ dấu ngoặc kép chỉ có thể được sử dụng khi biểu tượng đang được hủy trích dẫn có chứa
giá trị có thể lặp lại, vì nó "nối" giá trị có thể lặp lại đó thành dạng gần như được trích dẫn. bỏ dấu ngoặc kép is
bí danh cho ~@ Biểu tượng.

(số lượng định nghĩa [1 2 3 4])
(gần như trích dẫn (+ (unquote-splice nums)))
; => (u '+' 1L 2L 3L 4L)

`(+ ~ @ nums)
; => (u '+' 1L 2L 3L 4L)

khi nào
khi nào tương tự như trừ khi, ngoại trừ nó kiểm tra khi điều kiện đã cho là Thật. Không phải vậy
có thể có một khác khối trong một khi nào vĩ mô. Phần sau cho thấy sự mở rộng của
vĩ mô.

(khi câu lệnh điều kiện)

(if có điều kiện (câu lệnh do))

trong khi
trong khi được sử dụng để thực thi một hoặc nhiều khối miễn là đáp ứng một điều kiện. Sau
ví dụ sẽ xuất ra "Hello world!" lên màn hình vô thời hạn:

(trong khi True (in "Hello world!"))

với
với được sử dụng để bao bọc việc thực thi một khối trong trình quản lý ngữ cảnh. Bối cảnh
sau đó người quản lý có thể thiết lập hệ thống cục bộ và chia nhỏ nó ra một cách có kiểm soát. Các
ví dụ điển hình về việc sử dụng với là khi xử lý tệp. với có thể ràng buộc ngữ cảnh với một
hoặc bỏ qua nó hoàn toàn, như được hiển thị bên dưới:

(với khối [[arg (expr)]])

(với khối [[(expr)]])

(với [[arg (expr)] [(expr)]] khối)

Ví dụ sau sẽ mở ra TIN TỨC tập tin và in nội dung của nó ra màn hình. Các
tập tin được tự động đóng sau khi nó đã được xử lý.

(với [[f (mở "NEWS")]] (print (.read f)))

với người trang trí
với người trang trí được sử dụng để bọc một hàm với một hàm khác. Chức năng thực hiện
trang trí phải chấp nhận một giá trị duy nhất: chức năng đang được trang trí và trả về một giá trị mới
chức năng. với người trang trí nhận tối thiểu hai tham số: hàm đang thực hiện
trang trí và chức năng được trang trí. Có thể có nhiều hơn một chức năng trang trí
đã áp dụng; chúng sẽ được áp dụng theo thứ tự từ ngoài cùng đến trong cùng, tức là. người đầu tiên
decorator sẽ là người ngoài cùng, v.v. Trình trang trí với các đối số được gọi là
như một lệnh gọi hàm.

(với-trang trí trang trí-vui vẻ
(định nghĩa một số hàm [] ...)

(với-trang trí decorator1 decorator2 ...
(định nghĩa một số hàm [] ...)

(với-trang trí (trang trí arg) ..
(định nghĩa một số hàm [] ...)

Trong ví dụ sau, inc-trang trí được sử dụng để trang trí chức năng Ngoài ra với một
hàm nhận hai tham số và gọi hàm được trang trí với các giá trị là
tăng lên 1. Khi trang trí Ngoài ra được gọi với các giá trị 1 và 1, kết thúc
kết quả sẽ là 4 (1 + 1 + 1 + 1).

=> (defn inc-decorator [func]
... (fn [giá trị-1 giá trị-2] (func (+giá trị-1 1) (+giá trị-2 1))))
=> (defn inc2-decorator [func]
... (fn [giá trị-1 giá trị-2] (func (+giá trị-1 2) (+giá trị-2 2))))

=> (with-decorator inc-decorator (defn add [ab] (+ ab)))
=> (phép cộng 1 1)
4
=> (with-decorator inc2-decorator inc-decorator
... (phép cộng định nghĩa [ab] (+ ab)))
=> (phép cộng 1 1)
8

với-gensyms
Mới trong phiên bản 0.9.12.

với-gensym được sử dụng để tạo một tập hợp gensym để sử dụng trong macro. Đoạn mã sau:

(with-gensyms [abc]
...)

mở rộng thành:

(hãy để [[a (gensym)
[b (gensym)
[c (gensym)]]
...)

XEM CŨNG THẾ:
Phần sử dụng gensym

năng suất
năng suất được sử dụng để tạo một đối tượng trình tạo trả về một hoặc nhiều giá trị. Máy phát điện
có thể lặp lại và do đó có thể được sử dụng trong các vòng lặp, danh sách hiểu và các
cấu trúc.

Các chức năng Số ngẫu nhiên cho thấy cách máy phát điện có thể được sử dụng để tạo chuỗi vô hạn
mà không tốn dung lượng bộ nhớ vô hạn.

=> (định nghĩa nhân [hệ số cơ số]
... (cho [[(, hệ số cơ sở) (hệ số cơ sở zip)]]
... (năng suất (* hệ số cơ sở)))

=> (nhân (phạm vi 5) (phạm vi 5))


=> (list-comp value [value (nhân (phạm vi 10) (phạm vi 10))])
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

=> (nhập ngẫu nhiên)
=> (xác định số ngẫu nhiên [thấp cao]
... (trong khi Đúng (năng suất (.randint ngẫu nhiên thấp cao))))
=> (list-comp x [x (lấy 15 (số ngẫu nhiên 1 50))])])
[7, 41, 6, 22, 32, 17, 5, 38, 18, 38, 17, 14, 23, 23, 19]

năng suất từ
Mới trong phiên bản 0.9.13.

TRĂN 3.3 UP ONLY!

năng suất từ được sử dụng để gọi một máy phát điện con. Điều này rất hữu ích nếu bạn muốn quy trình đăng ký của mình
có thể ủy quyền các quy trình của nó cho một quy trình điều tra khác, chẳng hạn, nếu sử dụng thứ gì đó ưa thích như
không đồng bộ.

Hy Trung tâm
Trung tâm Chức năng
mông
Cách sử dụng: (nhưng cuối cùng đối chiếu)

Trả về một trình lặp của tất cả trừ mục cuối cùng trong tập thể.

=> (danh sách (butlast (phạm vi 10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8]

=> (danh sách (butlast [1]))
[]

=> (danh sách (butlast []))
[]

=> (nhập itertools)
=> (danh sách (lấy 5 (butlast (itertools.count 10))))
[10, 11, 12, 13, 14]

va chạm?
Mới trong phiên bản 0.10.0.

Cách sử dụng: (va chạm? x)

Trả hàng Thật if x là có thể lặp lại và không phải là một chuỗi.

=> (đối chiếu? [1 2 3 4])
Thật

=> (coll? {"a" 1 "b" 2})
Thật

=> (coll? "abc")
Sai

khuyết điểm
Mới trong phiên bản 0.10.0.

Cách sử dụng: (khuyết điểm a b)

Trả về một ô khuyết điểm mới với ô tô a và cdr b.

=> (setv a (khuyết điểm 'hd' tl))

=> (= 'hd (xe a))
Thật

=> (= 'tl (cdr a))
Thật

khuyết điểm?
Mới trong phiên bản 0.10.0.

Cách sử dụng: (khuyết điểm? foo)

Kiểm tra xem foo là một ô khuyết điểm.

=> (setv a (khuyết điểm 'hd' tl))

=> (khuyết điểm? a)
Thật

=> (khuyết điểm? nil)
Sai

=> (khuyết điểm? [1 2 3])
Sai

Tháng mười hai
Cách sử dụng: (Tháng mười hai x)

Trả về một ít hơn x. Tương đương với (- x 1). Tăng LoạiLỗi if (Không (số? x)).

=> (3 tháng XNUMX)
2

=> (0 tháng XNUMX)
-1

=> (12.3 tháng XNUMX)
11.3

tháo rời
Mới trong phiên bản 0.10.0.

Cách sử dụng: (tháo rời cây &không bắt buộc [ mã nguồn sai])

Bán phá giá AST của Python cho Hy đã cho cây đến đầu ra tiêu chuẩn. Nếu như bộ mã hóa is Thật, chức năng
in mã Python để thay thế.

=> (tháo rời '(in "Hello World!"))
Mô-đun (
cơ thể = [
Expr (value = Call (func = Name (id = 'print'), args = [Str (s = 'Hello World!')], Keywords = [], starargs = None, kwargs = None))])

=> (tháo rời '(in "Hello World!") true)
print ('Xin chào Thế giới!')

trống?
Cách sử dụng: (trống? đối chiếu)

Trả hàng Thật if tập thể trống rỗng. Tương đương với (= 0 (len đối chiếu)).

=> (trống? [])
Thật

=> (trống? "")
Thật

=> (trống? (, 1 2))
Sai

mỗi?
Mới trong phiên bản 0.10.0.

Cách sử dụng: (mỗi? trước đối chiếu)

Trả hàng Thật if (trước x) là logic đúng cho mọi x in tập thể, Nếu không Sai. Trở về Thật
if tập thể trống rỗng.

=> (mọi? chẵn? [2 4 6])
Thật

=> (mọi? chẵn? [1 3 5])
Sai

=> (mọi? chẵn? [2 4 5])
Sai

=> (mọi? chẵn? [])
Thật

trôi nổi?
Cách sử dụng: (trôi nổi? x)

Trả hàng Thật if x là một cái phao.

=> (float? 3.2)
Thật

=> (float? -2)
Sai

cũng?
Cách sử dụng: (cũng? x)

Trả hàng Thật if x là thậm chí. Tăng LoạiLỗi if (Không (số? x)).

=> (chẵn? 2)
Thật

=> (chẵn? 13)
Sai

=> (chẵn? 0)
Thật

bản sắc
Cách sử dụng: (bản sắc x)

Trả về đối số được cung cấp cho hàm.

=> (sắc 4)
4

=> (danh sách (nhận dạng bản đồ [1 2 3 4]))
[1 2 3 4]

inc
Cách sử dụng: (bao gồm x)

Trả về nhiều hơn x. Tương đương với (+ x 1). Tăng LoạiLỗi if (Không (số? x)).

=> (có 3)
4

=> (có 0)
1

=> (có 12.3)
13.3

ví dụ?
Cách sử dụng: (ví dụ? tốt nghiệp lớp XNUMX x)

Trả hàng Thật if x là một ví dụ của tốt nghiệp lớp XNUMX.

=> (phiên bản? float 1.0)
Thật

=> (ví dụ? int 7)
Thật

=> (ví dụ? str (str "foo"))
Thật

=> (khử lớp TestClass [đối tượng])
=> (setv inst (TestClass))
=> (phiên bản? TestClass inst)
Thật

số nguyên?
Cách sử dụng: (số nguyên? x)

Trả hàng Thật if x là một số nguyên. Đối với Python 2, đây là int or Dài. Đối với Python 3,
đây là int.

=> (số nguyên? 3)
Thật

=> (số nguyên? -2.4)
Sai

xen kẽ
Mới trong phiên bản 0.10.1.

Cách sử dụng: (xen kẽ tiếp theo1 tiếp theo2 ...)

Trả về một mục có thể lặp lại của mục đầu tiên trong mỗi chuỗi, sau đó là mục thứ hai, v.v.

=> (danh sách (xen kẽ (phạm vi 5) (phạm vi 100 105)))
[0, 100, 1, 101, 2, 102, 3, 103, 4, 104]

=> (danh sách (xen kẽ (phạm vi 1000000) "abc"))
[0, 'a', 1, 'b', 2, 'c']

xen vào
Mới trong phiên bản 0.10.1.

Cách sử dụng: (đan xen mục tiếp theo)

Trả về một giá trị có thể lặp lại của các phần tử của chuỗi được phân tách bởi mục.

=> (list (interpose "!" "abcd"))
['A B C D']

=> (danh sách (mục đích -1 (phạm vi 5)))
[0, -1, 1, -1, 2, -1, 3, -1, 4]

có thể lặp lại?
Cách sử dụng: (có thể lặp lại? x)

Trả hàng Thật if x có thể lặp lại. Các đối tượng có thể lặp lại trả về một trình lặp mới khi (lặp đi lặp lại x) is
triệu tập. Tương phản với trình lặp?.

=> ;; hoạt động cho chuỗi
=> (có thể lặp lại? (str "abcde"))
Thật

=> ;; làm việc cho danh sách
=> (có thể lặp lại? [1 2 3 4 5])
Thật

=> ;; làm việc cho các bộ giá trị
=> (có thể lặp lại? (, 1 2 3))
Thật

=> ;; làm việc cho các giáo phái
=> (có thể lặp lại? {: a 1: b 2: c 3})
Thật

=> ;; hoạt động cho máy lặp / máy phát điện
=> (có thể lặp lại? (lặp lại 3))
Thật

trình lặp?
Cách sử dụng: (trình lặp? x)

Trả hàng Thật if x là một trình lặp. Các trình lặp lại là các đối tượng tự trả về như một
trình lặp khi (lặp đi lặp lại x) được gọi là. Tương phản với có thể lặp lại?.

=> ;; không hoạt động cho một danh sách
=> (trình lặp? [1 2 3 4 5])
Sai

=> ;; nhưng chúng tôi có thể lấy một iter từ danh sách
=> (trình lặp? (iter [1 2 3 4 5]))
Thật

=> ;; không hoạt động cho dict
=> (trình lặp? {: a 1: b 2: c 3})
Sai

=> ;; tạo một trình lặp từ dict
=> (biến lặp? (iter {: a 1: b 2: c 3}))
Thật

danh sách*
Cách sử dụng: (danh sách* cái đầu &còn lại đuôi)

Tạo một chuỗi các ô khuyết điểm lồng nhau (danh sách có dấu chấm) chứa các đối số. Nếu
danh sách đối số chỉ có một phần tử, trả về nó.

=> (danh sách * 1 2 3 4)
(1 2 3. 4)

=> (danh sách * 1 2 3 [4])
[1, 2, 3, 4]

=> (danh sách * 1)
1

=> (khuyết điểm? (danh sách * 1 2 3 4))
Thật

mở rộng vĩ mô
Mới trong phiên bản 0.10.0.

Cách sử dụng: (mở rộng vĩ mô hình thức)

Trả về mở rộng macro đầy đủ của hình thức.

=> (macroexpand '(-> (ab) (xy)))
(u'x '(u'a' u'b ') u'y')

=> (macroexpand '(-> (ab) (-> (cd) (ef))))
(u'e '(u'c' (u'a 'u'b') u'd ') u'f')

macroexpand-1
Mới trong phiên bản 0.10.0.

Cách sử dụng: (mở rộng vĩ mô-1 hình thức)

Trả về phần mở rộng macro bước đơn của hình thức.

=> (macroexpand-1 '(-> (ab) (-> (cd) (ef))))
(u '_>' (u'a 'u'b') (u'c 'u'd') (u'e 'u'f'))

kết hợp với
Mới trong phiên bản 0.10.1.

Cách sử dụng: (kết hợp với f &còn lại bản đồ)

Trả về một bản đồ bao gồm phần còn lại của các bản đồ được nối vào đầu tiên. Nếu một khóa xảy ra trong
nhiều hơn một bản đồ, (các) ánh xạ từ thứ hai (từ trái sang phải) sẽ được kết hợp với
ánh xạ trong kết quả bằng cách gọi (f val-trong-kết quả val-in-sau).

=> (merge-with (fn [xy] (+ xy)) {"a" 10 "b" 20} {"a" 1 "c" 30})
{u'a ': 11L, u'c': 30L, u'b ': 20L}

phủ định?
Cách sử dụng: (phủ định? x)

Trả hàng Thật if x nhỏ hơn XNUMX. Tăng LoạiLỗi if (Không (số? x)).

=> (phủ định? -2)
Thật

=> (phủ định? 3)
Sai

=> (phủ định? 0)
Sai

không?
Cách sử dụng: (không? x)

Trả hàng Thật if x is hư không / Không áp dụng.

=> (nil? nil)
Thật

=> (không? Không có)
Thật

=> (không? 0)
Sai

=> (setf x nil)
=> (không? x)
Thật

=> ;; list.append luôn trả về Không có
=> (nil? (.append [1 2 3] 4))
Thật

không ai?
Cách sử dụng: (không ai? x)

Trả hàng Thật if x is Không áp dụng.

=> (không có? Không có)
Thật

=> (không có? 0)
Sai

=> (setf x Không có)
=> (không có? x)
Thật

=> ;; list.append luôn trả về Không có
=> (không có? (.append [1 2 3] 4))
Thật

thứ n
Cách sử dụng: (thứ n tập thể n &không bắt buộc [vỡ nợ không])

Trả về n-item thứ trong một bộ sưu tập, tính từ 0. Trả về giá trị mặc định, hư không, Nếu
ngoài giới hạn (trừ khi được chỉ định khác). Tăng Giá trịError if n là tiêu cực.

=> (thứ n [1 2 4 7] 1)
2

=> (thứ n [1 2 4 7] 3)
7

=> (nil? (n [1 2 4 7] 5))
Thật

=> (thứ n [1 2 4 7] 5 "mặc định")
'vỡ nợ'

=> (thứ n (lấy 3 (bỏ 2 [1 2 3 4 5 6])) 2))
5

=> (thứ n [1 2 4 7] -1)
Traceback (cuộc gọi gần đây nhất cuối cùng):
hữu ích. Cảm ơn !
ValueError: Các chỉ số cho islice () phải là Không hoặc là số nguyên: 0 <= x <= sys.maxsize.

số?
Cách sử dụng: (số? x)

Trả hàng Thật if x là một số, như được định nghĩa trong Python's số. Số lớp học.

=> (số? -2)
Thật

=> (số? 3.2)
Thật

=> (số? "foo")
Sai

số lẻ?
Cách sử dụng: (số lẻ? x)

Trả hàng Thật if x là số lẻ. Tăng LoạiLỗi if (Không (số? x)).

=> (lẻ? 13)
Thật

=> (lẻ? 2)
Sai

=> (lẻ? 0)
Sai

vị trí?
Cách sử dụng: (vị trí? x)

Trả hàng Thật if x lớn hơn XNUMX. Tăng LoạiLỗi if (Không (số? x)).

=> (vị trí 3)
Thật

=> (vị trí -2)
Sai

=> (vị trí 0)
Sai

2
Cách sử dụng: (thứ hai đối chiếu)

Trả về thành viên thứ hai của tập thể. Tương đương với (được tập thể 1).

=> (giây [0 1 2])
1

một số
Mới trong phiên bản 0.10.0.

Cách sử dụng: (một số trước đối chiếu)

Trả về giá trị logic-true đầu tiên của (trước x) bất cứ gì x in tập thể, Nếu không hư không.
Trả hàng hư không if tập thể trống rỗng.

=> (một số chẵn? [2 4 6])
Thật

=> (nil? (một số chẵn? [1 3 5]))
Thật

=> (nil? (một số nhận dạng [0 "" []]))
Thật

=> (một số nhận dạng [0 "non-rỗng-string" []])
'non-rỗng-string'

=> (nil? (một số chẵn? []))
Thật

chuỗi?
Cách sử dụng: (chuỗi? x)

Trả hàng Thật if x là một chuỗi.

=> (chuỗi? "foo")
Thật

=> (chuỗi? -2)
Sai

Biểu tượng?
Cách sử dụng: (Biểu tượng? x)

Trả hàng Thật if x là một biểu tượng.

=> (ký hiệu? 'foo)
Thật

=> (ký hiệu? '[abc])
Sai

số không?
Cách sử dụng: (số không? x)

Trả hàng Thật if x là số không.

=> (không? 3)
Sai

=> (không? -2)
Sai

=> (không? 0)
Thật

Trình tự Chức năng
Các hàm trình tự có thể tạo hoặc hoạt động trên một trình tự có khả năng vô hạn mà không cần
yêu cầu trình tự được thực hiện đầy đủ trong một danh sách hoặc vùng chứa tương tự. Họ làm điều này bằng cách
trả về một trình lặp Python.

Chúng ta có thể sử dụng trình tạo số Fibonacci vô hạn chính tắc làm ví dụ về cách sử dụng
một số chức năng này.

(định nghĩa fib []
(thiết lập là 0)
(tập b 1)
(trong khi đúng
(nhường a)
(setv (, ab) (, b (+ ab)))))

Lưu ý (trong khi đúng ...) vòng. Nếu chúng tôi chạy điều này trong REPL,

=> (xơ)


Việc gọi hàm chỉ trả về một trình lặp, nhưng không hoạt động cho đến khi chúng ta sử dụng nó.
Bạn không nên thử một cái gì đó như thế này vì vòng lặp vô hạn sẽ chạy cho đến khi nó
tiêu thụ tất cả RAM có sẵn hoặc trong trường hợp này là cho đến khi tôi giết nó.

=> (list (fib))
[1] 91474 bị giết hy

Để nhận 10 số Fibonacci đầu tiên, hãy sử dụng lấy. Lưu ý rằng lấy cũng trả về một trình tạo,
vì vậy tôi tạo một danh sách từ nó.

=> (danh sách (lấy 10 (fib)))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Để nhận số Fibonacci ở chỉ số 9, (bắt đầu từ 0):

=> (nth (fib) 9)
34

chu kỳ
Cách sử dụng: (xe đạp đối chiếu)

Trả về một trình lặp vô hạn của các thành viên của coll.

=> (danh sách (lấy 7 (chu kỳ [1 2 3])))
[1, 2, 3, 1, 2, 3, 1]

=> (danh sách (lấy 2 (chu kỳ [1 2 3])))
[1, 2]

khác biệt
Cách sử dụng: (riêng biệt đối chiếu)

Trả về một trình lặp chỉ chứa các thành viên duy nhất trong tập thể.

=> (danh sách (riêng biệt [1 2 3 4 3 5 2]))
[1, 2, 3, 4, 5]

=> (danh sách (riêng biệt []))
[]

=> (danh sách (riêng biệt (iter [1 2 3 4 3 5 2])))
[1, 2, 3, 4, 5]

rơi vãi
Cách sử dụng: (rơi vãi n đối chiếu)

Trả về một trình lặp, bỏ qua trình lặp đầu tiên n Thành viên của tập thể. Tăng Giá trịError if n is
tiêu cực.

=> (danh sách (thả 2 [1 2 3 4 5]))
[3, 4, 5]

=> (danh sách (thả 4 [1 2 3 4 5]))
[5]

=> (danh sách (thả 0 [1 2 3 4 5]))
[1, 2, 3, 4, 5]

=> (danh sách (thả 6 [1 2 3 4 5]))
[]

thả cuối cùng
Cách sử dụng: (thả cuối cùng n đối chiếu)

Trả về một trình lặp của tất cả trừ biến cuối cùng n các mặt hàng trong tập thể. Tăng Giá trịError if n is
tiêu cực.

=> (danh sách (thả 5 cuối cùng (phạm vi 10 20)))
[10, 11, 12, 13, 14]

=> (danh sách (thả xuống 0 cuối cùng (phạm vi 5)))
[0, 1, 2, 3, 4]

=> (danh sách (thả xuống 100 cuối cùng (phạm vi 100)))
[]

=> (nhập itertools)
=> (danh sách (lấy 5 (thả xuống 100 cuối cùng (itertools.count 10))))
[10, 11, 12, 13, 14]

thả trong khi
Cách sử dụng: (thả trong khi trước đối chiếu)

Trả về một trình lặp, bỏ qua các thành viên của tập thể cho đến khi trước is Sai.

=> (danh sách (thả trong khi chẵn? [2 4 7 8 9]))
[7, 8, 9]

=> (danh sách (thả xuống dạng số? [1 2 3 Không có "a"])))
[Không, u'a ']

=> (danh sách (vị trí thả trong khi? [2 4 7 8 9]))
[]

lọc
Cách sử dụng: (lọc trước đối chiếu)

Trả về một trình lặp cho tất cả các mục trong tập thể vượt qua vị ngữ trước.

Xem thêm tẩy.

=> (danh sách (vị trí bộ lọc? [1 2 3 -4 5 -7]))
[1, 2, 3, 5]

=> (danh sách (lọc chẵn? [1 2 3 -4 5 -7]))
[2, -4]

làm phẳng
Mới trong phiên bản 0.9.12.

Cách sử dụng: (làm phẳng đối chiếu)

Trả về một danh sách tất cả các mục trong tập thể, bằng cách làm phẳng tất cả các danh sách được chứa và / hoặc
bộ dữ liệu.

=> (làm phẳng [1 2 [3 4] 5])
[1, 2, 3, 4, 5]

=> (làm phẳng ["foo" (, 1 2) [1 [2 3] 4] "thanh"])
['foo', 1, 2, 1, 2, 3, 4, 'bar']

lặp lại
Cách sử dụng: (lặp lại fn x)

Trả về một trình lặp của x, fn (x), fn (fn (x)), Vv

=> (danh sách (lấy 5 (lặp lại bao gồm 5)))
[5, 6, 7, 8, 9]

=> (danh sách (lấy 5 (lặp (fn [x] (* xx)) 5)))
[5, 25, 625, 390625, 152587890625]

đọc
Cách sử dụng: (đọc &không bắt buộc [từ tệp eof])

Đọc biểu thức Hy tiếp theo từ từ tập tin (mặc định là sys.stdin), và có thể mất một
byte đơn như EOF (mặc định là một chuỗi trống). Tăng EOFLỗi if từ tập tin kết thúc trước
một biểu thức hoàn chỉnh có thể được phân tích cú pháp.

=> (đọc)
(+2 2)
('+' 2 2)
=> (eval (đọc))
(+2 2)
4

=> (nhập io)
=> (bộ đệm khử (io.StringIO "(+ 2 2) \ n (- 2 1)"))
=> (eval (áp dụng read [] {"from_file" buffer}))
4
=> (eval (áp dụng read [] {"from_file" buffer}))
1

=>; giả sử "example.hy" chứa:
=>; (in "xin chào")
=>; (in "hy Friends!")
=> (với [[f (open "example.hy")]]
... (cố gắng
... (trong khi đúng
... (hãy [[exp (đọc f)]]]
... (làm
... (in "OHY" exp)
... (đánh giá điểm kinh nghiệm))))
... (bắt [e EOFError]
... (in "EOF!"))))
OHY ('in' 'xin chào')
xin chào
OHY ('in' 'hy friends!')
các bạn!
THÔI!

tẩy
Cách sử dụng: (tẩy trước đối chiếu)

Trả về một trình lặp từ tập thể với các yếu tố chuyển vị ngữ, trước, loại bỏ.

Xem thêm lọc.

=> (danh sách (bỏ số lẻ? [1 2 3 4 5 6 7]))
[2, 4, 6]

=> (danh sách (xóa vị trí? [1 2 3 4 5 6 7]))
[]

=> (danh sách (bỏ phủ định? [1 2 3 4 5 6 7]))
[1, 2, 3, 4, 5, 6, 7]

lặp lại
Cách sử dụng: (nói lại x)

Trả về một trình lặp (vô hạn) trong số x.

=> (danh sách (lấy 6 (lặp lại "s")))
[bạn là ', bạn', bạn ', bạn', bạn ', bạn']

nhiều lần
Cách sử dụng: (nhiều lần fn)

Trả về một trình lặp bằng cách gọi fn nhiều lần.

=> (nhập [ngẫu nhiên [randint]])

=> (danh sách (lấy 5 (lặp lại (fn [] (randint 0 10)))))
[6, 2, 0, 6, 7]

lấy
Cách sử dụng: (lấy n đối chiếu)

Trả về một trình lặp có chứa đầu tiên n Thành viên của tập thể. Tăng Giá trịError if n is
tiêu cực.

=> (danh sách (lấy 3 [1 2 3 4 5]))
[1, 2, 3]

=> (danh sách (lấy 4 (lặp lại "s")))
[u's ', u's', u's ', u's']

=> (danh sách (lấy 0 (lặp lại "s")))
[]

lấy thứ n
Cách sử dụng: (lấy thứ n n đối chiếu)

Trả về một trình lặp có chứa mọi n-thành viên thứ của tập thể.

=> (danh sách (lấy thứ 2 [1 2 3 4 5 6 7]))
[1, 3, 5, 7]

=> (danh sách (lấy thứ 3 [1 2 3 4 5 6 7]))
[1, 4, 7]

=> (danh sách (lấy thứ 4 [1 2 3 4 5 6 7]))
[1, 5]

=> (danh sách (lấy thứ 10 [1 2 3 4 5 6 7]))
[1]

tạm thời
Cách sử dụng: (tạm thời trước đối chiếu)

Trả về một trình lặp từ tập thể miễn là trước Trả về Thật.

=> (danh sách (vị trí tạm thời? [1 2 3 -4 5]))
[1, 2, 3]

=> (list (take-while neg? [-4 -3 1 2 5]))
[-4, -3]

=> (list (take-while neg? [1 2 3 -4 5]))
[]

kéo theo
Mới trong phiên bản 0.9.13.

Cách sử dụng: (có khóa kéo fn tập thể ...)

Tương đương với zip, nhưng sử dụng một hàm đa đối số thay vì tạo một bộ giá trị. Nếu như
kéo theo được gọi với N tập hợp, sau đó fn phải chấp nhận N đối số.

=> (toán tử nhập)
=> (danh sách (zipwith operator.add [1 2 3] [4 5 6]))
[5, 7, 9]

Người đọc Macros
Macro trình đọc cung cấp cho Lisp sức mạnh để sửa đổi và thay đổi cú pháp một cách nhanh chóng. Bạn không muốn
Ký hiệu đánh bóng? Một macro người đọc có thể dễ dàng làm điều đó. Muốn có cách của Clojure để có một
regex? Macro của trình đọc cũng có thể thực hiện điều này một cách dễ dàng.

cú pháp
=> (trình duyệt ^ [expr] (print expr))
=> # ^ (1 2 3 4)
(1 2 3)
=> # ^ "Xin chào"
"Xin chào"
=> #^1+2+3+4+3+2
1+2+3+4+3+2

Hy không có nghĩa đen cho bộ giá trị. Cho phép nói rằng bạn không thích (, ...) và muốn một cái gì đó khác. Điều này
là một trình đọc vấn đề mà macro có thể giải quyết một cách gọn gàng.

=> (trình giải mã t [expr] `(, ~ @ expr))
=> #t (1 2 3)
(1, 2, 3)

Bạn thậm chí có thể làm điều đó giống như Clojure và có một nghĩa đen cho các biểu thức chính quy!

=> (nhập lại)
=> (trình giải mã r [expr] `(re.compile ~ expr))
=> #r ". *"
Đối tượng <_sre.SRE_Pattern tại 0xcv7713ph15 #>

Thực hiện
người sửa lỗi lấy một ký tự duy nhất làm tên ký hiệu cho macro trình đọc; còn gì nữa
sẽ trả về một lỗi. Triển khai khôn ngoan, người sửa lỗi mở rộng thành một lambda được bao phủ bởi một
người trang trí. Trình trang trí này lưu lambda trong từ điển với tên mô-đun của nó và
Biểu tượng.

=> (trình duyệt ^ [expr] (print expr))
; => (with_decorator (hy.macros.reader ^) (fn [expr] (print expr)))

# mở rộng thành (disp_reader_macro ...) nơi mà biểu tượng và biểu thức được chuyển đến
chức năng chính xác.

=> # ^ ()
; => (disp_reader_macro ^ ())
=> # ^ "Xin chào"
"Xin chào"

Chú ý:
Do hạn chế trong trình phân tích cú pháp và lexer của Hy, macro trình đọc không thể xác định lại được định nghĩa
cú pháp chẳng hạn như () [] {}. Điều này rất có thể sẽ được giải quyết trong tương lai.

nội Hy Tài liệu
LƯU Ý:
Những bit này chủ yếu hữu ích cho những người hack bản thân Hy, nhưng cũng có thể được sử dụng để
những nghiên cứu sâu hơn về lập trình macro.

Hy mô hình
Giới thiệu đến Hy mô hình
Các mô hình Hy là một lớp rất mỏng nằm trên các đối tượng Python thông thường, đại diện cho nguồn Hy
mã dưới dạng dữ liệu. Các mô hình chỉ thêm thông tin vị trí nguồn và một số phương pháp để
hỗ trợ thao tác sạch đối với mã nguồn Hy, ví dụ như trong macro. Để đạt được điều đó
mục tiêu, các mô hình Hy là các mixin của một lớp Python cơ sở và HyObject.

HyObject
hy.models.HyObject là lớp cơ sở của các mô hình Hy. Nó chỉ thực hiện một phương pháp, thay thế,
mà thay thế vị trí nguồn của đối tượng hiện tại bằng vị trí được truyền dưới dạng đối số.
Điều này cho phép chúng tôi theo dõi vị trí ban đầu của các biểu thức được sửa đổi bởi
macro, là macro trong trình biên dịch hoặc trong macro thuần túy.

HyObject không nhằm mục đích sử dụng trực tiếp để khởi tạo các mô hình Hy, mà chỉ được sử dụng như một hỗn hợp
cho các lớp khác.

Hợp chất mô hình
Các danh sách được đặt trong ngoặc đơn và được đặt trong ngoặc vuông được bộ phân tích cú pháp Hy phân tích thành các mô hình phức hợp.

HyList
hy.models.list.HyList là lớp cơ sở của các mô hình Hy "có thể lặp lại". Công dụng cơ bản của nó là
đại diện cho dấu ngoặc [] danh sách, khi được sử dụng làm biểu thức cấp cao nhất, dịch sang
Danh sách các ký tự trong Python trong giai đoạn biên dịch.

Việc thêm HyList vào một đối tượng có thể lặp lại khác sẽ sử dụng lại lớp của đối tượng bên trái,
một hành vi hữu ích khi bạn muốn nối các đối tượng Hy trong một macro, chẳng hạn.

HyExpression
hy.models.biểu thức.HyExpression kế thừa HyList cho dấu ngoặc đơn () biểu thức. Các
kết quả biên dịch của những biểu thức đó phụ thuộc vào phần tử đầu tiên của danh sách:
trình biên dịch gửi các biểu thức giữa các biểu mẫu đặc biệt của trình biên dịch, macro do người dùng xác định và
các lệnh gọi hàm Python thông thường.

HyDict
hy.models.dict.HyDict kế thừa HyList cho dấu ngoặc nhọn {} biểu thức, biên dịch
xuống từ điển Python theo nghĩa đen.

Quyết định sử dụng một danh sách thay vì một dict làm lớp cơ sở cho HyDict cho phép dễ dàng hơn
thao tác với các dict trong macro, với lợi ích bổ sung là cho phép các biểu thức ghép
dưới dạng các khóa dict (ví dụ: HyExpression Lớp Python không thể băm).

Nguyên tử mô hình
Trong luồng đầu vào, các chuỗi được trích dẫn kép, tôn trọng ký hiệu Python cho các chuỗi,
được phân tích cú pháp dưới dạng một mã thông báo duy nhất, được phân tích cú pháp trực tiếp dưới dạng HyString.

Một chuỗi ký tự không bị gián đoạn, không bao gồm dấu cách, dấu ngoặc vuông, dấu ngoặc kép, dấu ngoặc kép
và nhận xét, được phân tích cú pháp như một số nhận dạng.

Các số nhận dạng được phân giải thành các mô hình nguyên tử trong giai đoạn phân tích cú pháp theo thứ tự sau:

· HyInteger

· HyFloat

· HyComplex (nếu nguyên tử không phải là một j)

· từ khóa hy (nếu nguyên tử bắt đầu bằng :)

· Dấu gạch ngang

HyString
hy.models.string.HyString là lớp cơ sở của các mô hình Hy tương đương với chuỗi. Nó cũng
đại diện cho chuỗi ký tự được trích dẫn kép, "", biên dịch thành chuỗi unicode
các chữ trong Python. HyStrings kế thừa các đối tượng unicode trong Python 2 và các đối tượng chuỗi trong
Python 3 (và do đó không phụ thuộc vào mã hóa).

HyString các mô hình dựa trên là bất biến.

Các chuỗi chữ Hy có thể kéo dài nhiều dòng và được trình phân tích cú pháp coi là một chuỗi
đơn vị, tôn trọng các thoát Python cho các chuỗi unicode.

Numeric mô hình
hy.models.integer.HyInteger đại diện cho các ký tự số nguyên (sử dụng Dài gõ trên Python 2,
int trên Python 3).

hy.models.float.HyFloat đại diện cho các ký tự dấu phẩy động.

hy.models.complex.HyComplex đại diện cho các từ phức tạp.

Các mô hình số được phân tích cú pháp bằng quy trình Python tương ứng và python số hợp lệ
các chữ sẽ được chuyển thành chữ Hy của chúng.

Dấu gạch ngang
hy.models.symbol.HySymbol là mô hình dùng để biểu diễn các ký hiệu trong ngôn ngữ Hy. Nó
kế thừa HyString.

Dấu gạch ngang các đối tượng bị xáo trộn trong giai đoạn phân tích cú pháp, để giúp khả năng tương tác của Python:

· Các ký hiệu được bao quanh bởi dấu hoa thị (*) được chuyển thành chữ hoa;

· Dấu gạch ngang (-) được chuyển thành dấu gạch dưới (_);

· Một dấu chấm hỏi ở cuối (?) được biến thành hàng đầu Là_.

Lưu ý: vì quá trình xử lý được thực hiện trong giai đoạn phân tích cú pháp, có thể
lập trình tạo HySymbols không thể được tạo bằng mã nguồn Hy. Như một
cơ chế được sử dụng bởi gensym để tạo ra các ký hiệu "không bị gián đoạn".

từ khóa hy
hy.models.keyword.HyKeyword đại diện cho các từ khóa bằng chữ Hy. Từ khóa là các ký hiệu bắt đầu bằng
a :. Lớp kế thừa HyString.

Để phân biệt Từ khóa Hy từ Dấu gạch ngang, không có khả năng (không tự nguyện)
xung đột, ký tự unicode sử dụng riêng "\ uFDD0" được thêm vào từ khóa
trước khi bảo quản.

Nhược điểm Tế bào
hy.models.cons.HyCons là một đại diện thân thiện với Python khuyết điểm tế bào. Ô khuyết điểm là
đặc biệt hữu ích để bắt chước các tính năng của các biến thể LISP "thông thường" như Scheme hoặc Common
ngọng.

Ô khuyết điểm là một đối tượng 2 mục, chứa xe hơi (đầu) và một cdr (đuôi). Trong một số Lisp
các biến thể, ô khuyết điểm là khối xây dựng cơ bản và biểu thức S thực sự là
được biểu diễn dưới dạng danh sách liên kết của các ô khuyết điểm. Đây không phải là trường hợp của Hy, như thường lệ
các biểu thức được tạo từ các danh sách Python được bao bọc trong một HyExpression. Tuy nhiên, HyCons
do đó bắt chước hành vi của các biến thể Lisp "thông thường":

· (khuyết điểm một cái gì đó không) is (HyExpression [thứ gì đó])

· (khuyết điểm một cái gì đó một số danh sách) is ((loại một số danh sách) (+ [thứ gì đó] một số danh sách)) (nếu
một số danh sách kế thừa từ ).

· (được (khuyết điểm a b) 0) is a

· (lát cắt (khuyết điểm a b) 1) is b

Hy hỗ trợ cú pháp danh sách dấu chấm, trong đó '(Một . b) có nghĩa (khuyết điểm 'a 'b)'(Một b . c) có nghĩa
(khuyết điểm 'a (khuyết điểm 'b 'C)). Nếu trình biên dịch gặp một ô khuyết điểm ở cấp cao nhất, nó sẽ tăng
một lỗi biên dịch.

HyCons bao bọc các đối số đã truyền (car và cdr) trong các kiểu Hy, để dễ dàng thao tác
ô khuyết điểm trong ngữ cảnh macro.

Hy nội Lý thuyết
Giới thiệu chung
Nội bộ Hy hoạt động bằng cách hoạt động như một giao diện người dùng cho mã bytecode của Python, do đó, chính Hy
biên dịch xuống Python Bytecode, cho phép thời gian chạy Python không sửa đổi để chạy mã Hy,
mà không nhận ra nó.

Cách chúng tôi thực hiện việc này là dịch Hy sang cơ cấu dữ liệu Python AST nội bộ và
xây dựng AST đó thành mã bytecode Python bằng cách sử dụng các mô-đun từ tiêu chuẩn Python
thư viện, để chúng tôi không phải sao chép tất cả công việc của nội bộ Python cho mọi
bản phát hành Python duy nhất.

Hy hoạt động trong bốn giai đoạn. Các phần sau sẽ trình bày từng bước của Hy từ nguồn đến
thời gian chạy.

Các bước 1 2: Mã thông báo Phân tích cú pháp
Giai đoạn đầu tiên của quá trình biên dịch Hy là ghép nguồn thành các mã thông báo mà chúng ta có thể xử lý. chúng tôi
sử dụng một dự án có tên là rply, là một trình phân tích cú pháp thực sự tốt (và nhanh), được viết trong một tập hợp con
của Python được gọi là rpython.

Tất cả mã lexing đều được định nghĩa trong hy.lex.lexer. Mã này chủ yếu chỉ xác định chữ Hy
ngữ pháp và tất cả các phần khó thực tế đều do rply đảm nhận - chúng tôi chỉ xác định
"callbacks" cho rply trong hy.lex.parser, lấy các mã thông báo được tạo và trả về
Hy các mô hình.

Bạn có thể coi các mô hình Hy là "AST" cho Hy, đó là những gì Macro hoạt động trên
(trực tiếp), và đó là những gì trình biên dịch sử dụng khi nó biên dịch Hy xuống.

XEM CŨNG THẾ:
Phần Hy mô hình để biết thêm thông tin về các mô hình Hy và ý nghĩa của chúng.

Bước 3: Hy Biên soạn đến Python AST
Đây là nơi mà hầu hết các điều kỳ diệu trong Hy đều xảy ra. Đây là nơi chúng tôi lấy Hy AST (các mô hình),
và biên dịch chúng thành Python AST. Một vài điều thú vị xảy ra ở đây để vượt qua một vài
các vấn đề trong AST và làm việc trong trình biên dịch là một số công việc quan trọng nhất mà chúng tôi thực hiện
có.

Trình biên dịch hơi phức tạp, vì vậy đừng cảm thấy tồi tệ nếu bạn không tìm kiếm nó trong lần chụp đầu tiên,
có thể mất một chút thời gian để làm đúng.

Điểm vào chính của Trình biên dịch là HyASTCompiler.compile. Phương thức này được gọi và
phương thức "công khai" duy nhất trên lớp (có nghĩa là, chúng tôi không thực sự hứa hẹn
API ngoài phương pháp đó).

Trên thực tế, ngay cả trong nội bộ, chúng tôi hầu như không lặp lại trực tiếp, chúng tôi hầu như luôn buộc
cây thông hỷ biên dịchvà thường sẽ làm điều này với các phần tử con của một biểu thức
mà chúng ta có. Người điều phối dựa trên Loại có quyền điều phối các phần tử phụ một cách chính xác.

Tất cả các phương thức tạo trước một biên dịch được đánh dấu bằng @builds () người trang trí. Bạn có thể
hoặc vượt qua lớp của mô hình Hy mà nó biên dịch hoặc bạn có thể sử dụng một chuỗi cho
biểu thức. Tôi sẽ làm rõ điều này trong một giây.

Tên Traineeship Loại-Công văn
Hãy bắt đầu trong biên dịch phương pháp. Điều đầu tiên chúng tôi làm là kiểm tra Loại vật
chúng tôi đang xây dựng. Chúng tôi tìm kiếm để xem liệu chúng tôi có một phương pháp có thể xây dựng thể loại() rằng chúng ta
có, và gửi đến phương thức có thể xử lý nó. Nếu chúng tôi không có bất kỳ phương pháp nào có thể
xây dựng loại hình đó, chúng tôi nâng cao nội bộ Ngoại lệ.

Ví dụ, nếu chúng ta có HyString, chúng tôi có ánh xạ gần như 1-1 từ Hy AST sang Python
AST. Các biên dịch_chuỗi phương pháp lấy HyStringvà trả về một ast.Str () đó là
được điền với số dòng và nội dung chính xác.

Mở rộng Macro
Nếu chúng tôi nhận được một HyExpression, chúng tôi sẽ cố gắng xem liệu đây có phải là Macro đã biết hay không và thúc đẩy để có
nó mở rộng bằng cách gọi hy.macros.macroexpand, sau đó đẩy lại kết quả vào
HyASTCompiler.compile.

Thứ hai Traineeship Biểu thức-Công văn
Trường hợp đặc biệt duy nhất là HyExpression, vì chúng ta cần tạo các AST khác nhau tùy thuộc vào
trên hình thức đặc biệt được đề cập. Ví dụ, khi chúng ta đánh một (nếu đúng đúng sai), Chúng tôi
cần tạo ra một ast.Ifvà biên dịch đúng cách các nút con. Đây là nơi @builds ()
với một Chuỗi làm đối số đi vào.

Đối với biểu thức biên dịch (được xác định với một @builds (HyExpression)) sẽ gửi
dựa trên chuỗi của đối số đầu tiên. Nếu vì lý do nào đó, đối số đầu tiên không
một chuỗi, nó cũng sẽ xử lý đúng trường hợp đó (rất có thể bằng cách tăng Ngoại lệ).

Nếu Hy không biết Chuỗi, nó sẽ mặc định tạo một ast.Call, sẽ cố gắng
thực hiện một cuộc gọi thời gian chạy (bằng Python, giống như foo ()).

Các vấn đề Đánh với Python AST
Python AST là tuyệt vời; đó là điều đã cho phép chúng tôi viết một dự án mạnh mẽ như vậy trên
Python mà không cần phải chiến đấu với Python quá khó. Giống như bất cứ điều gì, chúng tôi đã chia sẻ công bằng của mình về
và đây là danh sách ngắn các vấn đề phổ biến mà bạn có thể gặp phải.

Python khác biệt giữa Báo cáo Biểu thức.

Điều này nghe có vẻ không phải là một vấn đề lớn - trên thực tế, đối với hầu hết các lập trình viên Python, điều này sẽ
nhanh chóng trở thành khoảnh khắc "Vâng, vâng".

Trong Python, làm một cái gì đó như:

in cho x in phạm vi(10): vượt qua, bởi vì in in các biểu thức và cho không phải là một
biểu thức, đó là một câu lệnh luồng điều khiển. Những thứ như 1 + 1 là Biểu thức, như là lambda
x: 1 + x, nhưng các tính năng ngôn ngữ khác, chẳng hạn như if, cho, hoặc là trong khi là các câu lệnh.

Vì chúng không có "giá trị" nào đối với Python, điều này làm cho việc làm việc trong Hy trở nên khó khăn, vì làm một cái gì đó
Lượt thích (in (nếu đúng đúng sai)) không chỉ phổ biến, nó được mong đợi.

Do đó, chúng tôi tự động xử lý mọi thứ bằng cách sử dụng Kết quả đối tượng, nơi chúng tôi cung cấp bất kỳ ast.stmt
cần phải chạy và một ast.expr có thể được sử dụng để lấy giá trị của bất cứ thứ gì
vừa mới chạy. Hy thực hiện điều này bằng cách bắt buộc phân công mọi việc trong khi điều hành.

Ví dụ, chữ Hy:

(in (nếu đúng, sai))

Sẽ biến thành:

nếu đúng:
_mangled_name_here = Đúng
khác:
_mangled_name_here = Sai

in _mangled_name_here

OK, đó là một chút dối trá, vì chúng tôi thực sự biến câu nói đó thành:

in Đúng nếu Đúng khác Sai

Bằng cách buộc mọi thứ vào một ast.expr nếu chúng ta có thể, nhưng ý tưởng chung là đúng.

Bước 4: Python mã byte Đầu ra Runtime
Sau khi chúng ta có một cây Python AST hoàn chỉnh, chúng ta có thể thử và biên dịch nó sang Python
bytecode bằng cách đẩy nó qua đánh giá. Kể từ đây trở đi, chúng tôi không còn kiểm soát và
Python đang chăm sóc mọi thứ. Đây là lý do tại sao những thứ như truy nguyên Python, pdb và
ứng dụng django hoạt động.

Hy Macros
Sử dụng gensym cho Safer Macros
Khi viết macro, người ta phải cẩn thận để tránh nắm bắt các biến bên ngoài hoặc sử dụng
tên biến có thể xung đột với mã người dùng.

Chúng tôi sẽ sử dụng một macro ví dụ không (xem
http://letoverlambda.com/index.cl/guest/chap3.html# giây_5 để có một mô tả đầy đủ hơn.)
không là một ví dụ, một cái gì đó giống như một số if, dựa trên biểu thức, một trong những
3 dạng được gọi tùy thuộc vào việc biểu thức là dương, XNUMX hay âm.

Một lần vượt qua đầu tiên có thể giống như:

(defmacro nif [dạng expr pos-form zero-form neg-form]
`(để [[tên tối nghĩa ~ expr]]
(cond [(pos? dark-name) ~ pos-form]
[(số không? tên tối nghĩa) ~ dạng không]
[(neg? tên tối nghĩa) ~ neg-form])))

Ở đâu tên khó hiểu là một nỗ lực để chọn một số tên biến để không xung đột với
mã số. Nhưng tất nhiên, trong khi có thiện chí, điều này không có gì đảm bảo.

Phương pháp gensym được thiết kế để tạo ra một biểu tượng mới, độc đáo cho những dịp như vậy.
Một phiên bản tốt hơn nhiều của không sẽ là:

(defmacro nif [dạng expr pos-form zero-form neg-form]
(hãy để [[g (gensym)]]
`(để [[~ g ~ expr]]
(cond [(pos? ~ g) ~ pos-form]
[(zero? ~ g) ~ zero-form]
[(neg? ~ g) ~ neg-form]))))

Đây là một trường hợp dễ dàng, vì chỉ có một ký hiệu. Nhưng nếu có nhu cầu về một số
gensym's có một macro thứ hai với-gensyms về cơ bản mở rộng thành một loạt cho phép
các câu lệnh:

(with-gensyms [abc]
...)

mở rộng thành:

(hãy để [[a (gensym)
[b (gensym)
[c (gensym)]]
...)

vì vậy chúng tôi đã viết lại không sẽ trông giống như:

(defmacro nif [dạng expr pos-form zero-form neg-form]
(với-gensyms [g]
`(để [[~ g ~ expr]]
(cond [(pos? ~ g) ~ pos-form]
[(zero? ~ g) ~ zero-form]
[(neg? ~ g) ~ neg-form]))))

Cuối cùng, mặc dù chúng ta có thể tạo một macro mới thực hiện tất cả những điều này cho chúng ta. defmacro / g! sẽ mất
tất cả các ký hiệu bắt đầu bằng g! và tự động gọi gensym với phần còn lại của
Biểu tượng. Cho nên g! a sẽ trở thành (gensym "Một").

Phiên bản cuối cùng của chúng tôi về không, được xây dựng bằng defmacro / g! trở thành:

(defmacro / g! nif [expr pos-form zero-form neg-form]
`(để [[~ g! res ~ expr]]
(cond [(pos? ~ g! res) ~ pos-form]
[(zero? ~ g! res) ~ zero-form]
[(neg? ~ g! res) ~ neg-form]))))

Kiểm tra Macro Lập luận Nâng cao Trường hợp ngoại lệ
Hy Trình biên dịch Tích hợp sẵn

ĐÓNG GÓP MODULES INDEX


Nội dung:

Đảo âm Macros
Mới trong phiên bản 0.9.12.

Mô-đun macro anaphoric làm cho lập trình chức năng trong Hy rất ngắn gọn và dễ dàng
đọc.
Một macro đảo ngữ là một loại macro lập trình cố tình nắm bắt một số hình thức
được cung cấp cho macro có thể được tham chiếu bởi một anaphor (một biểu thức giới thiệu
khác). - Wikipedia (http://en.wikipedia.org/wiki/Anaphoric_macro)

Macros
ap-if
Cách sử dụng: (ap-if (foo) (in nó))

Đánh giá biểu mẫu đầu tiên về tính xác thực và liên kết nó với it cả đúng và sai
chi nhánh.

một quả đào
Cách sử dụng: (một quả đào [1 2 3 4 5] (in nó))

Đánh giá hình thức của từng yếu tố trong danh sách để biết tác dụng phụ.

ap-mỗi-khi
Cách sử dụng: (ap-mỗi-khi trước thân hình)

Đánh giá biểu mẫu cho mỗi phần tử mà biểu mẫu vị từ trả về Thật.

=> (ap-each-while [1 2 3 4 5 6] (<it 4) (in it))
1
2
3

bản đồ ứng dụng
Cách sử dụng: (ap-bản đồ hình thức danh sách)

Dạng bản đồ đảo ngữ hoạt động giống như bản đồ thông thường ngoại trừ một chức năng
đối tượng nó có dạng Hy. Tên đặc biệt it được liên kết với đối tượng hiện tại từ
danh sách trong lần lặp lại.

=> (danh sách (ap-map (* it 2) [1 2 3]))
[2, 4, 6]

ap-map-khi
Cách sử dụng: (ap-map-khi ưu tiên đại diện danh sách)

Đánh giá ánh xạ qua danh sách bằng cách sử dụng một hàm vị từ để xác định khi nào áp dụng
hình thức.

=> (danh sách (ap-map-khi lẻ? (* it 2) [1 2 3 4]))
[2, 2, 6, 4]

=> (danh sách (ap-map-khi chẵn? (* it 2) [1 2 3 4]))
[1, 4, 3, 8]

bộ lọc ap
Cách sử dụng: (bộ lọc ap hình thức danh sách)

Như với bản đồ ứng dụng chúng tôi có một dạng đặc biệt thay vì một hàm để lọc các phần tử của
danh sách. Tên đặc biệt it được liên kết với phần tử hiện tại trong lần lặp.

=> (danh sách (ap-filter (> (* it 2) 6) [1 2 3 4 5]))
[4, 5]

ap-từ chối
Cách sử dụng: (ap-từ chối hình thức danh sách)

Chức năng này ngược lại với bộ lọc ap, nó từ chối các phần tử đi qua
Thuộc tính . Tên đặc biệt it được liên kết với phần tử hiện tại trong lần lặp.

=> (danh sách (ap-từ chối (> (* it 2) 6) [1 2 3 4 5]))
[1, 2, 3]

sau giờ làm
Sử dụng (thời gian ap-dotimes n thân hình)

Hàm này đánh giá cơ thể n lần, với biến đặc biệt it ràng buộc từ 0 đến
1-n. Nó rất hữu ích cho các tác dụng phụ.

=> (setv n [])
=> (ap-dotimes 3 (.append n it))
=> n
[0, 1, 2]

ap-đầu tiên
Sử dụng (ap-trước ưu tiên danh sách)

Hàm này trả về phần tử đầu tiên chuyển vị ngữ hoặc Không áp dụng, Với
biến đặc biệt it liên kết với phần tử hiện tại trong lần lặp lại.

=> (ap-first (> it 5) (range 10))
6

cuối cùng
Sử dụng (cuối cùng ưu tiên danh sách)

Hàm này trả về phần tử cuối cùng chuyển vị ngữ hoặc Không áp dụng, với sự đặc biệt
biến it liên kết với phần tử hiện tại trong lần lặp lại.

=> (ap-last (> it 5) (range 10))
9

giảm nhẹ
Sử dụng (ap-giảm hình thức &không bắt buộc giá trị ban đầu)

Hàm này trả về kết quả của việc áp dụng biểu mẫu cho 2 phần tử đầu tiên trong phần thân và
áp dụng kết quả và phần tử thứ 3, v.v. cho đến khi hết danh sách. Tùy chọn một
giá trị ban đầu có thể được cung cấp để hàm sẽ được áp dụng cho giá trị ban đầu và
phần tử đầu tiên thay thế. Điều này cho thấy phần tử đang được lặp lại dưới dạng it và hiện tại
giá trị tích lũy như acc.

=> (ap-Reduce (+ it acc) (phạm vi 10))
45

lặp lại / lặp lại
Mới trong phiên bản 0.10.0.

Sản phẩm vòng lặp / tái phát macro cung cấp cho các lập trình viên một cách đơn giản để sử dụng tối ưu hóa cuộc gọi đuôi (TCO)
trong mã Hy của họ.
Một lệnh gọi đuôi là một lệnh gọi chương trình con xảy ra bên trong một thủ tục khác như là bước cuối cùng của nó
hoạt động; nó có thể tạo ra một giá trị trả về sau đó được trả về ngay lập tức bởi lệnh gọi
thủ tục. Nếu bất kỳ lệnh gọi nào mà một chương trình con thực hiện, thì cuối cùng nó có thể dẫn đến
chương trình con tương tự này đang được gọi lại trong chuỗi lệnh gọi, ở vị trí đuôi,
một chương trình con như vậy được cho là đệ quy đuôi, đây là một trường hợp đặc biệt của đệ quy.
Lệnh gọi đuôi rất quan trọng vì chúng có thể được triển khai mà không cần thêm ngăn xếp mới
khung vào ngăn xếp cuộc gọi. Hầu hết khung của quy trình hiện tại không cần thiết
nhiều hơn, và nó có thể được thay thế bằng khung của cuộc gọi đuôi. Chương trình sau đó có thể nhảy
vào chương trình con được gọi. Tạo mã như vậy thay vì chuỗi cuộc gọi tiêu chuẩn là
được gọi là loại bỏ cuộc gọi đuôi, hoặc tối ưu hóa cuộc gọi đuôi. Cho phép loại bỏ cuộc gọi đuôi
các lệnh gọi thủ tục ở vị trí đuôi để được triển khai hiệu quả như các câu lệnh goto,
do đó cho phép lập trình có cấu trúc hiệu quả. - Wikipedia (-
http://en.wikipedia.org/wiki/Tail_call)

Macros
vòng lặp
vòng lặp thiết lập một điểm đệ quy. Với vòng lặp, tái phát ràng buộc các biến được đặt trong
điểm đệ quy và gửi thực thi mã trở lại điểm đệ quy đó. Nếu như tái phát được sử dụng trong
một vị trí không có đuôi, một ngoại lệ được ném ra.

Cách sử dụng: (vòng ràng buộc &còn lại thân hình)

Ví dụ:

(yêu cầu hy.contrib.loop)

(định nghĩa giai thừa [n]
(vòng lặp [[trong] [tài khoản 1]]
(nếu (không? i)
acc
(định kỳ (dec i) (* acc i)))))

(giai thừa 1000)

người khai hoang
Mới trong phiên bản 0.10.0.

người khai hoang cho phép bạn tính quá tải một hàm theo số lượng args và / hoặc kwargs đã cho.
Lấy cảm hứng từ Clojure's take on định nghĩa.

=> (yêu cầu hy.contrib.multi)
=> (vui vẻ nhiều
... ([a] "a")
... ([ab] "ab")
... ([abc] "abc"))
=> (vui 1)
"a"
=> (vui có 1 2)
"ab"
=> (vui 1 2 3)
"abc"

HACK ON HY


Tham gia vfoXNUMXfipXNUMXhfpiXNUMXufhpiXNUMXuf Hyve!
Hãy đến hack Hy!

Hãy đi chơi với chúng tôi trên #hy on irc.freenode.net!

Hãy nói về nó trên Twitter với #hy dấu thăng!

Hãy viết blog về nó!

Vui lòng không phun sơn nó lên hàng rào của hàng xóm của bạn (mà không hỏi một cách tử tế)!

Gian lận!
Làm cái này:

1. Tạo một ảo môi trường:

$ virtualenv venv

và kích hoạt nó:

$. venv / bin / kích hoạt

hoặc dùng virtualenvwrapper để tạo và quản lý môi trường ảo của bạn:

$ mkvirtualenv hy
$ công việc hy vọng

2. Lấy mã nguồn:

$ git bản sao https://github.com/hylang/hy.git

hoặc sử dụng nĩa của bạn:

bản sao $ git [email được bảo vệ]: /hy.git

3. Cài đặt để hack:

$ cd hy /
$ pip cài đặt -e.

4. Cài đặt các yêu cầu phát triển y khác:

$ pip cài đặt -r yêu cầu-dev.txt

5. Làm những điều tuyệt vời; khiến ai đó hét lên thích thú / ghê tởm trước những gì bạn đã trải qua.

Kiểm tra!
Các bài kiểm tra được đặt tại kiểm tra /. Chúng tôi sử dụng mũi.

Để chạy các bài kiểm tra:

$ thử mũi

Viết bài kiểm tra --- bài kiểm tra là tốt!

Ngoài ra, tốt hơn là bạn nên chạy các bài kiểm tra cho tất cả các nền tảng được hỗ trợ và tuân thủ PEP 8
mã số. Bạn có thể làm như vậy bằng cách chạy tox:

độc tố $

Tài liệu!
Tài liệu được đặt tại tài liệu /. Chúng tôi sử dụng Người khó hiểu.

Để tạo tài liệu trong HTML:

$ cd tài liệu
$ tạo html

Viết tài liệu --- tài liệu rất tốt! Ngay cả tài liệu này!

Góp phần
Mọi đóng góp đều được hoan nghênh và đánh giá rất cao, mọi đóng góp đều giúp Hy nhiều hơn
tuyệt vời.

Yêu cầu kéo là rất tốt! Chúng tôi yêu họ; đây là hướng dẫn nhanh:

· Chuyển repo và tạo một nhánh chủ đề cho một tính năng / bản sửa lỗi. Tránh thực hiện các thay đổi trực tiếp
trên nhánh chủ.

· Tất cả các tính năng mới phải được đi kèm với các bài kiểm tra.

· Trước khi bạn gửi PR, vui lòng chạy các bài kiểm tra và kiểm tra mã của bạn so với phong cách
hướng dẫn. Bạn có thể làm cả hai điều này cùng một lúc:

$ làm cho d

· Thực hiện các cam kết thành các đơn vị hợp lý, để dễ dàng theo dõi và điều hướng sau này. Trước
gửi bài PR, thử chia nhỏ các cam kết thành các tập thay đổi dễ dàng quay lại
một lát sau. Ngoài ra, hãy đảm bảo rằng bạn không để lại khoảng trắng giả trong các tập tin thay đổi; điều này
tránh tạo ra các cam kết sửa chữa khoảng trắng sau này.

· Đối với các thông điệp cam kết, hãy cố gắng tuân thủ những điều sau:

· Hãy thử tuân theo giới hạn 50 ký tự cho dòng đầu tiên của thông báo cam kết Git.

· Để biết thêm chi tiết / giải thích, hãy theo dõi phần này với một dòng trống và tiếp tục
mô tả chi tiết về cam kết.

· Cuối cùng, thêm chính bạn vào tệp AUTHORS (như một cam kết riêng): bạn xứng đáng được như vậy :)

· Tất cả những thay đổi sắp tới cần phải được thực hiện bởi 2 thành viên khác nhau trong nhóm nòng cốt của Hylang.
Rõ ràng hoan nghênh việc xem xét bổ sung, nhưng chúng tôi cần tối thiểu 2 người ký tên cho bất kỳ
thay đổi.

· Nếu một thành viên cốt lõi đang gửi PR, vui lòng tìm 2 thành viên cốt lõi không bao gồm
Người đệ trình PR. Ý tưởng ở đây là người ta có thể làm việc với tác giả bài PR, và người thứ hai
toàn bộ thay đổi.

· Đối với tài liệu và những thay đổi nhỏ khác, chúng ta nên hợp nhất sau một ACK. Chúng tôi đã có
phạm vi bao phủ thấp, vì vậy sẽ rất tốt nếu giữ cho hàng rào đó ở mức thấp.

Trung tâm Đội
Nhóm phát triển cốt lõi của Hy bao gồm các nhà phát triển sau:

· Julien Danjou

· Morten Linderud

· J Kenneth Vua

· Gergely Nagy

· Tuukka rùa

· Tiếng Karen rỉ sét

· Abhishek L

· Christopher Allan Webber

· Konrad Hinsen

· Will Kahn-Greene

· paul Tagliamonte

· Nicolas Dandrimont

· Bob tolbert

· berker Bắc Kinh

· Clinton N. Dreisbach

· ông semaj

Sử dụng hy trực tuyến bằng các dịch vụ onworks.net


Máy chủ & Máy trạm miễn phí

Tải xuống ứng dụng Windows & Linux

  • 1
    NSIS: Hệ thống cài đặt tập lệnh Nullsoft
    NSIS: Hệ thống cài đặt tập lệnh Nullsoft
    NSIS (Cài đặt tập lệnh Nullsoft
    System) là một mã nguồn mở chuyên nghiệp
    hệ thống để tạo bộ cài đặt Windows. Nó
    được thiết kế nhỏ và linh hoạt
    như sở hữu ...
    Tải xuống NSIS: Hệ thống cài đặt tập lệnh Nullsoft
  • 2
    xác thực
    xác thực
    AuthPass là một mật khẩu nguồn mở
    quản lý với sự hỗ trợ cho phổ biến và
    Keepass đã được chứng minh (kdbx 3.x VÀ kdbx 4.x ...
    Tải xuống mật khẩu xác thực
  • 3
    Zabbix
    Zabbix
    Zabbix là một công ty mở cấp doanh nghiệp
    nguồn giải pháp giám sát phân tán
    được thiết kế để giám sát và theo dõi
    hiệu suất và tính khả dụng của mạng
    máy chủ, thiết bị ...
    Tải xuống Zabbix
  • 4
    KĐ3
    KĐ3
    Kho lưu trữ này không còn được duy trì
    và được giữ cho mục đích lưu trữ. Nhìn thấy
    https://invent.kde.org/sdk/kdiff3 for
    mã mới nhất và
    https://download.kde.o...
    Tải xuống KDiff3
  • 5
    USBLoaderGX
    USBLoaderGX
    USBLoaderGX là một GUI cho
    Bộ nạp USB của Waninkoko, dựa trên
    libwiigui. Nó cho phép liệt kê và
    khởi chạy trò chơi Wii, trò chơi Gamecube và
    homebrew trên Wii và WiiU ...
    Tải xuống USBLoaderGX
  • 6
    Chim lửa
    Chim lửa
    Firebird RDBMS cung cấp các tính năng ANSI SQL
    & chạy trên Linux, Windows &
    một số nền tảng Unix. Đặc trưng
    đồng thời và hiệu suất tuyệt vời
    & sức mạnh...
    Tải xuống Firebird
  • Khác »

Lệnh Linux

Ad