คุณสามารถเรียนรู้การเขียนโปรแกรมใช้งานได้ใน C หรือไม่? [ปิด]


9

จากการอภิปรายความคิดเห็นที่นี่ฉันสงสัยว่าคุณสามารถเรียนรู้การเขียนโปรแกรมฟังก์ชั่นใน C?


30
regardles ว่าคุณสามารถหรือไม่สามารถที่คุณไม่ควร
R. Martinho Fernandes

27
แน่นอน! ขั้นตอนแรกคือการเขียน Lisp interpreter ;-)
Ferruccio

ถ้าฉันได้มันขวาคำถามที่ควรจะได้รับการเรียนรู้เกี่ยวกับแนวความคิดต่างๆที่มี pseudocode โดยไม่ต้องใด ๆ ภาษาที่แท้จริงที่ทุกคน
SK-logic

@ SK-logic: ในการพูดให้เบา ๆ โปรแกรมเมอร์น้อยมากที่ได้เรียนรู้การเขียนโปรแกรมด้วย pseudocode ล้วนๆส่วนใหญ่ต้องทำให้มือสกปรกและใบหน้าของพวกเขาถูกตีด้วยข้อความแสดงข้อผิดพลาดจากคอมไพเลอร์ / ล่าม
sbi

4
@sbi โปรแกรมเมอร์ที่ดีที่สุดบางคนได้เรียนรู้การเขียนโปรแกรมเมื่อคอมไพเลอร์ไม่มีข้อผิดพลาดเลย การเขียนโค้ดบนบัตรเจาะต้องใช้ความเข้าใจในสิ่งที่คุณทำมานานก่อนที่คุณจะมีโอกาสเรียกใช้รหัส และไม่ต้องพูดถึงเลยว่าพื้นฐานของการเขียนโปรแกรมการทำงานนั้นได้ถูกสร้างขึ้นมานานก่อนที่คอมพิวเตอร์เครื่องแรกจะถูกสร้างขึ้น
SK-logic

คำตอบ:


21

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

ฉันคิดว่าคุณมีพื้นหลังอย่างน้อยใน OOP ถ้าคุณทำคุณควรตระหนักว่า OOP สามารถทำได้ใน C รวมถึง polymorphism, getters / setters, กฎการมองเห็น ฯลฯ เป็นต้น แต่มันค่อนข้างเจ็บปวดที่ต้องทำเช่นนั้นและคุณต้องรู้ทั้ง OOP และ C ภายใน ดึงมันออกมา มันเหมือนกันมากกับ FP

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


ตามคำขอมีบางสิ่งที่คุณสามารถเรียนรู้จาก FP จากนั้นนำไปใช้พูด, C, C ++ หรือ Java:

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

1
คุณสามารถให้ตัวอย่างที่เจาะจงว่าโปรแกรมเมอร์ C / C ++ / Java สามารถใช้ประโยชน์จากภูมิปัญญา LISP ได้อย่างไร มันสมเหตุสมผลในทางทฤษฎี แต่ฉันกำลังมองหาสิ่งที่เป็นรูปธรรม
งาน

@ งานสิ่งที่เป็นรูปธรรมจะมีประโยชน์อะไรบ้าง? มันขยายความคิดของพวกเขาและอาจทำให้พวกเขาคิดว่ารัฐที่เปลี่ยนแปลงไม่ได้มากเกินไปเป็นสิ่งไม่ดีคุณจะขออะไรอีก
dan_waterworth

ดังนั้นฉันสามารถสรุปได้จากสิ่งนี้ว่าในขณะที่เป็นไปได้ที่จะเรียนรู้ (บางส่วน) FP ใน C มันไม่มีเหตุผลที่จะทำเช่นนั้น?
sbi

@ งาน: ฉันได้เรียนรู้ FP เมื่อเรียน LISP ในฐานะนักเรียนเมื่อหลายปีก่อน ประมาณสิบปีต่อมาฉันใช้ FP ในการเขียนโปรแกรมเมตา
sbi

1
@sbi วิธีที่ฉันชอบในการเรียนรู้ภาษาและแนวคิดใหม่คือการใช้พวกเขา และ C เป็นภาษาที่เหมาะสมสำหรับการใช้คอมไพเลอร์ ใช่คุณสามารถเรียนรู้ FP กับ C
SK-logic

11

C สามารถถูกแฮ็กเพื่อเสนอแนวคิดการทำงานบางอย่าง:

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

