คุณสมบัติภาษาการเขียนโปรแกรมกึ่งพิเศษของนักฆ่า [ปิด]


25

เมื่อเรียนรู้ภาษาการเขียนโปรแกรมใหม่บางครั้งคุณจะพบคุณสมบัติภาษาที่ทำให้คุณต้องการในภาษาโปรแกรมอื่น ๆ ที่คุณรู้

มีคุณลักษณะภาษาอะไรบ้างในขณะที่เรียนรู้สิ่งใหม่ ๆ สำหรับคุณและคุณต้องการให้ภาษาโปรแกรมอื่นของคุณมี

ตัวอย่างนี้เป็นเครื่องกำเนิดไฟฟ้าใน Python หรือ C # ตัวอย่างอื่น ๆ อาจรวมถึงรายการ comprehensions ใน Python, เท็มเพลตใน C ++ หรือ LINQ ใน. NET หรือการประเมินสันหลังยาวใน Haskell

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

คำตอบ:


25

แทบทุกอย่างใน Haskell

  • monads ใช่ - คำที่น่ากลัวมากที่ทำให้การแยกวิเคราะห์ง่ายขึ้นเรื่อย ๆ , IO, การดำเนินการในรายการและสิ่งอื่น ๆ นั้นง่ายมาก (เมื่อคุณสังเกตเห็นรูปแบบทั่วไป)
  • ลูกศร เช่นเดียวกันสำหรับผู้ใช้ขั้นสูง;)
  • สิ่งมาตรฐานเช่น lambdas เป็นต้น
  • ฟังก์ชั่นการแกง
  • ชนิดข้อมูลเชิงพีชคณิต
  • การจับคู่รูปแบบ

และอื่น ๆ อีกมากมาย.

PS ใช่. ฉันเป็นแฟนบอย Haskell ถ้าใครถาม


12
เพื่อความเป็นธรรมคุณควรให้เครดิตแก่ ML สำหรับรายการส่วนใหญ่
munificent

1
ดี - ยกเว้น monads and arrows IIRC แต่พวกเขายังคงเป็นกึ่งที่ไม่ซ้ำกัน
Maciej Piechotka

มีเหตุผลใดสำหรับ downvote บ้าง?
Maciej Piechotka

2
+1 สำหรับการจับคู่รูปแบบ ฉันแสดงให้คนอื่นเห็นและพวกเขาไม่เข้าใจ ฉันคิดว่ามันเป็นอัจฉริยะ
Barry Brown

ข้อผูกมัด ( steve-yegge.blogspot.com/2010/12/… ) BTW ฉันแทบจะไม่คิดว่า lambdas นั้นมีเอกลักษณ์เฉพาะตัวคือ python, C #, javascript และอื่น ๆ Monads? ภาษาอื่น ๆ ส่วนใหญ่เรียกว่าเป็นการผูกมัด; หลักของ jquery นั้นเป็นชุดใหญ่ของ HTML / DOM และ AJAX monads (Google: jQuery.fn) การแกงเป็นเรื่องธรรมดาในทุกวันนี้
Evan Plaice

21

มาโครเสียงกระเพื่อม

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

เทมเพลตการเขียนโปรแกรม C ++ เทมเพลตมีความสามารถในสิ่งที่คล้ายกัน แต่ในภาษาที่แตกต่างจาก C ++ ปกติมาก


+1 ฉันหวังว่าสักวันฉันจะสามารถเขียนโปรแกรมด้วยภาษา Lisp ได้
Oliver Weiler

@Helper ... ผ่านเทมเพลต C ++ [เสียงหัวเราะที่น่ากลัว]
mlvljr

@mlvjr: คุณน่ากลัว
David Thornley

ในความเป็นจริงมันเป็นเพียงคุณลักษณะออกจากกล่องคุณเคยจะต้องในภาษา ด้วยมาโคร Lisp คุณสามารถเพิ่มคุณสมบัติอื่น ๆ ที่เป็นไปได้ทั้งหมดในภายหลัง
SK-logic

18

มัณฑนากร Python

มันง่ายมากที่จะใช้การบันทึกหรือเวลาของฟังก์ชั่นการใช้มัณฑนากร

