Các tính năng ngôn ngữ lập trình bán độc nhất của Killer [đã đóng]


25

Khi học một ngôn ngữ lập trình mới, đôi khi bạn bắt gặp một tính năng ngôn ngữ khiến bạn ước mình có ngôn ngữ lập trình khác mà bạn biết.

Một số tính năng ngôn ngữ mà tại thời điểm học rất mới đối với bạn và bạn muốn các ngôn ngữ lập trình khác của bạn có.

Một ví dụ về điều này là các trình tạo trong Python hoặc C #. Các ví dụ khác có thể bao gồm hiểu danh sách trong Python, mẫu trong C ++ hoặc LINQ trong .NET hoặc đánh giá lười biếng trong Haskell.

Những tính năng ngôn ngữ bán độc đáo nào khác mà bạn bắt gặp là những tính năng hoàn toàn mới và khai sáng cho bạn? Có những tính năng khác của các ngôn ngữ lập trình cũ vốn là duy nhất và đã lỗi thời?

Câu trả lời:


25

Thực tế bất cứ điều gì trong Haskell

  • Đơn nguyên. Có - từ đáng sợ lớn giúp trình phân tích cú pháp dễ dàng, IO, các thao tác trên Danh sách và những thứ khác trở nên dễ dàng (một khi bạn nhận thấy mô hình chung)
  • Mũi tên. Điều tương tự cho người dùng nâng cao;)
  • Những thứ tiêu chuẩn như lambdas, v.v.
  • Chức năng cà ri
  • Các kiểu dữ liệu đại số
  • Khớp mẫu

Và nhiều thứ khác nữa.

Tái bút Vâng. Tôi là fanboy của Haskell nếu có ai hỏi.


12
Để công bằng, bạn nên cung cấp tín dụng ML cho hầu hết danh sách đó.
khoan hồng

1
Vâng - ngoại trừ các đơn nguyên và mũi tên IIRC. Nhưng họ vẫn là semi -unique
Maciej Piechotka

Bất kỳ lý do cụ thể cho downvote?
Maciej Piechotka

2
+1 cho khớp mẫu. Tôi cho người khác xem và họ không hiểu. Tôi nghĩ đó là thiên tài.
Barry Brown

Bắt buộc ( steve-yegge.blogspot.com/2010/12/ ). BTW, tôi hầu như không coi lambdas là duy nhất, python, C #, javascript, v.v. Hầu hết các ngôn ngữ khác gọi nó là chuỗi; lõi jquery về cơ bản là một tập hợp lớn các đơn vị HTML / DOM và AJAX (Google: jQuery.fn). Cà ri cũng tương đối phổ biến hiện nay.
Evan Plaice

21

Macro Lisp.

Ngôn ngữ macro Lisp là Lisp, với một vài tính năng cú pháp được xác định trước nhằm mục đích thuận tiện. Sử dụng chúng, có thể thêm các tính năng chính cho ngôn ngữ, chẳng hạn như sự lựa chọn của một trong các kiểu định hướng đối tượng hoặc kết hợp xác định giống như Prolog, mà không cần nhìn ra chỗ khác. Nó làm cho setfmacro có thể, đó là một macro rất mạnh về mặt khái niệm: (setf A B)có nghĩa là, khi bạn đánh giá Abạn sẽ nhận được B, và điều đó có thể được mở rộng đến bất kỳ giới hạn nào bạn muốn.

Siêu lập trình mẫu C ++ có khả năng tương tự, nhưng trong một ngôn ngữ khác nhiều so với C ++ thông thường.


+1 Tôi hy vọng một ngày nào đó tôi sẽ có thể lập trình theo phương ngữ Lisp.
Oliver Weiler

@Helper ... thông qua các mẫu C ++ [tiếng cười đáng sợ]
mlvljr

@mlvjr: Bạn thật đáng sợ.
David Thornley

Trong thực tế, nó là duy nhất tính năng out-of-the-box bao giờ bạn sẽ cần trong một ngôn ngữ. Với các macro Lisp, bạn có thể thêm tất cả các tính năng có thể khác sau này.
SK-logic

18

Trang trí của Python.

Thật dễ dàng để thực hiện ghi nhớ hoặc thời gian của chức năng bằng cách sử dụng trình trang trí.

Ví dụ về bộ đếm thời gian chức năng.

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']

