อะไรคือความแตกต่างระหว่าง“ ฟังก์ชั่น” และ“ ขั้นตอน”?


203

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

ดังนั้นคำถามของฉันคือ:

ความแตกต่างในแง่ของการทำงานวัตถุประสงค์และการใช้งานของพวกเขาคืออะไร?

ตัวอย่างจะได้รับการชื่นชม


ดูเพิ่มเติมที่: stackoverflow.com/q/10388393/974555
gerrit

6
ฉันคิดว่า SICP ทำให้ถูกต้อง ฟังก์ชั่นที่มีอยู่เฉพาะในวิชาคณิตศาสตร์และพวกเขาเป็นตัวแทนของสิ่งที่เป็นความรู้ ขั้นตอนมีอยู่ในภาษาการเขียนโปรแกรม (รวมถึงฟังก์ชั่นที่ใช้งานได้) และเป็นตัวแทนของวิธีการความรู้ ฟังก์ชั่น : sqrt (x) = the y ที่ y ^ 2 = x ขั้นตอน : (define (sqrt x) (newtons-method (lambda (y) (- (square y) x)) 1.0)).
mk12

คำตอบ:


295

ฟังก์ชั่นคืนค่าและขั้นตอนเพียงแค่รันคำสั่ง

ฟังก์ชั่นชื่อมาจากคณิตศาสตร์ มันถูกใช้เพื่อคำนวณค่าตามอินพุต

ขั้นตอนคือชุดของคำสั่งที่สามารถดำเนินการตามลำดับ

ในภาษาการเขียนโปรแกรมส่วนใหญ่ฟังก์ชั่นแม้จะมีชุดคำสั่ง ดังนั้นความแตกต่างเป็นเพียงการคืนค่าส่วนหนึ่ง

แต่ถ้าคุณต้องการรักษาความสะอาดของฟังก์ชั่น (เพียงแค่ดูภาษาที่ใช้งานได้) คุณต้องแน่ใจว่าฟังก์ชั่นนั้นไม่มีผลข้างเคียง


คุณจะมั่นใจได้อย่างไรว่าไม่มีผลข้างเคียงทั้งในภาษาจาวา (c, c) หรือภาษาที่ประกาศ (scala, scheme)?
orlybg

1
@orlybg ในภาษาที่ประกาศความสอดคล้องมาจากการใช้ภาษา ข้อ จำกัด ขอบเขตของพวกเขาป้องกันไม่ให้มีผลข้างเคียง ในทางกลับกันภาษาที่จำเป็นใช้ประโยชน์จากผลข้างเคียงอย่างชัดเจน ผลข้างเคียงไม่ได้เลวร้ายเสมอไป
Tharindu Rusira

ฉันกำลังอ่านกวดวิชา Ada ต่อไปนี้ ( goanna.cs.rmit.edu.au/~dale/ada/aln/8_subprograms.html ) ซึ่งย่อหน้าที่สองของหน้านั้นเริ่มต้นด้วย "ขั้นตอนใน Ada คล้ายกับที่อยู่ในปาสกาล ขั้นตอนสามารถมีข้อความสั่งคืนได้ ". นี่เป็นข้อผิดพลาดในข้อความหรือไม่? หรือหมายความว่าสามารถมีข้อความสั่งคืน แต่ไม่ส่งคืนค่าใด ๆ
jviotti

3
ในปาสกาลโพรซีเดอร์ไม่มีคำสั่งส่งคืนเฉพาะฟังก์ชันทำเท่านั้น ต้องเป็นข้อผิดพลาดในข้อความ อย่างไรก็ตามโพรซีเดอร์สามารถมีคำสั่ง "exit" ซึ่งอาจทำหน้าที่เป็นคำสั่ง "return" โดยไม่มีอาร์กิวเมนต์หมายถึงไม่มีค่าส่งคืน
Eric Fortier

ฟังก์ชั่นสามารถรับอินพุตและส่งคืนเฉพาะเอาต์พุตเท่านั้น โพรซีเดอร์หรือแมโครสามารถรับอินพุตและไม่ส่งคืนข้อมูลใด ๆ ที่เรียกใช้งานจำนวนคำสั่งเท่านั้น ความแตกต่างหลักคือโพรซีเดอร์ไม่สามารถส่งคืนชนิดข้อมูลใด ๆ
EsmaeelE

