ภาษาแบบคงที่และแบบไดนามิกสามารถถูกมองว่าเป็นเครื่องมือที่แตกต่างกันสำหรับงานประเภทต่างๆหรือไม่?


9

ใช่มีการถามคำถามที่คล้ายกัน แต่มักจะมีจุดประสงค์ในการค้นหาว่า 'แบบไหนดีกว่ากัน'

ฉันถามเพราะฉันเข้ามาเป็นผู้พัฒนา JavaScript เป็นหลักและไม่มีประสบการณ์ในการเขียนภาษาแบบคงที่

ทั้งๆที่สิ่งนี้ฉันเห็นคุณค่าในการเรียนรู้ C สำหรับการจัดการความต้องการการดำเนินงานที่ระดับต่ำกว่าของรหัส (ซึ่งฉันคิดว่ามีหลายสิ่งที่จะทำอย่างไรกับ static vs dynamic ที่ระดับคอมไพเลอร์) แต่สิ่งที่ฉันพยายามคาดศีรษะ มีบริบทเฉพาะของโครงการหรือไม่ (อาจมีการดำเนินการเกี่ยวกับข้อมูลแบบไดนามิกบางประเภท) ที่เกี่ยวข้องกับสิ่งอื่นนอกเหนือจากประสิทธิภาพที่เหมาะสมกับ Java หรือ C # เทียบกับ Python


5
คำตอบคือ "ใช่" ภาษาแต่ละประเภท - แน่นอนว่าแต่ละภาษา - มีจุดแข็งและจุดอ่อนดังนั้นจึงเหมาะกับงานบางอย่างมากกว่าภาษาอื่น ๆ
ChrisF

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

คำตอบ:


10

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

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


3
@Erik: ฉันไม่แน่ใจว่าฉันจะพูดอย่างนั้น สิ่งต่าง ๆ เปลี่ยนไปในระหว่างการพัฒนา ข้อกำหนดสามารถเปลี่ยนแปลงได้หรือคุณพบว่าคุณใช้งานข้อกำหนดไม่ถูกต้องและต้องมีการอัพเดทรหัส ความสามารถในการเปลี่ยนสิ่งหนึ่งและใช้รวบรวมข้อผิดพลาดที่เกิดขึ้นจะแสดงให้คุณที่จะหาทุกอย่างอื่นที่ต้องมีการเปลี่ยนแปลงมีขนาดใหญ่เพิ่มความสะดวกสบายและความเร็วของการพัฒนาที่คุณสูญเสียในภาษาที่ใช้เทคนิคที่ไม่สามารถใช้ได้ นั่นเป็นหนึ่งในเหตุผลที่คุณไม่เห็นแอพที่ซับซ้อนที่พัฒนาในภาษาไดนามิก
Mason Wheeler

9
@Mason Wheeler: คำตอบที่ดีมาก +1 ฉันจะเพิ่มการตรวจสอบประเภทคงที่ยังช่วยในการค้นหาข้อบกพร่องก่อนหน้านี้โดยมีความถูกต้องของประเภทการตรวจสอบคอมไพเลอร์ เช่นฉันดีบั๊กโปรแกรม Ruby 200 บรรทัดเมื่อวานนี้และมีข้อบกพร่องสองข้อที่เกี่ยวข้องกับประเภทที่ฉันสามารถตรวจพบได้โดยการเรียกใช้โปรแกรม ฉันไม่ต้องการคิดว่าจะเกิดอะไรขึ้นในโครงการ 100000 บรรทัด ดังนั้นการพิมพ์แบบไดนามิกจะช่วยให้คุณมีความยืดหยุ่นมากขึ้นซึ่งเป็นสิ่งที่ดีในบริบทที่คุณอธิบายในราคาที่คุณไม่สามารถหาข้อบกพร่องบางอย่างในเวลารวบรวม ดังนั้นการพิมพ์แบบสแตติกไม่เพียง แต่เกี่ยวข้องกับประสิทธิภาพ แต่ยังรวมถึงความถูกต้องอีกด้วย
จอร์โจ