ตัวอย่างของฟังก์ชั่นจับเวลา

class FuncTimer(object):
    """ Time how much time a function takes """
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
        self.start_time = time.time()
    def __call__(self, *args):
        self.memo['return'] = self.fn(*args)
        print("Function '%s' took %u seconds" % (self.fn.__name__, time.time() - self.start_time))
        return self.memo['return']

ตอนนี้ถ้าคุณมีฟังก์ชั่น foo ที่คุณต้องการเวลาคุณก็สามารถทำได้

@FuncTimer
def foo():
    # foo's implememtation goes here

คุณจะเห็นสิ่งที่ชอบ

ฟังก์ชั่น 'foo' ใช้เวลา 3 วินาที


Java มีคำอธิบายประกอบซึ่งมีวัตถุประสงค์และไวยากรณ์คล้ายกัน แต่ทำงานแตกต่างกันมาก
Casebash

1
+1: การตกแต่งของ Python ทำให้ฉันประทับใจมากกว่าฟีเจอร์อื่น ๆ ในภาษา พวกมันสวยงามและเรียบง่ายมาก!
Adam Paynter

บางทีคุณอาจแบ่งปันตัวอย่างง่ายๆกับเรา ฉันไม่รู้จัก Python ที่จะซื่อสัตย์
ShdNx

@ShdNx ฉันเพิ่งเพิ่มตัวอย่าง
grokus

1
ไม่ควรคำนวณเวลาเริ่มต้นเป็นส่วนหนึ่งของการโทรหรือไม่
Detly

14

การส่งไปที่void*C คุณสามารถส่งทุกอย่างเป็นไบต์ดิบและทำทุกอย่างที่คุณต้องการด้วยข้อมูลเหล่านี้

(ใช่ทุกวันนี้มันไม่เหมือนใคร ... )


1
วัตถุใน. Net ภาษาคล้ายกันมาก ปลอดภัยกว่าประเภทอื่น ๆ เท่านั้น
Maciej Piechotka

คุณสามารถส่งต่อไปยังวัตถุในหลายภาษา ปัญหาหลักคือหลายภาษาแยกดั้งเดิมและวัตถุ
Casebash

5
@Maciej: แม้กระทั่งใน. NET คุณไม่สามารถใช้งาน Object ดั้งเดิมได้ คุณทำกล่องพวกมันและมันเป็นสัตว์ร้ายที่ต่างออกไป นอกจากนี้ยังแตกต่างกันโดยสิ้นเชิงในการคัดเลือกvoid*...
Dean Harding

1
การส่งไปที่PointerPascal และ Object Pascal ทำสิ่งเดียวกัน
Frank Shearar

1
@DeanHarding: เอ่อคุณมี C int64_tที่คุณไม่สามารถส่งได้อย่างปลอดภัยเสมอvoid *(ขออภัยปลาย 2 ปี - ตอบ)
Maciej Piechotka

12

ผลตอบแทนใน Python

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


1
อัตราผลตอบแทนอยู่ในรายการของคำถามแล้ว
ตรินิแดด

ทั้งหมดนี้กลับไปสู่ ​​BCPL
Peter Taylor

8

การแสดงออกของแลมบ์ดา (การปิดฟังก์ชันที่ซ้อนกันวิธีการไม่ระบุชื่อสิ่งที่คุณเรียกว่า)

ฉันมาเจอพวกเขาครั้งแรกใน Perl รักพวกเขาทันทีและสงสัยว่าทำไมภาษาอื่นไม่มีพวกเขา ทุกวันนี้ฉันคิดว่ามันคงไม่เหมือนเดิมอีกแล้ว แม้แต่ PHP ก็สามารถแฮ็คมันได้ แต่พวกเขาก็ไม่เหมือนใครในเวลานั้น


5
ไม่เหมือนใครตราบใดที่คุณนับกลับไปที่ Lisp ซึ่งเป็นภาษาโปรแกรมที่เก่าที่สุดเป็นอันดับสอง ;-)
Michael H.

-1: ไม่ใช่กึ่งพิเศษ
Casebash


7