42

ขึ้นอยู่กับบริบท

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

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

ในภาษาที่ใช้งานได้โดยทั่วไปจะไม่มีสิ่งเช่นโพรซีเดอร์ - ทุกอย่างเป็นฟังก์ชั่น


และเอกสารของภาษาโปรแกรมสามารถเรียกใช้ฟังก์ชั่นและขั้นตอนต่าง ๆ ได้ตามต้องการเพราะผู้คนจะยอมรับชื่อใด ๆ ตั้งแต่พื้นหลังเบื้องหลังชื่อเหล่านั้นได้ถูกลบไปนานแล้ว
Arne Babenhauserheide

18

ตัวอย่างใน C:

// function
int square( int n ) {
   return n * n;
}

// procedure
void display( int n ) {
   printf( "The value is %d", n );
}

แม้ว่าคุณควรทราบว่ามาตรฐาน C ไม่ได้พูดถึงขั้นตอนการทำงานเท่านั้น


4
... มาตรฐาน C ไม่ได้พูดถึงขั้นตอนการทำงานเท่านั้น นั่นเป็นเพราะมันมีฟังก์ชั่นเท่านั้น void functionฟังก์ชั่นที่ให้ผลตอบแทนอะไรเป็น Kernighan & Ritchie Ch 1.7: "ใน C ฟังก์ชันจะเทียบเท่ากับรูทีนย่อยหรือฟังก์ชันใน Fortran หรือขั้นตอนหรือฟังก์ชันใน Pascal" กล่าวอีกนัยหนึ่ง ... คำตอบนี้ผิด
Mogsdad

8
คำตอบนั้นไม่ผิดและเป็นตัวอย่างที่ดีของความแตกต่างระหว่างฟังก์ชั่นบริสุทธิ์และขั้นตอน K&R เรียกรูทีนย่อยทุกตัวว่า "ฟังก์ชั่น" เพื่อให้สิ่งต่าง ๆ เป็นเรื่องง่าย แต่รูทีนย่อยที่มีผลข้างเคียงคือ "ขั้นตอน" จริง ๆ แล้วไม่ใช่ "ฟังก์ชั่น" ในแง่ที่ยอมรับจากคณิตศาสตร์ C อาจเป็นภาษาที่ดีกว่าถ้ามันแยกแยะฟังก์ชั่นจริงจากขั้นตอนนี้จะช่วยในการวิเคราะห์แบบคงที่การเพิ่มประสิทธิภาพการทำงานและการขนาน
Sam Watkins

12

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


11

มีรูทีนย่อย term หรือโปรแกรมย่อยซึ่งย่อมาจากชิ้นส่วนของพารามิเตอร์ที่สามารถเรียกได้จากที่ต่าง ๆ

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


6

ความแตกต่างพื้นฐาน

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

ความแตกต่างขั้นสูง

  • ข้อยกเว้นสามารถจัดการได้โดยบล็อก try-catch ในกระบวนงานในขณะที่บล็อก try-catch ไม่สามารถใช้ในฟังก์ชันได้
  • เราสามารถไปจัดการการทำธุรกรรมในขั้นตอนในขณะที่ฟังก์ชั่นที่เราไม่สามารถ

ใน SQL:

  • ขั้นตอนการอนุญาตSELECTเช่นเดียวกับดราก้อน ( INSERT, UPDATE, DELETE) งบในขณะที่ฟังก์ชั่นช่วยให้เพียงSELECTคำสั่งในนั้น
  • ขั้นตอนไม่สามารถนำไปใช้ในSELECTคำสั่งในขณะที่ฟังก์ชั่นสามารถฝังตัวในSELECTคำสั่ง
  • กระบวนงานที่เก็บไว้ไม่สามารถใช้ในคำสั่ง SQL ที่ใดก็ได้ในบล็อกWHERE(หรือ a HAVINGหรือ a SELECT) ในขณะที่ฟังก์ชั่นสามารถ
  • ฟังก์ชันที่ส่งคืนตารางสามารถใช้เป็น Rowset อื่นได้ สามารถใช้ในJOINบล็อกที่มีตารางอื่น ๆ
  • ฟังก์ชั่นอินไลน์สามารถถูกมองว่าเป็นมุมมองที่รับพารามิเตอร์และสามารถใช้ในJOINบล็อกและการดำเนินการ Rowset อื่น ๆ

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

