Booleans

/me จะแทนค่าความจริงด้วยฟังก์ชั่นได้ยังไง? คำถามลอยไปลอยมา

หนึ่งในคำตอบที่น่าสนใจ เกิดจากความจริงอย่างหนึ่ง คือ ค่าความจริง ไม่ว่าจะ จริง(True) หรือ เท็จ(False) มักใช้พร้อมๆ Conditional Statements ซึ่งโดยทั่วไปแล้ว มันคือ “ถ้า…เป็นจริง ฉันจะทำ… ถ้าไม่ฉันจะทำ…”

ดูเหมือนว่าพฤติกรรมของ Booleans คือ เงื่อนไขสำหรับเลือก actions อันใดอันหนึ่ง จาก 2 เหตุการณ์ ดังนั้นเราสามารถใช้พฤติกรรมลักษณะนี้ในการสร้าง Booleans ด้วยฟังก์ชั่นที่รับตัวแปร 2 ตัว แล้วเลือกตัวใดตัวหนึ่งออกไป ดังนี้

TRUE เป็นฟังก์ชั่นที่ return ตัวแปรแรกเสมอ และ FALSE เป็นฟังก์ชั่นที่ return ตัวแปรที่สองเสมอ เมื่อเปลี่ยนเป็น arrow functions จะได้ดังนี้

ทำนองเดียวกับกับตัวเลข /me จำเป็นต้องสร้าง to_boolean เพื่อใช้ในเปลี่ยนฟังก์ชั่นค่าความจริงพวกนี้ไปเป็น native javascript

ตรวจสอบอีกที

#ง่ายกว่างี้มีอีกไหม? #ง่ายกว่างี้มีอีกไหม? #ง่ายกว่างี้มีอีกไหม? #ง่ายกว่างี้มีอีกไหม? #ง่ายกว่างี้มีอีกไหม?

เมื่อได้ Booleans แล้ว เครื่องมือต่อมาที่ขาดไม่ได้คือ IF “ถ้า….ถ้าใช้ แล้ว….ถ้าไม่ แล้ว…..” และแน่นอนว่า จากรูปแบบของ Booleans แล้ว /me สามารถนำมาสร้าง IF ได้อย่างง่ายดาย

แต่ความจริงแล้ว IF เป็นแค่ syntactic sugar ที่ช่วยอำนวยความสะดวกในการอ่านโค้ดและเขียนโค้ดเท่านั้นเอง เพราะว่าเราสามารถใช้ Booleans แทน IF ได้เลยทันที เพราะทั้งคู่ใช้ concept เหมือนกัน

ด้วยเงื่อนไขที่เหมือนกันนี้ เรายังสามารถ refactoring IF ให้มีความง่ายมากขึ้น

เพราะว่า ทุกครั้งที่ IF(boolean)(ActionThen)(ActionElse) เทียบเท่ากับ boolean(ActionThen)(ActionElse) ดังนั้น IF(boolean) เทียบเท่ากับ boolean

#ฮูเร้ #ฮูเร้ #ฮูเร้ #ฮูเร้ #ฮูเร้ #ฮูเร้

และนี้ ก็เป็นอีก checkpoint สำหรับ isPrime(p)

// โค้ดดูเปลี่ยนไปจากเดิมเยอะ เพราะว่า /me เปลี่ยนจาก psudo-code เป็น javascript ที่ควรจะเป็น แต่ดูเหมือนว่าก็ยังไม่เป็นรูปเป็นร่างเท่าที่ควร เฮ้ออออ~ #สู้ต่อไปทาเคชิ

หลังจากที่เราสร้าง TRUE, FALSE และ IF ได้แล้ว /me อยากจะแถมเครื่องมืออีกอย่างที่น่าสนใจ(แต่ isPrime ของเราไม่ต้องใช้มัน) และมันก็คือ

Logic Operations

สำหรับโปรแกรมเมอร์บางคนอาจจะงงๆ เพราะมักคุ้นเคยกับ &&, ||, ! หรือ สำหรับสาวก python ก็จะใช้เป็นคำว่า and, or, not

เราสามารถ implement ได้ดังนี้

สามารถอธิบายง่ายๆ โดยใช้หลักของ logic ทั่วไป

* พฤติกรรมของ AND
สร้างจากความจริง 2 ข้อคือ