Bây giờ nếu bạn có một chức năng mà bạn muốn thời gian, bạn chỉ cần làm điều này,

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

Bạn sẽ thấy một cái gì đó như,

Chức năng 'foo' mất 3 giây.


Java có các chú thích, có mục đích và cú pháp tương tự, nhưng hoạt động rất khác nhau
Casebash

1
+1: Trình trang trí của Python đã gây ấn tượng với tôi hơn hầu hết các tính năng khác trong ngôn ngữ. Chúng rất đẹp và đơn giản!
Adam Paynter

Có lẽ bạn có thể chia sẻ một ví dụ đơn giản với chúng tôi? Tôi không biết Python thành thật.
ShdNx

@ShdNx, tôi vừa thêm một ví dụ.
Grokus

1
Không nên tính thời gian bắt đầu như một phần của cuộc gọi?
gièm pha

14

Truyền tới void*C. Bạn có thể truyền mọi thứ thành byte thô và làm bất cứ điều gì bạn muốn với những dữ liệu này.

(Vâng, ngày nay nó là duy nhất ...)


1
Đối tượng trong các ngôn ngữ .Net rất giống nhau. Chỉ có nhiều loại an toàn hơn, vv
Maciej Piechotka

Bạn có thể truyền vào đối tượng bằng nhiều ngôn ngữ. Vấn đề chính là nhiều ngôn ngữ tách biệt nguyên thủy và đối tượng
Casebash

5
@Maciej: ngay cả trong .NET, bạn không thể thực sự chuyển nguyên thủy sang Object. Bạn đóng hộp chúng, và nó hoàn toàn là một con thú khác. Bên cạnh đó, điều đó vẫn hoàn toàn khác so với việc chuyển sang void*...
Dean Harding

1
Truyền tới Pointertrong Pascal và Object Pascal cũng làm điều tương tự.
Frank Shearar

1
@DeanHending: Vâng - trong C bạn có int64_tmà bạn không thể luôn luôn an toàn void *(Xin lỗi vì đã trễ - 2 năm - trả lời).
Maciej Piechotka

12

Năng suất trong Python

Trong Python (và tôi tin vào C #), bạn có thể định nghĩa một trình tạo được gọi là tạm dừng thực thi chức năng tại một yieldcâu lệnh, trả về giá trị và trong các cuộc gọi tiếp theo, khởi động lại chức năng nơi nó dừng lại (với trạng thái được bảo toàn giữa các cuộc gọi). Điều này rất tốt để tạo danh sách dài các giá trị mà bạn chỉ quan tâm đến giá trị hiện tại của hàm (rất phổ biến). Nó cho phép bạn xây dựng các chuỗi dài vô hạn trong khi chỉ chiếm không gian rất hạn chế trong bộ nhớ.


1
Năng suất đã được liệt kê trong câu hỏi.
Trinidad

Điều này đi tất cả các cách trở lại BCPL.
Peter Taylor

8

Biểu thức Lambda (bao đóng, hàm lồng nhau, phương thức ẩn danh, bất cứ điều gì bạn gọi chúng).

Lần đầu tiên tôi bắt gặp chúng ở Perl, ngay lập tức yêu chúng và tự hỏi tại sao các ngôn ngữ khác không có chúng. Ngày nay tôi đoán nó không còn độc đáo nữa; thậm chí PHP đã quản lý để hack chúng bằng cách nào đó. Nhưng họ là bán độc nhất vào thời điểm đó.


5
Độc đáo, miễn là bạn tính trở lại Lisp, đây là ngôn ngữ lập trình lâu đời thứ hai. ;-)
Michael H.

-1: Không bán độc đáo
Casebash


7

Các bộ trong Delphi rất hữu ích, gần như chỉ là một mảng boolean. Chúng rất hữu ích để lưu biểu mẫu cài đặt với 32 hộp kiểm. Nhưng họ đã có tất cả các hàm lý thuyết tập hợp giống nhau (nghĩa là khác biệt, giao nhau, hợp nhất).

Tôi không chắc chúng có bị lỗi mốt không, nhưng tôi sử dụng chúng mọi lúc.


Đẹp, nhưng sẽ không dễ thực hiện trong Java, ví dụ: boolean []?
Đánh dấu C

Vâng, bạn có thể, nhưng tôi không nghĩ nó ngắn gọn như: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormset = bộ TForm;
Peter Turner

7

Gửi

