ฟังก์ชั่นการรับค่าจากฟังก์ชั่นอื่นถือว่าบริสุทธิ์หรือไม่


9

ฉันกำลังพยายามหาวิธีจัดการกับค่าตัวแปรเริ่มต้นเมื่อสร้างฟังก์ชั่นที่ไม่มีผลข้างเคียงและสิ้นสุดลงด้วยสิ่งต่อไปนี้:

function getDefaultSeparator() {
    return ':';
}

function process(input, separator) {
    var separator = separator || getDefaultSeparator();

    // Use separator in some logic

    return output;
}

ตัวคั่นเริ่มต้นจะใช้ในฟังก์ชั่นอื่นและฉันต้องการกำหนดไว้ในที่เดียวเท่านั้น

หากนี่คือฟังก์ชั่นที่บริสุทธิ์ความแตกต่างจากการใช้ค่าคงที่ DEFAULT_SEPARATOR ทั่วโลกแทนคืออะไร


5
ไม่มีความแตกต่างที่เป็นสาระสำคัญเว้นแต่ว่าคุณวางแผนที่จะใช้ฟังก์ชันเป็นตัวยึดตำแหน่งสำหรับตรรกะบางอย่างที่จะเพิ่มในภายหลัง
Robert Harvey

3
ซ้ำซ้อนที่เป็นไปได้ของฟังก์ชั่นไม่บริสุทธิ์ทันทีถ้ามันใช้ฟังก์ชั่นเป็นพารามิเตอร์หรือไม่? . คำถามไม่ได้ซ้ำกันแน่นอน แต่คำตอบควรเหมือนกัน ("มันขึ้นอยู่กับความบริสุทธิ์ของฟังก์ชั่นอื่น ๆ ")
jpmc26

1
การใช้ค่าคงที่ส่วนกลางไม่ทำให้ฟังก์ชันไม่บริสุทธิ์ การใช้ค่าโกลบอลที่คุณถือว่าเป็นค่าคงที่
chepner

Btw คุณสามารถแกงprocess(ด้วยคำสั่งพารามิเตอร์กลับรายการ) และกว่าฟังก์ชั่น curried เฉพาะเพื่อvar processDefault = process(":")
bob

คำตอบ:


22

ฟังก์ชั่นการรับค่าจากฟังก์ชั่นอื่นถือว่าบริสุทธิ์หรือไม่

ขึ้นอยู่กับสิ่งที่ฟังก์ชั่นอื่นทำและสิ่งที่ฟังก์ชั่นการโทรทำ การปนเปื้อนนั้นไม่บริสุทธิ์

การเรียกฟังก์ชันบริสุทธิ์ไม่เปลี่ยนความบริสุทธิ์ของฟังก์ชันการโทร การเรียกฟังก์ชั่นที่ไม่บริสุทธิ์ทำให้ฟังก์ชั่นการโทรไม่บริสุทธิ์โดยอัตโนมัติเช่นกัน

ในตัวอย่างของคุณมันขึ้นอยู่กับความบริสุทธิ์ของชิ้นส่วนที่คุณทิ้งไว้ถ้ามันบริสุทธิ์ฟังก์ชั่นทั้งหมดจะบริสุทธิ์

หากนี่คือฟังก์ชั่นที่บริสุทธิ์ความแตกต่างจากการใช้ค่าคงที่ DEFAULT_SEPARATOR ทั่วโลกแทนคืออะไร

ไม่มีอะไร ฟังก์ชั่นที่ส่งกลับค่าเดิมมักจะแยกไม่ออกจากค่าคงที่ ในความเป็นจริงนั้นเป็นวิธีการที่ค่าคงที่ถูกสร้างแบบจำลองใน calcul-แคลคูลัส


2
"การเรียกฟังก์ชั่นที่ไม่บริสุทธิ์ทำให้ฟังก์ชั่นการโทรที่ไม่บริสุทธิ์โดยอัตโนมัติ" คุณแน่ใจหรือไม่? AFAICS การเรียกฟังก์ชั่นที่ไม่บริสุทธิ์ไม่ได้ทำให้ผู้เรียกไม่บริสุทธิ์โดยอัตโนมัติ
Deduplicator

2
@Dupuplicator: ขึ้นอยู่กับการวิเคราะห์แบบคงที่ที่คุณสามารถทำได้ (ต้องใส่ใจ) แน่นอนว่าถ้ามีฟังก์ชั่นfuncที่มีผลข้างเคียงเมื่อคุณผ่านเป็น 0 แต่ไม่ใช่เมื่อคุณผ่านใน 1 คุณสามารถพูดได้อย่างมีเหตุผลว่าแม้ว่าfuncตัวเอง "ไม่บริสุทธิ์" ฟังก์ชั่นที่เรียกมันว่าfunc(1)(และไม่สนใจค่าส่งคืน พูด) ไม่จำเป็นต้องไม่บริสุทธิ์ การโทรfuncก็เพียงพอที่จะ "ทำให้เสีย" ผู้โทรซึ่งอาจไม่บริสุทธิ์ แต่ฟังก์ชั่นที่ไม่บริสุทธิ์อาจจะได้รับการพิสูจน์ว่าบริสุทธิ์หลังจากทั้งหมด อย่างน้อยใน javascript ที่ไม่ได้กำหนดบริสุทธิ์ / ไม่บริสุทธิ์ในภาษา
Steve Jessop

6

ใช่ทั้งสองเป็นฟังก์ชั่นที่บริสุทธิ์ (สมมติว่าส่วนที่ elided นั้นยังบริสุทธิ์) เพราะ:

  1. ผลลัพธ์ขึ้นอยู่กับพารามิเตอร์เท่านั้น
  2. ไม่มีผลข้างเคียง

โปรดทราบว่าถ้าgetDefaultSeparator()ไม่ใช่ฟังก์ชั่นที่บริสุทธิ์ก็จะไม่process()บริสุทธิ์

ใน Javascript ไม่มีความแตกต่างที่มีความหมายระหว่างการใช้ฟังก์ชั่นแท้หรือค่าคงที่และทั้งสองอย่างสามารถใช้งานได้โดยฟังก์ชั่นแท้ตราบใดที่ความสามารถของ Javascript ในการกำหนดฟังก์ชั่นใหม่หรือแก้ไขค่าคงที่

แนวคิดหลักที่อยู่เบื้องหลังฟังก์ชั่นบริสุทธิ์คือพวกเขาสามารถถูกแทนที่ด้วยค่าที่พวกเขากลับมาโดยไม่ส่งผลกระทบต่อผลลัพธ์ของโปรแกรม


1

อย่างที่คนอื่นพูดแน่นอนมันยังคงเป็นฟังก์ชั่นที่บริสุทธิ์

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

การใช้ฟังก์ชั่นจะช่วยให้คุณมีความยืดหยุ่นมากขึ้นในการเปลี่ยนการใช้งานซึ่งกล่าวได้ว่าวิธีการทำงานนั้นให้การเชื่อมต่อที่แน่นกว่าตัวแปรทั่วโลก

คำถามคือว่าเราต้องการมันหรือไม่?

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

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

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

(ในบันทึกอื่นถ้ารหัสของคุณมีขนาดที่สำคัญใด ๆ ฉันจะสนับสนุนให้ใช้โมดูลที่มีฟิลด์และวิธีการมากกว่าตัวแปรและฟังก์ชั่นทั่วโลก)

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