5

อย่างเคร่งครัดฟังก์ชั่น f เชื่อฟังคุณสมบัติที่ f (x) = f (y) ถ้า x = y คือมันคำนวณผลลัพธ์เดียวกันทุกครั้งที่ถูกเรียกด้วยอาร์กิวเมนต์เดียวกัน (และทำให้มันไม่เปลี่ยนสถานะของ ระบบ.)

ดังนั้น rand () หรือ print ("Hello") ฯลฯ ไม่ใช่ฟังก์ชัน แต่เป็นขั้นตอน ในขณะที่ sqrt (2.0) ควรเป็นฟังก์ชั่น: ไม่มีผลที่สังเกตได้หรือการเปลี่ยนแปลงสถานะไม่ว่าจะมีคนเรียกมันบ่อยแค่ไหนและมันกลับมาเสมอ 1.41 และบางอย่าง


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

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

4

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

ในทางกลับกันฟังก์ชั่นเป็นโค้ดที่ค่อนข้างอิสระในโปรแกรมที่มีขนาดใหญ่กว่า ในคำอื่น ๆ ฟังก์ชั่นคือการดำเนินการตามขั้นตอน


4

นี่เป็นคำถามเก่าที่รู้จักกันดี แต่ฉันต้องการแบ่งปันข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับการวิจัยและการออกแบบภาษาการเขียนโปรแกรมที่ทันสมัย

คำตอบพื้นฐาน

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

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

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

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

อย่างไรก็ตามหากไม่ต้องการผลลัพธ์ของการเรียกใช้ฟังก์ชันก็สามารถเพิกเฉยได้ (อย่างน้อยมีเหตุผล) และการเรียกใช้ฟังก์ชั่นคำจำกัดความ / ฟังก์ชั่นควรสอดคล้องกับคำจำกัดความขั้นตอน / การเรียกขั้นตอนด้วยวิธีนี้ ภาษาที่คล้ายกับ ALGOL เช่น C, C ++ และ Java ทั้งหมดนำเสนอคุณลักษณะของ "ฟังก์ชัน" ในรูปแบบนี้: โดยการเข้ารหัสประเภทผลลัพธ์voidเป็นกรณีพิเศษของฟังก์ชั่นที่ดูเหมือนกระบวนการแบบดั้งเดิมไม่จำเป็นต้องให้คุณสมบัติของ "ขั้นตอน "แยกต่างหาก สิ่งนี้จะช่วยป้องกันบางส่วนในการออกแบบภาษา