1
@MasonWheeler สองปีและ C # และ Java มากขึ้นกว่าที่ฉันต่อรองในภายหลังตอนนี้ฉันจะไม่เห็นด้วยกับสิ่งที่สอง แอพพลิเคชั่นบนเว็บที่ซับซ้อนทำด้วยภาษาแบบไดนามิกทั้งหมด เวลาในการคอมไพล์เทียบกับเวลาไม่มีความหมายเมื่อคุณสามารถทำการเปลี่ยนแปลงที่มองเห็นได้ทันที และฉันได้พัฒนาความเห็นว่าการเอะอะในเรื่องประเภทต่าง ๆ มีความหมายมากกว่าในภาษาขั้นตอนมากกว่าในภาษาที่ควรได้รับการขับเคลื่อนโดย OOP โดยที่ข้อมูลไม่ควรเปลี่ยนมืออย่างต่อเนื่องตั้งแต่แรก
Erik Reppen

1
@Erik: * เสียวสะดุ้ง * ก่อนอื่นให้ตัดสินการพิมพ์แบบคงที่เป็นแนวคิดโดย Java เปรียบเสมือนการตัดสินรถยนต์ตามแนวคิดโดย Pinto และประการที่สองสิ่งใดก็ตามที่การเปลี่ยนแปลงสามารถ "มองเห็นได้ทันที" คือตามคำนิยามไม่ใช่โปรแกรมที่ซับซ้อนมากเพราะถึงแม้จะมีฮาร์ดแวร์ที่ทันสมัยโปรแกรมที่ซับซ้อนก็ใช้เวลาพอสมควรในการเตรียมโค้ดไม่ว่าจะเป็นคอมไพเลอร์หรือล่าม หรือคอมไพเลอร์ JIT) กำลังเตรียมการ แม้แต่เว็บแอปพลิเคชั่นที่น่าประทับใจที่สุดก็มักจะเป็นโปรแกรมที่ง่ายมากที่ได้รับการสนับสนุนจากฐานข้อมูลที่ซับซ้อนซึ่งเป็นเรื่องที่แตกต่างกันโดยสิ้นเชิง
Mason Wheeler

1
ความสามารถในการสร้าง abstractions ที่ซับซ้อนคือ orthogonal เพื่อให้มีระบบแบบคงที่ vs แบบไดนามิกและ orthogonal ถึงความเร็ว มีระบบแบบสแตติกออกมีที่ช่วยให้บทคัดย่อที่มีประสิทธิภาพอย่างไม่น่าเชื่อ (แม้ว่าบางครั้ง arcane) การมีการเปลี่ยนแปลงที่ปรากฏขึ้นทันทีนั้นขึ้นอยู่กับระบบประเภท: คุณสามารถสร้างล่ามสำหรับภาษาที่พิมพ์แบบคงที่ได้
Rufflewind

4

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

แต่ระบบประเภทนั้นยากที่จะทำให้ถูกต้อง ผมไม่เชื่อว่ามีเป็นระบบที่สมบูรณ์แบบชนิดในธรรมชาติในขณะที่เขียนนี้ (โดย "ระบบประเภทที่สมบูรณ์แบบ" ฉันหมายถึงระบบประเภทที่เข้มงวดซึ่งไม่จำเป็นต้องมีคำอธิบายประกอบโค้ดอย่างละเอียดที่ไม่สร้างข้อผิดพลาดประเภทบวกเท็จและมีข้อผิดพลาดประเภทที่ง่ายสำหรับโปรแกรมเมอร์ที่จะเข้าใจ) ยิ่งไปกว่านั้น ยากที่จะเข้าใจระบบที่ดีที่มีอยู่จริง เมื่อฉันเรียนรู้ Haskell ฉันไม่สามารถบอกคุณได้ถึงข้อผิดพลาดประเภทที่คลุมเครือที่ฉันได้รับขณะที่พยายามเขียนสิ่งที่ดูเหมือน (ถึงฉัน) เช่นรหัสที่ถูกต้อง โดยปกติแล้วรหัสไม่ถูกต้องจริง (ซึ่งเป็นจุดที่ชอบระบบพิมพ์) แต่ใช้เวลามากทำงานเพื่อทำความเข้าใจข้อความแสดงข้อผิดพลาดจากคอมไพเลอร์เพื่อให้ฉันสามารถแก้ไขปัญหาพื้นฐานได้ ในภาษา OO ในที่สุดคุณอาจพบว่าตัวเองคิดว่า "เรื่องนี้ควรจะcontravariantกับประเภทของการป้อนข้อมูลไม่ covariant!" หรือ (มีโอกาสมากขึ้น) กลับไป typecasts ที่จะหนีจากขอบเขตของระบบการพิมพ์ที่ ระบบประเภทสามารถรับได้มากกว่าที่คุณคิด