Từ Erlang. Gửi tin nhắn không đồng bộ đến một chủ đề khác.

Expr1 ! Expr2

Nhận được

Từ Erlang. Nhận được tin nhắn từ một chủ đề khác.

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

5

Thuộc tính C #

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

đấu với

(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
Vâng, họ tốt hơn, nhưng đây là một ví dụ tồi. Sự khác biệt sẽ nhỏ hơn nhiều nếu getter / setter thực sự làm điều gì đó đặc biệt và phiên bản C # được ghi lại ít hơn.
Bart van Heukelom

1
Sếp của tôi mạnh mẽ chống lại các thuộc tính tự động của C # và bất cứ khi nào chúng tôi có tranh luận về nó, không ai trong chúng tôi có thể thấy lý do tại sao người kia đúng hay sai. Tôi chỉ yêu họ vì họ làm cho mã sạch hơn rất nhiều và tiết kiệm cho tôi rất nhiều thời gian trong thời gian dài.
mbillard

2
Chỉ không cho phép điều này để khuyến khích mọi người có getters và setters trên tất cả. Chỉ nên sử dụng các getters và setters có ý nghĩa như các hành động trên một đối tượng.
David Thornley

3
Chúng không được gọi là thuộc tính C #, chúng được gọi là Thuộc tính tự động
Jaco Pretorius

1
Tự động tài sản là rất phổ biến những ngày này. Python, Objective-C ...
Casebash

5

Công đoàn ở C

Tôi không thể thành thật nói rằng tôi đã không viết đủ C để tạo ra bất kỳ thứ nào trong số này nhưng tôi đã làm việc với mã khác.

Khi nói đến việc đóng gói các hỗn hợp dữ liệu khác nhau trong các ứng dụng thao tác các bit / byte thô như mạng hoặc lưu trữ dữ liệu nhị phân. Trong các ngôn ngữ được gõ mạnh, không có cách nào dễ dàng để làm tương đương.

Tuyên bố miễn trừ trách nhiệm:

Mặc dù trong một số trường hợp, các hiệp hội cực kỳ hữu ích, nhưng chúng không được tìm thấy ở hầu hết các ngôn ngữ cấp cao hơn vì chúng không phải là loại an toàn. IE, bạn có thể làm cho dữ liệu chảy qua ranh giới của các biến bằng cách sử dụng các hiệp hội (một không lớn không có trong thế giới an toàn loại). Với sức mạnh lớn đến trách nhiệm lớn.


2
IMHO cho một lý do tốt. Giải thích lại dữ liệu là một cách dễ dàng để tự mình chụp ảnh ( en.wikipedia.org/wiki/Aliasing_(computing) ). Sử dụng tốt hơn chuyển đổi rõ ràng IMHO. Các công đoàn làm đúng cách là các loại dữ liệu đại số IMHO.
Maciej Piechotka

@Maciej Tôi đã thêm từ chối trách nhiệm cần thiết. Mặc dù, tôi không chắc liệu nó có giải thích chính xác những nguy hiểm của việc sử dụng công đoàn hay không vì tôi không thực sự có kiến ​​thức sâu sắc về việc sử dụng chúng. Tôi chỉ biết rằng, nơi tôi đã thấy họ sử dụng mã này ngắn gọn hơn và dễ làm việc hơn so với ngôn ngữ cấp cao hơn tương đương.
Evan Plaice

Vấn đề là C là 'ngôn ngữ cấp cao hơn' (chỉ ngôn ngữ cấp cao cấp thấp hơn). Vì K & R C, nó nhận được rất nhiều quy tắc cho phép sử dụng mã di động nhanh hơn. Giá là trình biên dịch có thể giả định những thứ khác nhau và một số bị nhầm lẫn. MOST của việc unionsử dụng là an toàn, một số thành ngữ được hỗ trợ tốt (mặc dù về mặt kỹ thuật không chính xác) - xem cellperformance.beyond3d.com/articles/2006/06/ .
Maciej Piechotka

Delphi đã mở rộng recordcú pháp của mình để hỗ trợ các công đoàn: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

Tôi thực sự thích công cụ sửa đổi trừ khi trong Ruby . Nó có vẻ rất tự nhiên và thay thế rất nhiều tình huống trong đó mã của bạn dường như rất lộn xộn nếu không có nó.

puts "All good" unless input.nil?

Làm thế nào bạn có thể không thích điều đó? : D


6
Perl đã có nó trước Ruby. Tôi cũng thích nó.
Barry Brown

1
Nemerle có các từ khóa tương tự cho unlesswhenthay thế các kịch bản phân nhánh phổ biến nhất mà theo truyền thống sẽ sử dụng if/else.
MattDavey

5

cú pháp đối số python ưa thích

Tôi không chắc nó độc đáo đến mức nào, nhưng trong python bạn có thể làm những thứ hay ho như có các cặp từ khóa tự động được tạo thành từ điển và ngược lại. Tương tự với danh sách:

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')

tài liệu python (cuộn xuống để biết thêm công cụ đối số)


1
+1 để có thể vượt qua một tham số sâu trong danh sách mà không phải truyền giá trị cho tất cả các tham số tùy chọn trước nó.
eswald

4

Bộ tiền xử lý C. Bạn thậm chí có thể viết mã chung cho các nền tảng khác nhau với - ít hơn hoặc nhiều hơn - ifdefs.


2
Có những bộ tiền xử lý tốt hơn có sẵn để thực hiện bước bổ sung của riêng họ và làm việc với tất cả các ngôn ngữ.
David Thornley

Tôi khá hài lòng với ifdef, ifndef và những thứ khác.
ern0

3

Mục tiêu-C

Các danh mục cung cấp một cách dễ dàng để mở rộng chức năng của một đối tượng trong thời gian chạy (nghĩ thành phần so với kế thừa). Ví dụ kinh điển là thêm trình kiểm tra chính tả vào lớp NSString.

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

Cũng hữu ích cho các sửa lỗi tác động thấp, vì việc triển khai một phương thức của một danh mục sẽ ghi đè lên việc thực hiện cha mẹ của nó.


1
Rất giống với các phương thức mở rộng trong C #
Casebash

2

Phương thức tiêm của Ruby kết hợp với tính năng Symbol # to_proc của Ruby 1.9 cho phép người ta viết một số mã cực kỳ súc tích (nhưng vẫn có thể đọc được):

ví dụ (1..10).inject(:+)

tính tổng các số nguyên từ 1 đến 10 => 55

Nhìn thấy những ví dụ như thế này khiến tôi muốn học Ruby, điều mà tôi mới bắt đầu làm.


9
Công bằng mà nói, tiêm là phiên bản gấp / gấp / gấp của Ruby từ các ngôn ngữ như Lisp, Haskell, v.v.
mipadi

Tôi sẽ không thực sự gọi đây là duy nhất.
Daenyth

1
Tiêu đề của câu hỏi nói "bán độc nhất", không phải là duy nhất. Chắc chắn tính đồng nhất của mã được cung cấp bởi sự kết hợp giữa chích (hoặc bản đồ, v.v.) và Ký hiệu # to_proc vượt xa các ngôn ngữ chính như C, Java và C ++.
tcrosley

Rất súc tích (và tôi thích nó), nhưng tôi không chắc nó khác với thứ gì đó như: Enumerable.Range (1, 10) .Aggregate ((s, x) => s + x); từ C # hoặc các ngôn ngữ khác
FinnNk

1

Cơ chế liên kết trong JavaFX (RIP). Các ràng buộc từ khóa cho phép bạn để ràng buộc giá trị của một biến với giá trị của một biểu thức và nhận được bạn thoát khỏi tất cả những xấu xí Listener nào mã boilerplate.

Mặc dù JavaFX khá thất bại theo nhiều cách, tôi thấy nhiều tính năng của ngôn ngữ kịch bản khá hay.


1

Chuỗi mixins cộng với đánh giá hàm thời gian biên dịch trong D là một tính năng sát thủ khá độc đáo. Vâng, về mặt kỹ thuật đó là hai tính năng, nhưng sức mạnh thực sự đến từ việc kết hợp chúng. Với sự kết hợp này, bạn có thể viết các hàm D thông thường tạo mã dưới dạng chuỗi tại thời gian biên dịch, sau đó trộn mã này vào bất kỳ phạm vi nào và để nó được đánh giá là mã D thông thường. Mã được biên dịch hoàn toàn tĩnh và thực thi chính xác như thể nó đã được viết tay. Tính năng này thậm chí còn được sử dụng để xử lý một vài tình huống dính trong thư viện chuẩn.


Tôi cũng thích kiểu trả về tự động được suy ra từ một phương thức ..
nawfal
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.