เซตใน Delphi นั้นมีประโยชน์มาก ๆ เพียงแค่อาร์เรย์แบบบูลที่มีชื่อ มีประโยชน์มากสำหรับการบันทึกฟอร์มการตั้งค่าด้วยช่องทำเครื่องหมาย 32 ช่อง แต่พวกเขามีฟังก์ชั่นทฤษฎีเซตเดียวกันทั้งหมด (เช่นความแตกต่างจุดตัดสหภาพ)

ฉันไม่แน่ใจว่าพวกเขาหลุดออกจากแฟชั่น แต่ฉันใช้พวกเขาตลอดเวลา


ดี แต่นั่นจะไม่ง่ายที่จะนำไปใช้ใน Java ตัวอย่างเช่น: boolean []?
ทำเครื่องหมาย C

ใช่คุณทำได้ แต่ฉันไม่คิดว่ามันสั้นกระชับเท่า: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormSet = ชุดของ TForm;
Peter Turner

7

ส่ง

จาก Erlang ส่งข้อความแบบอะซิงโครนัสไปยังเธรดอื่น

Expr1 ! Expr2

รับ

จาก Erlang รับข้อความจากเธรดอื่น

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end

5

คุณสมบัติ C #

/// <summary>
/// Get ID
/// </summary>
public int ID
{
    get; set;
}

VS

(Java)

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}

2
ใช่พวกเขาดีกว่า แต่นี่เป็นตัวอย่างที่ไม่ดี ความแตกต่างจะเล็กกว่ามากหากผู้ทะเยอทะยาน / ผู้ตั้งค่าจะทำอะไรที่พิเศษจริง ๆ และรุ่น C # นั้นมีเอกสารน้อยกว่า
Bart van Heukelom

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

2
เพียงไม่อนุญาตให้ทำเช่นนี้เพื่อกระตุ้นให้ผู้คนมีผู้ได้รับและผู้ตั้งตนไปทั่ว ควรใช้เฉพาะผู้ได้รับและผู้ตั้งค่าที่เข้าท่าว่าเป็นการกระทำบนวัตถุ
David Thornley

3
พวกเขาไม่ได้เรียกคุณสมบัติ C # พวกเขาเรียกว่าคุณสมบัติอัตโนมัติ
Jaco Pretorius

1
วันนี้คุณสมบัติอัตโนมัติเป็นเรื่องธรรมดามาก Python, Objective-C ...
Casebash

5

สหภาพแรงงานใน

ฉันไม่สามารถพูดได้อย่างตรงไปตรงมาว่าฉันไม่ได้เขียน C เพียงพอที่จะทำสิ่งเหล่านี้ด้วยตัวเอง แต่ฉันได้ทำงานกับรหัสของผู้อื่นที่ทำ

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

Disclaimer:

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