ที่จริงการเรียนรู้การทำงานการเขียนโปรแกรมทางออกที่ดีที่สุดของคุณเป็นหนึ่งที่โดดเด่นภาษาเขียนโปรแกรมการทำงานเช่นเสียงกระเพื่อมและภาษาท้องถิ่นของตน ( Clojure , Scheme ) ErlangและHaskell หนึ่งในนั้นเป็นเครื่องมือที่สมบูรณ์แบบที่ทำงานภายในความคิดการเขียนโปรแกรมการทำงาน F #เป็นตัวเลือกที่ดีเช่นกันหากคุณมีพื้นหลังเป็น. Net แต่เป็นภาษาแบบหลายกระบวนทัศน์ไม่ใช่ภาษาโปรแกรมที่ใช้งานได้อย่างเคร่งครัด


ในฐานะที่เป็นtdammersบันทึกในความคิดเห็น:

จริงๆแล้ว LISP, clojure และแบบแผนก็เป็นแบบหลายกระบวนทัศน์เช่นกัน Haskell ในขณะที่บริสุทธิ์และขี้เกียจเริ่มต้นยังช่วยให้การเขียนโปรแกรมที่จำเป็นในขณะที่อยู่ในบริบท monadic และได้รับการสนับสนุนอย่างกว้างขวางสำหรับการประมวลผลพร้อมกัน ทั้งหมดนี้มีกลไกที่ใช้ส่วนใหญ่ของภูมิปัญญาที่รวบรวมในโลก OOP - การห่อหุ้มการสืบทอดความรับผิดชอบเดี่ยวองค์ประกอบ ฯลฯ มันไม่ได้เกี่ยวกับว่าภาษาอนุญาตกรอบความคิดอื่น ๆ หรือไม่ มันเกี่ยวกับกระบวนทัศน์ที่เป็นจุดเริ่มต้นของภาษา

ที่ดีที่สุดของความรู้ของฉันชัดและภาษาท้องถิ่นและ Erlang มีผู้สมัครที่ดีกว่า F # เพราะพวกเขาสนับสนุนให้เขียนโปรแกรมการทำงานมากกว่ากระบวนทัศน์อื่น ๆ สิ่งที่tdammersสวยงามสหรัฐอเมริกาเป็นจุดเริ่มต้นของภาษา F # ครอบคลุมการเขียนโปรแกรมที่ใช้งานได้ แต่ไม่สนับสนุนให้ใช้กับกระบวนทัศน์อื่น ๆ ที่สนับสนุนความจำเป็นและการเขียนโปรแกรม oo


เกี่ยวกับประโยคสุดท้ายของคุณ: ในกรณีนี้ฉันขอยืนยันว่า F # เป็นตัวเลือกที่ดีกว่าเพราะมันจะไม่จับคุณในความคิดเชิงหน้าที่ ในภาษาแบบหลายกระบวนทัศน์เมื่อคุณเริ่มตอกตะปูเกลียวคุณสามารถเปลี่ยนเป็นไขควงได้ เมื่อติดอยู่ในกระบวนทัศน์เดียวคุณอาจพลาดความแตกต่างระหว่างสกรูและตะปู
R. Martinho Fernandes

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

ฉันเชื่อว่าการเรียนรู้เมื่อกระบวนทัศน์นั้นเหมาะสมและเมื่อมันไม่เหมาะสมสำหรับงานบางอย่างเป็นส่วนหนึ่งของการเรียนรู้บางทีอาจเป็นสิ่งสำคัญที่สุด
R. Martinho Fernandes

4
จริงๆแล้ว LISP, clojure และแบบแผนก็เป็นกระบวนทัศน์ที่หลากหลายเช่นกัน Haskell ในขณะที่บริสุทธิ์และขี้เกียจเริ่มต้นยังช่วยให้การเขียนโปรแกรมที่จำเป็นในขณะที่อยู่ในบริบท monadic และได้รับการสนับสนุนอย่างกว้างขวางสำหรับการประมวลผลพร้อมกัน ทั้งหมดนี้มีกลไกที่ใช้ส่วนใหญ่ของภูมิปัญญาที่รวบรวมในโลก OOP - การห่อหุ้มการสืบทอดความรับผิดชอบเดี่ยวองค์ประกอบ ฯลฯ มันไม่ได้เกี่ยวกับว่าภาษาอนุญาตกรอบความคิดอื่น ๆ หรือไม่ มันเกี่ยวกับกระบวนทัศน์ที่เป็นจุดเริ่มต้นของภาษา
tdammers

