โปรดอธิบายบางประเด็นของ Paul Graham เกี่ยวกับ Lisp


146

ฉันต้องการความช่วยเหลือบางทำความเข้าใจบางจุดจากพอลเกรแฮมสิ่งที่ทำให้เสียงกระเพื่อมที่แตกต่างกัน

  1. แนวคิดใหม่ของตัวแปร ใน Lisp ตัวแปรทั้งหมดเป็นตัวชี้อย่างมีประสิทธิภาพ ค่าคือสิ่งที่มีประเภทไม่ใช่ตัวแปรและการกำหนดหรือตัวแปรที่มีผลผูกพันหมายถึงการคัดลอกพอยน์เตอร์ไม่ใช่สิ่งที่พวกเขาชี้ไปที่

  2. ประเภทสัญลักษณ์ สัญลักษณ์แตกต่างจากสตริงที่คุณสามารถทดสอบความเท่าเทียมกันโดยการเปรียบเทียบตัวชี้

  3. สัญกรณ์สำหรับรหัสโดยใช้สัญลักษณ์ของต้นไม้

  4. ภาษาทั้งหมดใช้ได้เสมอ ไม่มีความแตกต่างที่แท้จริงระหว่างเวลาอ่านเวลาคอมไพล์และรันไทม์ คุณสามารถรวบรวมหรือเรียกใช้รหัสในขณะที่อ่านอ่านหรือเรียกใช้รหัสในขณะที่รวบรวมและอ่านหรือรวบรวมรหัสที่รันไทม์

ประเด็นเหล่านี้หมายความว่าอย่างไร พวกเขาแตกต่างกันในภาษาเช่น C หรือ Java อย่างไร ภาษาอื่นที่ไม่ใช่ภาษาตระกูล Lisp มีโครงสร้างเหล่านี้หรือไม่?


10
ผมไม่แน่ใจว่าแท็กทำงานเขียนโปรแกรมคือการรับประกันที่นี่เป็นก็เป็นไปได้อย่างเท่าเทียมกันที่จะเขียนความจำเป็นหรือ OO รหัสใน Lisps เป็นจำนวนมากก็คือการเขียนโค้ดการทำงาน - และในความเป็นจริงมีจำนวนมากของการไม่ทำงานเสียงกระเพื่อม รหัสรอบ ๆ ฉันขอแนะนำให้คุณลบแท็ก fp และเพิ่ม clojure แทนหวังว่านี่อาจจะนำข้อมูลที่น่าสนใจจาก Lispers ที่ใช้ JVM
Michał Marczyk

58
พวกเรามีpaul-grahamแท็กที่นี่เหรอ? !!! เยี่ยมมาก
หายไป faktor

@missingfaktor บางทีมันอาจจะต้องมีคำร้องขอ burninate
cat

คำตอบ:


98

คำอธิบายของ Matt นั้นดีมาก - และเขาใช้การเปรียบเทียบกับ C และ Java ซึ่งฉันจะไม่ทำ - แต่ด้วยเหตุผลบางอย่างฉันสนุกกับการพูดคุยเรื่องนี้เป็นครั้งคราว - นี่คือภาพของฉัน ที่คำตอบ

กับคะแนน (3) และ (4):

คะแนน (3) และ (4) ในรายการของคุณน่าสนใจที่สุดและยังคงเกี่ยวข้องในขณะนี้

เพื่อให้เข้าใจพวกเขาจะมีประโยชน์ที่จะมีภาพที่ชัดเจนของสิ่งที่เกิดขึ้นกับรหัส Lisp - ในรูปแบบของตัวอักษรที่พิมพ์โดยโปรแกรมเมอร์ - ในทางที่จะถูกประหารชีวิต ลองใช้ตัวอย่างที่เป็นรูปธรรม:

;; a library import for completeness,
;; we won't concern ourselves with it
(require '[clojure.contrib.string :as str])

;; this is the interesting bit:
(println (str/replace-re #"\d+" "FOO" "a123b4c56"))

ตัวอย่างนี้ClojureaFOObFOOcFOOรหัสพิมพ์ออก โปรดทราบว่าเนื้อหาของ Clojure ไม่ตรงตามจุดที่สี่ในรายการของคุณเนื่องจากการอ่านไม่เปิดให้ผู้ใช้รหัสจริงๆ; ฉันจะหารือเกี่ยวกับสิ่งที่มันหมายถึงการเป็นอย่างอื่นแม้ว่า

ดังนั้นสมมติว่าเรามีรหัสนี้ในไฟล์ที่ใดที่หนึ่งและเราขอให้ Clojure เรียกใช้งาน นอกจากนี้สมมติว่า (เพื่อประโยชน์ของความเรียบง่าย) ที่เราทำผ่านการนำเข้าห้องสมุดมา บิตที่น่าสนใจเริ่มต้นที่(printlnและสิ้นสุดที่)ไกลไปทางขวา นี่คือ lexed / parsed ตามที่คาดไว้ แต่มีจุดสำคัญเกิดขึ้น: ผลลัพธ์ไม่ใช่การแสดง AST เฉพาะคอมไพเลอร์เฉพาะ - เป็นเพียงโครงสร้างข้อมูล Clojure / Lisp ปกติคือรายการซ้อนที่มีสัญลักษณ์มากมาย สตริงและ - ในกรณีนี้ - วัตถุรูปแบบการรวบรวม regex เดียวที่สอดคล้องกับ#"\d+"แท้จริง (เพิ่มเติมเกี่ยวกับเรื่องนี้ด้านล่าง) Lisps บางตัวเพิ่มการบิดเล็กน้อยของตัวเองลงในกระบวนการนี้ แต่ Paul Graham ส่วนใหญ่อ้างถึง Common LISP ในประเด็นที่เกี่ยวข้องกับคำถามของคุณ Clojure นั้นคล้ายกับ CL

ภาษาทั้งหมดในเวลารวบรวม:

หลังจากจุดนี้คอมไพเลอร์ทั้งหมดเกี่ยวข้องกับ (นี่ก็จะเป็นจริงสำหรับล่าม Lisp; รหัส Clojure เกิดขึ้นเสมอที่จะรวบรวม) เป็นโครงสร้างข้อมูล Lisp ที่ Lisp โปรแกรมเมอร์ที่ใช้ในการจัดการ ณ จุดนี้มีความเป็นไปได้ที่ชัดเจน: ทำไมไม่อนุญาตให้โปรแกรมเมอร์ Lisp เขียนฟังก์ชั่น Lisp ที่จัดการข้อมูล Lisp ที่เป็นตัวแทนของโปรแกรม Lisp และข้อมูลที่แปลงผลลัพธ์เป็นตัวแทนของโปรแกรมที่ถูกแปลงเพื่อใช้แทนต้นฉบับ? กล่าวอีกนัยหนึ่ง - ทำไมไม่อนุญาตให้โปรแกรมเมอร์ Lisp ลงทะเบียนฟังก์ชั่นเป็นปลั๊กอินคอมไพเลอร์แปลก ๆ เรียกว่า macros ใน Lisp และแน่นอนระบบเสียงกระเพื่อมที่เหมาะสมมีความสามารถนี้

ดังนั้นแมโครเป็นฟังก์ชั่น Lisp ปกติที่ใช้งานในการแสดงของโปรแกรม ณ เวลาคอมไพล์ก่อนช่วงการรวบรวมขั้นสุดท้ายเมื่อมีการปล่อยรหัสวัตถุจริง เนื่องจากไม่มีข้อ จำกัด เกี่ยวกับชนิดของรหัสแมโครที่ได้รับอนุญาตให้เรียกใช้ (โดยเฉพาะอย่างยิ่งรหัสที่เรียกใช้มักจะถูกเขียนด้วยการใช้สิ่งอำนวยความสะดวกของแมโครอย่างเสรี) เราสามารถพูดได้ว่า "ทั้งภาษาพร้อมใช้งานในเวลารวบรวม "

ภาษาทั้งหมดในเวลาที่อ่าน:

ลองกลับไปที่#"\d+"ตัวอักษร Regex นั้น ดังที่ได้กล่าวมาแล้วสิ่งนี้จะถูกแปลงเป็นวัตถุรูปแบบที่คอมไพล์จริงในเวลาอ่านก่อนคอมไพเลอร์ได้ยินการกล่าวถึงรหัสใหม่ครั้งแรกที่เตรียมไว้สำหรับการรวบรวม มันเกิดขึ้นได้อย่างไร?

ดีทาง Clojure จะดำเนินการในขณะนี้ภาพจะค่อนข้างแตกต่างกว่าสิ่งที่พอลเกรแฮมมีอยู่ในใจแม้สิ่งที่เป็นไปได้ด้วยสับฉลาด ใน Common Lisp เรื่องราวจะดูค่อนข้างสะอาดกว่าแนวคิด พื้นฐานมีความคล้ายคลึงกัน: Lisp Reader เป็นเครื่องสถานะซึ่งนอกเหนือจากการดำเนินการเปลี่ยนสถานะและในที่สุดก็ประกาศว่ามันได้มาถึง "รัฐที่ยอมรับ" จะกระจายโครงสร้างข้อมูลเสียงกระเพื่อมที่ตัวละครแทน ดังนั้นตัวละครจึง123กลายเป็นตัวเลข123เป็นต้นจุดสำคัญมาถึงแล้ว: เครื่องรัฐนี้สามารถแก้ไขได้ด้วยรหัสผู้ใช้. (ตามที่ระบุไว้ก่อนหน้านี้เป็นจริงทั้งหมดในกรณีของ CL; สำหรับ Clojure, แฮ็ค (ท้อและไม่ได้ใช้ในทางปฏิบัติ) เป็นสิ่งจำเป็น แต่ฉันพูดนอกเรื่องมันเป็นบทความของ PG ที่ฉันควรจะทำอย่างละเอียดดังนั้น ... )

ดังนั้นหากคุณเป็นโปรแกรมเมอร์ Common LISP และคุณชอบแนวคิดของตัวอักษรเวกเตอร์สไตล์ Clojure คุณสามารถเพียงแค่เสียบฟังก์ชั่นของผู้อ่านเพื่อตอบสนองอย่างเหมาะสมกับลำดับอักขระบางตัว[หรือ#[อาจเป็นไปได้ ]จุดเริ่มต้นของตัวอักษรเวกเตอร์สิ้นสุดที่ตรงกัน ฟังก์ชั่นดังกล่าวเรียกว่ามาโครผู้อ่านและเช่นเดียวกับมาโครปกติสามารถรันโค้ด Lisp ใด ๆ รวมถึงโค้ดที่ถูกเขียนด้วยสัญกรณ์ขี้ขลาดที่เปิดใช้งานโดยมาโครผู้อ่านที่ลงทะเบียนก่อนหน้านี้ ดังนั้นจึงมีทั้งภาษาในเวลาอ่านสำหรับคุณ

ห่อมันขึ้นมา:

จริงๆแล้วสิ่งที่แสดงให้เห็นแล้วคือว่าเราสามารถเรียกใช้ฟังก์ชั่น Lisp ปกติในเวลาอ่านหรือรวบรวมเวลา ขั้นตอนเดียวที่ต้องทำจากที่นี่เพื่อทำความเข้าใจว่าการอ่านและการคอมไพล์เป็นไปได้อย่างไรในการอ่านการคอมไพล์หรือรันไทม์คือการตระหนักว่าการอ่านและการคอมไพล์นั้นดำเนินการโดยฟังก์ชั่น Lisp คุณสามารถโทรreadหรือevalอ่านข้อมูลเสียงกระเพื่อมได้ตลอดเวลาจากคอมไพล์สตรีมหรือคอมไพล์และรันโค้ด Lisp ตามลำดับ นั่นคือภาษาทั้งหมดที่นั่นตลอดเวลา

โปรดสังเกตว่าข้อเท็จจริงที่ว่า Lisp เป็นไปตามจุด (3) จากรายการของคุณมีความสำคัญต่อวิธีการจัดการเพื่อตอบสนองจุด (4) - รสชาติของมาโครที่จัดทำโดย Lisp นั้นอาศัยรหัสที่แสดงโดยข้อมูล LIS ปกติอย่างมาก สิ่งที่เปิดใช้งานโดย (3) อนึ่งเฉพาะส่วน "tree-ish" ของรหัสมีความสำคัญอย่างยิ่งที่นี่ - คุณอาจมี Lisp ที่เขียนโดยใช้ XML


4
ระวัง: โดยกล่าวว่า "ปกติ (compiler) แมโคร" คุณอยู่ใกล้กับหมายความว่าแมโครคอมไพเลอร์มีแมโคร "ปกติ" เมื่ออยู่ใน Common เสียงกระเพื่อม (อย่างน้อย) "เรียบเรียงแมโคร" เป็นที่เฉพาะเจาะจงมากและสิ่งที่แตกต่างกัน: lispworks com / เอกสาร / lw51 / CLHS / ร่างกาย / …
Ken

Ken: จับได้ดีขอบคุณ! ฉันจะเปลี่ยนเป็น "แมโครปกติ" ซึ่งฉันคิดว่าไม่น่าจะทำให้ใคร ๆ
Michał Marczyk

คำตอบที่ยอดเยี่ยม ฉันเรียนรู้เพิ่มเติมจากภายใน 5 นาทีกว่าที่ฉันมีในเวลาหลายชั่วโมง googling / ไตร่ตรองคำถาม ขอบคุณ
Charlie ดอกไม้

แก้ไข: argh เข้าใจผิดประโยคทำงาน ถูกต้องสำหรับไวยากรณ์ (ต้องการ "เพียร์" เพื่อยอมรับการแก้ไขของฉัน)
Tatiana Racheva

S-expressions และ XML สามารถกำหนดโครงสร้างเดียวกันได้ แต่ XML นั้นละเอียดกว่ามากดังนั้นจึงไม่เหมาะกับไวยากรณ์
Sylwester

66

1) แนวคิดใหม่ของตัวแปร ใน Lisp ตัวแปรทั้งหมดเป็นตัวชี้อย่างมีประสิทธิภาพ ค่าคือสิ่งที่มีประเภทไม่ใช่ตัวแปรและการกำหนดหรือตัวแปรที่มีผลผูกพันหมายถึงการคัดลอกพอยน์เตอร์ไม่ใช่สิ่งที่พวกเขาชี้ไป

(defun print-twice (it)
  (print it)
  (print it))

'it' เป็นตัวแปร มันสามารถถูกผูกไว้กับค่าใด ๆ ไม่มีข้อ จำกัด และไม่มีประเภทที่เกี่ยวข้องกับตัวแปร หากคุณเรียกใช้ฟังก์ชันอาร์กิวเมนต์ไม่จำเป็นต้องคัดลอก ตัวแปรคล้ายกับตัวชี้ มันมีวิธีการเข้าถึงค่าที่ถูกผูกไว้กับตัวแปร ไม่จำเป็นต้องสำรองหน่วยความจำ เราสามารถส่งผ่านวัตถุข้อมูลใด ๆ เมื่อเราเรียกใช้ฟังก์ชั่น: ขนาดและประเภทใด ๆ

วัตถุข้อมูลมี 'ชนิด' และวัตถุข้อมูลทั้งหมดสามารถสอบถามได้สำหรับ 'ชนิด'

(type-of "abc")  -> STRING

2) ประเภทสัญลักษณ์ สัญลักษณ์แตกต่างจากสตริงที่คุณสามารถทดสอบความเท่าเทียมกันโดยการเปรียบเทียบตัวชี้

สัญลักษณ์เป็นวัตถุข้อมูลที่มีชื่อ โดยปกติชื่อสามารถใช้เพื่อค้นหาวัตถุ:

|This is a Symbol|
this-is-also-a-symbol

(find-symbol "SIN")   ->  SIN

เนื่องจากสัญลักษณ์เป็นวัตถุข้อมูลจริงเราจึงสามารถทดสอบว่าเป็นวัตถุเดียวกันหรือไม่:

(eq 'sin 'cos) -> NIL
(eq 'sin 'sin) -> T

สิ่งนี้ทำให้เราสามารถเขียนประโยคที่มีสัญลักษณ์:

(defvar *sentence* '(mary called tom to tell him the price of the book))

ตอนนี้เราสามารถนับจำนวน THE ในประโยค:

(count 'the *sentence*) ->  2

ในสัญลักษณ์ Common LISP ไม่เพียง แต่มีชื่อ แต่ยังสามารถมีค่าฟังก์ชั่นรายการทรัพย์สินและแพคเกจ ดังนั้นสัญลักษณ์สามารถใช้ในการตั้งชื่อตัวแปรหรือฟังก์ชั่น รายการคุณสมบัติมักใช้เพื่อเพิ่ม meta-data เข้ากับสัญลักษณ์

3) สัญลักษณ์สำหรับรหัสโดยใช้สัญลักษณ์ต้นไม้

เสียงกระเพื่อมใช้โครงสร้างข้อมูลพื้นฐานในการแสดงรหัส

รายการ (* 3 2) สามารถเป็นได้ทั้งข้อมูลและรหัส:

(eval '(* 3 (+ 2 5))) -> 21

(length '(* 3 (+ 2 5))) -> 3

ต้นไม้:

CL-USER 8 > (sdraw '(* 3 (+ 2 5)))

[*|*]--->[*|*]--->[*|*]--->NIL
 |        |        |
 v        v        v
 *        3       [*|*]--->[*|*]--->[*|*]--->NIL
                   |        |        |
                   v        v        v
                   +        2        5

4) ภาษาทั้งหมดใช้ได้เสมอ ไม่มีความแตกต่างที่แท้จริงระหว่างเวลาอ่านเวลาคอมไพล์และรันไทม์ คุณสามารถรวบรวมหรือเรียกใช้รหัสในขณะที่อ่านอ่านหรือเรียกใช้รหัสในขณะที่รวบรวมและอ่านหรือรวบรวมรหัสที่รันไทม์

เสียงกระเพื่อมให้ฟังก์ชั่นการอ่านในการอ่านข้อมูลและรหัสจากข้อความโหลดไปโหลดรหัส EVAL ในการประเมินรหัส, คอมไพล์ในการรวบรวมรหัสและพิมพ์เพื่อเขียนข้อมูลและรหัสเป็นข้อความ

ฟังก์ชั่นเหล่านี้พร้อมใช้งานเสมอ พวกเขาจะไม่หายไป พวกเขาสามารถเป็นส่วนหนึ่งของโปรแกรมใด ๆ นั่นหมายความว่าโปรแกรมใด ๆ สามารถอ่านโหลดแปลหรือพิมพ์รหัสได้เสมอ

พวกเขาแตกต่างกันในภาษาเช่น C หรือ Java อย่างไร

ภาษาเหล่านั้นไม่มีสัญลักษณ์รหัสเป็นข้อมูลหรือการประเมินผลข้อมูลเป็นรหัส วัตถุข้อมูลใน C มักจะไม่ได้พิมพ์

ภาษาอื่นที่ไม่ใช่ภาษาตระกูล LISP มีโครงสร้างเหล่านี้หรือไม่?

หลายภาษามีความสามารถบางอย่างเหล่านี้

ความแตกต่าง:

ใน Lisp ความสามารถเหล่านี้ได้รับการออกแบบเป็นภาษาเพื่อให้ใช้งานง่าย


33

สำหรับคะแนน (1) และ (2) เขากำลังพูดถึงประวัติศาสตร์ ตัวแปรของ Java นั้นค่อนข้างเหมือนกันซึ่งเป็นสาเหตุที่คุณต้องเรียกว่า. equals () เพื่อเปรียบเทียบค่า

(3) กำลังพูดถึง S-expressions โปรแกรมเสียงกระเพื่อมถูกเขียนในรูปแบบนี้ซึ่งให้ประโยชน์มากกว่าไวยากรณ์แบบ ad-hoc เช่น Java และ C เช่นการจับรูปแบบซ้ำ ๆ ในมาโครด้วยวิธีที่สะอาดกว่ามาโคร C หรือเทมเพลต C ++ และจัดการโค้ดด้วยรายการแกนหลักเดียวกัน การดำเนินงานที่คุณใช้สำหรับข้อมูล

(4) ยกตัวอย่าง C: ภาษาเป็นสองภาษาย่อยที่แตกต่างกันจริงๆ: สิ่งที่ถ้า () และในขณะที่ () และตัวประมวลผลล่วงหน้า คุณใช้ตัวประมวลผลล่วงหน้าเพื่อบันทึกไม่ต้องทำซ้ำตัวเองตลอดเวลาหรือข้ามรหัสด้วย # if / # ifdef แต่ทั้งสองภาษานั้นค่อนข้างแยกจากกันและคุณไม่สามารถใช้ในขณะที่ () ในเวลารวบรวมอย่างที่คุณสามารถ #if

C ++ ทำให้แม่แบบนี้ยิ่งแย่ลงไปอีก ตรวจสอบการอ้างอิงบางอย่างเกี่ยวกับการเขียนโปรแกรมแม่แบบการทำแผนที่ซึ่งให้วิธีการสร้างรหัสในเวลารวบรวมและเป็นเรื่องยากมากสำหรับผู้ที่ไม่ใช่ผู้เชี่ยวชาญที่จะปิดล้อม นอกจากนี้เป็นแฮ็กและกลอุบายจำนวนมากโดยใช้เทมเพลตและมาโครที่คอมไพเลอร์ไม่สามารถให้การสนับสนุนชั้นหนึ่งได้ - ถ้าคุณทำข้อผิดพลาดทางไวยากรณ์อย่างง่ายคอมไพเลอร์ไม่สามารถให้ข้อความแสดงข้อผิดพลาดที่ชัดเจนได้

ด้วย Lisp คุณมีทั้งหมดนี้ในภาษาเดียว คุณใช้สิ่งเดียวกันในการสร้างรหัสในเวลาทำงานตามที่คุณเรียนรู้ในวันแรกของคุณ นี่ไม่ได้เป็นการแนะนำ metaprogramming ว่าเป็นเรื่องเล็กน้อย แต่ก็ตรงไปตรงมามากขึ้นด้วยภาษาชั้นหนึ่งและการสนับสนุนคอมไพเลอร์


7
โอ้ด้วยพลังนี้ (และความเรียบง่าย) ตอนนี้มีอายุมากกว่า 50 ปีและง่ายพอที่จะใช้งานได้ซึ่งโปรแกรมเมอร์มือใหม่สามารถปฎิบัติตามคำแนะนำน้อยที่สุดและเรียนรู้เกี่ยวกับพื้นฐานภาษา คุณจะไม่ได้ยินคำกล่าวอ้างที่คล้ายกันของ Java, C, Python, Perl, Haskell และอื่น ๆ เป็นโครงการเริ่มต้นที่ดี!
Matt Curtis

9
ฉันไม่คิดว่าตัวแปร Java เป็นเหมือนสัญลักษณ์เสียงกระเพื่อมเลย ไม่มีสัญกรณ์สำหรับสัญลักษณ์ใน Java และสิ่งเดียวที่คุณสามารถทำได้กับตัวแปรคือรับค่าของเซลล์ Strings สามารถฝึกงาน แต่พวกเขาไม่ได้มักจะชื่อจึงไม่ได้ทำให้ความรู้สึกที่จะพูดคุยเกี่ยวกับว่าพวกเขาสามารถจะยกมาประเมินผ่าน ฯลฯ
เคน

2
อายุมากกว่า 40 ปีอาจมีความแม่นยำมากกว่านี้ :) @Ken: ฉันคิดว่าเขาหมายถึง 1) ตัวแปรที่ไม่ใช่ดั้งเดิมใน java คือโดย refence ซึ่งคล้ายกับเสียงกระเพื่อมและ 2) สตริง interned ใน java คล้ายกับสัญลักษณ์ในเสียงกระเพื่อม - แน่นอนอย่างที่คุณพูดคุณไม่สามารถอ้างอิงหรือประเมินค่าสตริง / รหัสใน Java ดังนั้นพวกเขาจึงค่อนข้างแตกต่างกัน

3
@Dan - ไม่แน่ใจว่าเมื่อมีการนำการใช้งานครั้งแรกมารวมกัน แต่กระดาษ McCarthyเริ่มต้นในการคำนวณเชิงสัญลักษณ์ถูกตีพิมพ์ในปี 1960
Inaimathi

Java ได้รับการสนับสนุนบางส่วน / ไม่สม่ำเสมอสำหรับ "สัญลักษณ์" ในรูปแบบของ Foo.class / foo.getClass () - เช่นวัตถุ Class <Foo> ประเภทของชนิดเป็นแบบอะนาล็อกบิต - เป็นค่า enum เพื่อ ระดับ. แต่เงาน้อยที่สุดของสัญลักษณ์ Lisp
BRPocock

-3

คะแนน (1) และ (2) ก็พอดีกับ Python เช่นกัน ยกตัวอย่างง่ายๆ "a = str (82.4)" ล่ามก่อนสร้างวัตถุจุดลอยตัวที่มีค่า 82.4 จากนั้นจะเรียกตัวสร้างสตริงซึ่งจะส่งคืนสตริงที่มีค่า '82 .4 ' 'a' ทางด้านซ้ายมือเป็นเพียงฉลากสำหรับวัตถุสตริงนั้น วัตถุจุดลอยตัวดั้งเดิมถูกเก็บรวบรวมขยะเนื่องจากไม่มีการอ้างอิงอีกต่อไป

ใน Scheme ทุกอย่างจะถือว่าเป็นวัตถุในลักษณะที่คล้ายกัน ฉันไม่แน่ใจเกี่ยวกับ Common LISP ฉันจะพยายามหลีกเลี่ยงการคิดในแง่ของแนวคิด C / C ++ พวกเขาทำให้ฉันช้าลงเมื่อฉันพยายามทำให้หัวของฉันเรียบง่ายสวยงาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.