ນີ້ແມ່ນຄໍາສັ່ງ hy ທີ່ສາມາດດໍາເນີນການໄດ້ໃນ OnWorks ຜູ້ໃຫ້ບໍລິການໂຮດຕິ້ງຟຣີໂດຍໃຊ້ຫນຶ່ງໃນຫຼາຍໆບ່ອນເຮັດວຽກອອນໄລນ໌ຂອງພວກເຮົາເຊັ່ນ Ubuntu Online, Fedora Online, Windows online emulator ຫຼື MAC OS online emulator
ໂຄງການ:
NAME
hy - hy ເອກະສານ [ຮູບ: Hy] [image]
ພະຍາຍາມ Hy https://try-hy.appspot.com
P&IP https://pypi.python.org/pypi/hy
ແຫຼ່ງຂໍ້ມູນ https://github.com/hylang/hy
ບັນຊີລາຍຊື່ hylang-ສົນທະນາ
irc #ເອີ ໃນ Freenode
ສ້າງ ສະຖານະພາບ
Travis CI.UNINDENT
Hy ເປັນພາສາທີ່ຍອດຢ້ຽມຂອງ Lisp ທີ່ຝັງຢູ່ໃນ Python.
ນັບຕັ້ງແຕ່ Hy ປ່ຽນລະຫັດ Lisp ເຂົ້າໄປໃນ Python Abstract Syntax Tree, ທ່ານມີ
ໂລກທີ່ສວຍງາມທັງຫມົດຂອງ Python ຢູ່ປາຍນິ້ວມືຂອງທ່ານ, ໃນຮູບແບບ Lisp!
ເນື້ອໃນ:
ດ່ວນ
[ຮູບພາບ: ກອດຂອງ Karen Rustard] [ຮູບພາບ]
(ຂໍຂອບໃຈ Karen Rustad ສໍາລັບ Cuddles!)
ວິທີການ ເຖິງ GET HY REAL FAST:
1. ສ້າງກ virtual Python ສະພາບແວດລ້ອມ.
2. ເປີດໃຊ້ສະພາບແວດລ້ອມ Virtual Python ຂອງທ່ານ.
3. ຕິດຕັ້ງ hy ຈາກ P&IP ກັບ pip ການຕິດຕັ້ງ hy.
4. ເລີ່ມ REPL ກັບ hy.
5. ພິມສິ່ງທີ່ຢູ່ໃນ REPL:
=> (ພິມ "Hy!")
ເຮີ້ຍ!
=> (defn salutationsnm [ຊື່] (ພິມ (+ "Hy "ຊື່ "!")))
=> (ຄໍາຊົມເຊີຍ "ຊື່ຂອງເຈົ້າ")
ຊື່ຂອງເຈົ້າ!
ແລະອື່ນໆ
6. ກົດ CTRL-D ເມື່ອທ່ານກໍາລັງເຮັດ.
ໂອພະເຈົ້າ! ນັ້ນແມ່ນ ອັດສະຈັນ! I ຕ້ອງການ to ຂຽນ a Hy ໂຄງການ.
7. ເປີດບັນນາທິການໂຄງການ elite ແລະປະເພດ:
(ພິມ "ຂ້ອຍຈະເຂົ້າລະຫັດໃນ syntax Python, ແຕ່ຫຼັງຈາກນັ້ນຂ້ອຍໄດ້ຮັບ Hy.")
8. ບັນທຶກເປັນ awesome.hy.
9. ແລະດໍາເນີນການໂຄງການ Hy ທໍາອິດຂອງທ່ານ:
hy awesome.hy
10.
ຫາຍໃຈເລິກໆເພື່ອບໍ່ໃຫ້ເກີດການລະບາຍອາກາດສູງ.
11.
ຍິ້ມຢ່າງໂຫດຮ້າຍ ແລະ ຍ່າງອອກໄປທີ່ hydeaway ຂອງເຈົ້າ ແລະເຮັດສິ່ງທີ່ເວົ້າບໍ່ໄດ້.
TUTORIAL
ຍິນດີຕ້ອນຮັບສູ່ການສອນ Hy!
ໂດຍຫຍໍ້, Hy ແມ່ນພາສາ Lisp, ແຕ່ເປັນພາສາທີ່ປ່ຽນໂຄງສ້າງຂອງມັນໃຫ້ເປັນ Python ...
ການປ່ຽນເປັນຕົ້ນໄມ້ syntax ທີ່ບໍ່ມີຕົວຕົນຂອງ Python ແທ້ໆ! (ຫຼືຈະເຮັດໃຫ້ມັນມີຄວາມເຂັ້ມແຂງຫຼາຍ
ເງື່ອນໄຂ, Hy ແມ່ນ lisp-stick ໃນ Python!)
ນີ້ແມ່ນດີຫຼາຍເພາະວ່າມັນຫມາຍຄວາມວ່າ Hy ມີຫຼາຍສິ່ງຫຼາຍຢ່າງ:
· Lisp ທີ່ມີຄວາມຮູ້ສຶກ Pytonic ຫຼາຍ
·ສໍາລັບ Lispers, ເປັນວິທີທີ່ດີທີ່ຈະໃຊ້ອໍານາດບ້າຂອງ Lisp ແຕ່ໃນໂລກກວ້າງຂອງ Python's
ຫ້ອງສະຫມຸດ (ເປັນຫຍັງແມ່ນແລ້ວ, ຕອນນີ້ທ່ານສາມາດຂຽນຄໍາຮ້ອງສະຫມັກ Django ໃນ Lisp!)
· ສໍາລັບ Pythonistas, ເປັນວິທີທີ່ດີທີ່ຈະເລີ່ມຄົ້ນຫາ Lisp, ຈາກຄວາມສະດວກສະບາຍຂອງ Python!
·ສໍາລັບທຸກຄົນ: ເປັນພາສາທີ່ຫນ້າສົນໃຈທີ່ມີຫຼາຍຂອງຄວາມຄິດ neat!
ພື້ນຖານ intro to lisp ສໍາລັບການ Pythonistas
ຕົກລົງ, ບາງທີເຈົ້າບໍ່ເຄີຍໃຊ້ Lisp ມາກ່ອນ, ແຕ່ເຈົ້າເຄີຍໃຊ້ Python!
ໂຄງການ "ສະບາຍດີໂລກ" ໃນ Hy ແມ່ນງ່າຍດາຍທີ່ສຸດ. ໃຫ້ລອງມັນ:
(ພິມ "ສະບາຍດີໂລກ")
ເຫັນບໍ? ງ່າຍ! ດັ່ງທີ່ທ່ານອາດຈະໄດ້ຄາດເດົາ, ນີ້ແມ່ນຄືກັນກັບສະບັບ Python ຂອງ:
ພິມ "ສະບາຍດີໂລກ"
ເພື່ອເພີ່ມຄະນິດສາດທີ່ງ່າຍດາຍຫຼາຍ, ພວກເຮົາສາມາດເຮັດໄດ້:
(+ 1 3)
ເຊິ່ງຈະກັບຄືນມາ 4 ແລະຈະເທົ່າກັບ:
1 + 3
ສິ່ງທີ່ທ່ານຈະສັງເກດເຫັນແມ່ນວ່າລາຍການທໍາອິດໃນບັນຊີລາຍການແມ່ນການທໍາງານທີ່ຖືກເອີ້ນແລະ
ສ່ວນທີ່ເຫຼືອຂອງການໂຕ້ຖຽງແມ່ນການໂຕ້ຖຽງທີ່ຖືກສົ່ງຜ່ານ. ໃນຄວາມເປັນຈິງ, ໃນ Hy (ເຊັ່ນດຽວກັນກັບສ່ວນໃຫຍ່
Lisps) ພວກເຮົາສາມາດສົ່ງຜ່ານຫຼາຍ argument ໄປຫາຕົວປະຕິບັດການບວກ:
(+ 1 3 55)
ຊຶ່ງຈະກັບຄືນມາ 59.
ບາງທີເຈົ້າເຄີຍໄດ້ຍິນຂອງ Lisp ມາກ່ອນແຕ່ບໍ່ຮູ້ຫຼາຍກ່ຽວກັບມັນ. Lisp ບໍ່ຍາກຄືກັບເຈົ້າ
ອາດຈະຄິດ, ແລະ Hy ສືບທອດມາຈາກ Python, ດັ່ງນັ້ນ Hy ເປັນວິທີທີ່ດີທີ່ຈະເລີ່ມຕົ້ນການຮຽນຮູ້ Lisp.
ສິ່ງທີ່ສໍາຄັນທີ່ຈະແຈ້ງກ່ຽວກັບ Lisp ແມ່ນວ່າມີວົງເລັບຫຼາຍ. ນີ້ອາດຈະ
ທໍາອິດເບິ່ງຄືວ່າສັບສົນ, ແຕ່ມັນບໍ່ຍາກຫຼາຍ. ໃຫ້ເຮົາເບິ່ງຄະນິດສາດທີ່ງ່າຍດາຍບາງຢ່າງທີ່
ຫໍ່ຢູ່ໃນວົງເລັບທີ່ພວກເຮົາສາມາດເຂົ້າໄປໃນນາຍພາສາ Hy:
(setv ຜົນໄດ້ຮັບ (- (/ (+ 1 3 88) 2) 8))
ນີ້ຈະກັບຄືນມາ 38. ແຕ່ເປັນຫຍັງ? ດີ, ພວກເຮົາສາມາດເບິ່ງການສະແດງອອກທຽບເທົ່າໃນ
python:
ຜົນໄດ້ຮັບ = ((1 + 3 + 88) / 2) − 8
ຖ້າທ່ານພະຍາຍາມຊອກຫາວິທີຂ້າງເທິງນີ້ເຮັດວຽກຢູ່ໃນ python, ແນ່ນອນ, ແນ່ນອນ
ຄິດອອກຜົນໄດ້ຮັບໂດຍການແກ້ໄຂແຕ່ລະວົງເລັບພາຍໃນ. ນັ້ນແມ່ນຄວາມຄິດພື້ນຖານດຽວກັນໃນ
ຮິ. ລອງເຮັດບົດຝຶກຫັດນີ້ກ່ອນໃນ Python:
ຜົນໄດ້ຮັບ = ((1 + 3 + 88) / 2) − 8
# ຫຍໍ້ເປັນ...
ຜົນໄດ້ຮັບ = (92/2) − 8
# ຫຍໍ້ເປັນ...
ຜົນໄດ້ຮັບ = 46 − 8
# ຫຍໍ້ເປັນ...
ຜົນໄດ້ຮັບ = 38
ຕອນນີ້ໃຫ້ລອງເຮັດສິ່ງດຽວກັນໃນ Hy:
(setv ຜົນໄດ້ຮັບ (- (/ (+ 1 3 88) 2) 8))
; ຫຍໍ້ເປັນ...
(setv ຜົນໄດ້ຮັບ (- (/ 92 2) 8))
; ຫຍໍ້ເປັນ...
(ຜົນ setv (- 46 8))
; ຫຍໍ້ເປັນ...
(ຜົນ setv 38)
ດັ່ງທີ່ທ່ານອາດຈະຄາດເດົາ, ນີ້ສະແດງອອກສຸດທ້າຍກັບ ຊຸດ ໝາຍເຖິງການກຳນົດຕົວແປ
"ຜົນໄດ້ຮັບ" ເຖິງ 38.
ເຫັນບໍ? ບໍ່ຍາກເກີນໄປ!
ນີ້ແມ່ນພື້ນຖານຂອງ Lisp. Lisp ຫຍໍ້ມາຈາກ "ການປຸງແຕ່ງບັນຊີລາຍຊື່"; ນີ້ຫມາຍຄວາມວ່າ
ໂຄງປະກອບການຂອງໂຄງການແມ່ນຕົວຈິງແລ້ວບັນຊີລາຍຊື່ຂອງບັນຊີລາຍຊື່. (ຖ້າທ່ານຄຸ້ນເຄີຍກັບ Python
ບັນຊີລາຍຊື່, ຈິນຕະນາການໂຄງສ້າງດຽວກັນທັງຫມົດຂ້າງເທິງແຕ່ມີວົງເລັບສີ່ຫລ່ຽມແທນ, ໃດ
ທ່ານຈະສາມາດເບິ່ງໂຄງສ້າງຂ້າງເທິງນີ້ເປັນທັງໂຄງການແລະໂຄງສ້າງຂໍ້ມູນ.) ນີ້ແມ່ນ
ເຂົ້າໃຈງ່າຍຂຶ້ນໂດຍມີຕົວຢ່າງຫຼາຍ, ສະນັ້ນໃຫ້ເຮົາຂຽນໂຄງການ Python ງ່າຍດາຍ, ທົດສອບມັນ,
ແລະຫຼັງຈາກນັ້ນສະແດງໃຫ້ເຫັນໂຄງການ Hy ທຽບເທົ່າ:
def simple_conversation():
ພິມ "ສະບາຍດີ! ຂ້ອຍຢາກຮູ້ຈັກເຈົ້າ. ບອກຂ້ອຍກ່ຽວກັບຕົວເອງ!"
name = raw_input("ເຈົ້າຊື່ຫຍັງ?")
age = raw_input("ອາຍຸຂອງເຈົ້າແມ່ນຫຍັງ?")
ພິມ "ສະບາຍດີ" +ຊື່ + "! ຂ້ອຍເຫັນເຈົ້າ " + ອາຍຸ + "ປີ."
simple_conversation()
ຖ້າພວກເຮົາດໍາເນີນການໂຄງການນີ້, ມັນອາດຈະເປັນຄື:
ສະບາຍດີ! ຂ້ອຍຢາກຮູ້ຈັກເຈົ້າ. ບອກຂ້ອຍກ່ຽວກັບຕົວທ່ານເອງ!
ເຈົ້າຊື່ຫຍັງ? ແກຣີ
ອາຍຸຂອງເຈົ້າແມ່ນຫຍັງ? 38
ສະບາຍດີ Gary! ຂ້ອຍເຫັນເຈົ້າອາຍຸ 38 ປີ.
ຕອນນີ້ໃຫ້ເບິ່ງໂຄງການ Hy ທຽບເທົ່າ:
(defn ການສົນທະນາແບບງ່າຍດາຍ []
(ພິມ "ສະບາຍດີ! ຂ້ອຍຢາກຮູ້ຈັກເຈົ້າ. ບອກຂ້ອຍກ່ຽວກັບຕົວເອງ!")
(ຊື່ setv (ການປ້ອນຂໍ້ມູນດິບ "ຊື່ຂອງເຈົ້າແມ່ນຫຍັງ?"))
(setv age (ການປ້ອນຂໍ້ມູນດິບ "ອາຍຸຂອງເຈົ້າແມ່ນຫຍັງ?"))
(ພິມ (+ "ສະບາຍດີ" ຊື່ "! ຂ້ອຍເຫັນເຈົ້າເປັນ"
ອາຍຸ "ປີ.")))
(ການສົນທະນາງ່າຍດາຍ)
ຖ້າທ່ານເບິ່ງໂຄງການຂ້າງເທິງ, ຕາບໃດທີ່ທ່ານຈື່ຈໍາວ່າອົງປະກອບທໍາອິດໃນແຕ່ລະ
ບັນຊີລາຍຊື່ຂອງໂຄງການແມ່ນຫນ້າທີ່ (ຫຼືມະຫາພາກ ... ພວກເຮົາຈະໄປຫາຜູ້ທີ່ຕໍ່ມາ) ຖືກເອີ້ນ
ແລະສ່ວນທີ່ເຫຼືອແມ່ນການໂຕ້ຖຽງ, ມັນງ່າຍທີ່ຈະຄິດອອກວ່າທັງຫມົດນີ້ຫມາຍຄວາມວ່າແນວໃດ.
(ດັ່ງທີ່ເຈົ້າອາດຈະຄາດເດົາຄືກັນ, defn ແມ່ນວິທີການ Hy ຂອງການກໍານົດວິທີການ.)
ຢ່າງໃດກໍຕາມ, ຫຼາຍໆຄົນພົບວ່າມັນສັບສົນໃນຕອນທໍາອິດເພາະວ່າມີວົງເລັບຫຼາຍ,
ແຕ່ມີຫຼາຍຢ່າງທີ່ສາມາດຊ່ວຍເຮັດໃຫ້ມັນງ່າຍຂຶ້ນ: ຮັກສາການຫຍໍ້ໜ້າໃຫ້ງາມ ແລະ
ໃຊ້ຕົວແກ້ໄຂທີ່ມີການຈັບຄູ່ວົງເລັບ (ນີ້ຈະຊ່ວຍໃຫ້ທ່ານຊອກຫາສິ່ງທີ່ແຕ່ລະຄົນ
ວົງເລັບຄູ່ກັບ) ແລະສິ່ງຕ່າງໆຈະເລີ່ມມີຄວາມຮູ້ສຶກສະດວກສະບາຍ.
ມີບາງຂໍ້ໄດ້ປຽບທີ່ຈະມີໂຄງສ້າງລະຫັດທີ່ຕົວຈິງແລ້ວເປັນຂໍ້ມູນງ່າຍດາຍຫຼາຍ
ໂຄງສ້າງຫຼັກຂອງ Lisp ແມ່ນອີງໃສ່. ສໍາລັບສິ່ງຫນຶ່ງ, ມັນຫມາຍຄວາມວ່າໂຄງການຂອງທ່ານແມ່ນ
ງ່າຍທີ່ຈະ parse ແລະວ່າໂຄງປະກອບການຕົວຈິງທັງຫມົດຂອງໂຄງການແມ່ນໄດ້ຮັບການເປີດເຜີຍຫຼາຍຢ່າງຈະແຈ້ງ
ໃຫ້ເຈົ້າ. (ມີຂັ້ນຕອນເພີ່ມເຕີມໃນ hy ບ່ອນທີ່ໂຄງສ້າງທີ່ທ່ານເຫັນຖືກປ່ຽນເປັນ Python's
ການເປັນຕົວແທນຂອງຕົນເອງ ... ໃນ "ບໍລິສຸດ" Lisps ເຊັ່ນ Common Lisp ຫຼື Emacs Lisp, ຂໍ້ມູນ
ໂຄງສ້າງທີ່ທ່ານເຫັນຢູ່ໃນລະຫັດແລະໂຄງສ້າງຂໍ້ມູນທີ່ຖືກປະຕິບັດແມ່ນມີຫຼາຍ
ໃກ້ຕົວ.)
ຄວາມຫມາຍອື່ນຂອງນີ້ແມ່ນ macros: ຖ້າໂຄງສ້າງຂອງໂປລແກລມເປັນຂໍ້ມູນງ່າຍໆ
ໂຄງສ້າງ, ນັ້ນຫມາຍຄວາມວ່າທ່ານສາມາດຂຽນລະຫັດທີ່ສາມາດຂຽນລະຫັດໄດ້ງ່າຍ, ຫມາຍຄວາມວ່າ
ການປະຕິບັດລັກສະນະພາສາໃຫມ່ທັງຫມົດສາມາດໄວຫຼາຍ. ກ່ອນໜ້ານີ້ Hy, ນີ້ບໍ່ແມ່ນ
ເປັນໄປໄດ້ຫຼາຍສໍາລັບນັກຂຽນໂປລແກລມ Python ... ດຽວນີ້ເຈົ້າຍັງສາມາດໃຊ້ macros ໄດ້ຢ່າງບໍ່ໜ້າເຊື່ອ
ພະລັງງານ (ພຽງແຕ່ລະມັດລະວັງເພື່ອບໍ່ໃຫ້ເຂົາເຈົ້າແນໃສ່ຕີນ)!
Hy is a ມີລົດຊາດ lisp Python
Hy ປ່ຽນເປັນຕົ້ນໄມ້ syntax ທີ່ບໍ່ມີຕົວຕົນຂອງ Python, ສະນັ້ນໃນໄວໆນີ້ທ່ານຈະເລີ່ມຊອກຫາສິ່ງນັ້ນ
ພະລັງງານທີ່ຄຸ້ນເຄີຍຂອງ python ແມ່ນຢູ່ໃນປາຍນິ້ວມືຂອງທ່ານ.
ທ່ານມີການເຂົ້າເຖິງປະເພດຂໍ້ມູນຂອງ Python ແລະຫ້ອງສະຫມຸດມາດຕະຖານໃນ Hy. ໃຫ້ທົດລອງ
ກັບເລື່ອງນີ້ຢູ່ໃນນາຍພາສາຂອງລາວ:
=> [1 2 3]
[1, 2, 3]
=> {"ຫມາ" "ເປືອກ"
... "ແມວ" "ເມວ"}
...
{'dog': 'ເປືອກ', 'ແມວ': 'meow'}
=> ( , 1 2 3 )
(1, 2, 3)
ຖ້າທ່ານຄຸ້ນເຄີຍກັບ Lisps ອື່ນໆ, ທ່ານອາດຈະສົນໃຈວ່າ Hy ສະຫນັບສະຫນູນ Common
Lisp ວິທີການອ້າງອີງ:
=> '(1 2 3)
(1L 2L 3L)
ທ່ານຍັງມີການເຂົ້າເຖິງທຸກປະເພດທີ່ມີຢູ່' ວິທີການທີ່ດີ:
=> (.strip "fooooo")
"ຟູ້"
ນີ້ແມ່ນຫຍັງ? ແທ້ຈິງແລ້ວ, ນີ້ແມ່ນຄືກັນກັບ:
"fooooo ".strip()
ຖືກຕ້ອງ---Lisp ກັບ notation dot! ຖ້າຫາກວ່າພວກເຮົາມີສະຕຣິງນີ້ກໍານົດເປັນຕົວປ່ຽນແປງ, ພວກເຮົາ
ຍັງສາມາດເຮັດໄດ້ດັ່ງຕໍ່ໄປນີ້:
(setv this-string "fooooo")
(this-string.strip)
ຈະເປັນແນວໃດກ່ຽວກັບເງື່ອນໄຂ?:
(ຖ້າ (ພະຍາຍາມບາງອັນ)
(ພິມ "ນີ້ແມ່ນຖ້າເປັນຈິງ")
(ພິມ "ນີ້ແມ່ນຖ້າບໍ່ຖືກຕ້ອງ"))
ດັ່ງທີ່ທ່ານສາມາດບອກຂ້າງເທິງ, ການໂຕ້ຖຽງທໍາອິດທີ່ຈະ if ແມ່ນການທົດສອບຄວາມຈິງ, ການໂຕ້ຖຽງທີສອງແມ່ນ
ຮ່າງກາຍຖ້າເປັນຄວາມຈິງ, ແລະການໂຕ້ຖຽງທີສາມ (ທາງເລືອກ!) ແມ່ນຖ້າບໍ່ຖືກຕ້ອງ (ie. ອື່ນ).
ຖ້າທ່ານຕ້ອງການເຮັດເງື່ອນໄຂທີ່ສັບສົນຫຼາຍ, ທ່ານຈະພົບວ່າທ່ານບໍ່ມີ ເອລີຟ
ມີຢູ່ໃນ Hy. ແທນທີ່ຈະ, ທ່ານຄວນໃຊ້ບາງສິ່ງບາງຢ່າງທີ່ເອີ້ນວ່າ ຂົ້ນ. ໃນ Python, ເຈົ້າອາດຈະເຮັດ
ບາງສິ່ງບາງຢ່າງເຊັ່ນ:
somevar = 33
ຖ້າ somevar > 50:
ພິມ "ຕົວແປນັ້ນໃຫຍ່ເກີນໄປ!"
elif somevar < 10:
ພິມ "ຕົວແປນັ້ນນ້ອຍເກີນໄປ!"
ອື່ນ:
ພິມ "ຕົວແປນັ້ນແມ່ນຖືກຕ້ອງ!"
ໃນ Hy, ເຈົ້າຈະເຮັດ:
(ຂໍ້
[(> somevar 50)
(ພິມ "ຕົວແປນັ້ນໃຫຍ່ເກີນໄປ!")]
[(< somevar 10)
(ພິມ "ຕົວແປນັ້ນນ້ອຍເກີນໄປ!")]
[ຈິງ
(ພິມ "ຕົວແປນັ້ນແມ່ນຖືກຕ້ອງ!")])
ສິ່ງທີ່ທ່ານຈະສັງເກດເຫັນແມ່ນວ່າ ຂົ້ນ ປິດລະຫວ່າງຄໍາຖະແຫຼງທີ່ດໍາເນີນການແລະ
ກວດສອບເງື່ອນໄຂສໍາລັບຄວາມຈິງຫຼືຜິດ, ແລະຫຼັງຈາກນັ້ນເລັກນ້ອຍຂອງລະຫັດທີ່ຈະປະຕິບັດຖ້າຫາກວ່າມັນ turns
ອອກໄປເປັນຄວາມຈິງ. ທ່ານຍັງຈະສັງເກດເຫັນວ່າ ອື່ນ ຖືກປະຕິບັດໃນຕອນທ້າຍຂອງພຽງແຕ່ໂດຍ
ການກວດສອບ ທີ່ແທ້ຈິງ -- ນັ້ນແມ່ນຍ້ອນວ່າ ທີ່ແທ້ຈິງ ຈະເປັນຄວາມຈິງສະເຫມີໄປ, ສະນັ້ນຖ້າຫາກວ່າພວກເຮົາໄດ້ໄປໄກນີ້, ພວກເຮົາຈະ
ແລ່ນອັນນັ້ນສະເໝີ!
ເຈົ້າອາດຈະສັງເກດເຫັນຂ້າງເທິງວ່າຖ້າທ່ານມີລະຫັດເຊັ່ນ:
(ຖ້າຫາກວ່າບາງເງື່ອນໄຂ
(ຮ່າງກາຍ-ຖ້າ-ຈິງ)
(ຮ່າງກາຍ-ຖ້າ-ຜິດ))
ແຕ່ລໍຖ້າ! ຈະເປັນແນວໃດຖ້າຫາກວ່າທ່ານຕ້ອງການທີ່ຈະປະຕິບັດຫຼາຍກ່ວາຫນຶ່ງຄໍາຖະແຫຼງທີ່ຢູ່ໃນຮ່າງກາຍຂອງຫນຶ່ງຂອງ
ເຫຼົ່ານີ້?
ທ່ານສາມາດເຮັດໄດ້ດັ່ງຕໍ່ໄປນີ້:
(ຖ້າ (ພະຍາຍາມບາງອັນ)
(ເຮັດ
(ພິມ "ນີ້ແມ່ນຖ້າເປັນຈິງ")
(ພິມ "ແລະເປັນຫຍັງບໍ່, ໃຫ້ເວົ້າຕໍ່ໄປວ່າມັນເປັນຄວາມຈິງແນວໃດ!))
(ພິມ "ອັນນີ້ຍັງພຽງແຕ່ປອມ"))
ເຈົ້າສາມາດເຫັນໄດ້ວ່າພວກເຮົາໃຊ້ do ເພື່ອຫໍ່ຫຼາຍຄໍາຖະແຫຼງການ. ຖ້າເຈົ້າຄຸ້ນເຄີຍກັບຄົນອື່ນ
Lisps, ນີ້ແມ່ນທຽບເທົ່າຂອງ ຄາດ ຢູ່ບ່ອນອື່ນ.
ຄຳເຫັນເລີ່ມຕົ້ນດ້ວຍເຄື່ອງໝາຍຈຸດ:
(ພິມ "ນີ້ຈະດໍາເນີນການ")
; (ພິມ "ແຕ່ນີ້ຈະບໍ່")
(+ 1 2 3); ພວກເຮົາຈະດໍາເນີນການເພີ່ມ, ແຕ່ບໍ່ແມ່ນຄໍາເຫັນນີ້!
Looping ບໍ່ຍາກແຕ່ມີປະເພດຂອງໂຄງສ້າງພິເສດ. ໃນ Python, ພວກເຮົາອາດຈະເຮັດ:
ສໍາລັບຂ້ອຍໃນ ລະດັບ(10):
ພິມ "'i' ຕອນນີ້ຢູ່ທີ່ " + str(i)
ທຽບເທົ່າໃນ Hy ຈະເປັນ:
(ສຳລັບ [i (ຊ່ວງ 10)]
(ພິມ (+ "'i' ຕອນນີ້ຢູ່ທີ່ " (str i))))
ນອກນັ້ນທ່ານຍັງສາມາດນໍາເຂົ້າແລະນໍາໃຊ້ຫ້ອງສະຫມຸດ Python ຕ່າງໆ. ຍົກຕົວຢ່າງ:
(ການນໍາເຂົ້າ os)
(ຖ້າ (os.path.isdir "/tmp/somedir")
(os.mkdir "/tmp/somedir/anotherdir")
(ພິມ "Hey, ເສັ້ນທາງນັ້ນບໍ່ມີ!"))
ຜູ້ຈັດການບໍລິບົດຂອງ Python (ກັບ ຖະແຫຼງການ) ຖືກນໍາໃຊ້ເຊັ່ນນີ້:
(ກັບ [[f (ເປີດ "/tmp/data.in")]]
(ພິມ (. ອ່ານ f)))
ເຊິ່ງເທົ່າກັບ:
ດ້ວຍ open("/tmp/data.in") ເປັນ f:
ພິມ f.read()
ແລະແມ່ນແລ້ວ, ພວກເຮົາມີລາຍຊື່ຄວາມເຂົ້າໃຈ! ໃນ Python ເຈົ້າອາດຈະເຮັດ:
odds_squared = [
pow(ຕົວເລກ, 2)
ສໍາລັບຕົວເລກໃນ ລະດັບ(100)
ຖ້າຕົວເລກ %2 == 1]
ໃນ Hy, ທ່ານສາມາດເຮັດສິ່ງເຫຼົ່ານີ້ເຊັ່ນ:
(setv odds-squared
(list-comp
(ເລກ 2)
(ຕົວເລກ (ໄລຍະ 100))
(= (% ເລກ 2) 1)))
; ແລະ, ຕົວຢ່າງທີ່ຖືກລັກຢ່າງບໍ່ມີຄວາມອັບອາຍຈາກຫນ້າ Clojure:
; ໃຫ້ບອກລາຍຊື່ທ່ອນໄມ້ທັງໝົດຂອງກະດານໝາກຮຸກ:
(list-comp
(, xy)
(x (ໄລຍະ 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, 'F'), (1. , 'G'), (XNUMX, 'H'),
; (2, 'A'), (2, 'B'), (2, 'C'), (2, 'D'), (2, 'E'), (2, 'F'), (2, 'F'), (2. , 'G'), (XNUMX, 'H'),
; (3, 'A'), (3, 'B'), (3, 'C'), (3, 'D'), (3, 'E'), (3, 'F'), (3, 'F'), (3. , 'G'), (XNUMX, 'H'),
; (4, 'A'), (4, 'B'), (4, 'C'), (4, 'D'), (4, 'E'), (4, 'F'), (4, 'F'), (4. , 'G'), (XNUMX, 'H'),
; (5, 'A'), (5, 'B'), (5, 'C'), (5, 'D'), (5, 'E'), (5, 'F'), (5, 'F'), (5. , 'G'), (XNUMX, 'H'),
; (6, 'A'), (6, 'B'), (6, 'C'), (6, 'D'), (6, 'E'), (6, 'F'), (6, 'F'), (6. , 'G'), (XNUMX, 'H'),
; (7, 'A'), (7, 'B'), (7, 'C'), (7, 'D'), (7, 'E'), (7, 'F'), (7, 'F'), (7. , 'G'), (XNUMX, 'H')]
Python ມີການສະຫນັບສະຫນູນສໍາລັບການໂຕ້ຖຽງ fancy ຕ່າງໆແລະການໂຕ້ຖຽງຄໍາຫລັກ. ໃນ Python ພວກເຮົາອາດຈະ
ເບິ່ງ:
>>> def optional_arg(pos1, pos2, keyword1=None, keyword2=42):
... ກັບຄືນ [pos1, pos2, keyword1, keyword2]
...
>>> optional_arg(1, 2)
[1, 2, ບໍ່ມີ, 42]
>>> optional_arg(1, 2, 3, 4)
[1, 2, 3, 4]
>>> optional_arg(keyword1=1, pos2=2, pos1=3, keyword2=4)
[3, 2, 1, 4]
ສິ່ງດຽວກັນໃນ Hy:
=> (defn optional-arg [pos1 pos2 &optional keyword1 [keyword2 42]]
... [pos1 pos2 keyword1 keyword2])
=> (ທາງເລືອກ-arg 1 2)
[1 2 ບໍ່ມີ 42]
=> (ທາງເລືອກ-arg 1 2 3 4)
[1 2 3 4]
ຖ້າທ່ານກໍາລັງໃຊ້ເວີຊັນຂອງ Hy past 0.10.1 (ເຊັ່ນ: git master), ມັນກໍ່ມີອັນໃຫມ່ທີ່ສວຍງາມ.
syntax argument ຄໍາສໍາຄັນ:
=> (ທາງເລືອກ-arg :keyword1 1
... :pos2 2
... :pos1 3
... :keyword2 4)
[3, 2, 1, 4]
ຖ້າບໍ່ດັ່ງນັ້ນ, ທ່ານສາມາດນໍາໃຊ້ໄດ້ຕະຫຼອດເວລາ ນໍາໃຊ້. ແຕ່ແມ່ນຫຍັງ ນໍາໃຊ້?
ທ່ານຄຸ້ນເຄີຍກັບການຜ່ານເຂົ້າ *args ແລະ **ກອງ ໃນ Python?:
>>> args = [1 2]
>>> kwargs = {"keyword2": 3
... "keyword1": 4}
>>> optional_arg(*args, **kwargs)
ພວກເຮົາສາມາດແຜ່ພັນນີ້ດ້ວຍ ນໍາໃຊ້:
=> (setv args [1 2])
=> (setv kwargs {"keyword2" 3
... "keyword1" 4})
=> (ນຳໃຊ້ທາງເລືອກ-arg args kwargs)
[1, 2, 4, 3]
ນອກນັ້ນຍັງມີໂຄງສ້າງການໂຕ້ຖຽງຄໍາຫລັກແບບວັດຈະນານຸກົມທີ່ມີລັກສະນະຄ້າຍຄື:
(defn ຮູບແບບອື່ນ [&key {"key1" "val1" "key2" "val2"}]
[key1 key2])
ຄວາມແຕກຕ່າງທີ່ນີ້ແມ່ນຍ້ອນວ່າມັນເປັນວັດຈະນານຸກົມ, ທ່ານບໍ່ສາມາດອີງໃສ່ສະເພາະໃດນຶ່ງ
ຄໍາສັ່ງກັບການໂຕ້ຖຽງ.
Hy ຍັງສະຫນັບສະຫນູນ *args ແລະ **ກອງ. ໃນ Python:
def some_func(foo, bar, *args, **kwargs):
ນໍາເຂົ້າ pprint
pprint.pprint((foo, bar, args, kwargs))
ທຽບເທົ່າ Hy:
(defn some-func [foo bar &rest args &kwargs kwargs]
(ນໍາເຂົ້າ pprint)
(pprint.pprint(, foo bar args kwargs)))
ສຸດທ້າຍ, ແນ່ນອນ, ພວກເຮົາຕ້ອງການຫ້ອງຮຽນ! ໃນ Python, ພວກເຮົາອາດຈະມີຫ້ອງຮຽນເຊັ່ນ:
ຫ້ອງຮຽນ FooBar(ວັດຖຸ):
"" "" ""
ຫ້ອງຮຽນຕົວຢ່າງອື່ນອີກ
"" "" ""
def __init__(ຕົນເອງ, x):
self.x = x
def get_x(ຕົນເອງ):
"" "" ""
ກັບຄືນສໍາເນົາຂອງພວກເຮົາ x
"" "" ""
ກັບຄືນຕົນເອງ.x
ໃນ Hy:
(defclass FooBar [object]
"ຊັ້ນຕົວຢ່າງອີກອັນຫນຶ່ງ"
[[--ໃນມັນ--
(fn [ຕົນເອງ x]
(setv self.xx)
; ໃນປັດຈຸບັນຕ້ອງການສໍາລັບ --init-- ເນື່ອງຈາກວ່າ __init__ ຕ້ອງການບໍ່ມີ
; ຫວັງວ່າມັນຈະຫາຍໄປ :)
ບໍ່ມີ)]
[ໄດ້-x
(fn [ຕົນເອງ]
"ສົ່ງຄືນສໍາເນົາ x ຂອງພວກເຮົາ"
self.x)]])
ທ່ານຍັງສາມາດເຮັດຄຸນລັກສະນະລະດັບຊັ້ນຮຽນໄດ້. ໃນ Python:
ລູກຄ້າຊັ້ນຮຽນ (model.Model):
name=models.CharField(max_length=255)
ທີ່ຢູ່ =models.TextField()
note=models.TextField()
ໃນ Hy:
(defclass ລູກຄ້າ [model.Model]
[[ຊື່ (ໂມເດວ.CharField :max-length 255})]
[ທີ່ຢູ່ (models.TextField)]
[ບັນທຶກ (model.TextField)]])
Hy <-> Python interop
ໂດຍການນໍາເຂົ້າ Hy, ທ່ານສາມາດນໍາໃຊ້ Hy ໂດຍກົງຈາກ Python!
ຖ້າທ່ານບັນທຶກຕໍ່ໄປນີ້ໃນ ທັກທາຍ.hy:
(defn ທັກທາຍ [ຊື່] (ພິມ "ສະບາຍດີຈາກ hy," ຊື່))
ຫຼັງຈາກນັ້ນ, ທ່ານສາມາດນໍາໃຊ້ມັນໄດ້ໂດຍກົງຈາກ python, ໂດຍການນໍາເຂົ້າ hy ກ່ອນທີ່ຈະນໍາເຂົ້າໂມດູນ. ໃນ
python:
ນໍາເຂົ້າ hy
ນໍາເຂົ້າຄໍາຊົມເຊີຍ
greetings.greet("Foo")
ທ່ານຍັງສາມາດປະກາດຟັງຊັນໃນ python (ຫຼືແມ້ກະທັ້ງ class!) ແລະໃຊ້ມັນໃນ Hy!
ຖ້າທ່ານບັນທຶກຕໍ່ໄປນີ້ໃນ ທັກທາຍ.py ໃນ Python:
def ທັກທາຍ(ຊື່):
ພິມ("ສະບາຍດີ, %s" % (ຊື່))
ທ່ານສາມາດນໍາໃຊ້ມັນໃນ Hy:
(ການນໍາເຂົ້າຊົມເຊີຍ)
(.ທັກທາຍທັກທາຍ "foo")
ເພື່ອໃຊ້ການໂຕ້ຖຽງຄໍາຫລັກ, ທ່ານສາມາດນໍາໃຊ້ໃນ ທັກທາຍ.py:
def ທັກທາຍ(ຊື່, title="Sir"):
print("ສະບາຍດີ, %s %s" % (ຊື່,ຊື່))
(ການນໍາເຂົ້າຊົມເຊີຍ)
(.ທັກທາຍທັກທາຍ "Foo")
(.ທັກທາຍ "Foo" "Darth")
(apply (. greetings greet) ["Foo"] {"title" "ພຣະຜູ້ເປັນເຈົ້າ"})
ຊຶ່ງຈະອອກ:
ຊົມເຊີຍ, ທ່ານ Foo
ຊົມເຊີຍ, Darth Foo
ຊົມເຊີຍ, ພຣະຜູ້ເປັນເຈົ້າ Foo
ເຄັດລັບ!
Hy ຍັງມີບາງອັນທີ່ເອີ້ນວ່າ "ມະຫາພາກກະທູ້", ເປັນລັກສະນະທີ່ສະອາດແທ້ໆ
Clojure ຂອງ. "ມະຫາພາກກະທູ້" (ຂຽນເປັນ ->) ຖືກນໍາໃຊ້ເພື່ອຫຼີກເວັ້ນການຮັງເລິກຂອງ
ສຳ ນວນ.
macro threading ແຊກແຕ່ລະ expression ເຂົ້າໄປໃນ argument ທຳອິດຂອງ expression ຕໍ່ໄປ
ສະຖານທີ່.
ເອົາແບບຄລາສສິກ:
(loop (ພິມ (eval (ອ່ານ))))
ແທນທີ່ຈະຂຽນແບບນັ້ນ, ເຮົາສາມາດຂຽນໄດ້ດັ່ງນີ້:
(-> (ອ່ານ) (eval) (ພິມ) (ວົງ))
ໃນປັດຈຸບັນ, ການນໍາໃຊ້ python-sh, ພວກເຮົາສາມາດສະແດງວິທີການ macro threading (ເນື່ອງຈາກວ່າການຕັ້ງຄ່າຂອງ python-sh)
ສາມາດນໍາໃຊ້ຄືກັບທໍ່:
=> (ນໍາເຂົ້າ [sh [cat grep wc]])
=> (-> (cat "/usr/share/dict/words") (grep "-E" "^hy") (wc "-l"))
210
ເຊິ່ງ, ແນ່ນອນ, ຂະຫຍາຍອອກໄປ:
(wc (grep (cat "/usr/share/dict/words") "-E" "^hy") "-l")
ອ່ານໄດ້ຫຼາຍ, ບໍ່ແມ່ນບໍ? ໃຊ້ macro threading!
HY STYLE GUIDE
"ເຈົ້າຮູ້, ລັດຖະມົນຕີ, ຂ້ອຍບໍ່ເຫັນດີກັບ Dumbledore ໃນຫຼາຍໆຂໍ້ ... ແຕ່ທ່ານບໍ່ສາມາດປະຕິເສດລາວ.
ໄດ້ຮູບແບບ…” — Phineas Nigellus Black, Harry Potter ແລະ ໄດ້ ຄໍາສັ່ງ of ໄດ້ Phoenix
ຄູ່ມືແບບ Hyve ຕັ້ງໃຈເປັນກົດລະບຽບພື້ນຖານສໍາລັບ Hyve (ແມ່ນແລ້ວ, ຊຸມຊົນ Hy
prides ຕົວຂອງມັນເອງໃນການເພີ່ມເຕີມ Hy ກັບທຸກສິ່ງທຸກຢ່າງ) ຂຽນລະຫັດ Hy idiomatic. Hy ມາຈາກຫຼາຍ
ຈາກ Clojure & Common Lisp, ໃນຂະນະທີ່ຮັກສາ Python interopability ຢູ່ສະເໝີ.
prelude
ໄດ້ ຕາວ of Hy
ອູມມອນຖາມພະຫົວວ່າ, "ເຈົ້າກຳລັງບັນຍາຍເລື່ອງຫຍັງ?"
"ພຣະນິບພານ Sutra."
"ພຣະນິບພານມີພຣະທັມ XNUMX ອັນ, ບໍ່ແມ່ນບໍ?"
"ມັນມີ."
Ummon ຖາມ, ເອົາຈອກຂຶ້ນ, "ມີຄຸນງາມຄວາມດີຫຼາຍອັນນີ້?"
"ບໍ່ມີເລີຍ," ພຣະສົງກ່າວ.
"ແຕ່ຄົນບູຮານເວົ້າວ່າມັນມີ, ບໍ່ແມ່ນບໍ?" Ummon ກ່າວ.
"ເຈົ້າຄິດແນວໃດກັບສິ່ງທີ່ພວກເຂົາເວົ້າ?"
Ummon ຕີຈອກແລະຖາມວ່າ, "ເຈົ້າເຂົ້າໃຈບໍ?"
“ບໍ່,” ພຣະສົງເວົ້າ.
"ຫຼັງຈາກນັ້ນ," Ummon ເວົ້າວ່າ, "ທ່ານຄວນຈະສືບຕໍ່ການບັນຍາຍຂອງທ່ານກ່ຽວກັບ sutra."
— ມະຫາພາກ (koan).
ຕໍ່ໄປນີ້ສະແດງໃຫ້ເຫັນເຖິງບັນຊີລາຍຊື່ຫຍໍ້ຂອງການຕັດສິນໃຈອອກແບບທີ່ໄດ້ເຂົ້າໄປໃນການສ້າງຂອງ
ຮິ.
· ເບິ່ງຄື Lisp; DTRT ກັບມັນ (ເຊັ່ນ: dashes ຫັນໄປຫາ underscores, earmuffs ຫັນໄປຫາ
all-caps).
·ພວກເຮົາຍັງເປັນ Python. ພາຍໃນສ່ວນໃຫຍ່ແປ 1:1 ເປັນ Python ພາຍໃນ.
· ໃຊ້ Unicode ຢູ່ທົ່ວທຸກແຫ່ງ.
· ແກ້ໄຂການຕັດສິນໃຈທີ່ບໍ່ດີໃນ Python 2 ເມື່ອພວກເຮົາສາມາດເຮັດໄດ້ (ເບິ່ງ true_division).
· ເມື່ອສົງໃສ, ກະລຸນາເລື່ອນໄປທີ່ Python.
· ຖ້າທ່ານຍັງບໍ່ແນ່ໃຈ, ໃຫ້ເລື່ອນໄປທີ່ Clojure.
· ຖ້າເຈົ້າບໍ່ແນ່ໃຈຫຼາຍ, ໃຫ້ເລື່ອນໄປທີ່ Common Lisp.
· ຈົ່ງຈື່ໄວ້ວ່າພວກເຮົາບໍ່ແມ່ນ Clojure. ພວກເຮົາບໍ່ແມ່ນ Lisp ທົ່ວໄປ. ພວກເຮົາແມ່ນ Homoiconic Python, ກັບ
ບິດພິເສດທີ່ເຮັດໃຫ້ຄວາມຮູ້ສຶກ.
Layout & ຫຍໍ້ ໜ້າ
· ຫຼີກເວັ້ນການສະຖານທີ່ຕິດຕາມ. ພວກເຂົາດູດ!
· ການຫຍໍ້ໜ້າຈະເປັນ 2 ຊ່ອງ (ບໍ່ມີແຖບແຂງ), ຍົກເວັ້ນເມື່ອກົງກັບການຫຍໍ້ໜ້າຂອງ
ແຖວທີ່ຜ່ານມາ.
;; ດີ (ແລະມັກ)
(defn fib [n]
(ຖ້າ (<= n 2)
n
(+ (fib (- ນ 1)) (fib (- ນ 2))))))
;; ຍັງບໍ່ເປັນຫຍັງ
(defn fib [n]
(ຖ້າ (<= n 2) n (+ (fib (- n 1))) (fib (- n 2))))))
;; ຍັງບໍ່ເປັນຫຍັງ
(defn fib [n]
(ຖ້າ (<= n 2)
n
(+ (fib (- ນ 1)) (fib (- ນ 2))))))
;; ຂີ້ຄ້ານຂີ້ຄ້ານ
(defn fib [n]
(ຖ້າ (<= n 2)
n ;; ແມ່ນແລ້ວ, ຂ້ອຍມັກການຕີກະແຈຊ່ອງແບບສຸ່ມ
(+ (fib (- ນ 1)) (fib (- ນ 2))))))
· ວົງເລັບຕ້ອງ ບໍ່ເຄີຍ ຖືກປະໄວ້ຢູ່ຄົນດຽວ, ໂສກເສົ້າແລະໂດດດ່ຽວຢູ່ໃນສາຍຂອງຕົນເອງ.
;; ດີ (ແລະມັກ)
(defn fib [n]
(ຖ້າ (<= n 2)
n
(+ (fib (- ນ 1)) (fib (- ນ 2))))))
;; ຂີ້ຄ້ານຂີ້ຄ້ານ
(defn fib [n]
(ຖ້າ (<= n 2)
n
(+ (fib (- ນ 1)) (fib (- ນ 2)))
)
); GAH, ເຜົາມັນດ້ວຍໄຟ
· ຈັດຮຽງຕາມແນວຕັ້ງ ໃຫ້ ຕັນ.
(ໃຫ້ [[foo (bar)]
[qux (baz)]]
(foo qux))
· ຄຳເຫັນໃນແຖວຈະເປັນສອງຊ່ອງຈາກທ້າຍລະຫັດ; ພວກເຂົາເຈົ້າສະເຫມີຕ້ອງມີ
ຊ່ອງຫວ່າງລະຫວ່າງຕົວອັກສອນຄຳເຫັນ ແລະຈຸດເລີ່ມຕົ້ນຂອງຄຳເຫັນ. ນອກຈາກນັ້ນ, ພະຍາຍາມບໍ່
ຄໍາເຫັນທີ່ຈະແຈ້ງ.
;; ດີ
(setv ind (dec x)); ດັດສະນີເລີ່ມຕົ້ນຈາກ 0
;; ສອດຄ່ອງກັບສະໄຕລ໌ ແຕ່ພຽງແຕ່ລະບຸຢ່າງຊັດເຈນ
(setv ind (dec x)); ຕັ້ງດັດຊະນີເປັນ x-1
;; ບໍ່ດີ
(setv ind (dec x));ພິມຄຳສັບເພື່ອຄວາມມ່ວນຊື່ນ
ລະຫັດ ແບບ
· ເປັນສົນທິສັນຍາ, ພະຍາຍາມບໍ່ໃຊ້ def ສໍາລັບສິ່ງອື່ນນອກຈາກຕົວແປທົ່ວໂລກ; ໃຊ້ ຊຸດ
ພາຍໃນຟັງຊັນ, loops, ແລະອື່ນໆ.
;; ດີ (ແລະມັກ)
( def * ຈໍາກັດ * 400000 )
(defn fibs [ab]
(ໃນຂະນະທີ່ເປັນຄວາມຈິງ
(ຜົນຜະລິດ ກ)
(setv (, ab) (, b (+ ab)))))
;; ບໍ່ດີ (ແລະບໍ່ມັກ)
(defn fibs [ab]
(ໃນຂະນະທີ່ເປັນຄວາມຈິງ
(ຜົນຜະລິດ ກ)
(def (, ab) (, b (+ ab)))))
· ຢ່າໃຊ້ syntax s-expression ບ່ອນທີ່ syntax vector ແມ່ນມີຈຸດປະສົງ. ສໍາລັບຕົວຢ່າງ, ຄວາມຈິງ
ວ່າອະດີດຂອງສອງຕົວຢ່າງນີ້ເຮັດວຽກພຽງແຕ່ຍ້ອນວ່າ compiler ບໍ່ພຽງແຕ່ເກີນໄປ
ເຄັ່ງຄັດ. ໃນຄວາມເປັນຈິງ, syntax ທີ່ຖືກຕ້ອງໃນສະຖານທີ່ເຊັ່ນນີ້ແມ່ນອັນສຸດທ້າຍ.
;; ບໍ່ດີ (ແລະຊົ່ວ)
(defn foo (x) (ພິມ x))
(foo 1)
;; ດີ (ແລະມັກ)
(defn foo [x] (ພິມ x))
(foo 1)
· ນຳໃຊ້ macro threading ຫຼື threading tail macro ເມື່ອພົບກັບການຝັງເລິກ
s-ສະແດງອອກ. ຢ່າງໃດກໍຕາມ, ມີຄວາມຍຸຕິທໍາໃນເວລາທີ່ນໍາໃຊ້ພວກມັນ. ໃຊ້ພວກມັນໃນເວລາທີ່ຄວາມຊັດເຈນແລະ
readability ປັບປຸງ; ບໍ່ສ້າງ convoluted, ຍາກທີ່ຈະເຂົ້າໃຈສໍານວນ.
;; ຕ້ອງການ
( def * ຊື່ *
(ກັບ [f (ເປີດ "names.txt")]
(-> (.read f) (.strip) (.replace "\"" "") (.split ",") (ຈັດຮຽງ))))
;; ບໍ່ດີປານໃດ
( def * ຊື່ *
(ກັບ [f (ເປີດ "names.txt")]
(ຈັດຮຽງ (.split "," (. ແທນທີ່ "\"" "" (.strip (.read f)))))))
;; ອາດຈະບໍ່ເປັນຄວາມຄິດທີ່ດີ
( defn square? [x]
(->> 2 (pow (int (sqrt x))) (= x)))
· ການໝາຍຈຸດແບບ Clojure ແມ່ນມັກຫຼາຍກວ່າການເອີ້ນໂດຍກົງຂອງວິທີການຂອງວັດຖຸ,
ເຖິງແມ່ນວ່າທັງສອງຈະສືບຕໍ່ໄດ້ຮັບການສະຫນັບສະຫນູນ.
;; ດີ
(ກັບ [fd (ເປີດ "/ etc / passwd")]
(ພິມ (.readlines fd)))
;; ບໍ່ດີປານໃດ
(ກັບ [fd (ເປີດ "/ etc / passwd")]
(ພິມ (fd.readlines)))
ສະຫຼຸບ
“ແຟຊັນຈະຫາຍໄປ, ແບບເປັນນິລັນດອນ”—Yves Saint Laurent
ຄູ່ມືນີ້ແມ່ນພຽງແຕ່ຊຸດຄໍາແນະນໍາຂອງຊຸມຊົນ, ແລະແນ່ນອນ, ຄໍາແນະນໍາຂອງຊຸມຊົນເຮັດ
ບໍ່ມີຄວາມຫມາຍໂດຍບໍ່ມີຊຸມຊົນທີ່ມີການເຄື່ອນໄຫວ. ການປະກອບສ່ວນແມ່ນຍິນດີຕ້ອນຮັບ. ເຂົ້າຮ່ວມກັບພວກເຮົາທີ່ #hy in
freenode, blog ກ່ຽວກັບມັນ, tweet ກ່ຽວກັບມັນ, ແລະສໍາຄັນທີ່ສຸດ, ມີຄວາມມ່ວນກັບ Hy.
ຂໍຂອບໃຈ
· ຄູ່ມືນີ້ໄດ້ຮັບການດົນໃຈຫຼາຍຈາກ @paultag ຕອບ blog ຂອງ Hy ການຢູ່ລອດ ຄູ່ມື
·ທ Clojure ແບບ ຄູ່ມື
ເອກະສານອ້າງອີງ INDEX
ເນື້ອໃນ:
ຄໍາສັ່ງ ອອນໄລນ໌ ການໂຕ້ຕອບ
hy
ຄໍາສັ່ງ ອອນໄລນ໌ ທາງເລືອກໃນການ
-c
ປະຕິບັດລະຫັດ Hy ໃນ ຄໍາສັ່ງ.
$ hy -c "(ພິມ (+ 2 2))"
4
-i
ປະຕິບັດລະຫັດ Hy ໃນ ຄໍາສັ່ງ, ຫຼັງຈາກນັ້ນຢູ່ໃນ REPL.
-m
ປະຕິບັດລະຫັດ Hy ໃນ ໂມດູນ, ລວມທັງ defmain ຖ້າກໍານົດ.
ໄດ້ -m ທຸງຢຸດລາຍການທາງເລືອກເພື່ອໃຫ້ການໂຕ້ຖຽງທັງຫມົດຫຼັງຈາກ ໂມດູນ ຊື່
ຖືກສົ່ງກັບໂມດູນໃນ sys.argv.
ໃໝ່ໃນເວີຊັ່ນ 0.10.2.
--Spy ພິມລະຫັດ Python ທຽບເທົ່າກ່ອນທີ່ຈະດໍາເນີນການ. ຍົກຕົວຢ່າງ:
=> (defn salutationsnm [ຊື່] (ພິມ (+ "Hy "ຊື່ "!")))
def salutationsnm(ຊື່):
ພິມຄືນ (((u'Hy ' + ຊື່) + u'!'))
=> (ຄໍາຊົມເຊີຍ "ຊື່ຂອງເຈົ້າ")
ຄຳຊົມເຊີຍnm(u'ຊື່ຂອງເຈົ້າ')
ຊື່ຂອງເຈົ້າ!
=>
ໃໝ່ໃນເວີຊັ່ນ 0.9.11.
--show-tracebacks
ພິມ tracebacks ຂະຫຍາຍສໍາລັບການຍົກເວັ້ນ Hy.
ໃໝ່ໃນເວີຊັ່ນ 0.9.12.
-v ພິມໝາຍເລກລຸ້ນ Hy ແລະອອກ.
hyc
ຄໍາສັ່ງ ອອນໄລນ໌ ທາງເລືອກໃນການ
ໄຟລ໌[, fileN]
ລວບລວມລະຫັດ Hy ກັບ Python bytecode. ຕົວຢ່າງ, ບັນທຶກລະຫັດຕໍ່ໄປນີ້ເປັນ
hyname.hy:
(defn hy-hy [ຊື່]
(ພິມ (+ "Hy "ຊື່ "!")))
(hy-hy "Afroman")
ຈາກນັ້ນແລ່ນ:
$ hyc hyname.hy
$ python hyname.pyc
ອີ່ອາໂຟຣແມນ!
hy2py
ໃໝ່ໃນເວີຊັ່ນ 0.10.1.
ຄໍາສັ່ງ ອອນໄລນ໌ ທາງເລືອກໃນການ
-s
--with-source
ສະແດງໂຄງສ້າງແຫຼ່ງທີ່ວິເຄາະແລ້ວ.
-a
--with-ast
ສະແດງ AST ທີ່ສ້າງຂຶ້ນ.
-e.g
-- ໂດຍບໍ່ມີການ python
ຢ່າສະແດງລະຫັດ Python ທີ່ສ້າງຂຶ້ນຈາກ AST.
Hy (ໄດ້ ພາສາ)
ຄໍາເຕືອນ:
ນີ້ແມ່ນບໍ່ຄົບຖ້ວນ; ກະລຸນາພິຈາລະນາປະກອບສ່ວນເຂົ້າໃນຄວາມພະຍາຍາມເອກະສານ.
ທິດສະດີ of Hy
Hy ຮັກສາ, ຫຼາຍກວ່າສິ່ງອື່ນ, ຄວາມເຂົ້າກັນໄດ້ 100% ໃນທັງສອງທິດທາງກັບ Python
ຕົວຂອງມັນເອງ. ລະຫັດ Hy ທັງໝົດປະຕິບັດຕາມກົດລະບຽບງ່າຍໆບໍ່ຫຼາຍປານໃດ. ຈື່ໄວ້, ຍ້ອນວ່າມັນຈະເຂົ້າມາ
ມີປະໂຫຍດ.
ກົດລະບຽບເຫຼົ່ານີ້ຊ່ວຍໃຫ້ແນ່ໃຈວ່າລະຫັດ Hy ແມ່ນ idiomatic ແລະການໂຕ້ຕອບໃນທັງສອງພາສາ.
· ສັນຍາລັກໃນ earmufs ຈະຖືກແປເປັນຕົວພິມໃຫຍ່ຂອງສະຕຣິງນັ້ນ. ສໍາລັບ
ຍົກຕົວຢ່າງ, ຟູ ຈະກາຍເປັນ FOO.
· UTF-8 ຫນ່ວຍງານຈະຖືກເຂົ້າລະຫັດໂດຍໃຊ້ ລະຫັດໂທດ ແລະນຳໜ້າດ້ວຍ hy_. ຕົວຢ່າງ, ⚘
ຈະກາຍເປັນ hy_w7h, ♥ ຈະກາຍເປັນ hy_g6h, ແລະ i♥u ຈະກາຍເປັນ hy_iu_t0x.
· ສັນຍາລັກທີ່ປະກອບດ້ວຍ dashes ຈະໃຫ້ເຂົາເຈົ້າທົດແທນທີ່ມີຂີດກ້ອງ. ຍົກຕົວຢ່າງ,
render-ແມ່ແບບ ຈະກາຍເປັນ render_template. ນີ້ຫມາຍຄວາມວ່າສັນຍາລັກທີ່ມີ dashes ຈະ
shadow ທຽບເທົ່າ underscore ຂອງເຂົາເຈົ້າ, ແລະໃນທາງກັບກັນ.
Built-Ins
Hy ມີລັກສະນະພິເສດຈໍານວນຫນຶ່ງທີ່ຖືກນໍາໃຊ້ເພື່ອຊ່ວຍສ້າງ Python AST ທີ່ຖືກຕ້ອງ.
ຕໍ່ໄປນີ້ແມ່ນຮູບແບບ "ພິເສດ", ເຊິ່ງອາດຈະມີພຶດຕິກໍາທີ່ບໍ່ຄາດຄິດເລັກນ້ອຍໃນ
ບາງສະຖານະການ.
.
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
. ຖືກນໍາໃຊ້ເພື່ອປະຕິບັດການເຂົ້າເຖິງຄຸນລັກສະນະຂອງວັດຖຸ. ມັນໃຊ້ DSL ຂະຫນາດນ້ອຍເພື່ອອະນຸຍາດໃຫ້ໄວ
ການເຂົ້າເຖິງຄຸນສົມບັດ ແລະລາຍການໃນໂຄງສ້າງຂໍ້ມູນທີ່ຕິດກັນ.
ຕົວຢ່າງ,
(. foo bar baz [(+ 1 2)] frob)
ລວບລວມລົງເປັນ:
foo.bar.baz[1+2].frob
. ລວບລວມການໂຕ້ຖຽງທໍາອິດຂອງມັນ (ໃນຕົວຢ່າງ, ຟູ) ເປັນວັດຖຸທີ່ຈະເຮັດໄດ້
ການອ້າງອີງຄຸນສົມບັດ. ມັນໃຊ້ສັນຍາລັກເປົ່າເປັນຄຸນລັກສະນະເພື່ອເຂົ້າເຖິງ (ໃນຕົວຢ່າງ, ພາທະນາຍຄວາມ,
ຖານ, frob), ແລະລວບລວມເນື້ອໃນຂອງລາຍຊື່ (ໃນຕົວຢ່າງ, [(+ 1 2)]) ສໍາລັບການດັດສະນີ.
ການໂຕ້ຖຽງອື່ນຖິ້ມຄວາມຜິດພາດການລວບລວມ.
ການເຂົ້າເຖິງຄຸນລັກສະນະທີ່ບໍ່ຮູ້ຈັກຖິ້ມເປັນ ຄຸນສົມບັດຜິດພາດ. ການເຂົ້າເຖິງກະແຈທີ່ບໍ່ຮູ້ຈັກຖິ້ມເປັນ
ຄວາມຜິດພາດດັດຊະນີ (ໃນລາຍການ ແລະ tuples) ຫຼື ກ ຜິດພາດ (ໃນວັດຈະນານຸກົມ).
->
-> (or the ກະທູ້ ມະຫາພາກ) ຖືກນໍາໃຊ້ເພື່ອຫຼີກເວັ້ນການຮັງຂອງສໍານວນ. ມະຫາພາກກະທູ້
ແຊກແຕ່ລະ expression ເຂົ້າໄປໃນບ່ອນໂຕ້ຖຽງທຳອິດຂອງ expression ຕໍ່ໄປ. ຕໍ່ໄປນີ້
ລະຫັດສະແດງໃຫ້ເຫັນນີ້:
=> (defn output [ab] (ພິມ ab))
=> (-> (+ 4 6) (ຜົນຜະລິດ 5))
10 5
- >>
- >> (or the ກະທູ້ ຫາງ ມະຫາພາກ) ແມ່ນຄ້າຍຄືກັນກັບ ກະທູ້ ມະຫາພາກ, ແຕ່ແທນທີ່ຈະ
ການໃສ່ແຕ່ລະສະແດງອອກເຂົ້າໃນການໂຕ້ຖຽງທໍາອິດຂອງການສະແດງອອກຕໍ່ໄປ, ມັນຕື່ມມັນໃສ່
ການໂຕ້ຖຽງສຸດທ້າຍ. ລະຫັດຕໍ່ໄປນີ້ສະແດງໃຫ້ເຫັນນີ້:
=> (defn output [ab] (ພິມ ab))
=> (->> (+ 4 6) (ຜົນຜະລິດ 5))
5 10
ນໍາໃຊ້
ນໍາໃຊ້ ຖືກນໍາໃຊ້ເພື່ອນໍາໃຊ້ບັນຊີລາຍຊື່ທາງເລືອກຂອງການໂຕ້ຖຽງແລະວັດຈະນານຸກົມທາງເລືອກຂອງ kwargs
ກັບຫນ້າທີ່.
ການນໍາໃຊ້: (ສະຫມັກ fn-ຊື່ [args] [kwargs])
ຕົວຢ່າງ:
( defn thunk []
"ສະບາຍດີ")
(ຂໍຂອບໃຈ)
;=> "ຢູ່ນີ້"
(defn ການຊື້ທັງຫມົດ [ຈໍານວນລາຄາ & ທາງເລືອກ [ຄ່າທໍານຽມ 1.05] [vat 1.1]]
(* ຈຳນວນຄ່າທຳນຽມ vat))
(ນຳໃຊ້ການຊື້ທັງໝົດ [10 15])
;=> 173.25
(ນຳໃຊ້ການຊື້ທັງໝົດ [10 15] {"vat" 1.05})
;=> 165.375
(apply total-purchase [] {"price" 10 "amount" 15 "vat" 1.05})
;=> 165.375
ແລະ
ແລະ ຖືກໃຊ້ໃນການສະແດງອອກຢ່າງມີເຫດຜົນ. ມັນໃຊ້ເວລາຢ່າງຫນ້ອຍສອງຕົວກໍານົດການ. ຖ້າຕົວກໍານົດການທັງຫມົດ
ປະເມີນ ທີ່ແທ້ຈິງ, ພາລາມິເຕີສຸດທ້າຍຖືກສົ່ງຄືນ. ໃນກໍລະນີອື່ນໆ, ຄ່າທີ່ບໍ່ຖືກຕ້ອງທໍາອິດ
ຈະຖືກສົ່ງຄືນ. ຕົວຢ່າງການນໍາໃຊ້:
=> (ແລະ True False)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ແລະ True True)
ທີ່ແທ້ຈິງ
=> (ແລະຄວາມຈິງ 1)
1
=> (ແລະ True [] False True)
[]
ຫມາຍເຫດ:
ແລະ short-circuits ແລະຢຸດເຊົາການປະເມີນຕົວກໍານົດການທັນທີທີ່ທໍາອິດຜິດ
ພົບ.
=> (ແລະຜິດ (ພິມ "ສະບາຍດີ"))
ທີ່ບໍ່ຖືກຕ້ອງ
ຢືນຢັນ
ຢືນຢັນ ຖືກນໍາໃຊ້ເພື່ອກວດສອບເງື່ອນໄຂໃນຂະນະທີ່ໂຄງການກໍາລັງເຮັດວຽກ. ຖ້າເງື່ອນໄຂບໍ່ແມ່ນ
ພົບ, ເປັນ ການຢືນຢັນຜິດພາດ ຖືກຍົກຂຶ້ນມາ. ຢືນຢັນ ອາດຈະໃຊ້ເວລາຫນຶ່ງຫຼືສອງຕົວກໍານົດການ. ທໍາອິດ
ພາລາມິເຕີແມ່ນເງື່ອນໄຂໃນການກວດສອບ, ແລະມັນຄວນຈະປະເມີນ ທີ່ແທ້ຈິງ or ທີ່ບໍ່ຖືກຕ້ອງ. ໄດ້
ພາລາມິເຕີທີສອງ, ທາງເລືອກ, ແມ່ນປ້າຍຊື່ສໍາລັບການຢືນຢັນ, ແລະເປັນສະຕຣິງທີ່ຈະເປັນ
ຍົກຂຶ້ນມາດ້ວຍ ການຢືນຢັນຜິດພາດທີ່ຢູ່ ຍົກຕົວຢ່າງ:
(ຢືນຢັນ (= variable expect-value))
(ຢືນຢັນຜິດ)
; ການຢືນຢັນຜິດພາດ
(ຢືນຢັນ (= 1 2) "ຫນຶ່ງຄວນເທົ່າກັບສອງ")
; ການຢືນຢັນຄວາມຜິດພາດ: ຫນຶ່ງຄວນເທົ່າກັບສອງ
ສະຫາຍດຣ
ສະຫາຍດຣ ຖືກນໍາໃຊ້ເພື່ອເຊື່ອມໂຍງຄີທີ່ມີຄ່າໃນວັດຈະນານຸກົມຫຼືເພື່ອກໍານົດດັດສະນີຂອງບັນຊີລາຍຊື່
ເປັນມູນຄ່າ. ມັນໃຊ້ເວລາຢ່າງຫນ້ອຍສາມຕົວກໍານົດການ: the ຂໍ້ມູນ ໂຄງປະກອບການ ທີ່ຈະໄດ້ຮັບການດັດແກ້, a ທີ່ສໍາຄັນ
or ດັດຊະນີ, ແລະ ມູນຄ່າ. ຖ້າຫຼາຍກວ່າສາມຕົວກໍານົດການຖືກນໍາໃຊ້, ມັນຈະເຊື່ອມໂຍງເປັນຄູ່.
ຕົວຢ່າງຂອງການນໍາໃຊ້:
=>(ໃຫ້ [[ການລວບລວມ {}]]
... (assoc ເກັບ "ຫມາ" "ເປືອກ")
... (ເກັບກໍາຂໍ້ມູນພິມ))
{u'Dog': u'Bark'}
=>(ໃຫ້ [[ການລວບລວມ {}]]
... (assoc ເກັບ "ຫມາ" "ເປືອກ" "ແມວ" "Meow")
... (ເກັບກໍາຂໍ້ມູນພິມ))
{u'Cat': u'Meow', u'Dog': u'Bark'}
=>(ໃຫ້ [[ຄໍເລັກຊັນ [1 2 3 4]]]
... (assoc collection 2 None)
... (ເກັບກໍາຂໍ້ມູນພິມ))
[1, 2, ບໍ່ມີ, 4]
ຫມາຍເຫດ:
ສະຫາຍດຣ ປັບປຸງໂຄງສ້າງຂໍ້ມູນໃນສະຖານທີ່ແລະຜົນຕອບແທນ ບໍ່ມີ.
ພັກຜ່ອນ
ພັກຜ່ອນ ແມ່ນໃຊ້ເພື່ອແຍກອອກຈາກວົງ. ມັນຢຸດ loop ໃນທັນທີ. ຕໍ່ໄປນີ້
ຕົວຢ່າງມີອັນເປັນນິດ ໃນຂະນະທີ່ loop ທີ່ຖືກຢຸດເຊົາທັນທີທີ່ຜູ້ໃຊ້ເຂົ້າມາ k.
(ໃນຂະນະທີ່ True (ຖ້າ (= "k" (raw-input "? "))
(ພັກຜ່ອນ)
(ພິມ "ລອງອີກຄັ້ງ")))
ຂົ້ນ
ຂົ້ນ ສາມາດຖືກນໍາໃຊ້ເພື່ອສ້າງຮັງ if ຖະແຫຼງການ. ຕົວຢ່າງຕໍ່ໄປນີ້ສະແດງໃຫ້ເຫັນເຖິງ
ການພົວພັນລະຫວ່າງມະຫາພາກແລະການຂະຫຍາຍຂອງມັນ:
(cond [ເງື່ອນໄຂ-1 ຜົນໄດ້ຮັບ-1]
[ເງື່ອນໄຂ-2 ຜົນໄດ້ຮັບ-2])
(ຖ້າເງື່ອນໄຂ-1 ຜົນໄດ້ຮັບ-1
(ຖ້າເງື່ອນໄຂ-2 ຜົນໄດ້ຮັບ-2))
ດັ່ງທີ່ສະແດງຢູ່ຂ້າງລຸ່ມນີ້, ມີພຽງແຕ່ການຈັບຄູ່ຜົນໄດ້ຮັບທໍາອິດທີ່ຖືກປະຕິບັດ.
=> (defn check-value [ຄ່າ]
... (cond [(< ຄ່າ 5) (ພິມ "ຄ່ານ້ອຍກວ່າ 5")]
... [(= ຄ່າ 5) (ພິມ "ຄ່າເທົ່າກັບ 5")]
... [(> ຄ່າ 5) (ພິມ "ຄ່າແມ່ນໃຫຍ່ກວ່າ 5")]
... [ຄວາມຈິງ (ພິມ "ຄຸນຄ່າເປັນສິ່ງທີ່ບໍ່ຄວນເປັນ")]))
=> (ເຊັກ-ຄ່າ 6)
ຄ່າແມ່ນໃຫຍ່ກວ່າ 5
ດໍາເນີນການຕໍ່
ດໍາເນີນການຕໍ່ ສົ່ງຄືນການປະຕິບັດໄປຫາຈຸດເລີ່ມຕົ້ນຂອງ loop. ໃນຕົວຢ່າງຕໍ່ໄປນີ້,
(ຜົນຂ້າງຄຽງ 1) ຖືກເອີ້ນໃຫ້ແຕ່ລະຄັ້ງ. (ຜົນຂ້າງຄຽງ 2)ຢ່າງໃດກໍຕາມ, ພຽງແຕ່ເອີ້ນວ່າ
ທຸກໆມູນຄ່າອື່ນໆໃນບັນຊີລາຍຊື່.
;; ສົມມຸດວ່າ (ຜົນຂ້າງຄຽງ 1) ແລະ (ຜົນຂ້າງຄຽງ 2) ແມ່ນຫນ້າທີ່ແລະ
;; ການເກັບກໍາແມ່ນບັນຊີລາຍຊື່ຂອງຄ່າຕົວເລກ
(ສໍາລັບ [x collection]
(ເຮັດ
(ຜົນຂ້າງຄຽງ 1 x)
(ຖ້າ (% x 2)
(ສືບຕໍ່))
(ຜົນຂ້າງຄຽງ 2 x)))
dict-comp
dict-comp ຖືກນໍາໃຊ້ເພື່ອສ້າງວັດຈະນານຸກົມ. ມັນໃຊ້ເວລາສາມຫຼືສີ່ຕົວກໍານົດການ. ທໍາອິດ
ສອງຕົວກໍານົດການແມ່ນສໍາລັບການຄວບຄຸມມູນຄ່າກັບຄືນ (ຄູ່ຄ່າທີ່ສໍາຄັນ) ໃນຂະນະທີ່ທີສາມແມ່ນ
ໃຊ້ເພື່ອເລືອກລາຍການຈາກລໍາດັບ. ຕົວກໍານົດການສີ່ແລະທາງເລືອກສາມາດຖືກນໍາໃຊ້ເພື່ອ
ກັ່ນຕອງບາງລາຍການໃນລໍາດັບໂດຍອີງໃສ່ການສະແດງອອກເງື່ອນໄຂ.
=> (dict-comp x (* x 2) [x (ໄລຍະ 10)] (odd? x))
{1:2, 3:6, 9:18, 5:10, 7:14}.
do / ຄາດ
do ແລະ ຄາດ ຖືກນໍາໃຊ້ເພື່ອປະເມີນແຕ່ລະການໂຕ້ຖຽງຂອງພວກເຂົາແລະກັບຄືນອັນສຸດທ້າຍ. ກັບຄືນ
ຄ່າຈາກທຸກໆອັນທີ່ບໍ່ແມ່ນການໂຕ້ຖຽງສຸດທ້າຍແມ່ນຖືກຍົກເລີກ. ມັນສາມາດຖືກນໍາໃຊ້ໃນ lambda or
list-comp ເພື່ອປະຕິບັດເຫດຜົນທີ່ສັບສົນຫຼາຍດັ່ງທີ່ສະແດງຢູ່ໃນຫນຶ່ງໃນຕົວຢ່າງຕໍ່ໄປນີ້.
ການນໍາໃຊ້ຕົວຢ່າງບາງຢ່າງ:
=> (ຖ້າເປັນຄວາມຈິງ
... (ເຮັດ (ພິມ "ຜົນກະທົບຂ້າງຄຽງ rock!")
... (ພິມ "ແມ່ນແລ້ວ, ແທ້!")))
ຜົນຂ້າງຄຽງ Rock!
ແມ່ນແລ້ວ!
;; ສົມມຸດວ່າ (ຜົນກະທົບຂ້າງຄຽງ) ແມ່ນຫນ້າທີ່ທີ່ພວກເຮົາຕ້ອງການໂທຫາແຕ່ລະຄົນ
;; ແລະທຸກໆມູນຄ່າໃນບັນຊີລາຍຊື່, ແຕ່ມູນຄ່າກັບຄືນມາທີ່ພວກເຮົາບໍ່ສົນໃຈ
=> (list-comp (ເຮັດ (ຜົນຂ້າງຄຽງ x)
... (ຖ້າ (< x 5) (* 2 x) .
... (* 4x)))
... (x (ໄລຍະ 10)))
[0, 2, 4, 6, 8, 20, 24, 28, 32]
do ສາມາດຍອມຮັບຈໍານວນຂອງການໂຕ້ຖຽງ, ຈາກ 1 ຫາ n.
def / ຊຸດ
def ແລະ ຊຸດ ຖືກນໍາໃຊ້ເພື່ອຜູກມັດມູນຄ່າ, ວັດຖຸ, ຫຼືຫນ້າທີ່ເປັນສັນຍາລັກ. ຍົກຕົວຢ່າງ:
=> (ຊື່ define ["Alice" "Bob" "Charlie"])
=> (ພິມຊື່)
[u'Alice', u'Bob', u'Charlie']
=> (setv counter (fn [ລາຍການເກັບ] (.count collection item)))
=> (ເຄົາເຕີ [1 2 3 4 5 2 3] 2)
2
defclass
ຫ້ອງຮຽນໃຫມ່ໄດ້ຖືກປະກາດດ້ວຍ defclass. ມັນສາມາດໃຊ້ເວລາສອງຕົວກໍານົດການທາງເລືອກ: ເປັນ vector
ການກໍານົດຊັ້ນຮຽນສູງສຸດທີ່ເປັນໄປໄດ້ແລະ vector ອື່ນທີ່ມີຄຸນລັກສະນະຂອງໃຫມ່
class ເປັນ vectors ສອງລາຍການ.
(ຊື່ປະເພດ defclass [super-class-1 super-class-2]
[[ຄຸນຄ່າຄຸນສົມບັດ]])
ທັງສອງຄ່າແລະຟັງຊັນສາມາດຖືກຜູກມັດຢູ່ໃນຊັ້ນຮຽນໃຫມ່ດັ່ງທີ່ສະແດງໂດຍຕົວຢ່າງຂ້າງລຸ່ມນີ້:
=> (defclass Cat []
... [[ບໍ່ມີອາຍຸສູງສຸດ]
... [ສີ "ຂາວ"]
... [ເວົ້າ (fn [ຕົນເອງ] (ພິມ "Meow"))]])
=> (ຈຸດປ້ອງກັນ (ແມວ))
=> (setv spot.colour "Black")
'ດຳ'
=> (ຈຸດເວົ້າ)
Meow
defn / defun
defn ແລະ defun macro ຖືກນໍາໃຊ້ເພື່ອກໍານົດຫນ້າທີ່. ພວກເຂົາເຈົ້າໃຊ້ເວລາສາມຕົວກໍານົດການ: ໄດ້ ຊື່
ຂອງຟັງຊັນເພື່ອກໍານົດ, vector ຂອງ ພາລາມິເຕີ, ແລະ ຮ່າງກາຍ ຂອງຫນ້າທີ່:
(ຊື່ defn [params] body)
ພາລາມິເຕີອາດມີຄໍາສໍາຄັນຕໍ່ໄປນີ້ຢູ່ທາງຫນ້າຂອງພວກເຂົາ:
&ທາງເລືອກ
ພາຣາມິເຕີເປັນທາງເລືອກ. ພາລາມິເຕີສາມາດໄດ້ຮັບເປັນສອງລາຍການລາຍການ, ບ່ອນທີ່
ອົງປະກອບທໍາອິດແມ່ນຊື່ພາລາມິເຕີແລະທີສອງແມ່ນຄ່າເລີ່ມຕົ້ນ. ພາລາມິເຕີ
ຍັງສາມາດຖືກມອບໃຫ້ເປັນລາຍການດຽວ, ໃນກໍລະນີນີ້ຄ່າເລີ່ມຕົ້ນແມ່ນ ບໍ່ມີ.
=> (defn total-value [value &optional [value-added-tax 10]]
... (+ (/ (* value-added-tax) 100) value))
=> (ລວມມູນຄ່າ 100)
110.0
=> (ມູນຄ່າລວມ 100 1)
101.0
&ກະແຈ
&kwargs
ພາຣາມິເຕີຈະມີ 0 ຫຼືຫຼາຍກວ່ານັ້ນ arguments.
ຕົວຢ່າງລະຫັດຕໍ່ໄປນີ້ກໍານົດຫນ້າທີ່ທີ່ຈະພິມຄໍາສໍາຄັນທັງຫມົດ
ການໂຕ້ຖຽງແລະຄຸນຄ່າຂອງພວກເຂົາ.
=> (defn print-parameters [&kwargs kwargs]
... (ສໍາລັບ [(, kv) (.items kwargs)] (ພິມ kv)))
=> (ນຳໃຊ້ print-parameters [] {"parameter-1" 1"parameter-2" 2})
ພາຣາມິເຕີ-2 2
ພາຣາມິເຕີ-1 1
&ພັກຜ່ອນ ພາຣາມິເຕີຈະມີ 0 ຫຼືຫຼາຍກວ່ານັ້ນ arguments. ບໍ່ມີຕໍາແຫນ່ງອື່ນ
arguments ອາດຈະຖືກກໍານົດຫຼັງຈາກອັນນີ້.
ຕົວຢ່າງລະຫັດຕໍ່ໄປນີ້ກໍານົດຟັງຊັນທີ່ສາມາດໃຫ້ 0 ຫາ n ຕົວເລກ
ຕົວກໍານົດການ. ຈາກນັ້ນມັນຈຶ່ງລວມເອົາທຸກຕົວເລກຄີກ ແລະ ລົບທຸກໆຕົວເລກຄູ່.
=> (defn zig-zag-sum [&ຕົວເລກສ່ວນທີ່ເຫຼືອ]
(ໃຫ້ [[ odd-numbers (list-comp x [x num] (odd? x))]
[ຕົວເລກຄູ່ (ບັນຊີລາຍຊື່-comp x [x ຕົວເລກ] (ເຖິງ? x))]]
(- (ລວມເລກຄີກ) (ລວມເລກຄູ່))))
=> (zig-zag-sum)
0
=> (zig-zag-sum 3 9 4)
8
=> ( zig-zag-sum 1 2 3 4 5 6 )
-3
defn-alias / defun-alias
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ໄດ້ defn-alias ແລະ defun-alias macro ແມ່ນຄ້າຍຄືຫຼາຍ defn, ມີຄວາມແຕກຕ່າງທີ່
ແທນທີ່ຈະກໍານົດຫນ້າທີ່ທີ່ມີຊື່ດຽວ, ເຫຼົ່ານີ້ຍັງສາມາດກໍານົດນາມແຝງ. ອື່ນໆ
ກ່ວາການເອົາບັນຊີລາຍຊື່ຂອງສັນຍາລັກສໍາລັບຊື່ຫນ້າທີ່ເປັນພາລາມິເຕີທໍາອິດ, defn-alias ແລະ
defun-alias ແມ່ນບໍ່ແຕກຕ່າງຈາກ defn ແລະ defun.
=> (defn-alias [ນາມແຝງຊື່ຫຼັກ] []
... (ພິມ "ສະບາຍດີ!"))
=> (ຊື່ຫຼັກ)
"ສະບາຍດີ!"
=> (ນາມແຝງ)
"ສະບາຍດີ!"
defmain
ໃໝ່ໃນເວີຊັ່ນ 0.10.1.
ໄດ້ defmain macro ກໍານົດຫນ້າທີ່ຕົ້ນຕໍທີ່ຖືກເອີ້ນວ່າທັນທີດ້ວຍ sys.argv as
arguments ຖ້າແລະພຽງແຕ່ຖ້າໄຟລ໌ນີ້ຖືກປະຕິບັດເປັນ script. ໃນຄໍາສັບຕ່າງໆອື່ນໆ, ນີ້:
(defmain [&rest args]
(ເຮັດ-ບາງສິ່ງບາງຢ່າງ-ດ້ວຍການໂຕ້ຖຽງ))
ເທົ່າກັບ:
def main(*args):
do_something_with(args)
ກັບຄືນ 0
ຖ້າ __name__ == "__main__":
sys ນຳ ເຂົ້າ
retval = main(*sys.arg)
ຖ້າ isinstance(retval, int):
sys.exit(retval)
ໃຫ້ສັງເກດວ່າຕາມທີ່ເຈົ້າເຫັນຂ້າງເທິງ, ຖ້າທ່ານສົ່ງຄືນຈໍານວນເຕັມຈາກຟັງຊັນນີ້, ນີ້ຈະເປັນ
ໃຊ້ເປັນສະຖານະການອອກສໍາລັບສະຄິບຂອງທ່ານ. (Python ເລີ່ມຕົ້ນທີ່ຈະອອກຈາກສະຖານະ 0 ຖ້າບໍ່ດັ່ງນັ້ນ,
ຊຶ່ງຫມາຍຄວາມວ່າທຸກຢ່າງບໍ່ເປັນຫຍັງ!)
(ນັບຕັ້ງແຕ່ (sys.exit 0) ບໍ່ໄດ້ດໍາເນີນການຢ່າງຊັດເຈນໃນກໍລະນີຂອງຜົນຕອບແທນທີ່ບໍ່ແມ່ນຈໍານວນເຕັມຈາກ
defmain, ມັນເປັນຄວາມຄິດທີ່ດີທີ່ຈະໃສ່ ( defmain ) ເປັນລະຫັດສຸດທ້າຍໃນໄຟລ໌ຂອງທ່ານ.)
defmacro
defmacro ຖືກນໍາໃຊ້ເພື່ອກໍານົດ macro. ຮູບແບບທົ່ວໄປແມ່ນ (defmacro ຊື່ [ຕົວກໍານົດການ]
expr).
ຕົວຢ່າງຕໍ່ໄປນີ້ກໍານົດມະຫາພາກທີ່ສາມາດໃຊ້ເພື່ອແລກປ່ຽນຄໍາສັ່ງຂອງອົງປະກອບໃນລະຫັດ,
ໃຫ້ຜູ້ໃຊ້ຂຽນລະຫັດໃນ infix notation, ບ່ອນທີ່ operator ແມ່ນຢູ່ໃນລະຫວ່າງ
ໂຕປະຕິບັດການ.
=> (defmacro infix [ລະຫັດ]
... (ອ້າງສິດ (
... (unquote (ຮັບລະຫັດ 1))
... (unquote (ຮັບລະຫັດ 0))
... (unquote (ຮັບລະຫັດ 2)))))
=> (infix (1 + 1))
2
defmacro-alias
defmacro-alias ຖືກນໍາໃຊ້ເພື່ອກໍານົດ macro ທີ່ມີຊື່ຫຼາຍ (aliases). ຮູບແບບທົ່ວໄປ
is (defmacro-alias [ຊື່] [ຕົວກໍານົດການ] expr). ມັນສ້າງ macro ຫຼາຍອັນດຽວກັນ
ບັນຊີລາຍຊື່ພາລາມິເຕີແລະເນື້ອໃນ, ພາຍໃຕ້ບັນຊີລາຍຊື່ທີ່ກໍານົດໄວ້ຂອງຊື່.
ຕົວຢ່າງຕໍ່ໄປນີ້ກໍານົດສອງ macro, ທັງສອງອະນຸຍາດໃຫ້ຜູ້ໃຊ້ຂຽນລະຫັດໃນ
infix notation.
=> (defmacro-alias [infix infi] [ລະຫັດ]
... (ອ້າງສິດ (
... (unquote (ຮັບລະຫັດ 1))
... (unquote (ຮັບລະຫັດ 0))
... (unquote (ຮັບລະຫັດ 2)))))
=> (infix (1 + 1))
2
=> (infi (1 + 1))
2
defmacro/g!
ໃໝ່ໃນເວີຊັ່ນ 0.9.12.
defmacro/g! ເປັນສະບັບພິເສດຂອງ defmacro ທີ່ຖືກນໍາໃຊ້ເພື່ອສ້າງອັດຕະໂນມັດ gensym
ສໍາລັບສັນຍາລັກໃດໆທີ່ເລີ່ມຕົ້ນດ້ວຍ g!.
ຍົກຕົວຢ່າງ, g!a ຈະກາຍເປັນ (gensym "ກ").
ເບິ່ງ ຍັງ:
ພາກສ່ວນການນໍາໃຊ້ -gensym
ຜູ້ລະເມີດ
ໃໝ່ໃນເວີຊັ່ນ 0.9.12.
ຜູ້ລະເມີດ ກໍານົດມະຫາພາກຂອງຜູ້ອ່ານ, ຊ່ວຍໃຫ້ທ່ານສາມາດປັບໂຄງສ້າງຫຼືດັດແປງ syntax.
=> (defreader ^ [expr] (ພິມ expr))
=> #^(1 2 3 4)
( 1 2 3 4 )
=> #^ "ສະບາຍດີ"
"ສະບາຍດີ"
ເບິ່ງ ຍັງ:
ໝວດ Reader Macros
ໄດ້
ໃໝ່ໃນເວີຊັ່ນ 0.9.12.
ໄດ້ ເອົາວັດຖຸອອກຈາກ namespace ໃນປັດຈຸບັນ.
=> (setv foo 42)
=> (del foo)
=> ຟູ
Traceback (ການໂທຫຼ້າສຸດສຸດທ້າຍ):
ໄຟລ໌ " ", ແຖວ 1, ໃນ
NameError: ຊື່ 'foo' ບໍ່ໄດ້ຖືກກໍານົດ
ໄດ້ ຍັງສາມາດເອົາວັດຖຸອອກຈາກແຜນທີ່, ລາຍຊື່, ແລະອື່ນໆອີກ.
=> (ການທົດສອບ setv (ບັນຊີລາຍຊື່ (ໄລຍະ 10)))
=> ການທົດສອບ
[0, 1, 2, 3, 4, 5, 6, 7, 8]
=> (del (slice test 2 4));; ເອົາລາຍການຈາກ 2 ຫາ 4 ຍົກເວັ້ນ
=> ການທົດສອບ
[0, 1, 4, 5, 6, 7, 8, 9]
=> (setv dic {"foo" "bar"})
=> ດິກ
{"foo": "bar"}
=> (del (ໄດ້ dic "foo"))
=> ດິກ
{}
ໂດໂຕ
ໃໝ່ໃນເວີຊັ່ນ 0.10.1.
ໂດໂຕ ຖືກນໍາໃຊ້ເພື່ອງ່າຍລໍາດັບຂອງວິທີການໂທຫາວັດຖຸ.
=> (doto [] (.append 1) (.append 2).reverse)
[2 1]
=> (ຊຸດສະສົມ [])
=> (.ຕື່ມການເກັບລວບລວມ 1)
=> (.ຕື່ມການເກັບລວບລວມ 2)
=> (.ການເກັບລວບລວມຄືນ)
=> ການເກັບກໍາ
[2 1]
ການປະເມີນ
ການປະເມີນ ປະເມີນການສະແດງອອກທີ່ອ້າງອີງແລະສົ່ງຄືນຄ່າ.
=> (eval '(ພິມ "ສະບາຍດີໂລກ"))
"ສະບາຍດີຊາວໂລກ"
eval-and-compile
eval-when-compile
ຄັ້ງທໍາອິດ / ລົດ
ຄັ້ງທໍາອິດ ແລະ ລົດ ແມ່ນ macro ສໍາລັບການເຂົ້າເຖິງອົງປະກອບທໍາອິດຂອງຄໍເລັກຊັນ:
=> (ອັນທໍາອິດ (ໄລຍະ 10))
0
ສໍາລັບການ
ສໍາລັບການ ຖືກນໍາໃຊ້ເພື່ອໂທຫາຫນ້າທີ່ສໍາລັບແຕ່ລະອົງປະກອບໃນບັນຊີລາຍຊື່ຫຼື vector. ຜົນໄດ້ຮັບຂອງແຕ່ລະຄົນ
ໂທຖືກຍົກເລີກແລະ ສໍາລັບການ ການສະແດງອອກກັບຄືນມາ ບໍ່ມີ ແທນ. ລະຫັດຕົວຢ່າງເຮັດຊ້ຳ
ໃນໄລຍະ ເກັບກໍາຂໍ້ມູນ ແລະສໍາລັບແຕ່ລະຄົນ element in ເກັບກໍາຂໍ້ມູນ ຮຽກຮ້ອງ ຜົນຂ້າງຄຽງ ການທໍາງານກັບ
element ເປັນການໂຕ້ຖຽງຂອງຕົນ:
;; ສົມມຸດວ່າ (ຜົນກະທົບຂ້າງຄຽງ) ແມ່ນຫນ້າທີ່ໃຊ້ຕົວກໍານົດການດຽວ
(ສໍາລັບ [ການລວບລວມອົງປະກອບ] (ອົງປະກອບຂ້າງຄຽງ))
;; ສໍາລັບສາມາດມີຕັນທາງເລືອກອື່ນ
(ສໍາລັບ [ການລວບລວມອົງປະກອບ] (ອົງປະກອບຂ້າງຄຽງ)
(ອື່ນໆ (ຜົນຂ້າງຄຽງ-2)))
ທາງເລືອກ ອື່ນ block ແມ່ນປະຕິບັດພຽງແຕ່ຖ້າຫາກວ່າ ສໍາລັບການ loop ສິ້ນສຸດລົງຕາມປົກກະຕິ. ຖ້າ
ການປະຕິບັດແມ່ນຢຸດເຊົາການ ພັກຜ່ອນ, ການ ອື່ນ block ບໍ່ປະຕິບັດ.
=> (ສໍາລັບ [ອົງປະກອບ [1 2 3]] (ຖ້າ (<ອົງປະກອບ 3)
... (ອົງປະກອບພິມ)
... (ແຕກ))
... (ອື່ນ (ພິມ "ວົງສໍາເລັດຮູບ")))
1
2
=> (ສໍາລັບ [ອົງປະກອບ [1 2 3]] (ຖ້າ (<ອົງປະກອບ 4)
... (ອົງປະກອບພິມ)
... (ແຕກ))
... (ອື່ນ (ພິມ "ວົງສໍາເລັດຮູບ")))
1
2
3
loop ສໍາເລັດ
genexpr
genexpr ຖືກນໍາໃຊ້ເພື່ອສ້າງການສະແດງອອກຂອງເຄື່ອງກໍາເນີດ. ມັນໃຊ້ເວລາສອງຫຼືສາມຕົວກໍານົດການ. ໄດ້
ພາລາມິເຕີທໍາອິດແມ່ນການສະແດງອອກທີ່ຄວບຄຸມມູນຄ່າກັບຄືນ, ໃນຂະນະທີ່ຕົວທີສອງຖືກນໍາໃຊ້
ເພື່ອເລືອກລາຍການຈາກລາຍຊື່. ຕົວກໍານົດການທີສາມແລະທາງເລືອກສາມາດຖືກນໍາໃຊ້ເພື່ອການກັ່ນຕອງອອກ
ບາງລາຍການຢູ່ໃນບັນຊີລາຍຊື່ໂດຍອີງໃສ່ການສະແດງອອກທີ່ມີເງື່ອນໄຂ. genexpr ແມ່ນຄ້າຍຄືກັນກັບ
list-comp, ຍົກເວັ້ນແຕ່ມັນຈະກັບຄືນເປັນ iterable ທີ່ປະເມີນຄ່າຫນຶ່ງໂດຍຫນຶ່ງແທນທີ່ຈະເປັນ
ການປະເມີນຜົນໃຫ້ເຂົາເຈົ້າທັນທີທັນໃດ.
=> (ການເກັບກໍາ def (ຊ່ວງ 10))
=> (def filtered (genexpr x [x collection] (ແມ້ແຕ່? x)))
=> (ລາຍຊື່ຖືກກັ່ນຕອງ)
[0, 2, 4, 6, 8]
gensym
ໃໝ່ໃນເວີຊັ່ນ 0.9.12.
gensym ຖືກນໍາໃຊ້ເພື່ອສ້າງສັນຍາລັກທີ່ເປັນເອກະລັກທີ່ອະນຸຍາດໃຫ້ macros ສາມາດຂຽນໄດ້ໂດຍບໍ່ມີການ
ການປະທະກັນຂອງຊື່ຕົວແປໂດຍບັງເອີນ.
=> (gensym)
u':G_1235'
=> (gensym "x")
u':x_1236'
ເບິ່ງ ຍັງ:
ພາກສ່ວນການນໍາໃຊ້ -gensym
ໄດ້ຮັບ
ໄດ້ຮັບ ຖືກນໍາໃຊ້ເພື່ອເຂົ້າເຖິງອົງປະກອບດຽວໃນລາຍຊື່ແລະວັດຈະນານຸກົມ. ໄດ້ຮັບ ໃຊ້ເວລາສອງຕົວກໍານົດການ:
ໄດ້ ຂໍ້ມູນ ໂຄງປະກອບການ ແລະ ດັດຊະນີ or ທີ່ສໍາຄັນ ຂອງລາຍການ. ຈາກນັ້ນມັນຈະສົ່ງຄືນຂໍ້ມູນທີ່ສອດຄ້ອງກັນ
ຄ່າຈາກວັດຈະນານຸກົມ ຫຼືລາຍການ. ຕົວຢ່າງການນໍາໃຊ້:
=> (ໃຫ້ [[ສັດ {"ໝາ" "ເປືອກ" "ແມວ" "ເມວ"}]
... [ຕົວເລກ ["ສູນ" "ຫນຶ່ງ" "ສອງ" "ສາມ"]]]
... (ພິມ (ເອົາສັດ "ໝາ"))
... (ພິມ (ໄດ້ຕົວເລກ 2)))
ເປືອກ
ສອງ
ຫມາຍເຫດ:
ໄດ້ຮັບ ເພີ່ມ KeyError ຖ້າວັດຈະນານຸກົມຖືກສອບຖາມສໍາລັບລະຫັດທີ່ບໍ່ມີຢູ່ແລ້ວ.
ຫມາຍເຫດ:
ໄດ້ຮັບ ຍົກ IndexError ຖ້າລາຍຊື່ຫຼື tuple ຖືກສອບຖາມສໍາລັບດັດສະນີທີ່ຢູ່ນອກ
ເຂດແດນ.
ທົ່ວໂລກ
ທົ່ວໂລກ ສາມາດໃຊ້ເພື່ອໝາຍສັນຍາລັກເປັນທົ່ວໂລກ. ນີ້ອະນຸຍາດໃຫ້ນັກຂຽນໂປລແກລມກໍານົດ a
ມູນຄ່າເປັນສັນຍາລັກທົ່ວໂລກ. ການອ່ານສັນຍາລັກທົ່ວໂລກບໍ່ຈໍາເປັນຕ້ອງມີ ທົ່ວໂລກ ຄໍາສໍາຄັນ --
ພຽງແຕ່ມອບຫມາຍໃຫ້ມັນເຮັດ.
ຕົວຢ່າງຕໍ່ໄປນີ້ສະແດງໃຫ້ເຫັນວິທີການສັນຍາລັກທົ່ວໂລກ a ຖືກມອບຫມາຍຄ່າໃນຫນ້າທີ່ແລະ
ຕໍ່ມາແມ່ນພິມອອກໃນຟັງຊັນອື່ນ. ໂດຍບໍ່ມີການ ທົ່ວໂລກ ຄໍາສໍາຄັນ, ຫນ້າທີ່ທີສອງ
ຈະຖິ້ມເປັນ ຊື່ຜິດພາດ.
(defn set-a [ຄ່າ]
(ທົ່ວໂລກ a)
(ຕັ້ງຄ່າ))
(defn print-a []
(ພິມ a))
(ຊຸດ 5)
(ພິມ-a)
if / ຖ້າບໍ່
ໃໝ່ໃນເວີຊັ່ນ 0.10.0: ຖ້າບໍ່ແມ່ນ
if ຖືກນໍາໃຊ້ເພື່ອເລືອກລະຫັດເພື່ອດໍາເນີນການຕາມເງື່ອນໄຂ. ມັນຕ້ອງມີເງື່ອນໄຂ
block ແລະຕັນທີ່ຈະປະຕິບັດຖ້າຫາກວ່າຕັນເງື່ອນໄຂປະເມີນເຖິງ ທີ່ແທ້ຈິງ. ທາງເລືອກ,
ມັນອາດຈະປະກອບດ້ວຍຕັນສຸດທ້າຍທີ່ຖືກປະຕິບັດໃນກໍລະນີທີ່ການປະເມີນເງື່ອນໄຂແມ່ນ
ທີ່ບໍ່ຖືກຕ້ອງ.
ຖ້າບໍ່ ແມ່ນຄ້າຍຄືກັນ, ແຕ່ຕັນທີສອງຈະຖືກປະຕິບັດເມື່ອເງື່ອນໄຂລົ້ມເຫລວໃນຂະນະທີ່
ຕັນທີສາມແລະສຸດທ້າຍຖືກປະຕິບັດເມື່ອການທົດສອບປະສົບຜົນສໍາເລັດ - ຄໍາສັ່ງກົງກັນຂ້າມຂອງ if.
ຕົວຢ່າງການ ນຳ ໃຊ້:
(ຖ້າຫາກວ່າ (ເງິນເຫຼືອ? ບັນຊີ)
(ພິມ "ໄປຊື້ເຄື່ອງ")
(ພິມ "ໄປເຮັດວຽກ"))
(ຖ້າບໍ່ແມ່ນ (ເງິນ-ຊ້າຍ? ບັນຊີ)
(ພິມ "ໄປເຮັດວຽກ")
(ພິມ "ໄປຊື້ເຄື່ອງ"))
ຄວາມຈິງຂອງ Python ແມ່ນເຄົາລົບ. ບໍ່ມີ, ທີ່ບໍ່ຖືກຕ້ອງ, ສູນຂອງປະເພດຕົວເລກ, ລໍາດັບຫວ່າງເປົ່າ,
ແລະວັດຈະນານຸກົມເປົ່າແມ່ນພິຈາລະນາ ທີ່ບໍ່ຖືກຕ້ອງ; ທຸກສິ່ງທຸກຢ່າງອື່ນແມ່ນພິຈາລະນາ ທີ່ແທ້ຈິງ.
lisp-ຖ້າ / ຊີວິດ ແລະ lisp-ຖ້າ-ບໍ່ / lif-not
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ໃໝ່ໃນເວີຊັ່ນ 0.10.2: lissp-if-not / lif-not
ສໍາລັບຜູ້ທີ່ມັກ Lispy ຫຼາຍ if ຂໍ້, ພວກເຮົາມີ lisp-ຖ້າ, ຫຼື ຊີວິດ. ນີ້ ພຽງແຕ່ ພິຈາລະນາ
ບໍ່ມີ / nil ຜິດ! ຄ່າ Python "false-ish" ອື່ນໆທັງໝົດແມ່ນຖືວ່າເປັນຄວາມຈິງ.
ກົງກັນຂ້າມ, ພວກເຮົາມີ lisp-ຖ້າ-ບໍ່ ແລະ lif-not ໃນຂະຫນານກັບ if ແລະ ຖ້າບໍ່ ເຊິ່ງປີ້ນກັບກັນ
ການປຽບທຽບ.
=> (lisp-ຖ້າ "ຈິງ" "ຜິດ")
"ຄວາມຈິງ"
=> (lisp-if false "true" "false")
"ຄວາມຈິງ"
=> (lisp-if 0 "ຈິງ" "ຜິດ")
"ຄວາມຈິງ"
=> (lisp-if nil "ຈິງ" "false")
"ບໍ່ຖືກຕ້ອງ"
=> (lisp-ຖ້າບໍ່ມີ "ຈິງ" "ຜິດ")
"ບໍ່ຖືກຕ້ອງ"
=> (lisp-if-not nil "ຈິງ" "false")
"ຄວາມຈິງ"
=> (lisp-if-not ບໍ່ມີ "ຈິງ" "false")
"ຄວາມຈິງ"
=> (lisp-if-not False "true" "false")
"ບໍ່ຖືກຕ້ອງ"
; ທຽບເທົ່າແຕ່ສັ້ນກວ່າ
=> (ຖ້າ "ຈິງ" "ຜິດ")
"ຄວາມຈິງ"
=> ( lif nil "ຈິງ" "ຜິດ")
"ບໍ່ຖືກຕ້ອງ"
=> (lif-not none "ຈິງ" "false")
"ຄວາມຈິງ"
ການນໍາເຂົ້າ
ການນໍາເຂົ້າ ຖືກນໍາໃຊ້ເພື່ອນໍາເຂົ້າໂມດູນ, ເຊັ່ນໃນ Python. ມີຫຼາຍວິທີ ການນໍາເຂົ້າ ສາມາດເຮັດໄດ້
ຖືກນໍາໃຊ້.
;; ນໍາເຂົ້າແຕ່ລະໂມດູນເຫຼົ່ານີ້
;;
;; Python:
;; sys ນໍາເຂົ້າ
;; ນໍາເຂົ້າ os.path
(ນໍາເຂົ້າ sys os.path)
;; ນໍາເຂົ້າຈາກໂມດູນ
;;
;; Python: ຈາກການນໍາເຂົ້າ os.path ມີຢູ່, isdir, isfile
(ນໍາເຂົ້າ [os.path [ມີ isdir isfile]])
;; ນຳເຂົ້າດ້ວຍນາມແຝງ
;;
;; Python: ນໍາເຂົ້າ sys ເປັນ systest
(ນໍາເຂົ້າ [sys : as systest])
;; ທ່ານສາມາດລາຍຊື່ການນໍາເຂົ້າຫຼາຍເທົ່າທີ່ທ່ານຕ້ອງການຂອງປະເພດທີ່ແຕກຕ່າງກັນ.
(ນໍາເຂົ້າ [tests.resources [kwtest function-with-a-dash]]
[os.path [ມີ isdir isfile]]
[sys : ເປັນລະບົບ])
;; ນໍາເຂົ້າຟັງຊັນໂມດູນທັງຫມົດເຂົ້າໄປໃນ namespace ໃນປັດຈຸບັນ
(ນໍາເຂົ້າ [sys [*]])
lambda / fn
lambda ແລະ fn ສາມາດໃຊ້ເພື່ອກໍານົດຟັງຊັນທີ່ບໍ່ເປີດເຜີຍຊື່. ຕົວກໍານົດການແມ່ນຄ້າຍຄືກັນກັບ
defn: ຕົວກໍານົດການທໍາອິດແມ່ນ vector ຂອງພາລາມິເຕີແລະສ່ວນທີ່ເຫຼືອແມ່ນຮ່າງກາຍຂອງ
function lambda ສົ່ງຄືນຟັງຊັນໃໝ່. ໃນຕົວຢ່າງຕໍ່ໄປນີ້, ຟັງຊັນທີ່ບໍ່ເປີດເຜີຍຊື່
ຖືກກໍານົດແລະຖືກສົ່ງໄປຫາຫນ້າອື່ນສໍາລັບການກັ່ນຕອງຜົນຜະລິດ.
=> (ຄົນປ້ອງກັນ [{:ຊື່ "Alice": ອາຍຸ 20}
... {:ຊື່ "ບັອບ" :ອາຍຸ 25}
... {:ຊື່ "Charlie" : ອາຍຸ 50}
... {:ຊື່ "ເດບ":ອາຍຸ 5}])
=> (defn display-people [ຕົວກອງຄົນ]
... (ສໍາລັບ [ຄົນ] (ຖ້າ (ຄົນການກັ່ນຕອງ) (ພິມ (: ຊື່ຄົນ)))))
=> (ຄົນສະແດງ - ຄົນ (fn [ຄົນ] (< (: ບຸກຄົນອາຍຸ) 25)))
Alice
Dave
ເຊັ່ນດຽວກັນກັບຄໍານິຍາມຂອງຫນ້າທີ່ປົກກະຕິ, ຖ້າອົງປະກອບທໍາອິດຂອງຮ່າງກາຍແມ່ນສາຍ, ມັນ
ເຮັດຫນ້າທີ່ເປັນ docstring. ນີ້ແມ່ນເປັນປະໂຫຍດສໍາລັບການໃຫ້ docstrings ວິທີການຫ້ອງຮຽນ.
=> (setv ເວລາສາມ
... (fn [x]
... "ຄູນການປ້ອນຂໍ້ມູນດ້ວຍສາມ ແລະສົ່ງຜົນໄດ້ຮັບ."
... (* x 3)))
ນີ້ສາມາດຢືນຢັນໄດ້ໂດຍຜ່ານຕົວສ້າງຂອງ Python ຊ່ວຍເຫຼືອ ການທໍາງານຂອງ:
=> (ຊ່ວຍຄັ້ງສາມ)
ຊ່ວຍເຫຼືອກ່ຽວກັບການທໍາງານ times_three:
times_three(x)
ຄູນການປ້ອນຂໍ້ມູນດ້ວຍສາມ ແລະໃຫ້ຜົນໄດ້ຮັບ
(END)
ສຸດທ້າຍ
ໃໝ່ໃນເວີຊັ່ນ 0.10.2.
ສຸດທ້າຍ ສາມາດໃຊ້ເພື່ອເຂົ້າເຖິງອົງປະກອບສຸດທ້າຍຂອງຄໍເລັກຊັນ:
=> (ຫຼ້າສຸດ [2 4 6])
6
ໃຫ້
ໃຫ້ ແມ່ນໃຊ້ເພື່ອສ້າງຕົວແປທີ່ມີຂອບເຂດ. ເຂົາເຈົ້າໄດ້ຖືກສ້າງຕັ້ງຂື້ນໃນຕອນຕົ້ນຂອງ
ໃຫ້ ແບບຟອມແລະຢຸດຢູ່ຫຼັງຈາກແບບຟອມ. ຕົວຢ່າງຕໍ່ໄປນີ້ສະແດງໃຫ້ເຫັນເລື່ອງນີ້
ພຶດຕິກຳ:
=> (ໃຫ້ [[x 5]] (ພິມ x)
... (ໃຫ້ [[x 6]] (ພິມ x))
... (ພິມ x))
5
6
5
ໄດ້ ໃຫ້ macro ໃຊ້ເວລາສອງຕົວກໍານົດການ: ເປັນ vector ກໍານົດ ຕົວແປ ແລະ ຮ່າງກາຍ ເຊິ່ງໄດ້ຮັບ
ປະຕິບັດ. ຕົວແປ ເປັນ vector ທີ່ແຕ່ລະອົງປະກອບແມ່ນຕົວແປດຽວຫຼື vector
ການກໍານົດຄູ່ຄ່າທີ່ປ່ຽນແປງໄດ້. ໃນກໍລະນີຂອງຕົວແປດຽວ, ມັນຖືກມອບຫມາຍມູນຄ່າ
ບໍ່ມີ; ຖ້າບໍ່ດັ່ງນັ້ນ, ມູນຄ່າທີ່ສະຫນອງແມ່ນຖືກນໍາໃຊ້.
=> (ໃຫ້ [x [y 5]] (ພິມ xy))
ບໍ່ມີ 5
list-comp
list-comp ປະຕິບັດຄວາມເຂົ້າໃຈບັນຊີລາຍຊື່. ມັນໃຊ້ເວລາສອງຫຼືສາມຕົວກໍານົດການ. ທໍາອິດ
ພາລາມິເຕີແມ່ນການສະແດງອອກທີ່ຄວບຄຸມມູນຄ່າກັບຄືນ, ໃນຂະນະທີ່ທີສອງຖືກນໍາໃຊ້ເພື່ອ
ເລືອກລາຍການຈາກບັນຊີລາຍຊື່. ຕົວກໍານົດການທີສາມແລະທາງເລືອກສາມາດຖືກນໍາໃຊ້ເພື່ອການກັ່ນຕອງອອກບາງ
ຂອງລາຍການໃນບັນຊີລາຍຊື່ໂດຍອີງໃສ່ການສະແດງອອກທີ່ມີເງື່ອນໄຂ. ບາງຕົວຢ່າງ:
=> (ການເກັບກໍາ def (ຊ່ວງ 10))
=> (list-comp x [x collection])
[0, 1, 2, 3, 4, 5, 6, 7, 8]
=> (list-comp (* x 2) [x collection])
[0, 2, 4, 6, 8, 10, 12, 14, 16]
=> (list-comp (* x 2) [x collection] (< x 5))
[0, 2, 4, 6, 8]
ບໍ່
ບໍ່ ຖືກໃຊ້ໃນການສະແດງອອກຢ່າງມີເຫດຜົນ. ມັນໃຊ້ເວລາພາລາມິເຕີດຽວແລະສົ່ງຄືນການປີ້ນຄືນ
ມູນຄ່າຄວາມຈິງ. ຖ້າ ທີ່ແທ້ຈິງ ແມ່ນໃຫ້ເປັນຕົວກໍານົດການ, ທີ່ບໍ່ຖືກຕ້ອງ ຈະຖືກສົ່ງຄືນ, ແລະໃນທາງກັບກັນ.
ຕົວຢ່າງການ ນຳ ໃຊ້:
=> (ບໍ່ແມ່ນຄວາມຈິງ)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ບໍ່ແມ່ນຜິດ)
ທີ່ແທ້ຈິງ
=> (ບໍ່ແມ່ນບໍ່ມີ)
ທີ່ແທ້ຈິງ
or
or ຖືກໃຊ້ໃນການສະແດງອອກຢ່າງມີເຫດຜົນ. ມັນໃຊ້ເວລາຢ່າງຫນ້ອຍສອງຕົວກໍານົດການ. ມັນຈະກັບຄືນມາ
ຕົວກໍານົດການທໍາອິດທີ່ບໍ່ແມ່ນປອມ. ຖ້າບໍ່ມີຄ່າດັ່ງກ່າວ, ຕົວກໍານົດການສຸດທ້າຍຈະຖືກສົ່ງຄືນ.
=> (ຫຼື True False)
ທີ່ແທ້ຈິງ
=> (ແລະ False ທີ່ບໍ່ຖືກຕ້ອງ)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ແລະ False 1 True False)
1
ຫມາຍເຫດ:
or short-circuits ແລະຢຸດການປະເມີນຕົວກໍານົດການທັນທີທີ່ຄ່າທີ່ແທ້ຈິງທໍາອິດແມ່ນ
ພົບ.
=> (ຫຼືຖືກຕ້ອງ (ພິມ "ສະບາຍດີ"))
ທີ່ແທ້ຈິງ
ພິມ
ພິມ ຖືກນໍາໃຊ້ເພື່ອຜົນຜະລິດໃນຫນ້າຈໍ. ຕົວຢ່າງການນໍາໃຊ້:
(ພິມ "ສະບາຍດີໂລກ!")
ຫມາຍເຫດ:
ພິມ ກັບຄືນມາສະເໝີ ບໍ່ມີ.
quasiquote
quasiquote ອະນຸຍາດໃຫ້ທ່ານທີ່ຈະອ້າງອີງແບບຟອມ, ແຕ່ຍັງຄັດເລືອກເອົາການປະເມີນຜົນການສະແດງອອກ.
ການສະແດງອອກພາຍໃນ ກ quasiquote ສາມາດໄດ້ຮັບການຄັດເລືອກການປະເມີນຜົນໂດຍນໍາໃຊ້ unquote (~) The
ແບບຟອມການປະເມີນຜົນຍັງສາມາດຖືກແຍກໂດຍໃຊ້ unquote-splice (~@). Quasiquote ຍັງສາມາດເປັນ
ຂຽນໂດຍໃຊ້ backquote (`) ສັນຍາລັກ.
;; ໃຫ້ 'qux' ເປັນຕົວແປທີ່ມີຄ່າ (bar baz)
`(foo ~qux)
; ເທົ່າກັບ '(foo (bar baz))
`(foo ~@qux)
; ເທົ່າກັບ '(foo bar baz)
quote
quote ສົ່ງຄືນແບບຟອມທີ່ຜ່ານໄປໂດຍບໍ່ໄດ້ປະເມີນມັນ. quote ທາງເລືອກອື່ນສາມາດເປັນ
ຂຽນໂດຍໃຊ້ apostrophe (') ສັນຍາລັກ.
=> (setv x '(ພິມ "ສະບາຍດີໂລກ"))
; v variable x ຖືກຕັ້ງເປັນການສະແດງຜົນ & ບໍ່ໄດ້ປະເມີນ
=> x
(u'ພິມ' u'ສະບາຍດີໂລກ')
=> (eval x)
ສະບາຍດີໂລກ
ຕ້ອງການ
ຕ້ອງການ ຖືກນໍາໃຊ້ເພື່ອນໍາເຂົ້າມາໂຄຈາກໂມດູນທີ່ໃຫ້. ມັນໃຊ້ເວລາຢ່າງຫນ້ອຍຫນຶ່ງພາລາມິເຕີ
ການລະບຸໂມດູນທີ່ macros ຄວນຖືກນໍາເຂົ້າ. ຫຼາຍໂມດູນສາມາດນໍາເຂົ້າໄດ້
ກັບດຽວ ຕ້ອງການ.
ຕົວຢ່າງຕໍ່ໄປນີ້ຈະນໍາເຂົ້າມາໂຄຈາກ ໂມດູນ-1 ແລະ ໂມດູນ-2:
(ຕ້ອງການ module-1 module-2)
ສ່ວນທີ່ເຫຼືອ / cdr
ສ່ວນທີ່ເຫຼືອ ແລະ cdr ສົ່ງຄືນການເກັບກໍາທີ່ຜ່ານເປັນການໂຕ້ຖຽງໂດຍບໍ່ມີອົງປະກອບທໍາອິດ:
=> (ສ່ວນທີ່ເຫຼືອ (ຊ່ວງ 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
set-comp
set-comp ຖືກນໍາໃຊ້ເພື່ອສ້າງຊຸດ. ມັນໃຊ້ເວລາສອງຫຼືສາມຕົວກໍານົດການ. ຕົວກໍານົດການທໍາອິດແມ່ນ
ສໍາລັບການຄວບຄຸມມູນຄ່າກັບຄືນ, ໃນຂະນະທີ່ທີສອງຖືກນໍາໃຊ້ເພື່ອເລືອກລາຍການຈາກ a
ລຳດັບ. ຕົວກໍານົດການທີສາມແລະທາງເລືອກສາມາດຖືກນໍາໃຊ້ເພື່ອການກັ່ນຕອງອອກບາງສ່ວນຂອງລາຍການໃນ
ລໍາດັບໂດຍອີງໃສ່ການສະແດງອອກທີ່ມີເງື່ອນໄຂ.
=> (ຂໍ້ມູນ setv [1 2 3 4 5 2 3 4 5 3 4 5])
=> (set-comp x [x ຂໍ້ມູນ] (odd? x))
{1, 3, 5}
slice
slice ສາມາດຖືກນໍາໃຊ້ເພື່ອເອົາຊຸດຍ່ອຍຂອງບັນຊີລາຍຊື່ແລະສ້າງບັນຊີລາຍຊື່ໃຫມ່ຈາກມັນ. ແບບຟອມ
ໃຊ້ເວລາຢ່າງໜ້ອຍໜຶ່ງພາຣາມິເຕີທີ່ລະບຸລາຍຊື່ເພື່ອຕັດ. ສອງຕົວກໍານົດການທາງເລືອກສາມາດ
ໃຊ້ເພື່ອໃຫ້ຕໍາແຫນ່ງເລີ່ມຕົ້ນແລະສິ້ນສຸດຂອງຊຸດຍ່ອຍ. ຖ້າພວກເຂົາບໍ່ໄດ້ສະຫນອງ, ໄດ້
ຄ່າເລີ່ມຕົ້ນຂອງ ບໍ່ມີ ຈະຖືກໃຊ້ແທນ. ຕົວກໍານົດການທາງເລືອກທີສາມຖືກນໍາໃຊ້ເພື່ອ
ຂັ້ນຕອນການຄວບຄຸມລະຫວ່າງອົງປະກອບ.
slice ປະຕິບັດຕາມກົດລະບຽບດຽວກັນກັບຄູ່ຮ່ວມງານ Python ຂອງມັນ. ດັດຊະນີທາງລົບຖືກນັບ
ເລີ່ມແຕ່ຕອນທ້າຍຂອງລາຍການ. ການນໍາໃຊ້ຕົວຢ່າງບາງຢ່າງ:
=> (ການເກັບກໍາ def (ຊ່ວງ 10))
=> (ເກັບສະໄລ້)
[0, 1, 2, 3, 4, 5, 6, 7, 8]
=> (ເກັບສະໄລ້ 5)
[5, 6, 7, 8, 9]
=> (ເກັບສະໄລ້ 2 8)
[2, 3, 4, 5, 6, 7]
=> (ຊຸດສະສົມ 2 8 2)
[2, 4, 6]
=> (ເກັບສະໄລ້ -4 -2)
[6, 7]
ຖິ້ມ / ຍົກສູງບົດບາດ
ໄດ້ ຖິ້ມ or ຍົກສູງບົດບາດ ຮູບແບບສາມາດຖືກນໍາໃຊ້ເພື່ອຍົກສູງບົດບາດ ຂໍ້ຍົກເວັ້ນ ໃນເວລາແລ່ນ. ຕົວຢ່າງການນໍາໃຊ້:
(ຖິ້ມ)
; ປັບປຸງຂໍ້ຍົກເວັ້ນສຸດທ້າຍຄືນໃໝ່
(ຖິ້ມ IOError)
; ຖິ້ມ IOError
(ຖິ້ມ (IOError "foobar"))
; ຖິ້ມ IOError ("foobar")
ຖິ້ມ ສາມາດຍອມຮັບການໂຕ້ຖຽງດຽວ (an ຂໍ້ຍົກເວັ້ນ class ຫຼື instance) ຫຼືບໍ່ມີການໂຕ້ຖຽງກັບ
ຍົກລະດັບສຸດທ້າຍ ຂໍ້ຍົກເວັ້ນ.
ພະຍາຍາມ
ໄດ້ ພະຍາຍາມ ແບບຟອມແມ່ນໃຊ້ເພື່ອເລີ່ມຕົ້ນ a ພະຍາຍາມ / ຈັບ ຕັນ. ແບບຟອມແມ່ນໃຊ້ດັ່ງຕໍ່ໄປນີ້:
(ພະຍາຍາມ
(ຟັງຊັນຜິດພາດ)
(ຈັບ [e ZeroDivisionError] (ພິມ "ການແບ່ງໂດຍສູນ"))
(ອື່ນໆ (ພິມ "ບໍ່ມີຂໍ້ຜິດພາດ"))
(ສຸດທ້າຍ (ພິມ "ຫມົດແລ້ວ")))
ພະຍາຍາມ ຕ້ອງມີຢ່າງໜ້ອຍໜຶ່ງອັນ ຈັບ block, ແລະທາງເລືອກອາດຈະປະກອບມີ an ອື່ນ or ສຸດທ້າຍ
ຕັນ. ຖ້າຫາກວ່າຄວາມຜິດພາດແມ່ນຍົກຂຶ້ນມາກັບຕັນຈັບຄູ່ໃນລະຫວ່າງການປະຕິບັດຂອງ
error-prone-function, that ຈັບ block ຈະຖືກປະຕິບັດ. ຖ້າບໍ່ມີຂໍ້ຜິດພາດຖືກຍົກຂຶ້ນມາ, the ອື່ນ
block ຖືກປະຕິບັດ. ໄດ້ ສຸດທ້າຍ block ຈະຖືກປະຕິບັດສຸດທ້າຍໂດຍບໍ່ຄໍານຶງເຖິງບໍ່ວ່າຈະເປັນຫຼືບໍ່
ຄວາມຜິດພາດໄດ້ຍົກຂຶ້ນມາ.
ເວັ້ນເສຍແຕ່ວ່າ
ໄດ້ ເວັ້ນເສຍແຕ່ວ່າ macro ເປັນ shorthand ສໍາລັບການຂຽນ an if ຄໍາຖະແຫຼງທີ່ກວດເບິ່ງວ່າໃຫ້
ເງື່ອນໄຂແມ່ນ ທີ່ບໍ່ຖືກຕ້ອງ. ຕໍ່ໄປນີ້ສະແດງໃຫ້ເຫັນການຂະຫຍາຍຕົວຂອງມະຫາພາກນີ້.
(ເວັ້ນເສຍແຕ່ຄໍາຖະແຫຼງທີ່ມີເງື່ອນໄຂ)
(ຖ້າມີເງື່ອນໄຂ
ບໍ່ມີ
(ເຮັດຖະແຫຼງການ))
unquote
ພາຍໃນຮູບແບບ quasiquoted, unquote ບັງຄັບໃຫ້ປະເມີນຜົນຂອງສັນຍາລັກ. unquote ແມ່ນ aliased ກັບ
tilde (~) ສັນຍາລັກ.
(ຊື່ຫຍໍ້ "Cuddles")
(quasiquote (= ຊື່ (ຊື່ unquote)))
;=> (u'='u'name' u'Cuddles')
`(=ຊື່ ~ຊື່)
;=> (u'='u'name' u'Cuddles')
unquote-splice
unquote-splice ບັງຄັບໃຫ້ມີການປະເມີນຜົນຂອງສັນຍາລັກພາຍໃນຮູບແບບ quasiquoted, ຄືກັນກັບ
unquote. unquote-splice ສາມາດນໍາໃຊ້ໄດ້ພຽງແຕ່ເມື່ອສັນຍາລັກທີ່ຖືກ unquoted ມີ an
ມູນຄ່າ iterable, ຍ້ອນວ່າມັນ "splice" ທີ່ iterable ເຂົ້າໄປໃນຮູບແບບ quasiquoted. unquote-splice is
ນາມແຝງກັບ ~@ ສັນຍາລັກ.
(ຕົວເລກ def [1 2 3 4])
(quasiquote (+ (unquote-splice nums)))
;=> (u'+' 1L 2L 3L 4L)
`(+ ~@nums)
;=> (u'+' 1L 2L 3L 4L)
ໃນເວລາທີ່
ໃນເວລາທີ່ ແມ່ນຄ້າຍຄືກັນກັບ ເວັ້ນເສຍແຕ່ວ່າ, ຍົກເວັ້ນມັນທົດສອບເມື່ອເງື່ອນໄຂທີ່ໃຫ້ ທີ່ແທ້ຈິງ. ມັນບໍ່ແມ່ນ
ເປັນໄປໄດ້ທີ່ຈະມີ ອື່ນ ບລັອກໃນ a ໃນເວລາທີ່ ມະຫາພາກ. ຕໍ່ໄປນີ້ສະແດງໃຫ້ເຫັນການຂະຫຍາຍຕົວຂອງ
ມະຫາພາກ.
(ເມື່ອມີເງື່ອນໄຂ)
(ຖ້າຫາກວ່າມີເງື່ອນໄຂ (ເຮັດຄໍາສັ່ງ))
ໃນຂະນະທີ່
ໃນຂະນະທີ່ ຖືກນໍາໃຊ້ເພື່ອປະຕິບັດຫນຶ່ງຫຼືຫຼາຍຕັນຕາບໃດທີ່ເງື່ອນໄຂແມ່ນບັນລຸໄດ້. ຕໍ່ໄປນີ້
ຕົວຢ່າງຈະອອກ "ສະບາຍດີໂລກ!" ໄປທີ່ຫນ້າຈໍຢ່າງບໍ່ຢຸດຢັ້ງ:
(ໃນຂະນະທີ່ເປັນຄວາມຈິງ (ພິມ "ສະບາຍດີໂລກ!"))
ກັບ
ກັບ ຖືກນໍາໃຊ້ເພື່ອຫໍ່ການປະຕິບັດຂອງຕັນພາຍໃນຕົວຈັດການສະພາບການ. ສະພາບການ
ຜູ້ຈັດການສາມາດຕັ້ງຄ່າລະບົບທ້ອງຖິ່ນແລະທໍາລາຍມັນລົງໃນລັກສະນະທີ່ຄວບຄຸມ. ໄດ້
ຕົວຢ່າງ archetypical ຂອງການນໍາໃຊ້ ກັບ ແມ່ນເວລາປະມວນຜົນໄຟລ໌. ກັບ ສາມາດຜູກມັດບໍລິບົດເປັນ
ໂຕ້ແຍ້ງຫຼືບໍ່ສົນໃຈມັນຢ່າງສົມບູນ, ດັ່ງທີ່ສະແດງຂ້າງລຸ່ມນີ້:
(ກັບ [[arg (expr)]] ບລັອກ)
(ມີ [[(expr)]] ບລັອກ)
(ມີ [[arg (expr)] [(expr)]] ບລັອກ)
ຕົວຢ່າງຕໍ່ໄປນີ້ຈະເປີດ ຂ່າວ ໄຟລ໌ແລະພິມເນື້ອໃນຂອງມັນໃສ່ຫນ້າຈໍ. ໄດ້
ໄຟລ໌ຖືກປິດອັດຕະໂນມັດຫຼັງຈາກທີ່ມັນໄດ້ຖືກປຸງແຕ່ງ.
(ມີ [[f (ເປີດ "NEWS")]] (ພິມ (. ອ່ານ f)))
ກັບ-ອອກແບບ
ກັບ-ອອກແບບ ແມ່ນໃຊ້ເພື່ອຫໍ່ຟັງຊັນໜຶ່ງກັບອີກອັນໜຶ່ງ. ຫນ້າທີ່ປະຕິບັດການ
ການຕົກແຕ່ງຄວນຍອມຮັບຄ່າດຽວ: ຫນ້າທີ່ຖືກຕົກແຕ່ງ, ແລະສົ່ງຄືນໃຫມ່
function ກັບ-ອອກແບບ ໃຊ້ເວລາຢ່າງຫນ້ອຍສອງຕົວກໍານົດການ: ຫນ້າທີ່ປະຕິບັດ
ການຕົບແຕ່ງແລະຫນ້າທີ່ກໍາລັງຕົກແຕ່ງ. ຟັງຊັນເຄື່ອງຕົບແຕ່ງໄດ້ຫຼາຍກວ່າໜຶ່ງອັນ
ນຳໃຊ້; ພວກເຂົາເຈົ້າຈະຖືກນໍາໃຊ້ໃນຄໍາສັ່ງຈາກ outermost ກັບ innermost, ie. ທໍາອິດ
ເຄື່ອງຕົບແຕ່ງຈະເປັນຊັ້ນນອກທີ່ສຸດ, ແລະອື່ນໆ. ຜູ້ອອກແບບທີ່ມີການໂຕ້ຖຽງແມ່ນເອີ້ນວ່າພຽງແຕ່
ຄືກັບການເອີ້ນຟັງຊັນ.
(ກັບ-decorator decorator-ມ່ວນ
(defn ບາງຫນ້າທີ່ [] ... )
(ມີເຄື່ອງຕົບແຕ່ງ1 decorator2...
(defn ບາງຫນ້າທີ່ [] ... )
(ມີເຄື່ອງຕົບແຕ່ງ (decorator arg)..
(defn ບາງຫນ້າທີ່ [] ... )
ໃນຕົວຢ່າງຕໍ່ໄປນີ້, inc-decorator ຖືກນໍາໃຊ້ເພື່ອ decorate ຫນ້າທີ່ ນອກຈາກນັ້ນ ມີ
ຟັງຊັນທີ່ໃຊ້ສອງພາລາມິເຕີແລະເອີ້ນຟັງຊັນທີ່ຕົກແຕ່ງດ້ວຍຄ່າທີ່ເປັນ
incremented ໂດຍ 1. ໃນເວລາທີ່ຕົກແຕ່ງ ນອກຈາກນັ້ນ ຖືກເອີ້ນດ້ວຍຄ່າ 1 ແລະ 1, ສຸດທ້າຍ
ຜົນໄດ້ຮັບຈະເປັນ 4 (1 + 1 + 1 + 1).
=> (defn inc-decorator [func]
... (fn [value-1 value-2] (func (+ value-1 1) (+ value-2 1))))
=> (defn inc2-decorator [func]
... (fn [value-1 value-2] (func (+ value-1 2) (+ value-2 2))))
=> (with-decorator inc-decorator (defn ນອກຈາກນັ້ນ [ab] (+ ab)))
=> (ຕື່ມ 1 1)
4
=> (with-decorator inc2-decorator inc-decorator
... (defn ນອກຈາກນັ້ນ [ab] (+ ab)))
=> (ຕື່ມ 1 1)
8
with-gensyms
ໃໝ່ໃນເວີຊັ່ນ 0.9.12.
with-gensym ຖືກນໍາໃຊ້ເພື່ອສ້າງຊຸດຂອງ gensym ສໍາລັບການນໍາໃຊ້ໃນມະຫາພາກ. ລະຫັດຕໍ່ໄປນີ້:
(with-gensyms [abc]
... )
ຂະຫຍາຍໄປ:
(ໃຫ້ [[a (gensym)
[b (gensym)
[c (gensym)]]
... )
ເບິ່ງ ຍັງ:
ພາກສ່ວນການນໍາໃຊ້ -gensym
ຜົນຜະລິດ
ຜົນຜະລິດ ຖືກນໍາໃຊ້ເພື່ອສ້າງວັດຖຸເຄື່ອງກໍາເນີດທີ່ສົ່ງຄືນຄ່າຫນຶ່ງຫຼືຫຼາຍ. ເຄື່ອງກໍາເນີດໄຟຟ້າ
ແມ່ນ iterable ແລະດັ່ງນັ້ນສາມາດນໍາໃຊ້ໃນ loops, ບັນຊີລາຍການຄວາມເຂົ້າໃຈແລະອື່ນໆທີ່ຄ້າຍຄືກັນ
ກໍ່ສ້າງ.
ຟັງຊັນ ຕົວເລກແບບສຸ່ມ ສະແດງໃຫ້ເຫັນວິທີການຜະລິດສາມາດຖືກນໍາໃຊ້ເພື່ອສ້າງຊຸດທີ່ບໍ່ມີຂອບເຂດ
ໂດຍບໍ່ມີການບໍລິໂພກຈໍານວນອັນເປັນນິດຂອງຄວາມຊົງຈໍາ.
=> (defn ຄູນ [ຄ່າສໍາປະສິດຖານ]
... (ສໍາລັບ [[(, ຄ່າສໍາປະສິດຖານ) (ຄ່າສໍາປະສິດຖານ zip)]]
... (ຜົນຜະລິດ (* ຄ່າສໍາປະສິດຖານ))))
=> (ຄູນ (ໄລຍະ 5) (ໄລຍະ 5))
=> (ຄ່າ list-comp [value (multiply (range 10)) (range 10))])
[0, 1, 4, 9, 16, 25, 36, 49, 64]
=> (ນໍາເຂົ້າແບບສຸ່ມ)
=> (defn random-numbers [ສູງຕ່ໍາ]
... (ໃນຂະນະທີ່ True (ຜົນຜະລິດ (.random random ຕ່ໍາສູງ))))
=> (list-comp x [x (ເອົາ 15 (random-ຕົວເລກ 1 50))])])
[7, 41, 6, 22, 32, 17, 5, 38, 18, 38, 17, 14, 23, 23, 19]
ຜົນຜະລິດຈາກ
ໃໝ່ໃນເວີຊັ່ນ 0.9.13.
ພະຍັນຊະນະ 3.3 ແລະ UP ເທົ່ານັ້ນ!
ຜົນຜະລິດຈາກ ຖືກນໍາໃຊ້ເພື່ອໂທຫາເຄື່ອງກໍາເນີດຍ່ອຍ. ນີ້ແມ່ນເປັນປະໂຫຍດຖ້າທ່ານຕ້ອງການ coroutine ຂອງທ່ານ
ສາມາດມອບຫມາຍຂະບວນການຂອງມັນໃຫ້ກັບ coroutine ອື່ນ, ເວົ້າວ່າ, ຖ້າໃຊ້ບາງສິ່ງບາງຢ່າງເຊັ່ນ:
ບໍ່ສອດຄ່ອງກັນ.
Hy Core
Core ຫນ້າທີ່
butlast
ການນໍາໃຊ້: (ແຕ່ສຸດທ້າຍ coll)
ສົ່ງຄືນການຢ້ອນຫຼັງຂອງທັງໝົດ ຍົກເວັ້ນລາຍການສຸດທ້າຍໃນ coll.
=> (ບັນຊີລາຍຊື່ (butlast (ໄລຍະ 10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8]
=> (ບັນຊີລາຍຊື່ (butlast [1]))
[]
=> (ບັນຊີລາຍຊື່ (butlast []))
[]
=> (ການນໍາເຂົ້າ itertools)
=> (ລາຍຊື່ (ເອົາ 5 (butlast (itetools.count 10))))
[10, 11, 12, 13, 14]
ຄໍ?
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ການນໍາໃຊ້: (ຄໍ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ແມ່ນ iterable ແລະບໍ່ແມ່ນສາຍ.
=> (ຄໍລ? [1 2 3 4])
ທີ່ແທ້ຈິງ
=> (coll? {"a" 1 "b" 2})
ທີ່ແທ້ຈິງ
=> (coll? "abc")
ທີ່ບໍ່ຖືກຕ້ອງ
cons
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ການນໍາໃຊ້: (ຂໍ້ເສຍ a b)
ສົ່ງຄືນຕາລາງຂໍ້ເສຍໃໝ່ກັບລົດ a ແລະ cdr b.
=> (setv a (cons 'hd 'tl))
=> (= 'hd (ລົດ a))
ທີ່ແທ້ຈິງ
=> (= 'tl (cdr a))
ທີ່ແທ້ຈິງ
ຂໍ້ເສຍ?
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ການນໍາໃຊ້: (ຂໍ້ເສຍ? ຟູ)
ກວດເບິ່ງວ່າ ຟູ ເປັນຈຸລັງ cons.
=> (setv a (cons 'hd 'tl))
=> (ຂໍ້ເສຍ? a)
ທີ່ແທ້ຈິງ
=> (ຂໍ້ເສຍ? nil)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ຂໍ້ເສຍ? [1 2 3])
ທີ່ບໍ່ຖືກຕ້ອງ
Dec
ການນໍາໃຊ້: (ທັນວາ x)
ສົ່ງຄືນໜຶ່ງໜ້ອຍກວ່າ x. ເທົ່າກັບ (- x 1). ຍົກສູງ ປະເພດຄວາມຜິດພາດ if (ບໍ່ແມ່ນ (ຕົວເລກ? x)).
=> (ວັນທີ 3 ທັນວາ)
2
=> (ວັນທີ 0 ທັນວາ)
-1
=> (ວັນທີ 12.3 ທັນວາ)
11.3
disassemble
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ການນໍາໃຊ້: (ຖອດປະກອບ ເປັນໄມ້ຢືນຕົ້ນ &ທາງເລືອກ [ລະຫັດ ຜິດ])
ຖິ້ມ Python AST ສໍາລັບ Hy ເປັນໄມ້ຢືນຕົ້ນ ຜົນຜະລິດມາດຕະຖານ. ຖ້າ codegen is ທີ່ແທ້ຈິງ, ຫນ້າທີ່
ພິມລະຫັດ Python ແທນ.
=> ( disassemble '(ພິມ "ສະບາຍດີໂລກ!"))
ໂມດູນ(
ຮ່າງກາຍ=[
Expr(value=Call(func=Name(id='print'), args=[Str(s='Hello World!')], keywords=[], starargs=None, kwargs=None)])
=> ( disassemble '(ພິມ "ສະບາຍດີໂລກ!") ຄວາມຈິງ)
ພິມ('ສະບາຍດີໂລກ!')
ຫວ່າງ?
ການນໍາໃຊ້: (ຫວ່າງ? coll)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if coll ຫວ່າງເປົ່າ. ເທົ່າກັບ (= 0 (ເລນ coll)).
=> (ຫວ່າງ? [])
ທີ່ແທ້ຈິງ
=> (ເປົ່າ? "")
ທີ່ແທ້ຈິງ
=> (ຫວ່າງ? (, 1 2))
ທີ່ບໍ່ຖືກຕ້ອງ
ທຸກໆ?
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ການນໍາໃຊ້: (ທຸກໆ? ຄາດ coll)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if (ລ່ວງ x) ແມ່ນເຫດຜົນທີ່ແທ້ຈິງສໍາລັບທຸກໆ x in coll, ຖ້າບໍ່ດັ່ງນັ້ນ ທີ່ບໍ່ຖືກຕ້ອງທີ່ຢູ່ ກັບຄືນ ທີ່ແທ້ຈິງ
if coll ແມ່ນຫວ່າງເປົ່າ.
=> (ທຸກ? ແມ້ແຕ່? [2 4 6])
ທີ່ແທ້ຈິງ
=> (ທຸກ? ແມ້ແຕ່? [1 3 5])
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ທຸກ? ແມ້ແຕ່? [2 4 5])
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ທຸກ? ເຖິງແມ່ນ? [])
ທີ່ແທ້ຈິງ
ລອຍ?
ການນໍາໃຊ້: (ລອຍ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ແມ່ນການລອຍ.
=> (ເລື່ອນ? 3.2)
ທີ່ແທ້ຈິງ
=> (ເລື່ອນ? -2)
ທີ່ບໍ່ຖືກຕ້ອງ
ເຖິງແມ່ນວ່າ?
ການນໍາໃຊ້: (ແມ້ແຕ່? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ແມ່ນແມ້ແຕ່. ຍົກສູງ ປະເພດຄວາມຜິດພາດ if (ບໍ່ແມ່ນ (ຕົວເລກ? x)).
=> (ແມ້ແຕ່? 2)
ທີ່ແທ້ຈິງ
=> (ແມ້ແຕ່? 13)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ແມ້ແຕ່? 0)
ທີ່ແທ້ຈິງ
identity
ການນໍາໃຊ້: (ຕົວຕົນ x)
ສົ່ງຄືນອາກິວເມັນທີ່ສະໜອງໃຫ້ກັບຟັງຊັນ.
=> (ຕົວຕົນ 4)
4
=> (ລາຍຊື່ (ຕົວຕົນແຜນທີ່ [1 2 3 4]))
[1 2 3 4]
inc
ການນໍາໃຊ້: (inc x)
ໃຫ້ຜົນຕອບແທນຫນຶ່ງຫຼາຍກ່ວາ x. ເທົ່າກັບ (+ x 1). ຍົກສູງ ປະເພດຄວາມຜິດພາດ if (ບໍ່ແມ່ນ (ຕົວເລກ? x)).
=> (inc 3)
4
=> (inc 0)
1
=> (inc 12.3)
13.3
ຕົວຢ່າງ?
ການນໍາໃຊ້: (ຕົວຢ່າງ? ລະດັບ x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ເປັນຕົວຢ່າງຂອງ ລະດັບ.
=> (ຕົວຢ່າງ? float 1.0)
ທີ່ແທ້ຈິງ
=> (ຕົວຢ່າງ? int 7)
ທີ່ແທ້ຈິງ
=> (ຕົວຢ່າງ? str (str "foo"))
ທີ່ແທ້ຈິງ
=> (defclass TestClass [object])
=> (setv inst (TestClass))
=> (ຕົວຢ່າງ? TestClass inst)
ທີ່ແທ້ຈິງ
ຈຳນວນເຕັມ?
ການນໍາໃຊ້: (ຈໍານວນເຕັມ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ເປັນຈຳນວນເຕັມ. ສໍາລັບ Python 2, ນີ້ແມ່ນຄືກັນ int or ຍາວ. ສໍາລັບ Python 3,
ນີ້ແມ່ນ int.
=> (ຈຳນວນເຕັມ? 3)
ທີ່ແທ້ຈິງ
=> (ຈຳນວນເຕັມ? -2.4)
ທີ່ບໍ່ຖືກຕ້ອງ
ແຊກແຊງ
ໃໝ່ໃນເວີຊັ່ນ 0.10.1.
ການນໍາໃຊ້: (ແຊກແຊງ seq1 seq2 ... )
ໃຫ້ຜົນເປັນອັນຊ້ຳກັນຂອງລາຍການທຳອິດໃນແຕ່ລະລຳດັບ, ຈາກນັ້ນອັນທີສອງ, ແລະອື່ນໆ.
=> (ລາຍການ (ໄລຍະ 5) (ໄລຍະ 100 105)))
[0, 100, 1, 101, 2, 102, 3, 103, 4]
=> (ລາຍການ (ໄລຍະ 1000000) "abc"))
[0, 'a', 1, 'b', 2, 'c']
ແຊກແຊງ
ໃໝ່ໃນເວີຊັ່ນ 0.10.1.
ການນໍາໃຊ້: (interpose ລາຍການ seq)
ໃຫ້ຜົນເປັນອັນຊ້ຳກັນຂອງອົງປະກອບຂອງລຳດັບທີ່ແຍກກັນໂດຍລາຍການ.
=> (ລາຍຊື່ (interpose "!" "abcd"))
['ກຂຄງ']
=> (ລາຍການ (interpose -1 (ໄລຍະ 5)))
[0, -1, 1, -1, 2, -1, 3, -1, 4]
ຊ້ຳບໍ່ໜຳ?
ການນໍາໃຊ້: (ເຮັດໄດ້ບໍ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ແມ່ນ iterable. Iterable objects ກັບຄືນມາເປັນ iterator ໃໝ່ເມື່ອ (ມັນ x) is
ເອີ້ນວ່າ. ກົງກັນຂ້າມກັບ ຜູ້ເຮັດຊ້ຳ?.
=> ;; ເຮັດວຽກສໍາລັບສາຍ
=> (ມັນເປັນໄປໄດ້? (str "abcde"))
ທີ່ແທ້ຈິງ
=> ;; ເຮັດວຽກສໍາລັບລາຍການ
=> (ເຮັດໄດ້ບໍ່? [1 2 3 4 5])
ທີ່ແທ້ຈິງ
=> ;; ເຮັດວຽກສໍາລັບ tuples
=> (ເຮັດໄດ້ບໍ່? (, 1 2 3))
ທີ່ແທ້ຈິງ
=> ;; ເຮັດວຽກສໍາລັບ dicts
=> (ເຮັດໄດ້ບໍ? {:a 1 :b 2 :c 3})
ທີ່ແທ້ຈິງ
=> ;; ເຮັດວຽກສໍາລັບ iterators / generators
=> (ເຮັດຊ້ຳໄດ້ບໍ? (ຊ້ຳ 3))
ທີ່ແທ້ຈິງ
ຜູ້ເຮັດຊ້ຳ?
ການນໍາໃຊ້: (ຜູ້ເຮັດຊ້ຳ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ເປັນຜູ້ເຮັດຊ້ຳ. Iterators ແມ່ນວັດຖຸທີ່ກັບຄືນຕົນເອງເປັນ
iterator ເມື່ອ (ມັນ x) ເອີ້ນວ່າ. ກົງກັນຂ້າມກັບ ຊ້ຳບໍ່ໜຳ?.
=> ;; ບໍ່ເຮັດວຽກສໍາລັບບັນຊີລາຍຊື່
=> ( ທົດສະວັດ? [1 2 3 4 5])
ທີ່ບໍ່ຖືກຕ້ອງ
=> ;; ແຕ່ພວກເຮົາສາມາດໄດ້ຮັບ iter ຈາກບັນຊີລາຍຊື່
=> (iter? (iter [1 2 3 4 5]))
ທີ່ແທ້ຈິງ
=> ;; ບໍ່ໄດ້ເຮັດວຽກສໍາລັບ dict
=> (ຕົວຊີ້ບອກ? {:a 1 :b 2 :c 3})
ທີ່ບໍ່ຖືກຕ້ອງ
=> ;; ສ້າງ iterator ຈາກ dict ໄດ້
=> (iter? (iter {:a 1 :b 2 :c 3}))
ທີ່ແທ້ຈິງ
ລາຍຊື່*
ການນໍາໃຊ້: (ລາຍຊື່* ຫົວຫນ້າ &ພັກຜ່ອນ ຫາງ)
ສ້າງລະບົບຕ່ອງໂສ້ຂອງເຊລ cons ຊ້ອນ (ບັນຊີລາຍຊື່ຈຸດ) ທີ່ມີ arguments. ຖ້າ
ບັນຊີລາຍຊື່ argument ພຽງແຕ່ມີອົງປະກອບຫນຶ່ງ, ສົ່ງຄືນມັນ.
=> (ລາຍການ* 1 2 3 4)
(1 2 3. 4)
=> (ລາຍການ* 1 2 3 [4])
[1, 2, 3, 4]
=> (ລາຍຊື່* 1)
1
=> (cons? (ລາຍການ* 1 2 3 4))
ທີ່ແທ້ຈິງ
ຂະຫຍາຍມະຫາພາກ
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ການນໍາໃຊ້: (ຂະຫຍາຍມະຫາພາກ ແບບຟອມ)
ສົ່ງຄືນການຂະຫຍາຍມະຫາພາກອັນເຕັມທີ່ຂອງ ຮູບແບບ.
=> (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
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ການນໍາໃຊ້: (ມະຫາພາກ-1 ແບບຟອມ)
ສົ່ງຄືນການຂະຫຍາຍມະຫາພາກຂັ້ນຕອນດຽວຂອງ ຮູບແບບ.
=> (macroexpand-1 '(-> (ab) (-> (cd) (ef))))
(u'_>' (u'a' u'b') (u'c' u'd') (u'e' u'f'))
ຮວມກັບ
ໃໝ່ໃນເວີຊັ່ນ 0.10.1.
ການນໍາໃຊ້: (ລວມເຂົ້າກັບ f &ພັກຜ່ອນ ແຜນທີ່)
ສົ່ງຄືນແຜນທີ່ທີ່ປະກອບດ້ວຍສ່ວນທີ່ເຫຼືອຂອງແຜນທີ່ທີ່ເຂົ້າຮ່ວມກັບທໍາອິດ. ຖ້າກະແຈເກີດຂຶ້ນໃນ
ຫຼາຍກວ່າໜຶ່ງແຜນທີ່, ແຜນທີ່ຈາກຫຼັງ (ຊ້າຍຫາຂວາ) ຈະຖືກລວມເຂົ້າກັບ
ແຜນທີ່ໃນຜົນໄດ້ຮັບໂດຍການໂທຫາ (f val-in-ຜົນ val-in-latter).
=> (merge-with (fn [xy] (+ xy)) {"a" 10" b" 20} {"a" 1 "c" 30})
{u'a': 11L, u'c': 30L, u'b': 20L}
ບໍ່?
ການນໍາໃຊ້: (ບໍ່? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ແມ່ນຫນ້ອຍກວ່າສູນ. ຍົກສູງ ປະເພດຄວາມຜິດພາດ if (ບໍ່ແມ່ນ (ຕົວເລກ? x)).
=> (ບໍ່? -2)
ທີ່ແທ້ຈິງ
=> (ບໍ່? 3)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ບໍ່? 0)
ທີ່ບໍ່ຖືກຕ້ອງ
ບໍ່?
ການນໍາໃຊ້: (ບໍ່? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x is nil / ບໍ່ມີ.
=> (nil? nil)
ທີ່ແທ້ຈິງ
=> (nil? none)
ທີ່ແທ້ຈິງ
=> (ບໍ່? 0)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (setf x nil)
=> (nil? x)
ທີ່ແທ້ຈິງ
=> ;; list.append ສະເຫມີກັບຄືນບໍ່ມີ
=> (nil? (. append [1 2 3] 4))
ທີ່ແທ້ຈິງ
ບໍ່ມີ?
ການນໍາໃຊ້: (ບໍ່? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x is ບໍ່ມີ.
=> (ບໍ່? ບໍ່ມີ)
ທີ່ແທ້ຈິງ
=> (ບໍ່? 0)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (setf x ບໍ່ມີ)
=> (ບໍ່? x)
ທີ່ແທ້ຈິງ
=> ;; list.append ສະເຫມີກັບຄືນບໍ່ມີ
=> (ບໍ່? (. ຕື່ມ [1 2 3] 4))
ທີ່ແທ້ຈິງ
ນ
ການນໍາໃຊ້: (ທີ coll n &ທາງເລືອກ [ຄ່າເລີ່ມຕົ້ນ nil])
ກັບຄືນ n-th item in a collection, counting from 0. ສົ່ງຄືນຄ່າເລີ່ມຕົ້ນ, nil, ຖ້າ
ອອກຈາກຂອບເຂດ (ເວັ້ນເສຍແຕ່ໄດ້ລະບຸໄວ້ເປັນຢ່າງອື່ນ). ຍົກສູງ ຄ່າຜິດພາດ if n ແມ່ນທາງລົບ.
=> (ນທ [1 2 4 7] 1)
2
=> (ນທ [1 2 4 7] 3)
7
=> (nil? (ນທ [1 2 4 7] 5))
ທີ່ແທ້ຈິງ
=> (ທີ [1 2 4 7] 5 "ຄ່າເລີ່ມຕົ້ນ")
'ຄ່າເລີ່ມຕົ້ນ'
=> (nth (ເອົາ 3 (ລົງ 2 [1 2 3 4 5 6])) 2))
5
=> (ນທ [1 2 4 7] -1)
Traceback (ການໂທຫຼ້າສຸດສຸດທ້າຍ):
...
ValueError: Indices for islice() ຈະຕ້ອງເປັນ None ຫຼື integer: 0 <= x <= sys.maxsize.
ຕົວເລກ?
ການນໍາໃຊ້: (ຕົວເລກ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ເປັນຕົວເລກ, ຕາມທີ່ກຳນົດໄວ້ໃນ Python's ຕົວເລກ ຊັ້ນຮຽນ.
=> (ຕົວເລກ? -2)
ທີ່ແທ້ຈິງ
=> (ຕົວເລກ? 3.2)
ທີ່ແທ້ຈິງ
=> (ຕົວເລກ? "foo")
ທີ່ບໍ່ຖືກຕ້ອງ
ຄີກ?
ການນໍາໃຊ້: (ຄີກ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ຄີກ. ຍົກສູງ ປະເພດຄວາມຜິດພາດ if (ບໍ່ແມ່ນ (ຕົວເລກ? x)).
=> (ຄີກ? 13)
ທີ່ແທ້ຈິງ
=> (ຄີກ? 2)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ຄີກ? 0)
ທີ່ບໍ່ຖືກຕ້ອງ
pos?
ການນໍາໃຊ້: (ໂພດ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ແມ່ນໃຫຍ່ກວ່າສູນ. ຍົກສູງ ປະເພດຄວາມຜິດພາດ if (ບໍ່ແມ່ນ (ຕົວເລກ? x)).
=> (ໂພສ? 3)
ທີ່ແທ້ຈິງ
=> (ໂພດ? -2)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ໂພສ? 0)
ທີ່ບໍ່ຖືກຕ້ອງ
ຄັ້ງທີສອງ
ການນໍາໃຊ້: (ທີສອງ coll)
ສົ່ງຄືນສະມາຊິກທີສອງຂອງ coll. ເທົ່າກັບ (ໄດ້ຮັບ coll 1).
=> (ວິນາທີ [0 1 2])
1
ບາງ
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ການນໍາໃຊ້: (ບາງ ຄາດ coll)
ໃຫ້ຜົນເປັນຄ່າຕາມເຫດຜົນ-ຄວາມຈິງທຳອິດຂອງ (ລ່ວງ x) ສຳ ລັບໃດໆ x in coll, ຖ້າບໍ່ດັ່ງນັ້ນ nil.
Return nil if coll ແມ່ນຫວ່າງເປົ່າ.
=> (ບາງອັນ? [2 4 6])
ທີ່ແທ້ຈິງ
=> (nil? (ບາງອັນແມ່ນ? [1 3 5]))
ທີ່ແທ້ຈິງ
=> (nil? (ບາງຕົວຕົນ [0 "" []]))
ທີ່ແທ້ຈິງ
=> (ບາງຕົວຕົນ [0 "ບໍ່ຫວ່າງເປົ່າ" []])
'ສະຕຣິງທີ່ບໍ່ຫວ່າງເປົ່າ'
=> (nil? (ບາງຄົນແມ່ນແຕ່? []))
ທີ່ແທ້ຈິງ
ສາຍ?
ການນໍາໃຊ້: (ສາຍ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ເປັນສາຍ.
=> (string? "foo")
ທີ່ແທ້ຈິງ
=> (ສະຕຣິງ? -2)
ທີ່ບໍ່ຖືກຕ້ອງ
ສັນຍາລັກ?
ການນໍາໃຊ້: (ສັນຍາລັກ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ເປັນສັນຍາລັກ.
=> (ສັນຍາລັກ? 'foo)
ທີ່ແທ້ຈິງ
=> (ສັນຍາລັກ? '[abc])
ທີ່ບໍ່ຖືກຕ້ອງ
ສູນ?
ການນໍາໃຊ້: (ສູນ? x)
ຜົນຕອບແທນ ທີ່ແທ້ຈິງ if x ແມ່ນສູນ.
=> (ສູນ? 3)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ສູນ? -2)
ທີ່ບໍ່ຖືກຕ້ອງ
=> (ສູນ? 0)
ທີ່ແທ້ຈິງ
ລໍາດັບ ຫນ້າທີ່
ຟັງຊັນລໍາດັບສາມາດສ້າງຫຼືດໍາເນີນການຢູ່ໃນລໍາດັບທີ່ບໍ່ມີຂອບເຂດທີ່ມີທ່າແຮງທີ່ບໍ່ມີ
ຮຽກຮ້ອງໃຫ້ລໍາດັບຖືກຮັບຮູ້ຢ່າງເຕັມສ່ວນໃນບັນຊີລາຍຊື່ຫຼືບັນຈຸທີ່ຄ້າຍຄືກັນ. ພວກເຂົາເຈົ້າເຮັດສິ່ງນີ້ໂດຍ
ສົ່ງຄືນ Python iterator.
ພວກເຮົາສາມາດໃຊ້ເຄື່ອງກໍາເນີດເລກ Fibonacci infinite canonical ເປັນຕົວຢ່າງຂອງວິທີການນໍາໃຊ້
ບາງຫນ້າທີ່ເຫຼົ່ານີ້.
(defn fib []
(ຊຸດ a 0)
(ຊຸດ b 1)
(ໃນຂະນະທີ່ເປັນຄວາມຈິງ
(ຜົນຜະລິດ ກ)
(setv (, ab) (, b (+ ab)))))
ຫມາຍເຫດ (ໃນຂະນະທີ່ ທີ່ແທ້ຈິງ ... ) ວົງ. ຖ້າພວກເຮົາດໍາເນີນການນີ້ໃນ REPL,
=> (fib)
ການເອີ້ນຟັງຊັນຈະສົ່ງຄືນພຽງແຕ່ຕົວປ່ຽນແທນ, ແຕ່ບໍ່ໄດ້ຜົນຈົນກວ່າພວກເຮົາຈະບໍລິໂພກມັນ.
ພະຍາຍາມບາງສິ່ງບາງຢ່າງເຊັ່ນນີ້ບໍ່ໄດ້ແນະນໍາໃຫ້ເປັນ loop infinite ຈະດໍາເນີນການຈົນກ່ວາມັນ
ໃຊ້ RAM ທີ່ມີຢູ່ທັງຫມົດ, ຫຼືໃນກໍລະນີນີ້ຈົນກ່ວາຂ້ອຍຂ້າມັນ.
=> (ບັນຊີລາຍຊື່ (fib))
[1] 91474 ຂ້າ hy
ເພື່ອເອົາຕົວເລກ Fibonacci 10 ໂຕທຳອິດ, ໃຫ້ໃຊ້ ໃຊ້ເວລາ. ໃຫ້ສັງເກດວ່າ ໃຊ້ເວລາ ຍັງສົ່ງຄືນເຄື່ອງປັ່ນໄຟ,
ສະນັ້ນຂ້ອຍສ້າງບັນຊີລາຍຊື່ຈາກມັນ.
=> (ລາຍຊື່ (ເອົາ 10 (fib)))
[0, 1, 1, 2, 3, 5, 8, 13, 21]
ເພື່ອເອົາຕົວເລກ Fibonacci ຢູ່ດັດຊະນີ 9, (ເລີ່ມຈາກ 0):
=> (ທີ (fib) 9)
34
ວົງຈອນ
ການນໍາໃຊ້: (ຮອບວຽນ coll)
ສົ່ງຄືນການຊໍ້າຄືນທີ່ບໍ່ມີຂອບເຂດຂອງສະມາຊິກຂອງ coll.
=> (ບັນຊີລາຍຊື່ (ເອົາ 7 (ວົງຈອນ [1 2 3])))
[1, 2, 3, 1, 2, 3, 1]
=> (ບັນຊີລາຍຊື່ (ເອົາ 2 (ວົງຈອນ [1 2 3])))
[1, 2]
ແຕກຕ່າງກັນ
ການນໍາໃຊ້: (ທີ່ແຕກຕ່າງກັນ coll)
ສົ່ງຄືນຕົວແປທີ່ປະກອບມີສະມາຊິກທີ່ບໍ່ຊໍ້າກັນໃນ coll.
=> (ລາຍຊື່ (ແຕກຕ່າງກັນ [ 1 2 3 4 3 5 2 ]))
[1, 2, 3, 4, 5]
=> (ລາຍຊື່ (ທີ່ແຕກຕ່າງກັນ []))
[]
=> (ລາຍຊື່ (ທີ່ແຕກຕ່າງ (iter [ 1 2 3 4 3 5 2 ])))
[1, 2, 3, 4, 5]
ວາງ
ການນໍາໃຊ້: (ລົງ n coll)
ສົ່ງຄືນເຄື່ອງເຮັດຊ້ຳ, ຂ້າມອັນທຳອິດ n ສະມາຊິກຂອງ coll. ຍົກສູງ ຄ່າຜິດພາດ if n is
ກະທົບທາງລົບ.
=> (ບັນຊີລາຍຊື່ (ເລື່ອນ 2 [1 2 3 4 5]))
[3, 4, 5]
=> (ບັນຊີລາຍຊື່ (ເລື່ອນ 4 [1 2 3 4 5]))
[5]
=> (ບັນຊີລາຍຊື່ (ເລື່ອນ 0 [1 2 3 4 5]))
[1, 2, 3, 4, 5]
=> (ບັນຊີລາຍຊື່ (ເລື່ອນ 6 [1 2 3 4 5]))
[]
ຫຼຸດສຸດທ້າຍ
ການນໍາໃຊ້: (ຫຼຸດລົງສຸດທ້າຍ n coll)
ຕອບໂຕແທນທີ່ທັງໝົດ ຍົກເວັ້ນອັນສຸດທ້າຍ n ລາຍການໃນ coll. ຍົກສູງ ຄ່າຜິດພາດ if n is
ກະທົບທາງລົບ.
=> (ບັນຊີລາຍຊື່ (ເລື່ອນ 5 ສຸດທ້າຍ (ໄລຍະ 10 20)))
[10, 11, 12, 13, 14]
=> (ບັນຊີລາຍຊື່ (ເລື່ອນ - ສຸດທ້າຍ 0 (ໄລຍະ 5)))
[0, 1, 2, 3, 4]
=> (ບັນຊີລາຍຊື່ (ເລື່ອນ - ສຸດທ້າຍ 100 (ໄລຍະ 100)))
[]
=> (ການນໍາເຂົ້າ itertools)
=> (ລາຍຊື່ (ເອົາ 5 (ລຸດລົງ 100 ສຸດທ້າຍ (itetools.count 10))))
[10, 11, 12, 13, 14]
ລຸດລົງ
ການນໍາໃຊ້: (ຫຼຸດລົງໃນຂະນະທີ່ ຄາດ coll)
ສົ່ງຜົນເປັນ iterator, ຂ້າມສະມາຊິກຂອງ coll ຈົນກ່ວາ ຄາດ is ທີ່ບໍ່ຖືກຕ້ອງ.
=> (ບັນຊີລາຍຊື່ (drop-while even? [2 4 7 8 9]))
[7, 8, 9]
=> (ບັນຊີລາຍຊື່ ( drop-while ຕົວເລກ? [1 2 3 ບໍ່ມີ "a"])))
[ບໍ່ມີ, u'a']
=> (ບັນຊີລາຍຊື່ (drop-while pos? [2 4 7 8 9]))
[]
ການກັ່ນຕອງ
ການນໍາໃຊ້: (ການກັ່ນຕອງ ຄາດ coll)
ຕອບໂຕແທນທີ່ສຳລັບລາຍການທັງໝົດໃນ coll ທີ່ຜ່ານການຄາດຄະເນ ຄາດ.
ເບິ່ງ ເອົາ.
=> (ບັນຊີລາຍຊື່ (ການກັ່ນຕອງ pos? [1 2 3 -4 5 -7]))
[1, 2, 3, 5]
=> (ບັນຊີລາຍຊື່ (ການກັ່ນຕອງເຖິງແມ່ນ? [1 2 3 -4 5 -7]))
[2, -4]
ແບນ
ໃໝ່ໃນເວີຊັ່ນ 0.9.12.
ການນໍາໃຊ້: (ແປ coll)
ສົ່ງຄືນລາຍການດຽວຂອງລາຍການທັງໝົດໃນ coll, ໂດຍການແປລາຍການທີ່ມີທັງໝົດ ແລະ/ຫຼື
tuples.
=> (ແປ [1 2 [3 4] 5])
[1, 2, 3, 4, 5]
=> (ແປ ["foo" (, 1 2) [1 [2 3] 4] "bar"])
['foo', 1, 2, 1, 2, 3, 4, 'ບາ']
ເຮັດຊ້ ຳ
ການນໍາໃຊ້: (ເຮັດຊ້ຳ fn x)
ຕອບໂຕແທນຂອງ x, fn(x), fn(fn(x)), ແລະອື່ນໆ
=> (ລາຍຊື່ (ເອົາ 5 (iterate inc 5)))
[5, 6, 7, 8, 9]
=> (ລາຍຊື່ (ເອົາ 5 (iterate (fn [x] (* xx)) 5)))
[5, 25, 625, 390625, 152587890625]
ອ່ານ
ການນໍາໃຊ້: (ອ່ານ &ທາງເລືອກ [ຈາກໄຟລ໌ eof])
ອ່ານການສະແດງອອກ Hy ຕໍ່ໄປຈາກ ຈາກໄຟລ໌ (ຄ່າເລີ່ມຕົ້ນເປັນ sys.stdin), ແລະສາມາດເອົາ a
single byte ເປັນ EOF (ຄ່າເລີ່ມຕົ້ນເປັນ string ຫວ່າງເປົ່າ). ຍົກສູງ EOFError if ຈາກໄຟລ໌ ສິ້ນສຸດກ່ອນ
ການສະແດງອອກທີ່ສົມບູນສາມາດຖືກວິເຄາະ.
=> (ອ່ານ)
(+ 2 2)
('+' 2 2)
=> (eval (ອ່ານ))
(+ 2 2)
4
=> (ນໍາເຂົ້າ io)
=> (def buffer (io.StringIO "(+ 2 2)\n(- 2 1)"))
=> (eval (ນຳໃຊ້ອ່ານ [] {"from_file" buffer}))
4
=> (eval (ນຳໃຊ້ອ່ານ [] {"from_file" buffer}))
1
=> ; ສົມມຸດວ່າ "example.hy" ປະກອບມີ:
=> ; (ພິມ "ສະບາຍດີ")
=> ; (ພິມ "ແຟນ!")
=> (ດ້ວຍ [[f (ເປີດ "example.hy")]]
... (ພະຍາຍາມ
... (ໃນຂະນະທີ່ເປັນຄວາມຈິງ
... (ໃຫ້ [[exp (ອ່ານ f)]]
... (ເຮັດ
... (ພິມ "OHY" exp)
... (eval exp))))
... (ຈັບ [e EOFError]
... (ພິມ "EOF!"))))
ໂອ້ຍ ('ພິມ' 'ສະບາຍດີ')
ສະບາຍດີ
ໂອ້ຍ ('ພິມ' 'ແຟນ!')
ແຟນ!
EOF!
ເອົາ
ການນໍາໃຊ້: (ເອົາອອກ ຄາດ coll)
ສົ່ງຄືນຕົວແປຈາກ coll ມີອົງປະກອບທີ່ຜ່ານການຄາດຄະເນ, ຄາດ, ເອົາອອກ.
ເບິ່ງ ການກັ່ນຕອງ.
=> (ບັນຊີລາຍຊື່ (ເອົາຄີກ? [1 2 3 4 5 6 7]))
[2, 4, 6]
=> (ບັນຊີລາຍຊື່ (ລົບ pos? [1 2 3 4 5 6 7]))
[]
=> (ບັນຊີລາຍຊື່ (ເອົາ neg? [1 2 3 4 5 6 7]))
[1, 2, 3, 4, 5, 6, 7]
ຊ້ໍາ
ການນໍາໃຊ້: (ຊ້ຳ x)
ໃຫ້ຜົນເປັນຕົວຫຍໍ້ (ບໍ່ມີຂອບເຂດ) ຂອງ x.
=> (ລາຍຊື່ (ເອົາ 6 (ເຮັດຊ້ຳ "s")))
[u's', u's', u's', u's', u's', u's']
repeatedly
ການນໍາໃຊ້: (ຊ້ຳໆ fn)
ສົ່ງຄືນການເຮັດໃຫ້ຊ້ຳໂດຍການໂທ fn repeatedly
=> (ນໍາເຂົ້າ [random [randint]])
=> (ລາຍຊື່ (ເອົາ 5 (ຊ້ຳໆ (fn [] (randint 0 10)))))
[6, 2, 0, 6, 7]
ໃຊ້ເວລາ
ການນໍາໃຊ້: (ເອົາ n coll)
ໃຫ້ຜົນເປັນຕົວປ່ຽນແທນທີ່ບັນຈຸອັນທຳອິດ n ສະມາຊິກຂອງ coll. ຍົກສູງ ຄ່າຜິດພາດ if n is
ກະທົບທາງລົບ.
=> (ລາຍຊື່ (ເອົາ 3 [1 2 3 4 5]))
[1, 2, 3]
=> (ລາຍຊື່ (ເອົາ 4 (ເຮັດຊ້ຳ "s")))
[u's', u's', u's', u's]
=> (ລາຍຊື່ (ເອົາ 0 (ເຮັດຊ້ຳ "s")))
[]
ເອົາອັນທີ
ການນໍາໃຊ້: (ຕອນທີ n coll)
ໃຫ້ຜົນເປັນຕົວຢ້ອນຫຼັງທີ່ມີທຸກໆ n- ສະມາຊິກທີ coll.
=> (ບັນຊີລາຍຊື່ (take-nth 2 [1 2 3 4 5 6 7]))
[1, 3, 5, 7]
=> (ບັນຊີລາຍຊື່ (take-nth 3 [1 2 3 4 5 6 7]))
[1, 4, 7]
=> (ບັນຊີລາຍຊື່ (take-nth 4 [1 2 3 4 5 6 7]))
[1, 5]
=> (ບັນຊີລາຍຊື່ (take-nth 10 [1 2 3 4 5 6 7]))
[1]
ໃຊ້ເວລາໃນຂະນະທີ່
ການນໍາໃຊ້: (ໃຊ້ເວລາໃນຂະນະທີ່ ຄາດ coll)
ສົ່ງຄືນຕົວແປຈາກ coll ເປັນ ຄາດ ກັບຄືນມາ ທີ່ແທ້ຈິງ.
=> (ບັນຊີລາຍຊື່ (ໃຊ້ເວລາໃນຂະນະທີ່ pos? [ 1 2 3 -4 5]))
[1, 2, 3]
=> (ລາຍການ ( take-while neg ? [ -4 -3 1 2 5 ]))
[-4, -3]
=> (ລາຍການ ( take-while neg ? [ 1 2 3 -4 5 ]))
[]
zip ກັບ
ໃໝ່ໃນເວີຊັ່ນ 0.9.13.
ການນໍາໃຊ້: (zipwith fn coll ... )
ເທົ່າກັບ ໄປສະນີ, ແຕ່ໃຊ້ຟັງຊັນຫຼາຍ argument ແທນທີ່ຈະສ້າງ tuple. ຖ້າ
zip ກັບ ເອີ້ນວ່າ N collections, ຫຼັງຈາກນັ້ນ fn ຕ້ອງຍອມຮັບ N arguments.
=> (ຜູ້ປະກອບການນໍາເຂົ້າ)
=> (ບັນຊີລາຍຊື່ (zipwith operator.add [1 2 3] [4 5 6]))
[5, 7, 9]
Reader ມາໂຄຣ
ມະຫາພາກຂອງຜູ້ອ່ານໃຫ້ Lisp ມີອໍານາດໃນການແກ້ໄຂແລະປ່ຽນແປງ syntax ໃນທັນທີ. ເຈົ້າບໍ່ຕ້ອງການ
ຫມາຍເຫດໂປໂລຍ? ມະຫາພາກຜູ້ອ່ານສາມາດເຮັດແນວນັ້ນໄດ້ຢ່າງງ່າຍດາຍ. ຕ້ອງການວິທີການ Clojure ຂອງການມີ
regex? ມະຫາພາກຜູ້ອ່ານສາມາດເຮັດສິ່ງນີ້ໄດ້ຢ່າງງ່າຍດາຍ.
syntax
=> (defreader ^ [expr] (ພິມ expr))
=> #^(1 2 3 4)
( 1 2 3 4 )
=> #^ "ສະບາຍດີ"
"ສະບາຍດີ"
=> #^1+2+3+4+3+2
1+2+3+4+3+2
Hy ບໍ່ມີຕົວຫນັງສືສໍາລັບ tuples. ໃຫ້ເວົ້າວ່າເຈົ້າບໍ່ມັກ (, ... ) ແລະຕ້ອງການອັນອື່ນ. ນີ້
ເປັນບັນຫາທີ່ຜູ້ອ່ານມະຫາພາກສາມາດແກ້ໄຂໄດ້ຢ່າງເປັນລະບຽບ.
=> (defreader t [expr] `(, ~@expr))
=> #t(1 2 3)
(1, 2, 3)
ເຈົ້າສາມາດເຮັດມັນຄືກັບ Clojure ແລະມີຕົວຫນັງສືສໍາລັບການສະແດງອອກເປັນປົກກະຕິ!
=> (ນໍາເຂົ້າໃຫມ່)
=> (defreader r [expr] `(re.compile ~expr))
=> #r "*"
<_sre.SRE_Pattern object at 0xcv7713ph15#>
ການປະຕິບັດ
ຜູ້ລະເມີດ ໃຊ້ຕົວອັກສອນດຽວເປັນຊື່ສັນຍາລັກສໍາລັບ macro ຜູ້ອ່ານ; ຫຍັງອີກແລ້ວ
ຈະສົ່ງຄືນຂໍ້ຜິດພາດ. ການປະຕິບັດຢ່າງສະຫລາດ, ຜູ້ລະເມີດ ຂະຫຍາຍເຂົ້າໄປໃນ lambda ທີ່ປົກຄຸມດ້ວຍ a
ອອກແບບ. ເຄື່ອງຕົກແຕ່ງນີ້ຊ່ວຍປະຢັດ lambda ໃນວັດຈະນານຸກົມທີ່ມີຊື່ໂມດູນຂອງມັນແລະ
ສັນຍາລັກ.
=> (defreader ^ [expr] (ພິມ expr))
;=> (with_decorator (hy.macros.reader ^) (fn [expr] (ພິມ expr)))
# ຂະຫຍາຍເຂົ້າໄປໃນ (dispatch_reader_macro ... ) ບ່ອນທີ່ສັນຍາລັກແລະການສະແດງອອກແມ່ນຖືກສົ່ງໄປຫາ
ການທໍາງານທີ່ຖືກຕ້ອງ.
=> #^()
;=> (dispatch_reader_macro ^ ())
=> #^ "ສະບາຍດີ"
"ສະບາຍດີ"
ຄໍາເຕືອນ:
ເນື່ອງຈາກຂໍ້ຈໍາກັດໃນ lexer ແລະ parser ຂອງ Hy, macro ຜູ້ອ່ານບໍ່ສາມາດກໍານົດຄືນໃຫມ່ໄດ້.
syntax ເຊັ່ນ ()[]{}. ອັນນີ້ສ່ວນຫຼາຍອາດຈະຖືກແກ້ໄຂໃນອະນາຄົດ.
ພາຍໃນ Hy ເອກະສານ
ຫມາຍເຫດ:
bits ເຫຼົ່ານີ້ແມ່ນສ່ວນໃຫຍ່ແມ່ນເປັນປະໂຫຍດສໍາລັບຄົນທີ່ hack ສຸດ Hy ຕົວຂອງມັນເອງ, ແຕ່ຍັງສາມາດຖືກນໍາໃຊ້ສໍາລັບ
ເຫຼົ່ານັ້ນ delving deeper ໃນໂຄງການມະຫາພາກ.
Hy ແບບຈໍາລອງ
ການນໍາສະເຫນີ to Hy ແບບຈໍາລອງ
ຮູບແບບ Hy ແມ່ນຊັ້ນບາງໆຢູ່ເທິງສຸດຂອງວັດຖຸ Python ປົກກະຕິ, ເຊິ່ງເປັນຕົວແທນຂອງແຫຼ່ງ Hy
ລະຫັດເປັນຂໍ້ມູນ. ຕົວແບບພຽງແຕ່ເພີ່ມຂໍ້ມູນຕໍາແຫນ່ງແຫຼ່ງ, ແລະວິທີການຈໍານວນຫນ້ອຍຫນຶ່ງ
ສະຫນັບສະຫນູນການຫມູນໃຊ້ທີ່ສະອາດຂອງລະຫັດແຫຼ່ງ Hy, ສໍາລັບຕົວຢ່າງໃນມະຫາພາກ. ເພື່ອບັນລຸໄດ້
ເປົ້າໝາຍ, ຮູບແບບ Hy ແມ່ນ mixins ຂອງຊັ້ນ Python ພື້ນຖານ ແລະ HyObject.
HyObject
hy.models.HyObject ແມ່ນຊັ້ນພື້ນຖານຂອງແບບ Hy. ມັນພຽງແຕ່ປະຕິບັດວິທີການຫນຶ່ງ, ທົດແທນ,
ເຊິ່ງແທນທີ່ຕໍາແໜ່ງແຫຼ່ງຂອງວັດຖຸປັດຈຸບັນດ້ວຍອັນທີ່ຜ່ານເປັນ argument.
ນີ້ອະນຸຍາດໃຫ້ພວກເຮົາຕິດຕາມຕໍາແຫນ່ງຕົ້ນສະບັບຂອງການສະແດງອອກທີ່ໄດ້ຮັບການດັດແກ້ໂດຍ
macro, ບໍ່ວ່າຈະຢູ່ໃນ compiler ຫຼືໃນ macro hy ບໍລິສຸດ.
HyObject ບໍ່ໄດ້ມີຈຸດປະສົງເພື່ອຖືກນໍາໃຊ້ໂດຍກົງກັບຕົວແບບ Hy, ແຕ່ພຽງແຕ່ເປັນ mixin
ສໍາລັບຫ້ອງຮຽນອື່ນໆ.
ສົມທົບ ແບບຈໍາລອງ
ລາຍຊື່ວົງເລັບ ແລະວົງເລັບຖືກວິເຄາະເປັນຕົວແບບປະສົມໂດຍ Hy parser.
HyList
hy.models.list.HyList ແມ່ນຊັ້ນພື້ນຖານຂອງແບບ Hyterable "ມັນ". ການນໍາໃຊ້ພື້ນຖານຂອງມັນແມ່ນເພື່ອ
ເປັນຕົວແທນຂອງວົງເລັບ [] lists, ເຊິ່ງ, ເມື່ອໃຊ້ເປັນການສະແດງອອກໃນລະດັບສູງສຸດ, ແປເປັນ
Python ລາຍຊື່ຕົວຫນັງສືໃນໄລຍະການລວບລວມ.
ການເພີ່ມ HyList ໃຫ້ກັບວັດຖຸທີ່ເຮັດໄດ້ຊໍ້າກັນອີກຈະໃຊ້ class ຂອງວັດຖຸດ້ານຊ້າຍມືຄືນໃໝ່,
ພຶດຕິກໍາທີ່ເປັນປະໂຫຍດໃນເວລາທີ່ທ່ານຕ້ອງການ concatenate Hy objects ໃນ macro, ສໍາລັບການຍົກຕົວຢ່າງ.
HyExpression
hy.models.expression.HyExpression ມູນມໍລະດົກ HyList ສໍາລັບວົງເລັບ () ການສະແດງອອກ. ໄດ້
ຜົນການລວບລວມຂອງສຳນວນເຫຼົ່ານັ້ນແມ່ນຂຶ້ນກັບອົງປະກອບທຳອິດຂອງລາຍການ: the
compiler ສົ່ງການສະແດງອອກລະຫວ່າງ compiler ແບບຟອມພິເສດ, macros ທີ່ກໍານົດໂດຍຜູ້ໃຊ້, ແລະ
ການໂທຟັງຊັນ Python ປົກກະຕິ.
HyDict
hy.models.dict.HyDict ມູນມໍລະດົກ HyList ສໍາລັບ curly-blocked {} ການສະແດງອອກ, ເຊິ່ງລວບລວມ
ລົງໄປຫາວັດຈະນານຸກົມ Python ທີ່ຮູ້ຫນັງສື.
ການຕັດສິນໃຈຂອງການນໍາໃຊ້ບັນຊີລາຍຊື່ແທນທີ່ຈະເປັນ dict ເປັນຫ້ອງຮຽນພື້ນຖານສໍາລັບ HyDict ອະນຸຍາດໃຫ້ງ່າຍຂຶ້ນ
ການຫມູນໃຊ້ຂອງ dicts ໃນມະຫາພາກ, ມີຜົນປະໂຫຍດເພີ່ມເຕີມຂອງການອະນຸຍາດໃຫ້ສໍານວນປະສົມ
ເປັນ dict keys (ເປັນ, ສໍາລັບການຍົກຕົວຢ່າງ, the HyExpression ຫ້ອງຮຽນ Python ແມ່ນບໍ່ສາມາດ hashable).
ປະລໍາມະນູ ແບບຈໍາລອງ
ໃນກະແສການປ້ອນຂໍ້ມູນ, ສະຕຣິງທີ່ອ້າງອີງສອງເທື່ອ, ໂດຍເຄົາລົບໝາຍເຫດ Python ສຳລັບສະຕຣິງ,
ຖືກແຍກວິເຄາະເປັນໂທເຄັນດຽວ, ເຊິ່ງຖືກວິເຄາະໂດຍກົງເປັນ a HyString.
ຕົວອັກສອນທີ່ບໍ່ຕິດຂັດ, ບໍ່ລວມເອົາຍະຫວ່າງ, ວົງເລັບ, ວົງຢືມ, ວົງຢືມຄູ່
ແລະຄໍາຄິດເຫັນ, ຖືກວິເຄາະເປັນຕົວລະບຸ.
ຕົວລະບຸຖືກແກ້ໄຂເປັນແບບຈຳລອງປະລໍາມະນູໃນລະຫວ່າງໄລຍະການແຍກວິເຄາະຕາມລຳດັບຕໍ່ໄປນີ້:
· HyInteger
· HyFloat
· HyComplex (ຖ້າປະລໍາມະນູບໍ່ແມ່ນເປົ່າ j)
· HyKeyword (ຖ້າປະລໍາມະນູເລີ່ມຕົ້ນດ້ວຍ :)
· ສັນຍາລັກ
HyString
hy.models.string.HyString ແມ່ນຊັ້ນພື້ນຖານຂອງແບບສະຕຣິງທຽບເທົ່າ Hy. ມັນຍັງ
ເປັນຕົວແທນຂອງຕົວໜັງສືສະຕຣິງທີ່ອ້າງອີງສອງເທົ່າ, "", ເຊິ່ງລວບລວມລົງເປັນ unicode string
ຕົວໜັງສືໃນ Python. HyStrings ສືບທອດວັດຖຸ unicode ໃນ Python 2, ແລະ string objects ໃນ
Python 3 (ແລະດັ່ງນັ້ນຈຶ່ງບໍ່ຂຶ້ນກັບການເຂົ້າລະຫັດ).
HyString ຮູບແບບພື້ນຖານແມ່ນບໍ່ສາມາດປ່ຽນແປງໄດ້.
ສະຕຣິງຕົວໜັງສື Hy ສາມາດຂະຫຍາຍໄດ້ຫຼາຍສາຍ, ແລະຖືກພິຈາລະນາໂດຍຕົວວິເຄາະເປັນສາຍດຽວ
ຫນ່ວຍບໍລິການ, ເຄົາລົບ Python escapes ສໍາລັບ unicode strings.
Numeric ແບບຈໍາລອງ
hy.models.integer.HyInteger ເປັນຕົວແທນຂອງຕົວໜັງສືຈຳນວນເຕັມ (ໂດຍໃຊ້ ຍາວ ພິມຢູ່ໃນ Python 2,
ແລະ int ໃນ Python 3).
hy.models.float.HyFloat ເປັນຕົວແທນຂອງຕົວໜັງສືຈຸດລອຍ.
hy.models.complex.HyComplex ເປັນຕົວແທນຂອງຕົວຫນັງສືທີ່ສັບສົນ.
ໂມເດວຕົວເລກຖືກແຍກວິເຄາະໂດຍໃຊ້ Python routine ທີ່ສອດຄ້ອງກັນ, ແລະ python ຕົວເລກທີ່ຖືກຕ້ອງ
ຕົວໜັງສືຈະຖືກປ່ຽນເປັນ Hy ຂອງເຂົາເຈົ້າ.
ສັນຍາລັກ
hy.models.symbol.HySymbol ແມ່ນຕົວແບບທີ່ໃຊ້ເພື່ອເປັນຕົວແທນຂອງສັນຍາລັກໃນພາສາ Hy. ມັນ
ມູນມໍລະດົກ HyString.
ສັນຍາລັກ ວັດຖຸຖືກປົນເປື້ອນຢູ່ໃນຂັ້ນຕອນການແຍກວິເຄາະ, ເພື່ອຊ່ວຍໃຫ້ການເຮັດວຽກຮ່ວມກັນຂອງ Python:
·ສັນຍາລັກທີ່ອ້ອມຮອບດ້ວຍດາວ (*) ຖືກປ່ຽນເປັນຕົວພິມໃຫຍ່;
· ຂີດຕໍ່ (-) ຖືກປ່ຽນເປັນຂີດກ້ອງ (_);
· ຫນຶ່ງເຄື່ອງຫມາຍຄໍາຖາມຕໍ່ຫນ້າ (?) ໄດ້ກາຍເປັນການນໍາ ແມ່ນ_.
Caveat: ເປັນ mangling ແມ່ນເຮັດໄດ້ໃນໄລຍະ parsing, ມັນເປັນໄປໄດ້
ໂປຣແກມສ້າງ HySymbols ທີ່ບໍ່ສາມາດສ້າງດ້ວຍລະຫັດແຫຼ່ງ Hy. ດັ່ງກ່າວເປັນ
ກົນໄກຖືກນໍາໃຊ້ໂດຍ gensym ເພື່ອສ້າງສັນຍາລັກ "uninterned".
HyKeyword
hy.models.keyword.HyKeyword ເປັນຕົວແທນຂອງຄໍາສໍາຄັນໃນ Hy. ຄໍາສໍາຄັນແມ່ນສັນຍາລັກເລີ່ມຕົ້ນດ້ວຍ
a :. ຫ້ອງຮຽນສືບທອດ HyString.
ເພື່ອ ຈຳ ແນກ HyKeywords ຈາກ ສັນຍາລັກ, ໂດຍບໍ່ມີຄວາມເປັນໄປໄດ້ຂອງ (ບໍ່ສະຫມັກໃຈ)
ການປະທະກັນ, ລັກສະນະສ່ວນຕົວທີ່ໃຊ້ unicode "\uFDD0" ແມ່ນ prepended ກັບຄໍາທີ່ຮູ້ຫນັງສື
ກ່ອນທີ່ຈະເກັບຮັກສາ.
cons ຈຸລັງ
hy.models.cons.HyCons ເປັນຕົວແທນຂອງ Python-friendly cons ຈຸລັງ. ຈຸລັງ cons ແມ່ນ
ໂດຍສະເພາະແມ່ນເປັນປະໂຫຍດເພື່ອເຮັດຕາມລັກສະນະຂອງຕົວແປ LISP "ປົກກະຕິ" ເຊັ່ນ Scheme ຫຼື Common
ລີສ.
ເຊລ cons ແມ່ນວັດຖຸ 2 ລາຍການ, ປະກອບມີ a ລົດ (ຫົວ) ແລະ ກ cdr (ຫາງ). ໃນບາງ Lisp
variants, ຈຸລັງ cons ແມ່ນການກໍ່ສ້າງພື້ນຖານ, ແລະ S-expressions ແມ່ນຕົວຈິງແລ້ວ
ເປັນຕົວແທນເປັນລາຍການເຊື່ອມຕໍ່ຂອງຈຸລັງ cons. ນີ້ບໍ່ແມ່ນກໍລະນີໃນ Hy, ຕາມປົກກະຕິ
ການສະແດງອອກແມ່ນເຮັດຈາກລາຍຊື່ Python ຫໍ່ດ້ວຍ a HyExpressionທີ່ຢູ່ ຢ່າງໃດກໍ່ຕາມ, ໄດ້ HyCons
mimics ພຶດຕິກໍາຂອງຕົວແປ Lisp "ປົກກະຕິ" ດັ່ງນັ້ນ:
· (ຂໍ້ເສຍ ບາງສິ່ງບາງຢ່າງ nil) is (HyExpression [ບາງສິ່ງບາງຢ່າງ])
· (ຂໍ້ເສຍ ບາງສິ່ງບາງຢ່າງ ບາງລາຍການ) is ((ປະເພດ ບາງລາຍການ) (+ [ບາງສິ່ງບາງຢ່າງ] ບັນຊີລາຍຊື່ບາງ)) (if
ບາງລາຍການ ສືບທອດມາຈາກ ບັນຊີລາຍຊື່).
· (ໄດ້ຮັບ (ຂໍ້ເສຍ a b) 0) is a
· (ຊອຍ (ຂໍ້ເສຍ a b) 1) is b
Hy ສະຫນັບສະຫນູນ syntax ບັນຊີລາຍຊື່ dotted, ບ່ອນທີ່ '(ກ . b) ວິທີການ (ຂໍ້ເສຍ 'a 'ຂ) ແລະ '(ກ b . c) ວິທີການ
(ຂໍ້ເສຍ 'a (ຂໍ້ເສຍ 'b 'ຄ)). ຖ້າ compiler ພົບ cell cons ໃນລະດັບສູງສຸດ, ມັນເພີ່ມຂຶ້ນ
ການລວບລວມຄວາມຜິດພາດ.
HyCons wraps ການໂຕ້ຖຽງຜ່ານການ (ລົດແລະ cdr) ໃນປະເພດ Hy, ເພື່ອງ່າຍດາຍການຫມູນໃຊ້ຂອງ
ເຊລ cons ໃນບໍລິບົດມະຫາພາກ.
Hy ພາຍໃນ ທິດສະດີ
ພາບລວມ
ພາຍໃນ Hy ເຮັດວຽກໂດຍການເຮັດຫນ້າທີ່ເປັນຕົວຕໍ່ຫນ້າຂອງ Python bytecode, ດັ່ງນັ້ນ Hy ຕົວຂອງມັນເອງ
ລວບລວມລົງເປັນ Python Bytecode, ອະນຸຍາດໃຫ້ runtime Python ທີ່ບໍ່ມີການດັດແກ້ເພື່ອແລ່ນລະຫັດ Hy,
ໂດຍບໍ່ໄດ້ສັງເກດເຫັນມັນ.
ວິທີທີ່ພວກເຮົາເຮັດນີ້ແມ່ນໂດຍການແປ Hy ເຂົ້າໄປໃນໂຄງສ້າງຂໍ້ມູນພາຍໃນ Python AST, ແລະ
ການສ້າງ AST ເຂົ້າໄປໃນ Python bytecode ໂດຍໃຊ້ໂມດູນຈາກມາດຕະຖານ Python
ຫໍສະຫມຸດ, ດັ່ງນັ້ນພວກເຮົາບໍ່ຈໍາເປັນຕ້ອງຊ້ໍາກັນການເຮັດວຽກຂອງ Python ພາຍໃນສໍາລັບທຸກໆ
ການປ່ອຍ Python ດຽວ.
Hy ເຮັດວຽກຢູ່ໃນສີ່ຂັ້ນຕອນ. ພາກສ່ວນຕໍ່ໄປນີ້ຈະກວມເອົາແຕ່ລະຂັ້ນຕອນຂອງ Hy ຈາກແຫຼ່ງໄປຫາ
ເວລາແລ່ນ.
ຂັ້ນຕອນ 1 ແລະ 2: Tokenizing ແລະ ກຳ ລັງທັບເຮືອ
ຂັ້ນຕອນທໍາອິດຂອງການລວບລວມ Hy ແມ່ນເພື່ອ lex ແຫຼ່ງເຂົ້າໄປໃນ tokens ທີ່ພວກເຮົາສາມາດຈັດການກັບ. ພວກເຮົາ
ໃຊ້ໂຄງການທີ່ເອີ້ນວ່າ rply, ເຊິ່ງເປັນຕົວວິເຄາະທີ່ງາມ (ແລະໄວ), ຂຽນເປັນຊຸດຍ່ອຍ
ຂອງ Python ເອີ້ນວ່າ rpython.
ລະຫັດ lexing ແມ່ນຖືກກໍານົດໄວ້ທັງຫມົດໃນ hy.lex.lexer. ລະຫັດນີ້ສ່ວນຫຼາຍແມ່ນພຽງແຕ່ກໍານົດ Hy
ໄວຍະກອນ, ແລະທຸກພາກສ່ວນທີ່ຍາກທີ່ແທ້ຈິງໄດ້ຖືກປະຕິບັດໂດຍ rply - ພວກເຮົາພຽງແຕ່ກໍານົດ
"callbacks" ສໍາລັບ rply ໃນ hy.lex.parser, ເຊິ່ງໃຊ້ເວລາ tokens ທີ່ສ້າງຂຶ້ນ, ແລະສົ່ງຄືນ
ແບບ Hy.
ທ່ານສາມາດຄິດວ່າຕົວແບບ Hy ເປັນ "AST" ສໍາລັບ Hy, ມັນແມ່ນສິ່ງທີ່ Macros ດໍາເນີນການ
(ໂດຍກົງ), ແລະມັນເປັນສິ່ງທີ່ compiler ໃຊ້ໃນເວລາທີ່ມັນລວບລວມ Hy ລົງ.
ເບິ່ງ ຍັງ:
ສ່ວນ Hy ແບບຈໍາລອງ ສໍາລັບຂໍ້ມູນເພີ່ມເຕີມກ່ຽວກັບ Hy model ແລະສິ່ງທີ່ພວກເຂົາຫມາຍຄວາມວ່າ.
ຂັ້ນຕອນ 3: Hy ການລວບລວມ to Python AST
ນີ້ແມ່ນບ່ອນທີ່ magic ສ່ວນໃຫຍ່ໃນ Hy ເກີດຂຶ້ນ. ນີ້ແມ່ນບ່ອນທີ່ພວກເຮົາເອົາ Hy AST (ຕົວແບບ),
ແລະລວບລວມພວກມັນເຂົ້າໄປໃນ Python AST. ສອງສາມສິ່ງທີ່ຂີ້ຄ້ານເກີດຂຶ້ນຢູ່ບ່ອນນີ້ເພື່ອເຮັດວຽກຜ່ານມາສອງສາມຢ່າງ
ບັນຫາໃນ AST, ແລະການເຮັດວຽກໃນ compiler ແມ່ນບາງວຽກທີ່ສໍາຄັນທີ່ສຸດທີ່ພວກເຮົາເຮັດ
ມີ.
compiler ແມ່ນສັບສົນເລັກນ້ອຍ, ສະນັ້ນຢ່າຮູ້ສຶກບໍ່ດີຖ້າທ່ານບໍ່ເຮັດມັນໃນການສັກຢາຄັ້ງທໍາອິດ,
ມັນອາດຈະໃຊ້ເວລາເລັກນ້ອຍເພື່ອໃຫ້ຖືກຕ້ອງ.
ຈຸດເຂົ້າຕົ້ນຕໍຂອງ Compiler ແມ່ນ HyASTCompiler.compile. ວິທີການນີ້ແມ່ນ invoked, ແລະ
ວິທີການ "ສາທາລະນະ" ທີ່ແທ້ຈິງພຽງແຕ່ຢູ່ໃນຫ້ອງຮຽນ (ຫມາຍຄວາມວ່າ, ພວກເຮົາບໍ່ໄດ້ສັນຍາຢ່າງແທ້ຈິງ
API ນອກຈາກວິທີການທີ່).
ໃນຄວາມເປັນຈິງ, ເຖິງແມ່ນວ່າພາຍໃນ, ພວກເຮົາບໍ່ໄດ້ປະຕິເສດໂດຍກົງ, ພວກເຮົາເກືອບສະເຫມີບັງຄັບ
ຕົ້ນໄມ້ Hy ຜ່ານ ລວບລວມ, ແລະມັກຈະເຮັດສິ່ງນີ້ດ້ວຍອົງປະກອບຍ່ອຍຂອງການສະແດງຜົນ
ທີ່ພວກເຮົາມີ. ມັນຂຶ້ນກັບຜູ້ສົ່ງຕໍ່ປະເພດເພື່ອສົ່ງອົງປະກອບຍ່ອຍຢ່າງຖືກຕ້ອງ.
ວິທີການທັງຫມົດທີ່ preform ການລວບລວມແມ່ນຫມາຍດ້ວຍ @builds() ອອກແບບ. ເຈົ້າສາມາດ
ບໍ່ວ່າຈະຜ່ານຫ້ອງຮຽນຂອງຮູບແບບ Hy ທີ່ມັນລວບລວມ, ຫຼືທ່ານສາມາດນໍາໃຊ້ string ສໍາລັບ
ການສະແດງອອກ. ຂ້ອຍຈະລຶບມັນອອກໃນວິນາທີ.
ຫນ້າທໍາອິດ ຂັ້ນຕອນຂອງການ ປະເພດການຈັດສົ່ງ
ໃຫ້ເລີ່ມຕົ້ນໃນ ລວບລວມ ວິທີການ. ສິ່ງທໍາອິດທີ່ພວກເຮົາເຮັດແມ່ນກວດເບິ່ງປະເພດຂອງສິ່ງນັ້ນ
ພວກເຮົາກໍາລັງກໍ່ສ້າງ. ພວກເຮົາຊອກຫາເບິ່ງວ່າພວກເຮົາມີວິທີການທີ່ສາມາດສ້າງໄດ້ ປະເພດ() ວ່າພວກເຮົາ
ມີ, ແລະສົ່ງກັບວິທີການທີ່ສາມາດຈັດການກັບມັນໄດ້. ຖ້າພວກເຮົາບໍ່ມີວິທີການໃດໆທີ່ສາມາດເຮັດໄດ້
ການກໍ່ສ້າງປະເພດນັ້ນ, ພວກເຮົາຍົກສູງບົດບາດພາຍໃນ ຂໍ້ຍົກເວັ້ນ.
ສໍາລັບຕົວຢ່າງ, ຖ້າພວກເຮົາມີ a HyString, ພວກເຮົາມີແຜນທີ່ເກືອບ 1 ຕໍ່ 1 ຂອງ Hy AST ກັບ Python
AST. ໄດ້ compile_string ວິທີການໃຊ້ເວລາ HyString, ແລະສົ່ງຄືນເປັນ ast.Str() ນັ້ນແມ່ນ
ຕື່ມຂໍ້ມູນໃສ່ດ້ວຍຕົວເລກ ແລະ ເນື້ອໃນທີ່ຖືກຕ້ອງ.
ຂະຫຍາຍມະຫາພາກ
ຖ້າພວກເຮົາໄດ້ຮັບ a HyExpression, ພວກເຮົາຈະພະຍາຍາມເບິ່ງວ່ານີ້ແມ່ນ Macro ທີ່ຮູ້ຈັກ, ແລະຊຸກຍູ້ໃຫ້ມີ
ມັນຂະຫຍາຍອອກໂດຍການຮຽກຮ້ອງ hy.macros.macroexpand, ຫຼັງຈາກນັ້ນຍູ້ຜົນໄດ້ຮັບກັບຄືນໄປບ່ອນເຂົ້າໄປໃນ
HyASTCompiler.compile.
ຄັ້ງທີສອງ ຂັ້ນຕອນຂອງການ ການສະແດງອອກ-ການຈັດສົ່ງ
ກໍລະນີພິເສດພຽງແຕ່ແມ່ນ HyExpression, ເນື່ອງຈາກວ່າພວກເຮົາຈໍາເປັນຕ້ອງສ້າງ AST ທີ່ແຕກຕ່າງກັນຂຶ້ນກັບ
ໃນແບບຟອມພິເສດໃນຄໍາຖາມ. ສໍາລັບຕົວຢ່າງ, ໃນເວລາທີ່ພວກເຮົາຕີ (if ທີ່ແທ້ຈິງ ທີ່ແທ້ຈິງ ຜິດ), ພວກເຮົາ
ຈໍາເປັນຕ້ອງໄດ້ສ້າງເປັນ ast.ຖ້າ, ແລະລວບລວມຂໍ້ຍ່ອຍໄດ້ຢ່າງຖືກຕ້ອງ. ນີ້ແມ່ນບ່ອນທີ່ @builds()
ມີ String ເປັນ argument ເຂົ້າມາ.
ສໍາລັບ compile_expression (ເຊິ່ງຖືກກໍານົດດ້ວຍ @builds(HyExpression)) ຈະຈັດສົ່ງ
ອີງໃສ່ສະຕຣິງຂອງການໂຕ້ຖຽງທໍາອິດ. ຖ້າຫາກວ່າ, ສໍາລັບເຫດຜົນບາງຢ່າງ, ການໂຕ້ຖຽງທໍາອິດບໍ່ແມ່ນ
ຊ່ອຍແນ່, ມັນຈະຈັດການກໍລະນີນັ້ນໄດ້ຢ່າງຖືກຕ້ອງ (ສ່ວນຫຼາຍອາດຈະເປັນໂດຍການລ້ຽງ ຂໍ້ຍົກເວັ້ນ).
ຖ້າ String ບໍ່ຮູ້ຈັກ Hy, ມັນຈະເປັນຄ່າເລີ່ມຕົ້ນທີ່ຈະສ້າງ ast.ໂທ, ເຊິ່ງຈະພະຍາຍາມ
ໂທຫາ runtime (ໃນ Python, ບາງສິ່ງບາງຢ່າງເຊັ່ນ: foo()).
ບັນຫາ ມົນຕີ ກັບ Python AST
Python AST ແມ່ນຍິ່ງໃຫຍ່; ມັນເປັນສິ່ງທີ່ຊ່ວຍໃຫ້ພວກເຮົາຂຽນໂຄງການທີ່ມີປະສິດທິພາບດັ່ງກ່າວຢູ່ເທິງສຸດ
Python ໂດຍບໍ່ຈໍາເປັນຕ້ອງຕໍ່ສູ້ກັບ Python ຍາກເກີນໄປ. ເຊັ່ນດຽວກັບສິ່ງໃດກໍ່ຕາມ, ພວກເຮົາມີສ່ວນແບ່ງຍຸດຕິທໍາຂອງພວກເຮົາ
ບັນຫາ, ແລະນີ້ແມ່ນບັນຊີລາຍຊື່ສັ້ນຂອງເລື່ອງທົ່ວໄປທີ່ເຈົ້າອາດຈະພົບ.
Python ຄວາມແຕກຕ່າງ ລະຫວ່າງ ບົດລາຍງານ ແລະ ສຳ ນວນ.
ນີ້ອາດຈະບໍ່ເບິ່ງຄືວ່າເປັນເລື່ອງໃຫຍ່ - ໃນຄວາມເປັນຈິງ, ສໍາລັບນັກຂຽນໂປລແກລມ Python ສ່ວນໃຫຍ່, ນີ້ຈະເປັນ
ກາຍເປັນຊ່ວງເວລາ "ດີ, ແມ່ນແລ້ວ".
ໃນ Python, ເຮັດບາງສິ່ງບາງຢ່າງເຊັ່ນ:
ພິມ ສໍາລັບການ x in ລະດັບ(10): ຜ່ານ, ເພາະວ່າ ພິມ ພິມສໍານວນ, ແລະ ສໍາລັບການ ບໍ່ແມ່ນ
ການສະແດງອອກ, ມັນເປັນຄໍາຖະແຫຼງການໄຫຼຄວບຄຸມ. ສິ່ງທີ່ມັກ 1 + 1 ແມ່ນການສະແດງອອກ, ເຊັ່ນດຽວກັບ lambda
x: 1 + x, ແຕ່ລັກສະນະພາສາອື່ນໆ, ເຊັ່ນ: if, ສໍາລັບການ, ຫຼື ໃນຂະນະທີ່ ແມ່ນຄໍາຖະແຫຼງການ.
ເນື່ອງຈາກພວກເຂົາບໍ່ມີ "ຄຸນຄ່າ" ສໍາລັບ Python, ນີ້ເຮັດໃຫ້ການເຮັດວຽກຢູ່ໃນ Hy ຍາກ, ນັບຕັ້ງແຕ່ເຮັດບາງສິ່ງບາງຢ່າງ
ຄື (ພິມ (if ທີ່ແທ້ຈິງ ທີ່ແທ້ຈິງ ຜິດ)) ບໍ່ພຽງແຕ່ເປັນເລື່ອງທໍາມະດາ, ມັນຄາດວ່າ.
ດັ່ງນັ້ນ, ພວກເຮົາຈັດການສິ່ງຕ່າງໆໂດຍອັດຕະໂນມັດໂດຍໃຊ້ a ຜົນ ວັດຖຸ, ບ່ອນທີ່ພວກເຮົາສະເຫນີໃຫ້ເຖິງໃດໆ ast.stmt
ທີ່ຈໍາເປັນຕ້ອງໄດ້ຮັບການດໍາເນີນການ, ແລະດຽວ ast.expr ທີ່ສາມາດໃຊ້ເພື່ອໃຫ້ໄດ້ຄຸນຄ່າຂອງສິ່ງໃດກໍ່ຕາມ
ແມ່ນພຽງແຕ່ດໍາເນີນການ. Hy ເຮັດສິ່ງນີ້ໂດຍການບັງຄັບມອບຫມາຍໃຫ້ສິ່ງຕ່າງໆໃນຂະນະທີ່ແລ່ນ.
ສໍາລັບຕົວຢ່າງ, Hy:
(ພິມ (ຖ້າເປັນຈິງບໍ່ຖືກຕ້ອງ))
ຈະກາຍເປັນ:
ຖ້າເປັນຄວາມຈິງ:
_mangled_name_here = ຖືກ
ອື່ນ:
_mangled_name_here = ບໍ່ຖືກຕ້ອງ
ພິມ _mangled_name_here
ຕົກລົງ, ມັນເປັນເລື່ອງຕົວະເລັກນ້ອຍ, ເພາະວ່າພວກເຮົາປ່ຽນຄຳຖະແຫຼງນັ້ນເປັນ:
ພິມ True ຖ້າເປັນຈິງອີກຜິດ
ໂດຍບັງຄັບໃຫ້ສິ່ງຕ່າງໆເຂົ້າໄປໃນ ast.expr ຖ້າພວກເຮົາສາມາດເຮັດໄດ້, ແຕ່ແນວຄວາມຄິດທົ່ວໄປແມ່ນຖື.
ຂັ້ນຕອນ 4: Python ລະຫັດໄບຕ ຜົນຜະລິດ ແລະ ເວລາແລ່ນ
ຫຼັງຈາກທີ່ພວກເຮົາມີຕົ້ນໄມ້ Python AST ທີ່ສົມບູນ, ພວກເຮົາສາມາດພະຍາຍາມລວບລວມມັນກັບ Python
bytecode ໂດຍການຍູ້ມັນຜ່ານ ການປະເມີນ. ຈາກນີ້ສຸດອອກ, ພວກເຮົາບໍ່ມີຕໍ່ໄປອີກແລ້ວໃນການຄວບຄຸມ, ແລະ
Python ກໍາລັງເບິ່ງແຍງທຸກຢ່າງ. ນີ້ແມ່ນເຫດຜົນທີ່ວ່າສິ່ງຕ່າງໆເຊັ່ນ Python tracebacks, pdb ແລະ
ແອັບຯ django ເຮັດວຽກ.
Hy ມາໂຄຣ
ການນໍາໃຊ້ gensym ສໍາລັບການ ປອດໄພ ມາໂຄຣ
ໃນເວລາທີ່ຂຽນ macro, ຫນຶ່ງຕ້ອງລະມັດລະວັງເພື່ອຫຼີກເວັ້ນການຈັບຕົວແປພາຍນອກຫຼືການນໍາໃຊ້
ຊື່ຕົວແປທີ່ອາດຈະຂັດກັບລະຫັດຜູ້ໃຊ້.
ພວກເຮົາຈະໃຊ້ macro ຕົວຢ່າງ nif (ເບິ່ງ
http://letoverlambda.com/index.cl/guest/chap3.html#sec_5 ສໍາລັບຄໍາອະທິບາຍທີ່ສົມບູນຫຼາຍ.)
nif ເປັນຕົວຢ່າງ, ບາງສິ່ງບາງຢ່າງເຊັ່ນ: ຕົວເລກ if, ບ່ອນທີ່ອີງໃສ່ການສະແດງອອກ, ຫນຶ່ງໃນ
3 ຮູບແບບແມ່ນເອີ້ນວ່າຂຶ້ນກັບການສະແດງອອກເປັນບວກ, ສູນຫຼືລົບ.
ການຜ່ານຄັ້ງທຳອິດອາດຈະເປັນສິ່ງເຊັ່ນ:
(defmacro nif [expr pos-form zero-form neg-form]
`(ໃຫ້ [[obscure-name ~expr]]
(cond [(pos? obscure-name) ~pos-form]
[(ສູນ? obscure-name) ~ zero-form]
[(neg? obscure-name) ~neg-form])))
ບ່ອນທີ່ obsure ຊື່ ແມ່ນຄວາມພະຍາຍາມທີ່ຈະເລືອກເອົາບາງຊື່ຕົວແປເພື່ອບໍ່ໃຫ້ຂັດກັບອັນອື່ນ
ລະຫັດ. ແຕ່ແນ່ນອນ, ໃນຂະນະທີ່ມີຄວາມຕັ້ງໃຈດີ, ນີ້ບໍ່ແມ່ນການຮັບປະກັນ.
ວິທີການ gensym ຖືກອອກແບບມາເພື່ອສ້າງສັນຍາລັກໃຫມ່, ເປັນເອກະລັກສໍາລັບໂອກາດດັ່ງກ່າວ.
ສະບັບທີ່ດີກວ່າຫຼາຍຂອງ nif ຈະເປັນ:
(defmacro nif [expr pos-form zero-form neg-form]
(ໃຫ້ [[g (gensym)]]
`(ໃຫ້ [[~g ~expr]]
(cond [(pos? ~g) ~pos-form]
[(ສູນ? ~g) ~ zero-form]
[(neg? ~g) ~neg-form]))))
ນີ້ແມ່ນກໍລະນີທີ່ງ່າຍ, ເພາະວ່າມີພຽງແຕ່ສັນຍາລັກດຽວ. ແຕ່ຖ້າມີຄວາມຕ້ອງການຫຼາຍ
gensym ຂອງມີມະຫາພາກທີສອງທີ່ມີ gensyms ພື້ນຖານທີ່ຂະຫຍາຍໄປສູ່ຊຸດຂອງ ໃຫ້
ຖະແຫຼງການ:
(with-gensyms [abc]
... )
ຂະຫຍາຍໄປ:
(ໃຫ້ [[a (gensym)
[b (gensym)
[c (gensym)]]
... )
ດັ່ງນັ້ນພວກເຮົາຂຽນຄືນໃຫມ່ nif ເບິ່ງຄືວ່າ:
(defmacro nif [expr pos-form zero-form neg-form]
(ກັບ gensyms [g]
`(ໃຫ້ [[~g ~expr]]
(cond [(pos? ~g) ~pos-form]
[(ສູນ? ~g) ~ zero-form]
[(neg? ~g) ~neg-form]))))
ສຸດທ້າຍ, ເຖິງແມ່ນວ່າພວກເຮົາສາມາດສ້າງມະຫາພາກໃຫມ່ທີ່ເຮັດທັງຫມົດນີ້ສໍາລັບພວກເຮົາ. defmacro/g! ຈະໃຊ້ເວລາ
ສັນຍາລັກທັງຫມົດທີ່ເລີ່ມຕົ້ນດ້ວຍ g! ແລະອັດຕະໂນມັດໂທຫາ gensym ກັບສ່ວນທີ່ເຫຼືອຂອງ
ສັນຍາລັກ. ດັ່ງນັ້ນ g!a ຈະກາຍເປັນ (gensym "ກ").
ສະບັບສຸດທ້າຍຂອງພວກເຮົາຂອງ nif, ສ້າງດ້ວຍ defmacro/g! ກາຍເປັນ:
(defmacro/g! nif [expr pos-form zero-form neg-form]
`(ໃຫ້ [[~g!res ~expr]]
(cond [(pos? ~g!res) ~pos-form]
[(ສູນ? ~g!res) ~ສູນແບບຟອມ]
[(neg? ~g!res) ~neg-form]))))
ການກວດສອບ Macro Arguments ແລະ ການລ້ຽງ ຂໍ້ຍົກເວັ້ນ
Hy ຜູ້ລວບລວມຂໍ້ມູນ Built-Ins
ຜູ້ຄວບຄຸມ MODULES INDEX
ເນື້ອໃນ:
ອະເນກປະສົງ ມາໂຄຣ
ໃໝ່ໃນເວີຊັ່ນ 0.9.12.
ໂມດູນ macro anaphoric ເຮັດໃຫ້ການຂຽນໂປລແກລມທີ່ມີປະໂຫຍດໃນ Hy ຫຼາຍ concise ແລະງ່າຍທີ່ຈະ
ອ່ານ
macro anaphoric ແມ່ນປະເພດຂອງ macro ການຂຽນໂປລແກລມທີ່ເຈດຕະນາເກັບກໍາບາງຮູບແບບ
ສະໜອງໃຫ້ແກ່ມະຫາພາກທີ່ອາດຈະຖືກກ່າວເຖິງໂດຍ anaphor (ການສະແດງອອກໂດຍອ້າງອີງ
ກັບຄົນອື່ນ). — ວິກິພີເດຍ (http://en.wikipedia.org/wiki/Anaphoric_macro)
ມາໂຄຣ
ap-if
ການນໍາໃຊ້: (ap-if (foo) (ພິມ ມັນ))
ປະເມີນຮູບແບບທໍາອິດສໍາລັບຄວາມຈິງ, ແລະຜູກມັດມັນ it ທັງໃນຄວາມຈິງແລະບໍ່ຖືກຕ້ອງ
ສາຂາ.
ap-ແຕ່ລະ
ການນໍາໃຊ້: (ແຕ່ລະອັນ [1 2 3 4 5] (ພິມ ມັນ))
ປະເມີນແບບຟອມສໍາລັບແຕ່ລະອົງປະກອບໃນບັນຊີລາຍຊື່ສໍາລັບຜົນກະທົບຂ້າງຄຽງ.
ap-ແຕ່ລະຂະນະ
ການນໍາໃຊ້: (ap-ແຕ່ລະຄັ້ງ ບັນຊີລາຍຊື່ ຄາດ ຮ່າງກາຍ)
ປະເມີນແບບຟອມສໍາລັບແຕ່ລະອົງປະກອບທີ່ແບບຟອມ predicate ກັບຄືນມາ ທີ່ແທ້ຈິງ.
=> (ap-each-while [1 2 3 4 5 6] (< ມັນ 4) (ພິມມັນ))
1
2
3
ແຜນທີ່
ການນໍາໃຊ້: (ap-map ຮູບແບບ ບັນຊີລາຍຊື່)
ຮູບແບບ anaphoric ຂອງແຜນທີ່ເຮັດວຽກຄືກັນກັບແຜນທີ່ປົກກະຕິເວັ້ນເສຍແຕ່ວ່າແທນທີ່ຈະເປັນຫນ້າທີ່
ວັດຖຸມັນໃຊ້ແບບຟອມ Hy. ຊື່ພິເສດ it ຖືກຜູກມັດກັບວັດຖຸປະຈຸບັນຈາກ
ບັນຊີລາຍຊື່ໃນ iteration ໄດ້.
=> (ບັນຊີລາຍຊື່ (ap-map (* it 2) [1 2 3]))
[2, 4, 6]
ap-map-when
ການນໍາໃຊ້: (ap-map-when predfn ຕົວແທນ ບັນຊີລາຍຊື່)
ປະເມີນການສ້າງແຜນທີ່ຜ່ານລາຍຊື່ໂດຍໃຊ້ຟັງຊັນ predicate ເພື່ອກໍານົດເວລາທີ່ຈະນໍາໃຊ້
ແບບຟອມ.
=> (ລາຍການ (ap-map-when odd? (* it 2) [1 2 3 4]))
[2, 2, 6, 4]
=> (ລາຍການ (ap-map-when even? (* it 2) [1 2 3 4]))
[1, 4, 3, 8]
ap-filter
ການນໍາໃຊ້: (ap-filter ຮູບແບບ ບັນຊີລາຍຊື່)
ເຊັ່ນດຽວກັບ ແຜນທີ່ ພວກເຮົາເອົາຮູບແບບພິເສດແທນຫນ້າທີ່ເພື່ອກັ່ນຕອງອົງປະກອບຂອງ
ບັນຊີລາຍຊື່. ຊື່ພິເສດ it ຖືກຜູກມັດກັບອົງປະກອບປັດຈຸບັນໃນການເຮັດຊ້ຳ.
=> (ບັນຊີລາຍຊື່ (ap-filter (> (* it 2) 6) [1 2 3 4 5]))
[4, 5]
ap-ປະຕິເສດ
ການນໍາໃຊ້: (ap-ປະຕິເສດ ຮູບແບບ ບັນຊີລາຍຊື່)
ຫນ້າທີ່ນີ້ເຮັດກົງກັນຂ້າມກັບ ap-filter, ມັນປະຕິເສດອົງປະກອບທີ່ຜ່ານ
ຄາດ. ຊື່ພິເສດ it ຖືກຜູກມັດກັບອົງປະກອບປັດຈຸບັນໃນການເຮັດຊ້ຳ.
=> (ບັນຊີລາຍຊື່ (ap-reject (> (* it 2) 6) [1 2 3 4 5]))
[1, 2, 3]
ap-dotimes
ການນໍາໃຊ້ (ap-dotimes n ຮ່າງກາຍ)
ຫນ້າທີ່ນີ້ປະເມີນຮ່າງກາຍ n ເວລາ, ກັບຕົວແປພິເສດ it ຜູກພັນຈາກ 0 to
1-ນ. ມັນເປັນປະໂຫຍດສໍາລັບຜົນຂ້າງຄຽງ.
=> (setv n [])
=> (ap-dotimes 3 (. append n ມັນ))
=> ນ
[0, 1, 2]
ap-first
ການນໍາໃຊ້ (ap-first predfn ບັນຊີລາຍຊື່)
ຟັງຊັນນີ້ສົ່ງຄືນອົງປະກອບທໍາອິດທີ່ຜ່ານ predicate ຫຼື ບໍ່ມີ, ທີ່ມີ
ຕົວແປພິເສດ it ຜູກມັດກັບອົງປະກອບປັດຈຸບັນໃນການເຮັດຊ້ຳ.
=> (ap-first (> ມັນ 5) (ຊ່ວງ 10))
6
ap-ສຸດທ້າຍ
ການນໍາໃຊ້ (ap-ສຸດທ້າຍ predfn ບັນຊີລາຍຊື່)
ຟັງຊັນນີ້ສົ່ງຄືນອົງປະກອບສຸດທ້າຍທີ່ຜ່ານ predicate ຫຼື ບໍ່ມີ, ພິເສດ
ຕົວແປ it ຜູກມັດກັບອົງປະກອບປັດຈຸບັນໃນການເຮັດຊ້ຳ.
=> (ap-last (> ມັນ 5) (ໄລຍະ 10))
9
ap-ຫຼຸດຜ່ອນ
ການນໍາໃຊ້ (ap-reduce ຮູບແບບ ບັນຊີລາຍຊື່ &ທາງເລືອກ ມູນຄ່າເບື້ອງຕົ້ນ)
ຟັງຊັນນີ້ສົ່ງຄືນຜົນຂອງການນໍາໃຊ້ແບບຟອມກັບ 2 ອົງປະກອບທໍາອິດໃນຮ່າງກາຍແລະ
ການນໍາໃຊ້ຜົນໄດ້ຮັບແລະອົງປະກອບທີ 3 ແລະອື່ນໆຈົນກ່ວາບັນຊີລາຍຊື່ຫມົດ. ທາງເລືອກເປັນ
ສາມາດສະໜອງມູນຄ່າເບື້ອງຕົ້ນໄດ້ ດັ່ງນັ້ນຟັງຊັນຈະນຳໃຊ້ກັບຄ່າເບື້ອງຕົ້ນ ແລະຄ່າ
ອົງປະກອບທໍາອິດແທນ. ນີ້ເປີດເຜີຍໃຫ້ເຫັນອົງປະກອບທີ່ກໍາລັງຖືກ iterated ເປັນ it ແລະປະຈຸບັນ
ມູນຄ່າສະສົມເປັນ acc.
=> (ap-reduce (+ it acc) (ຊ່ວງ 10))
45
loop/recur
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
ໄດ້ loop / recur macro ໃຫ້ນັກຂຽນໂປລແກລມມີວິທີງ່າຍໆໃນການນໍາໃຊ້ການເພີ່ມປະສິດທິພາບການໂທຫາງ (TCO)
ໃນລະຫັດ Hy ຂອງເຂົາເຈົ້າ.
ການເອີ້ນຫາງແມ່ນການໂທແບບປົກກະຕິຍ່ອຍທີ່ເກີດຂຶ້ນພາຍໃນຂັ້ນຕອນອື່ນເປັນຂັ້ນຕອນສຸດທ້າຍ
ການປະຕິບັດ; ມັນອາດຈະຜະລິດເປັນມູນຄ່າກັບຄືນໄປບ່ອນທີ່ຫຼັງຈາກນັ້ນໄດ້ຖືກກັບຄືນມາທັນທີໂດຍການໂທ
ຂັ້ນຕອນການ. ຖ້າການເອີ້ນອັນໃດອັນໜຶ່ງທີ່ເຮັດໜ້າທີ່ຍ່ອຍປະຕິບັດ, ມັນອາດຈະນຳໄປສູ່ໃນທີ່ສຸດ
ກັບ routine ຍ່ອຍດຽວກັນນີ້ຖືກເອີ້ນອີກເທື່ອຫນຶ່ງລົງລະບົບຕ່ອງໂສ້ການໂທ, ແມ່ນຢູ່ໃນຕໍາແຫນ່ງຫາງ,
subroutine ດັ່ງກ່າວໄດ້ຖືກກ່າວເຖິງວ່າເປັນຫາງ recursive, ເຊິ່ງເປັນກໍລະນີພິເສດຂອງ recursion.
ການໂທຫາງແມ່ນສໍາຄັນເພາະວ່າພວກເຂົາສາມາດປະຕິບັດໄດ້ໂດຍບໍ່ຕ້ອງເພີ່ມ stack ໃຫມ່
ກອບໃສ່ stack ການໂທ. ສ່ວນໃຫຍ່ຂອງກອບຂອງຂັ້ນຕອນປະຈຸບັນແມ່ນບໍ່ຈໍາເປັນ
ຫຼາຍ, ແລະມັນສາມາດຖືກແທນທີ່ດ້ວຍກອບຂອງການໂທຫາງ. ຫຼັງຈາກນັ້ນ, ໂຄງການສາມາດເຕັ້ນໄປຫາ
ໄປຫາ routine ຍ່ອຍທີ່ເອີ້ນວ່າ. ການຜະລິດລະຫັດດັ່ງກ່າວແທນທີ່ຈະເປັນລໍາດັບການໂທມາດຕະຖານແມ່ນ
ເອີ້ນວ່າການລົບລ້າງການໂທຫາງ, ຫຼືການເພີ່ມປະສິດທິພາບການໂທຫາງ. ການກໍາຈັດການໂທຫາງອະນຸຍາດໃຫ້
ຂັ້ນຕອນການຮຽກຮ້ອງຢູ່ໃນທ່າຫາງທີ່ຈະຖືກປະຕິບັດຢ່າງມີປະສິດທິພາບຄືກັບຄໍາຖະແຫຼງທີ່ goto,
ດັ່ງນັ້ນຈຶ່ງເຮັດໃຫ້ໂຄງການທີ່ມີໂຄງສ້າງທີ່ມີປະສິດທິພາບ. — ວິກິພີເດຍ (-
http://en.wikipedia.org/wiki/Tail_call)
ມາໂຄຣ
loop
loop ສ້າງຈຸດ recursion. ກັບ loop, recur rebinds ຕົວແປທີ່ກໍານົດໄວ້ໃນ
ຈຸດ recursion ແລະສົ່ງການປະຕິບັດລະຫັດກັບຄືນໄປບ່ອນຈຸດ recursion ນັ້ນ. ຖ້າ recur ຖືກນໍາໃຊ້ໃນ
ຕໍາແຫນ່ງທີ່ບໍ່ແມ່ນຫາງ, ການຍົກເວັ້ນແມ່ນຖືກຖິ້ມ.
ການນໍາໃຊ້: (ວົງ ການຜູກມັດ &ພັກຜ່ອນ ຮ່າງກາຍ)
ຕົວຢ່າງ:
(ຕ້ອງການ hy.contrib.loop)
( defn factorial [n]
(ວົງ [[ໃນ] [acc 1]]
(ຖ້າ (ສູນ? i)
acc
(ເກີດຂຶ້ນຊ້ຳ (dec i) (* acc i)))))
(ໂຮງງານ 1000)
defmulti
ໃໝ່ໃນເວີຊັ່ນ 0.10.0.
defmulti ເຮັດໃຫ້ທ່ານ arity-overload ຟັງຊັນໂດຍຈໍານວນ args ແລະ/ຫຼື kwargs ທີ່ກໍານົດໄວ້.
ໄດ້ຮັບການດົນໃຈຈາກ Clojure's take on defn.
=> (ຕ້ອງການ hy.contrib.multi)
=> (ມ່ວນຫຼາຍ
... ([a] "ກ")
... ([ab] "ab")
... ([abc] "abc"))
=> (ມ່ວນ 1)
"ກ"
=> (ມ່ວນ 1 2)
"ab"
=> (ມ່ວນ 1 2 3)
"abc"
ການແຮັກ ON HY
ເຂົ້າຮ່ວມ ຂອງພວກເຮົາ ໄຮວີ!
ກະລຸນາມາ hack ສຸດ Hy!
ກະລຸນາມາ hang out ກັບພວກເຮົາ #ເອີ on irc.freenode.net!
ກະລຸນາສົນທະນາກ່ຽວກັບມັນກ່ຽວກັບ Twitter ກັບ #ເອີ ເຄື່ອງຫມາຍສີ່ຫຼ່ຽມ!
ກະລຸນາ blog ກ່ຽວກັບມັນ!
ກະລຸນາບໍ່ໄດ້ສີດມັນຢູ່ໃນຮົ້ວຂອງເພື່ອນບ້ານຂອງທ່ານ (ໂດຍບໍ່ມີການຂໍງາມ)!
ແຮກ!
ເຮັດສິ່ງນີ້:
1. ສ້າງກ virtual ສະພາບແວດລ້ອມ:
$ virtualenv venv
ແລະເປີດໃຊ້ມັນ:
$ . venv/bin/activate
ຫຼືການນໍາໃຊ້ virtualenvwrapper ເພື່ອສ້າງແລະຈັດການສະພາບແວດລ້ອມ virtual ຂອງທ່ານ:
$ mkvirtualenv hy
$ workon hy
2. ເອົາລະຫັດແຫຼ່ງ:
$ git clone https://github.com/hylang/hy.git
ຫຼືໃຊ້ສ້ອມຂອງເຈົ້າ:
clone $ git [email protected]: /hy.git
3. ຕິດຕັ້ງສໍາລັບການ hacking:
$ cd hy/
$ pip ຕິດຕັ້ງ -e .
4. ຕິດຕັ້ງຄວາມຕ້ອງການພັດທະນາ-y ອື່ນໆ:
$ pip ຕິດຕັ້ງ -r requirement-dev.txt
5. ເຮັດສິ່ງທີ່ຫນ້າຫວາດສຽວ; ເຮັດໃຫ້ຜູ້ໃດຜູ້ຫນຶ່ງ shriek ໃນຄວາມຍິນດີ / disgust ໃນສິ່ງທີ່ທ່ານໄດ້ເຮັດ.
ທົດສອບ!
ການທົດສອບແມ່ນຕັ້ງຢູ່ໃນ ການທົດສອບ/. ພວກເຮົາໃຊ້ ດັງ.
ເພື່ອດໍາເນີນການທົດສອບ:
$ ການກວດດັງ
ການທົດສອບການຂຽນ --- ການທົດສອບແມ່ນດີ!
ນອກຈາກນີ້, ມັນເປັນການດີທີ່ຈະດໍາເນີນການທົດສອບສໍາລັບທຸກເວທີທີ່ສະຫນັບສະຫນູນແລະສໍາລັບ PEP 8 ປະຕິບັດຕາມ
ລະຫັດ. ທ່ານສາມາດເຮັດໄດ້ໂດຍການແລ່ນ tox:
$ tox
ເອກະສານ!
ເອກະສານຕັ້ງຢູ່ໃນ docs/. ພວກເຮົາໃຊ້ sphinx.
ເພື່ອສ້າງເອກະສານໃນ HTML:
$ cd docs
$ ເຮັດ html
ຂຽນ docs---docs ແມ່ນດີ! ແມ່ນແຕ່ເອກະສານນີ້!
ການປະກອບສ່ວນ
ການປະກອບສ່ວນແມ່ນຍິນດີຕ້ອນຮັບ & ຊື່ນຊົມຢ່າງຫຼວງຫຼາຍ, ທຸກໆເລັກນ້ອຍຈະຊ່ວຍເຮັດໃຫ້ Hy ຫຼາຍຂຶ້ນ
ຫນ້າຫວາດສຽວ.
ການຮ້ອງຂໍດຶງແມ່ນດີຫຼາຍ! ພວກເຮົາຮັກພວກເຂົາ; ນີ້ແມ່ນຄໍາແນະນໍາດ່ວນ:
· Fork the repo ແລະສ້າງສາຂາຫົວຂໍ້ສໍາລັບຄຸນນະສົມບັດ / ການແກ້ໄຂ. ຫຼີກເວັ້ນການເຮັດການປ່ຽນແປງໂດຍກົງ
ໃນສາຂາແມ່ບົດ.
· ລັກສະນະທີ່ເຂົ້າມາທັງໝົດຄວນມາພ້ອມກັບການທົດສອບ.
·ກ່ອນທີ່ທ່ານຈະສົ່ງ PR, ກະລຸນາດໍາເນີນການທົດສອບແລະກວດເບິ່ງລະຫັດຂອງທ່ານຕໍ່ກັບຮູບແບບ
ຄູ່ມື. ທ່ານສາມາດເຮັດທັງສອງສິ່ງເຫຼົ່ານີ້ໃນເວລາດຽວກັນ:
$ ເຮັດໃຫ້ d
· ເຮັດໃຫ້ຄໍາຫມັ້ນສັນຍາເຂົ້າໄປໃນຫນ່ວຍງານທີ່ມີເຫດຜົນ, ດັ່ງນັ້ນມັນງ່າຍທີ່ຈະຕິດຕາມແລະນໍາທາງໃນພາຍຫຼັງ. ກ່ອນ
ສົ່ງ PR, ພະຍາຍາມ squashing commits ເຂົ້າໄປໃນການປ່ຽນແປງທີ່ງ່າຍທີ່ຈະກັບຄືນມາ
ຕໍ່ມາ. ນອກຈາກນີ້, ໃຫ້ແນ່ໃຈວ່າທ່ານບໍ່ປ່ອຍໃຫ້ຊ່ອງຫວ່າງ spurious ໃນຊຸດການປ່ຽນແປງ; ນີ້
ຫຼີກເວັ້ນການສ້າງການແກ້ໄຂຊ່ອງຫວ່າງໃນພາຍຫຼັງ.
· ເທົ່າທີ່ຂໍ້ຄວາມສັນຍາໄປ, ພະຍາຍາມປະຕິບັດຕາມຕໍ່ໄປນີ້:
· ພະຍາຍາມຕິດຢູ່ໃນຂີດຈຳກັດ 50 ຕົວອັກສອນສຳລັບແຖວທຳອິດຂອງຂໍ້ຄວາມ Git commit.
· ສໍາລັບລາຍລະອຽດ/ຄໍາອະທິບາຍເພີ່ມເຕີມ, ຕິດຕາມອັນນີ້ດ້ວຍເສັ້ນເປົ່າ ແລະສືບຕໍ່
ອະທິບາຍຄໍາຫມັ້ນສັນຍາໃນລະອຽດ.
·ສຸດທ້າຍ, ເພີ່ມຕົວທ່ານເອງໃສ່ໄຟລ໌ AUTHORS (ເປັນຄໍາຫມັ້ນສັນຍາແຍກຕ່າງຫາກ): ທ່ານສົມຄວນໄດ້ຮັບມັນ :)
·ທຸກການປ່ຽນແປງທີ່ເຂົ້າມາຈໍາເປັນຕ້ອງໄດ້ຮັບການຍອມຮັບໂດຍ 2 ສະມາຊິກທີ່ແຕກຕ່າງກັນຂອງທີມງານຫຼັກຂອງ Hylang.
ການທົບທວນຄືນເພີ່ມເຕີມແມ່ນຍິນດີຕ້ອນຮັບຢ່າງຈະແຈ້ງ, ແຕ່ພວກເຮົາຕ້ອງການຢ່າງຫນ້ອຍ 2 signoffs ສໍາລັບໃດໆ
ປ່ຽນແປງ.
· ຖ້າຫາກວ່າສະມາຊິກຫຼັກແມ່ນສົ່ງໃນ PR, ກະລຸນາຊອກຫາ 2 ສະມາຊິກຫຼັກທີ່ບໍ່ໄດ້ປະກອບມີ
PR ສົ່ງ. ແນວຄວາມຄິດຢູ່ທີ່ນີ້ແມ່ນວ່າຫນຶ່ງສາມາດເຮັດວຽກກັບຜູ້ຂຽນ PR, ແລະ acks ທີສອງ
ຊຸດການປ່ຽນແປງທັງຫມົດ.
· ສໍາລັບເອກະສານ & ການປ່ຽນແປງເລັກນ້ອຍອື່ນໆ, ພວກເຮົາດີທີ່ຈະລວມຫຼັງຈາກຫນຶ່ງ ACK. ພວກເຮົາໄດ້ຮັບ
ການຄຸ້ມຄອງຕໍ່າ, ສະນັ້ນມັນຈະເປັນການດີທີ່ຈະຮັກສາສິ່ງກີດຂວາງນັ້ນໃຫ້ຕໍ່າ.
Core ທີມງານ
ທີມງານພັດທະນາຫຼັກຂອງ Hy ປະກອບດ້ວຍຜູ້ພັດທະນາຕໍ່ໄປນີ້:
· Julian Danjou
· Morten Linderud
· J Kenneth ຄົນ
· Gergely ທີ່ຍິ່ງໃຫຍ່
· ເມືອງ Tuukka ເຕົ່າ
· Karen Rustad
· Abhishek L
· Christopher Allan Webber
· ຄອນຣາດ ຮິນເຊັນ
· ຈະ Kahn-Greene
· Paul Tagliamonte
· Nicolas Dandrimont
· Bob Tolbert
· Berker ເພັດສະໝອນ
· Clinton N. Dreisbach
· han ແຊມມະ
ໃຊ້ອອນໄລນ໌ hy ໂດຍໃຊ້ບໍລິການ onworks.net