2
IMHO ด้วยเหตุผลที่ดี การแปลข้อมูลซ้ำเป็นวิธีที่ยอดเยี่ยมในการถ่ายภาพด้วยตัวเอง ( en.wikipedia.org/wiki/Aliasing_(computing ) ควรใช้การแปลงที่ชัดเจนกว่า IMHO สหภาพที่ทำในสิ่งที่ถูกต้องคือประเภทข้อมูลพีชคณิต IMHO
Maciej Piechotka

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

ปัญหาคือ C คือ 'ภาษาระดับสูงกว่า' (เพียงภาษาระดับสูงระดับต่ำ) ตั้งแต่ K&R C จะได้รับกฎจำนวนมากที่อนุญาตให้ใช้รหัสพกพาที่เร็วขึ้น ราคาคือคอมไพเลอร์สามารถสมมติสิ่งต่าง ๆ และบางอย่างสับสน ที่สุดของunionการใช้งานที่มีความปลอดภัยและได้รับการสนับสนุนบางสำนวนดี (แม้ว่าในทางเทคนิคไม่ถูกต้อง) - ดูcellperformance.beyond3d.com/articles/2006/06/... (แม้ว่ามันจะเป็น poblem มากขึ้นกับสหภาพแรงงานชี้ดีสามารถปลอม)
Maciej Piechotka

Delphi ขยายrecordไวยากรณ์เพื่อรองรับสหภาพ:in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end;
Frank Shearar

5

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

puts "All good" unless input.nil?

คุณไม่ชอบสิ่งนั้นได้อย่างไร : D


6
Perl ได้ก่อนทับทิม ฉันรักมันเหมือนกัน.
Barry Brown

1
Nemerle มีคำหลักที่คล้ายกันสำหรับunlessและซึ่งแทนที่พบมากที่สุดแตกแขนงสถานการณ์ซึ่งเป็นประเพณีที่จะใช้when if/else
MattDavey

5

ไวยากรณ์อาร์กิวเมนต์หลามแฟนซี

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

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"


parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

python docs (เลื่อนลงเพื่อดูรายการการโต้แย้งเพิ่มเติม)


1
+1 สำหรับความสามารถในการส่งผ่านพารามิเตอร์ลึกลงไปในรายการโดยไม่ต้องผ่านค่าสำหรับพารามิเตอร์ทางเลือกทั้งหมดก่อน
eswald

4

ตัวประมวลผลล่วงหน้า C คุณยังสามารถเขียนรหัสทั่วไปไปยังแพลตฟอร์มต่าง ๆ ด้วย - น้อยลงหรือมากขึ้น - ifdefs


2
มีตัวประมวลผลล่วงหน้าที่ดีกว่าพร้อมใช้งานซึ่งมีขั้นตอนพิเศษของตัวเองและทำงานกับทุกภาษา
David Thornley

ฉันค่อนข้างมีความสุขกับ ifdef, ifndef และอื่น ๆ
ern0

3

หมวดหมู่วัตถุประสงค์ -C

หมวดหมู่นำเสนอวิธีที่ง่ายในการขยายการทำงานของวัตถุในขณะทำงาน ตัวอย่างคลาสสิกคือการเพิ่มเครื่องตรวจคำสะกดลงในคลาส NSString

@interface NSString (SpellChecker)
- (BOOL) checkSpelling;
@end

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


1
คล้ายกับวิธีการขยายใน C #
Casebash

2

วิธีการฉีดของRubyรวมกับคุณสมบัติSymbol # to_procของ Ruby 1.9 ทำให้เราสามารถเขียนโค้ดที่รัดกุม (แต่ยังคงอ่านได้) ได้อย่างไม่น่าเชื่อ:

เช่น (1..10).inject(:+)

ซึ่งจะรวมจำนวนเต็ม 1 ถึง 10 => 55

การเห็นตัวอย่างเช่นนี้ทำให้ฉันต้องการเรียนรู้ทับทิมซึ่งฉันเพิ่งเริ่มทำ


9
เพื่อความเป็นธรรม, ฉีดเป็นรุ่นทับทิมของพับ / foldl / foldr จากภาษาเช่นเสียงกระเพื่อม Haskell ฯลฯ
mipadi

ฉันจะไม่เรียกสิ่งนี้ว่า
Daenyth

1
ชื่อคำถามถามว่า "กึ่งไม่ซ้ำใคร" ไม่ซ้ำกัน ความรัดกุมของรหัสที่แน่นอนโดยการรวมกันของการฉีด (หรือแผนที่ ฯลฯ ) และ Symbol # to_proc เป็นวิธีที่นอกเหนือจากภาษาหลักเช่น C, Java และ C ++
tcrosley

รัดกุมมาก (และฉันชอบมัน) แต่ฉันไม่แน่ใจว่ามันแตกต่างจากสิ่งที่ชอบ: นับได้ช่วง (1, 10) .Aggregate ((s, x) => s + x); จาก C # หรือภาษาอื่น ๆ
FinnNk

1

กลไกการผูกใน JavaFX (RIP) ผูกคำหลักที่ช่วยให้คุณสามารถผูกค่าของตัวแปรที่จะคุ้มค่าของการแสดงออกและการที่คุณกำจัดทุกคนฟังที่น่าเกลียด แต่อย่างใดรหัสสำเร็จรูป

ในขณะที่ JavaFX นั้นค่อนข้างล้มเหลวในหลาย ๆ ด้าน แต่ฉันพบว่าคุณสมบัติต่าง ๆ ของภาษาสคริปต์ค่อนข้างดี


1

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


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