เมื่อ a เป็น FALSE แล้วแปลว่า “ไม่ว่ายังไงก็ตาม expression นี้ ก็เป็น false” จึงเลือกให้ return a ซึ่งมีค่าเป็น FALSE

เมื่อ a เป็น TRUE แล้วก็เลือก return b

* พฤติกรรมของ OR
สร้างจากความจริง 2 ข้อคือ

– ทำนองเดียวกับ AND –

* พฤติกรรมของ XOR
สร้างจากสัจพจน์ a xor b => (a and not b) or (not a and b) ดังนั้น

ถ้า a เป็น TRUE แล้ว จะเหลือแค่ (a and not b) ดังนั้น เราจึง return (not b)

ถ้า a เป็น FALSE แล้ว จะเหลือแค่ (not a and b) ดังนั้น เราจึง return (b)

และ สุดท้าย logic NOT

สังเกตว่ามันมีการสร้าง 2 แบบ สำหรับ Application order และ Normal order แล้วทั้ง 2 คืออะไร?

แน่นอนว่าหลายคนอาจสงสัยว่า Application order และ Normal order ต่างกันยังไง? ทั้งๆที่ทั้ง 2 NOT มีพฤติกรรมเหมือนกันคือการกลับค่าความจริง TRUE => FALSE และ FALSE => TRUE

ทั้งสองความลำดับการให้ความสำคัญระหว่าง arguments และ caller function โดย

> Normal order เลือกที่จะรัน caller function ก่อนที่จะไปรันแต่ละ arguments
> Application order เลือกที่จะรัน arguments ทุกค่าให้หมดก่อน แล้วจึงรัน caller function

ตัวอย่างง่ายๆ เช่น
// สมมติว่ามี functions เหล่านี้

ดูเหมือนว่า Application order เป็นสิ่งที่ดีกว่า เพราะว่า มันลดจำนวนครั้งในการรันคำสั่งได้มากกว่า แต่ในบางกรณี ก็ไม่ดีอย่างที่คิด เพราะว่า Application order ต้องรันทุกๆ arguments ก่อนซึ่งบางครั้งเราไม่จำเป็นขนาดนั้น เพราะเราอาจจะไม่จำเป็นต้องใช้มัน

แต่เราไม่มีสิทธิเลือกหรอกนะว่า จะใช้ Evaluation order แบบไหน เพราะว่าแต่ละภาษาเลือกมาให้เราใช้เรียบร้อยแล้ว และ javascript เลือก Application order นั้นเอง

กลับมาต่อกับเรื่อง NOT

* พฤติกรรมของ NOT
มีลักษณะต่างกับอันอื่น คือ มันจะสร้าง booleans ตัวใหม่มาแทนตัวเก่า ที่สลับ argumants กับตัวเดิม และนั้นก็คือ not

จบแล้วสำหรับ data type พื้นฐานอย่างค่าความจริง true, false และตัวดำเนินการทางลอจิก อย่าง AND, OR สุดท้ายก็เป็นหัวข้อที่เกินมาอย่างงงๆ Evaluation order

สำหรับตอนต่อไป /me จะพาไปเจอกับคำสั่งที่ขาดไม่ได้ นั้นก็คือคำสั่ง “เปรียบเทียบ”

PS. อ่านตอนก่อนหน้าได้ที่
EP1: Introduction
EP2: Numbers
EP3: Arithmetic operators
EP4: Booleans

ต้นฉบับ Programming with Nothing

PS2.โค้ดบางส่วนในบทความ อาจจะรันไม่ได้จริงๆ เพราะ javascript ไม่ได้เปลี่ยน multiple argument function เป็น nested single-argument function อัตโนมัติ อย่างในภาษา Haskell หรือ Lips ดังนั้นฟังก์ชั่นหลายตัวแปร จะต้องแปลงให้อยู่ในรูปตัวแปรเดียวก่อน ถึงจะสามารถรันได้อย่างปกติ แต่อาจจะทำให้อ่านยากมากขึ้น /me จึงขออธิบายด้วย multiple argument function

แต่สามารถ ดูโค้ดส่วนต่างๆได้ที่ Github จะทยอย push ตามบล๊อคที่ทยอยเขียน

ขอบคุณ คำอธิบาย Evaluation Order เพิ่มเติมจาก
CSE 505: Concepts of Programming Languages

Tell your friend about thisShare on Facebook
Facebook
0Tweet about this on Twitter
Twitter