สำหรับสิ่งที่คุ้มค่ามันเป็นความเข้าใจของฉันว่าความยากลำบากในการติดตั้งระบบประเภทที่ดีเป็นส่วนหนึ่งของแรงบันดาลใจของGilad Bracha ที่จะรวมการสนับสนุนประเภทระบบแบบเสียบได้ใน Newspeak


การทดสอบหน่วย WRT ฉันเห็นด้วยอย่างสมบูรณ์ คุณมักเห็นคนพูดว่า "ถ้าคุณมีการทดสอบหน่วยที่ดีพวกเขาสามารถตรวจสอบความถูกต้องของประเภทสำหรับคุณ" นั่นทำให้ฉันนึกถึงเสมอว่า Paul Graham (ใครเชื่ออย่างยิ่งว่าการพิมพ์แบบไดนามิกนั้นเป็นสิ่งที่ดีเสมอ) กล่าวว่าภาษาที่ทำให้คุณทำงานของคอมไพเลอร์ด้วยตนเองนั้นเป็นภาษาที่มีข้อบกพร่อง Sorta ทำให้คุณหยุดและคิด ...
Mason Wheeler

ฉันคิดว่าความกังวลมากมายเกี่ยวกับ 'อันตราย' ของภาษาที่พิมพ์แบบไดนามิกไม่ได้คำนึงถึงวิธีที่เราเขียนสิ่งนี้ Python และ JS ส่วนใหญ่สามารถเขียนสไตล์คอนโซลได้ การรวบรวมสกรูกับเวลาทำงานฉันสามารถลองใช้ได้ทันทีและดูว่าเกิดอะไรขึ้น อย่างไรก็ตามฉันคิดว่าคุณอยู่ในจุดที่ดีมาก ไม่มีอะไรทำให้ฉันบ้าคลั่งในการพัฒนาเว็บฝั่งไคลเอ็นต์มากกว่าเมื่อผู้ขายเบราว์เซอร์ที่ดีที่คาดคะเนทั้งหมดให้รหัสผ่านที่น่ากลัวในขณะที่ IE6 หรือ 7 ทำสิ่งที่ไม่คาดคิดซึ่งจะทำให้เสียเวลา ดูดในแบบทั่วไปมากขึ้น
Erik Reppen

@ mason-wheeler ประเภท mismatch เป็นข้อผิดพลาด trival และไม่ใช่ว่าภาษาแบบไดนามิกไม่ได้ตรวจสอบประเภทมันเป็นเพียงตอนรันไทม์ ฉันพบว่าภาษาของฉันคงที่ส่วนใหญ่มีระดับความครอบคลุมของการทดสอบหน่วยเดียวกันพวกเขาจะไม่สูญเสียการทดสอบใด ๆ จากการตรวจสอบคอมไพเลอร์ที่มีประเภทก่อนเวลาและภาษาแบบไดนามิกไม่ต้องเพิ่มการทดสอบเฉพาะเพื่อตรวจสอบประเภท ระบบรันไทม์จะตรวจสอบประเภทของคุณหากการทดสอบหน่วยของคุณครอบคลุมวิธีการของคุณมันจะจับพวกเขา
jbtule

4

เป็นเครื่องมือที่แตกต่างกัน แต่ไม่ใช่โดยประสิทธิภาพ มันเป็นเรื่องของความซับซ้อน

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

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

ดังนั้นภาษาแบบไดนามิกมักจะเหมาะกับโปรแกรมขนาดเล็ก (ฉันหมายถึงมีขนาดเล็กมาก) เช่นหน้าเว็บแบบไดนามิกเว็บเบราว์เซอร์ DSL (ไม่ใช่สำหรับแอปพลิเคชันเบราว์เซอร์!) หรือเชลล์สคริปต์ ภาษาแบบคงที่เหมาะสำหรับการเขียนโปรแกรมระบบหรือเนื้อหาอื่น ๆ

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