ตั้งแต่ SICP เป็นที่กล่าวถึงก็ยังเป็นที่น่าสังเกตว่าในภาษาโครงการที่ระบุโดยR nอาร์เอส , ขั้นตอนหรืออาจจะไม่ต้องกลับผลของการคำนวณที่ นี่คือการรวมกันของ "ฟังก์ชั่น" แบบดั้งเดิม (ส่งคืนผลลัพธ์) และ "ขั้นตอน" (ไม่ส่งคืนอะไร) เป็นหลักเหมือนกับแนวคิด "ฟังก์ชั่น" ของภาษาที่คล้ายกับ ALGOL หลายภาษา (และแบ่งปันการรับรองมาก ตัวถูกดำเนินการก่อนการโทร) อย่างไรก็ตามความแตกต่างแฟชั่นเก่ายังคงเกิดขึ้นได้แม้ในเอกสารเชิงบรรทัดฐานเช่นSRFI-96

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

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

  • เช่นเดียวกับใน R n RS เพียงทำเครื่องหมายผลลัพธ์ที่ไม่สนใจเป็นค่า "ไม่ระบุ" (ประเภทที่ไม่ระบุหากภาษาต้องพูดถึง) และเพียงพอที่จะถูกละเว้น
  • ระบุผลการสนใจเป็นค่าของประเภทหน่วยงานเฉพาะ (เช่นKernel 's #inert) ยังใช้งานได้
  • เมื่อประเภทนั้นเป็นประเภทด้านล่างเพิ่มเติมประเภทนั้นจะสามารถ (หวังว่า) จะได้รับการตรวจสอบแบบคงที่และป้องกันการใช้เป็นประเภทของการแสดงออก voidชนิดในภาษา ALGOL เหมือนเป็นสิ่งตัวอย่างของเทคนิคนี้ ISO C11 _Noreturnนั้นคล้ายกัน แต่บอบบางกว่าในประเภทนี้

อ่านเพิ่มเติม

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

เกี่ยวกับการเขียนโปรแกรมภาษามีหลายประการ:

  • ฟังก์ชั่นในสาขาต่าง ๆ ของคณิตศาสตร์ไม่ได้นิยามว่ามีความหมายเหมือนกันเสมอไป ฟังก์ชั่นในกระบวนทัศน์การเขียนโปรแกรมที่แตกต่างกันอาจแตกต่างกันมาก (บางครั้งไวยากรณ์ของการเรียกใช้ฟังก์ชันมีลักษณะคล้ายกัน) บางครั้งเหตุผลที่ทำให้เกิดความแตกต่างเหมือนกัน แต่บางครั้งก็ไม่
    • มันเป็นสำนวนในการคำนวณแบบจำลองโดยฟังก์ชั่นทางคณิตศาสตร์แล้วใช้การคำนวณพื้นฐานในภาษาการเขียนโปรแกรม โปรดใช้ความระมัดระวังเพื่อหลีกเลี่ยงการจับคู่เป็นรายบุคคลเว้นแต่คุณจะรู้ว่ากำลังพูดถึงอะไร
  • อย่าสับสนระหว่างโมเดลกับเอนทิตีถูกจำลอง
    • หลังเป็นเพียงหนึ่งในการนำไปใช้กับอดีต สามารถมีได้มากกว่าหนึ่งตัวเลือกขึ้นอยู่กับบริบท (เช่นสาขาคณิตศาสตร์ที่สนใจเป็นต้น)
    • โดยเฉพาะอย่างยิ่งจะมากหรือน้อยเหมือนกันไร้สาระที่จะ "ฟังก์ชั่น" รักษาเป็น "แมป" หรือส่วนย่อยของผลิตภัณฑ์คาร์ทีเซียนเหมือนหมายเลขธรรมชาติรักษาเป็นฟอนนอยมันน์-เข้ารหัสเลข (มองเช่นพวงของ{{{}}, {}}... )นอกเหนือจากบริบท จำกัด บางอย่าง .
  • ศาสตร์ฟังก์ชั่นสามารถเป็นบางส่วนหรือทั้งหมด ภาษาการเขียนโปรแกรมที่แตกต่างกันมีการรักษาที่แตกต่างกันที่นี่
    • บางภาษาการทำงานอาจเกียรติทั้งสิ้นของฟังก์ชั่นที่จะรับประกันการคำนวณภายในสายงานเสมอยุติในขั้นตอนที่แน่นอน อย่างไรก็ตามนี่ไม่ใช่การทำให้ทัวริงเสร็จสมบูรณ์ดังนั้นจึงเป็นการลดความหมายของการคำนวณและไม่ค่อยเห็นในภาษาวัตถุประสงค์ทั่วไปนอกเหนือจากความหมายของการพิมพ์ดีด (ซึ่งคาดว่าจะเป็นทั้งหมด)
    • หากความแตกต่างระหว่างโพรซีเดอร์และฟังก์ชันมีความสำคัญควรมี "โพรซีเดอร์ทั้งหมด" หรือไม่? อืม ...
  • โครงสร้างคล้ายกับฟังก์ชั่นในแคลคูลัสที่ใช้ในการสร้างแบบจำลองการคำนวณทั่วไปและความหมายของภาษาการเขียนโปรแกรม (เช่นแลมบ์ดา abstractions ในแลมบ์ดานิค ) สามารถมีกลยุทธ์การประเมินที่แตกต่างกันในตัวถูกดำเนินการ
    • ในการลดลงของแคลคูลัสแบบดั้งเดิมรวมถึงการประเมินการแสดงออกในภาษาหน้าที่บริสุทธิ์ไม่มีผลข้างเคียงที่เปลี่ยนแปลงผลของการคำนวณ เป็นผลให้ถูกดำเนินการไม่จำเป็นต้องได้รับการประเมินก่อนที่ร่างของฟังก์ชั่นเหมือนโครงสร้างข้อมูล (เพราะคงที่ในการกำหนด "ผลลัพธ์เดียวกัน" จะถูกเก็บไว้โดยใช้คุณสมบัติเช่นβ -equivalence ค้ำประกันโดยคริสตจักรร็อสสถานที่ให้บริการ )
    • อย่างไรก็ตามภาษาการเขียนโปรแกรมจำนวนมากอาจมีผลข้างเคียงในระหว่างการประเมินผลของนิพจน์ ซึ่งหมายความว่ากลยุทธ์การประเมินผลอย่างเข้มงวดเช่นการประเมินผลปรับใช้ไม่ได้เช่นเดียวกับคนที่ไม่ใช่การประเมินผลอย่างเข้มงวดเช่นโทรตามความจำเป็น สิ่งนี้มีความสำคัญเนื่องจากไม่มีความแตกต่างจึงไม่จำเป็นต้องแยกความแตกต่างของฟังก์ชั่นมาโคร (เช่นใช้กับข้อโต้แย้ง) จากฟังก์ชัน (ดั้งเดิม) แต่ขึ้นอยู่กับรสชาติของทฤษฎีสิ่งนี้ยังคงเป็นสิ่งประดิษฐ์ ที่กล่าวมาในแง่ที่กว้างกว่าแมโครที่มีลักษณะคล้ายหน้าที่ (โดยเฉพาะอย่างยิ่งวัตถุที่ถูกสุขลักษณะ ) เป็นฟังก์ชันทางคณิตศาสตร์ที่มีข้อ จำกัด ที่ไม่จำเป็นบางประการ (เฟสวากยสัมพันธ์) โดยไม่มีข้อ จำกัด มันอาจมีเหตุผลที่จะรักษามาโครที่คล้ายฟังก์ชัน (ชั้นหนึ่ง) เป็นขั้นตอน ...
    • สำหรับผู้อ่านที่สนใจในหัวข้อนี้พิจารณานามธรรมที่ทันสมัยบาง
  • ขั้นตอนมักพิจารณานอกขอบเขตของคณิตศาสตร์ดั้งเดิม อย่างไรก็ตามในการสร้างแบบจำลองแคลคูลัสความหมายของการคำนวณและการเขียนโปรแกรมภาษาเช่นเดียวกับการออกแบบภาษาการเขียนโปรแกรมร่วมสมัยอาจมีครอบครัวขนาดใหญ่ของแนวคิดที่เกี่ยวข้องแบ่งปันธรรมชาติ "callable" บางส่วนของพวกเขาจะใช้ในการใช้ / ขยาย / แทนที่ขั้นตอน / ฟังก์ชั่น มีความแตกต่างที่ลึกซึ้งยิ่งขึ้น
    • นี่คือบางคำที่เกี่ยวข้อง: ซับรูทีน / (stackless / stackful) coroutines / (undelimited คั่น) ... และแม้กระทั่ง (ไม่ได้ตรวจสอบ) ข้อยกเว้น

3

ในบริบทส่วนใหญ่: ฟังก์ชั่นส่งกลับค่าในขณะที่ขั้นตอนไม่ได้ ทั้งสองชิ้นเป็นรหัสที่รวมกลุ่มกันเพื่อทำสิ่งเดียวกัน

ในบริบทของการเขียนโปรแกรมการทำงาน (ที่ฟังก์ชันทั้งหมดส่งคืนค่า) ฟังก์ชันเป็นวัตถุนามธรรม:

f(x)=(1+x)
g(x)=.5*(2+x/2)

นี่ f คือฟังก์ชันเดียวกับ g แต่เป็นโพรซีเดอร์อื่น


3

ขั้นตอนภายในเราสามารถใช้คำสั่ง DML (แทรก / ปรับปรุง / ลบ) แต่ฟังก์ชั่นภายในเราไม่สามารถใช้คำสั่ง DML

ขั้นตอนสามารถมีทั้งพารามิเตอร์อินพุต \ เอาต์พุต แต่ฟังก์ชันสามารถมีพารามิเตอร์อินพุตได้เท่านั้น

เราสามารถใช้ Try-Catch Block ใน Stored Procedure แต่ในฟังก์ชั่นเราไม่สามารถใช้ Try-Catch block

เราไม่สามารถใช้ Stored Procedure ในคำสั่ง Select แต่ในฟังก์ชั่นเราสามารถใช้ในคำสั่ง Select

กระบวนงานที่เก็บไว้สามารถส่งกลับค่า 0 หรือ n (สูงสุด 1024), แต่ฟังก์ชันสามารถส่งกลับค่า 1 เท่านั้นซึ่งจำเป็น

กระบวนงานที่เก็บไว้ไม่สามารถเรียกจากฟังก์ชั่น แต่เราสามารถเรียกใช้ฟังก์ชันได้จากขั้นตอนที่จัดเก็บไว้

เราสามารถใช้ธุรกรรมใน Stored Procedure แต่ในฟังก์ชั่นเราไม่สามารถใช้ธุรกรรมได้

เราไม่สามารถใช้ Stored Procedure ในคำสั่ง SQL ได้ทุกที่ในส่วนที่ไหน / มี / เลือก แต่ในฟังก์ชั่นที่เราสามารถใช้ได้

เราไม่สามารถเข้าร่วม Stored Procedure แต่เราสามารถเข้าร่วมฟังก์ชั่นได้

สำหรับข้อมูลเพิ่มเติม .. คลิกที่นี่ ... http://dotnet-developers-cafe.blogspot.in/2013/08/difference-between-stored-procedure-and.html


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

คำตอบนี้ไม่ถูกต้องสมบูรณ์สำหรับภาษาโปรแกรมส่วนใหญ่ โพรซีเดอร์มีพารามิเตอร์อินพุตเท่านั้นและฟังก์ชันมีทั้งอินพุตและเอาต์พุต
AStopher

2

ฟังก์ชั่นคืนค่าและขั้นตอนเพียงแค่รันคำสั่ง

ฟังก์ชั่นชื่อมาจากคณิตศาสตร์ มันถูกใช้เพื่อคำนวณค่าตามอินพุต

ขั้นตอนคือชุดของคำสั่งที่สามารถดำเนินการตามลำดับ

ในภาษาการเขียนโปรแกรมส่วนใหญ่ฟังก์ชั่นแม้จะมีชุดคำสั่ง ดังนั้นความแตกต่างเป็นเพียงการคืนค่าส่วนหนึ่ง

แต่ถ้าคุณต้องการรักษาความสะอาดของฟังก์ชั่น (เพียงแค่ดูภาษาที่ใช้งานได้) คุณต้องแน่ใจว่าฟังก์ชั่นนั้นไม่มีผลข้างเคียง


1

สามารถใช้ฟังก์ชันได้ในคำสั่ง sql ในขณะที่โพรซีเดอร์ไม่สามารถใช้ภายในคำสั่ง sql ได้

คำสั่งแทรก, อัพเดตและสร้างไม่สามารถรวมอยู่ในฟังก์ชัน แต่โพรซีเดอร์สามารถมีคำสั่งเหล่านี้ได้

กระบวนงานสนับสนุนธุรกรรม แต่ฟังก์ชันไม่รองรับธุรกรรม

ฟังก์ชั่นจะต้องคืนค่าหนึ่งค่าเดียวเท่านั้น (อีกค่าสามารถส่งคืนโดยตัวแปร OUT) แต่โพรซีเดอร์ส่งคืนชุดข้อมูลและค่าส่งคืนเป็นจำนวนมาก

แผนการดำเนินการของทั้งฟังก์ชันและโพรซีเดอร์นั้นถูกแคชดังนั้นประสิทธิภาพจึงเหมือนกันทั้งสองกรณี


1

ฉันคัดค้านสิ่งที่ฉันเห็นอยู่เรื่อย ๆ ในคำตอบเหล่านี้ส่วนใหญ่สิ่งที่ทำให้ฟังก์ชั่นฟังก์ชั่นคือว่ามันส่งกลับค่า

ฟังก์ชั่นไม่ได้เป็นเพียงวิธีการเก่า ๆ ที่ส่งกลับค่า ไม่ใช่: เพื่อให้เมธอดเป็นฟังก์ชั่นจริงมันจะต้องคืนค่าเดิมที่ได้รับจากอินพุตที่ระบุเสมอ ตัวอย่างของวิธีการที่ไม่ใช่ฟังก์ชั่นเป็นrandomวิธีการในภาษาส่วนใหญ่เพราะแม้ว่ามันจะส่งกลับค่าค่าที่ไม่เหมือนกันเสมอ

ฟังก์ชั่นจึงคล้ายกับแผนที่มากขึ้น (เช่นx -> x'สำหรับฟังก์ชันหนึ่งมิติ) นี่คือความแตกต่างที่สำคัญมากระหว่างวิธีการปกติและฟังก์ชั่นเพราะเมื่อจัดการกับฟังก์ชั่นจริงเวลาและลำดับที่พวกเขาจะได้รับการประเมินไม่ควรที่จะเป็นเช่นนี้ไม่เสมอกรณีที่มีฟังก์ชั่นที่ไม่ใช่

นี่คืออีกตัวอย่างของวิธีการที่ไม่ใช่ฟังก์ชั่น แต่จะยังคงส่งคืนค่า

// The following is pseudo code:
g(x) = {
  if (morning()) {
     g = 2 * x;
  }
  else {
   g = x;
  }
  return g;
}

ฉันคัดค้านความคิดที่ว่ากระบวนการไม่คืนค่า ขั้นตอนเป็นเพียงวิธีเฉพาะในการพูดคุยเกี่ยวกับฟังก์ชั่นหรือวิธีการ ดังนั้นนั่นหมายความว่าหากวิธีการพื้นฐานที่โพรซีเดอร์ของคุณกำหนดหรือนำไปใช้นั้นจะส่งกลับค่าลองเดาว่าโพรซีเดอร์นั้นส่งคืนค่าใด ยกตัวอย่างโค้ดต่อไปนี้จากSICP :

// We can immediately translate this definition into a recursive procedure 
// for computing Fibonacci numbers:

(define (fib n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        (else (+ (fib (- n 1))
                 (fib (- n 2))))))

เมื่อเร็ว ๆ นี้คุณเคยได้ยินเกี่ยวกับกระบวนการแบบเรียกซ้ำไหม? พวกเขากำลังพูดถึงฟังก์ชั่นซ้ำ (ฟังก์ชั่นจริง) และมันจะคืนค่าและพวกเขากำลังใช้คำว่า "ขั้นตอน" แล้วความแตกต่างคืออะไร

วิธีคิดอีกอย่างของฟังก์ชั่น (นอกเหนือจากความหมายที่กล่าวถึงข้างต้น) เป็นการแสดงนามธรรมของอุดมคติเช่นตัวเลข 1 ขั้นตอนคือการใช้งานจริงของสิ่งนั้น โดยส่วนตัวฉันคิดว่าพวกเขาใช้แทนกันได้

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

อะนาล็อกสำหรับกระบวนการคือสูตรอาหาร ตัวอย่างเช่น; สมมติว่าคุณมีเครื่องที่เรียกว่าmake-piesเครื่องนี้จะใช้เวลาในส่วนผสมของและเครื่องนี้ผลตอบแทน(fruit, milk, flower, eggs, sugar, heat)pie

การเป็นตัวแทนของเครื่องนี้อาจดูเหมือน

make-pies (fruit, milk, flower, eggs, sugar, heat) = {
   return (heat (add fruit (mix eggs flower milk)))
}

แน่นอนว่าไม่ใช่วิธีเดียวที่จะทำให้พาย

ในกรณีนี้เราจะเห็นว่า:

A       function     is to a     machine
as a    procedure    is to a     recipe
as      attributes   are to      ingredients
as      output       is to       product

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


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

เห็นด้วยซึ่งเป็นเหตุผลที่ฉันสิ้นสุดเบย์บอกว่าคำพูดนั้นใช้แทนกันได้
dkinzer

1
ใช่ แต่คุณจะเริ่มต้นด้วยการบอกว่า "ฟังก์ชั่นไม่ได้เป็นเพียงวิธีการเก่า ๆ ที่ส่งกลับค่า" ในขณะที่ในหลายภาษาที่ว่าสิ่งที่ฟังก์ชั่น
Keith Thompson

0

ในบริบทของdb : กระบวนงานที่เก็บไว้เป็นแผนการดำเนินการล่วงหน้าที่ไม่มีฟังก์ชั่น


0

ในแง่ของС # / Java ฟังก์ชั่นคือบล็อกของรหัสซึ่งส่งกลับค่าเฉพาะ แต่ขั้นตอนคือบล็อกของรหัสที่กลับเป็นโมฆะ (ไม่มีอะไร) ใน C # / Java ทั้งฟังก์ชั่นและวิธีการมากขึ้นมักจะเรียกว่าเพียงแค่วิธีการ

    //This is a function
    public DateTime GetCurrentDate()
    {
        return DateTime.Now.Date;
    }

    //This is a procedure(always return void)
    public void LogMessage()
    {
        Console.WriteLine("Just an example message.");
    }

-3

ขั้นตอน: 1.Procedures คือชุดคำสั่งที่กำหนดการคำนวณแบบมีพารามิเตอร์ 2. กระบวนการไม่สามารถคืนค่าได้

3. ขั้นตอนไม่สามารถเรียกได้จากฟังก์ชั่น

ฟังก์ชั่น 1. ฟังก์ชั่นเชิงโครงสร้างคล้ายกับขั้นตอน แต่มีความหมายแบบจำลองในฟังก์ชั่นทางคณิตศาสตร์ 2. มันสามารถคืนค่า 3. ฟังก์ชั่นสามารถเรียกได้จากขั้นตอน


3. ขั้นตอนไม่สามารถเรียกได้จากฟังก์ชั่น สิ่งนี้เป็นจริงในภาษาใด ไม่ว่าฉันมีประสบการณ์ในการมีข้อ จำกัด นี้
Mogsdad

มันเป็นเรื่องจริง หากคุณเรียกขั้นตอนจากฟังก์ชั่นแสดงว่าไม่ใช่ฟังก์ชั่น ภาษาที่บังคับใช้นี้เป็นคำถามที่ดีซึ่งฉันไม่รู้คำตอบ อาจเป็นฟังก์ชั่นที่ใช้งานได้ แต่ถึงอย่างนั้นฉันก็ไม่แน่ใจ: ลิสต์บริสุทธิ์นั้นใช้งานได้ (ไม่มีชุด: ไม่มีผลข้างเคียง) แต่เนื่องจากมีแลมบ์ดาจึงเป็นไปได้ที่จะติดตั้งชุด คุณสามารถเขียนคอมไพเลอร์ที่บังคับใช้ไม่ได้ตั้งค่ามันจะต้องตรวจสอบการใช้งานทั้งหมดของมัน คุณสามารถลบ lambdas ออกจากภาษาได้ แต่นั่นจะแย่กว่านั้น
ctrl-alt-delor

โอ้ฉันแค่คิดถึงภาษา C ++: วิธี const ไม่สามารถเรียกใช้วิธีการไม่ const (แม้ว่าคุณจะต้องเปิดการตรวจสอบคอมไพเลอร์ที่ถูกต้องและไม่พยายามที่จะหลีกเลี่ยงได้)
ctrl-alt-delor

-7

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


อืมไม่. ขั้นตอนไม่ได้returnทำอะไรเลย คุณกำลังพูดถึงผลข้างเคียงซึ่งเป็นไปได้ทั้งสองอย่าง (ถ้าได้รับอนุญาตจากภาษา)
Mogsdad

ขั้นตอนสามารถคืนค่าจำนวนเท่าใดก็ได้จำนวนนั้นอาจเป็นศูนย์
user2766296

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

ฉันชอบคำตอบนี้และชอบผู้ที่มี downvote หลายแห่งเพราะในทางใดทางหนึ่งมันก็ขัดแย้งกันเพื่อให้เป็นที่นิยมใน SO ฉันจะให้ downvote กระบวนงานที่เก็บไว้ใน SQL Server ส่งคืน resultset (สิ่งที่คุณเรียกว่า "หลายค่า") ในขณะที่ฟังก์ชั่นสามารถส่งกลับค่าเดียวเท่านั้น (ซึ่งไม่ถูกต้องมากเนื่องจากคุณยังสามารถสร้างฟังก์ชั่นตารางที่มีค่า)
Ivanzinho
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.