2
@MartinhoFernandes: ใคร ๆ ก็เถียงว่าถูกขังอยู่ในกระบวนทัศน์เดียวเป็นวิธีที่สมบูรณ์แบบในการเรียนรู้เมื่อมันเจ็บปวดจริงๆในตูด :-)
Jörg W Mittag

2

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

http://www.johndcook.com/blog/2011/07/24/get-started-functional-programming/


2

TL; DR

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

การเขียนโปรแกรมฟังก์ชั่นคืออะไร?

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

ภาพประกอบสามภาพของการปิดประโยชน์

การใช้งานทั่วไปของการปิดคือการใช้กลไกความเป็นส่วนตัว ตัวอย่างเช่นรหัส Javascript - ในตัวอย่างที่ฉันเลือก Javascript เพราะเป็นภาษาที่ใช้งานได้กับ“ C-like syntax” และคำถามของคุณแนะนำว่าคุณคุ้นเคยกับ C:

create_counter = function()
{
  var x = 0;
  var counter = function()
  {
    ++x;
    return x;
  };
  return counter;
}

จากนั้นด้วย

a = create_counter();
b = create_counter();

เรามีสองฟังก์ชั่นaและการbนับคอลเลกชันที่แยกจากกัน ประเด็นของตัวอย่างคือตัวแปรxถูกจับโดยการปิดที่กำหนดการcounterปิดและทุกครั้งที่x counterการปิดใหม่is instantiated by the function, it gets its fresh own idea of whatคือ

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

var log = function(priority, message) {

};

ที่ขัดแย้งpriorityและmessageคาดว่าจะเป็นสตริงคนแรกเป็นหนึ่ง"debug", "info"และอื่น ๆ เราสามารถกำหนดโรงงานบันทึกเช่นนี้:

var logWithPriority = function(priority) {
  return function(message) {
    log(priority, message);
  };
};

และใช้มันเพื่อกำหนดสิ่งอำนวยความสะดวกสำหรับบันทึกรุ่นพิเศษของเรา:

var debug = logWithPriority("debug");
var info = logWithPriority("info");

สิ่งนี้มีประโยชน์มากเพราะแทนที่จะเขียนข้อผิดพลาดได้ง่าย - forลูปเช่นนี้

for(i = 0; i < journal.length; ++i) {
   log("info", journal[i]);
}

เราสามารถเขียนทำความสะอาดที่สั้นและง่ายมาก (ไม่มีiที่มากดีกว่า):

journal.forEach(logWithPriority("info"));

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

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

นี่คือวิธีการใช้การประเมินผลแบบขี้เกียจกับการปิด พิจารณาการใช้คลาสสิกของฟังก์ชันarrayMax ที่คืนค่าสูงสุดในอาเรย์:

function arrayMax(array) {
  return array.reduce(function(a, b) {
    return Math.min(a, b);
  };
}

ตัวแปรที่ขี้เกียจจะเป็น:

function arrayMax(array) {
  var memo = null;
  function actuallyCompute() {
    if(memo === null) {
      memo = array.reduce(function(a, b) {
        return Math.min(a, b);
      });
    }
    return memo;
  }
  return actuallyCompute;
}

ค่าส่งคืนคือการปิดซึ่งสามารถใช้ในการคำนวณค่าหรือดึงมันอีกครั้งถ้ามันได้รับการคำนวณแล้ว

ด้วยตัวอย่างทั้งสามนี้เราควรมั่นใจว่าการปิดและแอปพลิเคชันของพวกเขาเป็นแกนหลักของการเขียนโปรแกรมการทำงาน

ข้อสรุป

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


1
ขอบคุณสำหรับตัวอย่างที่ดีนี้ BTW ตามที่คุณกำหนดข้อมูล var มันจะเป็น journal.forEach (ข้อมูล) หรือไม่?
ejaenv

ใช่มันจะเป็นตัวแปรที่เหมาะสม! :)
Michael Le Barbier Grünewald

1

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

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


1

คุณไม่ควรเรียนรู้การเขียนโปรแกรมฟังก์ชั่นใน C แต่เป็นภาษาที่ใช้งานได้อย่างเข้มงวด (Haskell, Caml, Erlang ฯลฯ .)

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

อย่างไรก็ตามฉันคิดว่าการทำงานใน C เป็นแบบฝึกหัดที่ดีสำหรับคนที่รู้จักการทำงาน เพราะบุคคลนั้นจะเรียนรู้สิ่งที่เกิดขึ้นหลังฮูด - คอมพิวเตอร์กำลังทำอะไรอยู่

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