ดูที่นี่สำหรับรายละเอียดเพิ่มเติม: https://softwareengineering.stackexchange.com/a/105417/17428


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

2
@Giorgio ดีนั่นอาจเป็นเพราะฉันติดการตรวจสอบแบบคงที่ มันช่างน่ารักเหลือเกินสำหรับฉันและฉันก็ไม่สามารถอยู่ได้โดยปราศจากพวกมันแม้แต่น้อย: p
Eonil

ฉันเห็นข้อดีของภาษาแบบคงที่ (และฉันได้ตอบคำถามของคุณแล้ว) เมื่อเร็ว ๆ นี้ฉันใช้ Python และ Common LISP และฉันยอมรับว่าในทางปฏิบัติคุณจะได้รับผลลัพธ์ที่ดีถ้าคุณใช้การออกแบบที่สะอาดและโดยเฉพาะอย่างยิ่งใน Python ถ้าคุณเขียนการทดสอบที่เพียงพอ ภาษาเหล่านี้มีประสิทธิภาพมากในการสร้างต้นแบบที่สามารถเปลี่ยนเป็นรหัสการผลิตของคุณได้อย่างง่ายดาย แต่ใช่สำหรับโครงการที่ซับซ้อนกว่านี้ฉันต้องการได้รับความช่วยเหลือมากที่สุดเท่าที่จะหาได้ดังนั้นฉันจึงชอบภาษาแบบคงที่
Giorgio

1

ปัจจุบันฉันเขียนโปรแกรมในภาษาประเภทคงที่ (C # และ F #) แต่ฉันสนุกกับการเขียนโปรแกรมในภาษาไดนามิก (Smalltalk, Ruby) มีข้อดีและข้อเสียมากมายที่ผู้คนเชื่อมโยงกับประเภทหนึ่งและอีกประเภทหนึ่งที่เกี่ยวกับภาษามากกว่าเมื่อคุณบังคับใช้ประเภท ตัวอย่างเช่นภาษาแบบไดนามิกมักจะมีไวยากรณ์ที่สะอาดและกระชับยิ่งขึ้นอย่างไรก็ตาม F # และ OCaml ที่มีระบบการอนุมานประเภทมีการล้างไวยากรณ์เป็นภาษาแบบไดนามิกใด ๆ และด้วยการพิมพ์แบบสแตติกคุณมีการรีแฟคเตอร์อัตโนมัติและการเติมข้อความอัตโนมัติ แต่สมอลล์ทอล์คโดยมีรหัสแหล่งที่มาทั้งหมดในฐานข้อมูลและแต่ละวิธีที่คอมไพล์แยกต่างหากเป็นภาษาแรกที่มีการรีฟิลอัตโนมัติอัตโนมัติ ในที่สุดภาษาแบบไดนามิกและแบบสแตติกสมัยใหม่ในปัจจุบันจะเป็นประเภทที่ปลอดภัยซึ่งเป็นสิ่งสำคัญที่สุดของระบบการพิมพ์ของคุณ


บางครั้งฉันสงสัยว่าการพิมพ์แบบคงที่เป็นเพียงส่วนเล็ก ๆ ของสมการที่ทำให้ภาษามีความยืดหยุ่นมากขึ้นหรือน้อยลง ฉันคิดว่าสิ่งที่ฉันเริ่มรู้ก็คือผู้คนจำนวนมากชอบชุดรางที่นุ่มสบายที่จะแนะนำพวกเขาแทนที่จะมีการครองราชย์ฟรีเพื่อทำสิ่งที่อันตรายอย่างไร้เหตุผลเช่นผู้ประกอบการที่บรรทุกเกินพิกัด VS ทำให้ฉันอยากเตะลูกสุนัขบางครั้ง แต่ฉันอยากรู้อยากเห็นเกี่ยวกับ F # และสิ่งที่คุณพูดเกี่ยวกับมันทำให้ฉันอยากรู้อยากเห็นมากขึ้น ฉันคิดว่านี่เป็นสิ่งที่มากกว่าแค่สิ่ง C # ที่คุณสามารถส่งไปยังประเภทที่ครอบคลุมมากขึ้นโดยปริยาย
Erik Reppen

@erik, โอ้ใช่มากกว่าการพิมพ์โดยนัยและ var: F # การอนุมานประเภท
jbtule

-1

ตอนนี้เป็นปี 2558 ซึ่งเพิ่มตัวอย่างข้อมูลที่น่าสนใจในการสนทนา:

  1. ส่วนสำคัญของโลกแบ็กเอนด์ขององค์กรกำลังพิจารณาหรือเริ่มใช้ Python (ไดนามิก) แทน Java (static static)
  2. โลกหน้าขององค์กรกำลังมองเห็นสิ่งต่าง ๆ เช่น AngularJS v2 ตาม TypeScipt: ส่วนขยายที่พิมพ์ของ Javascript

ดังนั้นแบ็กเอนด์จึงเบื่อกับแจ็คเก็ตแบบตรงที่ไม่จำเป็นของการพิมพ์ที่เข้มงวดในขณะที่พวกแบ็คเอนด์เบื่อหน่ายกับความวุ่นวายในการพิมพ์แบบไดนามิก

ค่อนข้างแดกดัน: ฉันสงสัยว่าพวกเขาจะได้พบกันในกลางหรือเร่งผ่านกันด้วยเสียงบูมของเส้นตายผ่าน ... ;)


ถ้าคุณไม่แสดงหลักฐานใด ๆ ฉันจะอ้างว่าในโลกที่แบ็กเอนด์ที่เลวร้ายที่สุดกำลังจะเปลี่ยนเป็นโก ตำนานที่ว่าภาษาการเขียนโปรแกรมแบบสแตติกมักจะมีพิธีจำนวนมากได้ถูก debunked มานานแล้วด้วยระบบการอนุมานที่ทรงพลังกว่าและการใช้งาน REPL ที่มั่นคง
Den

ปลายด้านหลังมีการพิมพ์แบบไดนามิกมากมายในเครื่องชั่งขนาดใหญ่ โดยเฉพาะอย่างยิ่ง Django เป็นที่นิยมอย่างมากในการสื่อสารมวลชนและดำเนินการด้านหลังสำหรับ NYT, Guardian และ Washington Post Walmart ทำงานบนโหนด ตำนานเดียวคือความคิดที่ว่าคุณไม่สามารถเขียนสเกลได้หากไม่มีสแตติกประเภท และหลังจากที่ได้ใช้เวลาคิดเกี่ยวกับภัยพิบัติฐานรหัสดั้งเดิมของ Java ที่ฉันพบฉันคิดว่าคนที่สบายใจที่ทำเช่นนั้นดีกว่าสำหรับพวกเขาไม่ว่าพวกเขาจะทำงานกับสเตติกหรือไดนามิก
Erik Reppen

อันที่จริงฉันควรมีทีม Python ที่มีทักษะในโครงการองค์กรขนาดใหญ่ของฉันแทนที่จะเป็นจาวาที่แย่เพียงแค่ชี้แจงตำแหน่งของฉัน: ฉันโพสต์คำตอบข้างต้นเป็นการประเมินของ
Cornel Masson

อันที่จริงฉันควรมีทีม Python ที่มีทักษะในโครงการองค์กรขนาดใหญ่ของฉันมากกว่า Java ที่ยากจน เพียงเพื่อชี้แจง: ฉันโพสต์คำตอบข้างต้นเป็นข้อสังเกตเกี่ยวกับแนวโน้มที่ฉันเห็นในฐานลูกค้าของฉันเครือข่ายอุตสาหกรรมและการวิจัยทั่วไป แบ็กเอนด์ที่เข้มงวดแบบดั้งเดิมจะโอบกอดความเข้มงวดน้อยลง มันไม่ได้แม้แต่ความเห็นที่ว่า "ถูกต้อง" (ถ้ามี) - ไม่แน่ใจว่าทำไมฉันถึงได้ลงคะแนน บางทีอาจจะประชดจะหายไป ...
แหล Masson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.