Lập trình tự động: viết mã viết mã [đã đóng]


105

Sau khi đọc cuốn sách Lập trình viên thực dụng , một trong những lập luận tôi thấy thú vị nhất là "viết mã viết mã".

Tôi đã thử tìm kiếm trên mạng để tìm thêm một số giải thích hoặc bài viết về nó, và trong khi tôi tìm thấy một số bài viết hay về chủ đề này, tôi vẫn không tìm thấy bất kỳ triển khai mã cụ thể hoặc ví dụ hay nào.

Tôi cảm thấy nó vẫn không phải là một cuộc tranh luận quá phổ biến, một cái gì đó thiếu tài liệu hoặc nó không được nhiều người chấp nhận và tôi muốn biết thêm về nó.

Bạn nghĩ gì về chủ đề này? Nó có phải là cái gì đó sẽ thực sự tăng năng suất của bạn? Một số tài nguyên tốt về chủ đề này, trong số các cuốn sách, blog, trình chiếu, vv là gì?


Một số ví dụ mã sẽ được đánh giá rất cao để cho phép tôi hiểu rõ hơn về việc thực hiện nó.


Đây là trang wiki về chủ đề này với các kỹ thuật lập trình có liên quan khác nhau, như Lập trình Meta, Lập trình tạo và Tạo mã.


32
Tôi đã từng viết mã trong đó viết mã viết mã ... :)
Stewol

9
@Benjol: Bạn đã viết bằng Lisp chưa?
soạn nhạc

11
Ngoài ra, các ngôn ngữ phía máy chủ luôn thực hiện việc này bằng cách tạo HTML, CSS và JavaScript. Bạn có thể có một tập lệnh phía máy chủ tạo tập lệnh phía máy chủ tạo html bằng javascript để tạo nhiều html hơn và không ai sẽ để mắt đến nó vì mức độ phổ biến của nó.
zzzzBov

8
Nếu bạn chưa có, hãy xem loạt bài viết về IBM trên IBM này: " Nghệ thuật lập trình siêu dữ liệu " Phần 1 , Phần 2Phần 3 .
John Tobler

3
AtomWeaver ( Atomweaver.com ) là một ví dụ điển hình về lập trình tự động: Đầu tiên, bạn tạo các chương trình nhỏ có thể tái sử dụng trong Lua. Sau đó, bạn mô hình hóa hệ thống của mình bằng cách sử dụng lại các tài sản này. Sau đó, AtomWeaver dệt một chương trình Lua có chứa "máy phát điện mini" của bạn để tạo mã nguồn cuối cùng của hệ thống. Sau đó, bạn có thể điều chỉnh mô hình của mình và tạo lại.
Rui Curado

Câu trả lời:


49

Trong thế giới Lisp, khá phổ biến để xem mã viết mã viết mã (vân vân). Vì vậy, bất kỳ dự án Lisp hoặc Scheme có kích thước vừa phải sẽ đóng vai trò là một ví dụ mã tốt. Tôi khuyên bạn nên xem trình biên dịch vợt và các nguồn thời gian chạy, cũng như Bigloo , các thư viện của họ thật tuyệt vời.

Về năng suất: Tôi đang sử dụng siêu lập trình như một kỹ thuật chi phối trong hầu hết tất cả các công việc phát triển của mình và rõ ràng nó giúp ích rất nhiều, vừa giảm kích thước mã vừa tăng khả năng đọc. Điều quan trọng là trong việc sử dụng tên miền Ngôn ngữ cụ thể , và Lập trình meta là một trong những cách hiệu quả nhất thực hiện chúng.


67

Tôi thích đi xa hơn một chút, và thay vì viết mã viết mã, viết mã tạo ra các đối tượng, phương thức, hàm. Điều này có thể đạt được với các macro Lisp hoặc các khả năng sửa đổi chương trình động của Ruby chẳng hạn.

Sự khác biệt nhỏ là bạn không kết thúc với các tệp nguồn được tạo tự động. Thông thường các tệp này không phải là con người có thể đọc được và không thể sửa đổi, vậy tại sao phải bận tâm với chúng. Tôi không thích ý tưởng tăng cơ sở mã của mình bằng thứ gì đó tôi không thể kiểm soát.

Một cuốn sách tôi rất thích đọc về chủ đề này là Metaprogramming Ruby (nếu bạn biết ngôn ngữ Ruby)


Chỉnh sửa sau câu hỏi sau trong bình luận:

Tại sao nó hữu ích, tôi vẫn phải viết mã tạo? Tôi có nên viết một mã có thể tạo ra những thứ khác nhau tùy thuộc vào đầu vào của người dùng, để tôi có thể sử dụng lại nhiều lần không?

Đầu tiên, siêu lập trình không phải là một mục tiêu, mà là một công cụ. Đừng sử dụng siêu lập trình vì "tuyệt vời" hoặc "X cho biết mọi nhà phát triển nên sử dụng nó".

Tôi nghĩ một lý do chính đáng để sử dụng siêu lập trình là để khái quát một số mẫu chung (mẫu như một cái gì đó lặp lại) mà bạn đã tìm thấy trong mã của mình và không có kỹ thuật lập trình thông thường nào khác (kế thừa, mẫu thiết kế, v.v.) có thể đạt được.

Như Jordan đã nói , một trường hợp sử dụng điển hình là xử lý cơ sở dữ liệu và ORM (Ánh xạ quan hệ đối tượng). Một lần nữa, trong Ruby, bạn nên xem ActiveRecord , một ví dụ tuyệt vời về siêu lập trình được áp dụng cho ORM.

Như lưu ý cuối cùng:

Đừng nghĩ rằng "Tôi muốn áp dụng siêu lập trình, tôi có thể áp dụng nó trong mã của mình ở đâu?".

Hãy suy nghĩ "Tôi thấy mô hình này lặp đi lặp lại trên toàn bộ mã của tôi, tôi không thể tìm cách tái cấu trúc mã thành một cái gì đó nhỏ hơn và có thể tái sử dụng nhiều hơn. Có lẽ siêu lập trình có thể giúp tôi?"


3
@Jose: Thông thường nhất bạn tạo mã thông qua các mẫu. Ví dụ, có vận tốc apache (N-) hoặc các mẫu T4 của studio hình ảnh. Sau đó, bạn chỉ cần có một chương trình cung cấp siêu dữ liệu vào các mẫu của bạn và tạo các tệp mới từ đó. Điều này khá dễ dàng và tôi đang làm tất cả thời gian để tạo bộ xương UI, Thực thể, v.v.
Falcon

2
@Jose Faeti, hãy xem kỹ hơn về các macro Lisp (hoặc Clojure hoặc Nemerle, tùy thuộc vào sở thích nền tảng của bạn).
SK-logic

1
Tôi sẽ thêm siêu lập trình có thể thay thế một số mẫu như chính sách hoặc trạng thái, nhưng không có chi phí thời gian chạy. Điều này không chỉ cho các vấn đề không thể đạt được với tái cấu trúc thông thường, mà đôi khi còn là một giải pháp thay thế tốt hơn.
deadalnix

1
@Jose Faeti: Tôi thấy rằng bạn biết một số Python. Nó cũng có khả năng siêu lập trình, mặc dù tôi chưa thực sự sử dụng chúng. Hãy xem Python PDF nguy hiểm nâng cao
Kit

3
@Falcon: IMO đó là cách tồi tệ nhất để tạo mã; nó rất kém đối với các ngôn ngữ không có tiện ích lập trình meta tích hợp. Thay vì tạo Java hoặc C #, sẽ tốt hơn nếu viết mã đó bằng ngôn ngữ JVM hoặc .NET cấp cao hơn.
kevin cline

19

Thậm chí tốt hơn, sử dụng mã mà người khác đã viết mà viết mã cho bạn.

Tự động hóa mã nói chung là tốt cho ORM và mã tương tác cơ sở dữ liệu khác, và tất nhiên để xây dựng mã lặp đi lặp lại nhưng tương tự.

Tất nhiên, nếu bạn đang xây dựng nhiều lớp học tương tự, có lẽ bạn đã hoàn thành điều tương tự bằng ngôn ngữ động sớm hơn nhiều, nhưng tôi lạc đề.

Điều này được nhiều người chấp nhận, mặc dù bạn sẽ thường tìm thấy phần mềm được gắn nhãn là trình tạo mã.

Xem các công ty và sản phẩm như CodeSmith và MyGeneration hoặc duyệt qua bài viết Wikipedia này: http://en.wikipedia.org/wiki/Comparison_of_code_generation_tools


6
Nó không tốt hơn. Mã nhỏ quý giá của bạn không thể được quản lý chính xác bởi một số công cụ tạo mã của bloke khác, vì các bloke khác không biết gì về thông tin cụ thể của bạn. Việc sử dụng siêu lập trình hiệu quả nhất là triển khai các ngôn ngữ cụ thể cho miền - và, như tên cho thấy, chúng đặc trưng cho miền rất có vấn đề của bạn, chúng không thể được thực hiện bởi bất kỳ ai khác ngoài bạn.
SK-logic

@ SK-logic: những gì về mã ORM được tạo ra? Nó được tạo bởi một công cụ / thư viện khác và vẫn đáp ứng nhiều nhu cầu của dự án.
David

@David, thành thật mà nói, tôi không hoàn toàn bị thuyết phục với các ORM chung chung. Tôi đã có rất nhiều vấn đề với họ trong quá khứ, thường sử dụng các ORM cụ thể của riêng tôi để thay thế.
SK-logic

1
@Jordan, tất cả những công cụ đó quá cụ thể (và tệ hơn - dựa trên văn bản , tức là kém hơn về thiết kế). Thay vào đó, tôi đang nói về siêu lập trình thích hợp.
SK-logic

1
@AtillaOzgur, họ có thể "rất tốt", đúng vậy. Nhưng chúng không tốt hơn eDSL. Việc tạo mã độc lập rõ ràng là hạn chế hơn và kém linh hoạt hơn nhiều so với lập trình siêu dữ liệu macro.
SK-logic

16

Một trong những ví dụ kinh điển là lex và yacc. Mục đích chính của họ là để tránh sự quyết liệt của việc viết bất kỳ loại trình phân tích cú pháp nào. Trên đường đi, họ làm cho việc xây dựng các trình phân tích cú pháp phức tạp với nhiều quy tắc và trạng thái nhanh hơn rất nhiều và họ cũng tránh được tất cả các lỗi bất ngờ do mọi người tự tạo ra.

Đây cũng là ý tưởng đằng sau c, là một công cụ để viết chương trình biên dịch chương trình. Điều tương tự cũng xảy ra với bất kỳ ngôn ngữ cấp cao nào bạn quan tâm để đặt tên. Đối với các công cụ viết mã cho bạn, có một vài mô hình đơn giản.

Một IDE phù hợp sẽ giúp bằng cách cung cấp tài liệu trong tầm tay, hoàn thành tự động thông minh và các đoạn mã. IDE cũng bao gồm nhiều mẫu khác nhau, vì vậy bạn không phải bắt đầu một chương trình từ đầu. Có các chương trình để có một sơ đồ uml và các lớp thô trong một ngôn ngữ cấp cao.

Cuối cùng, bạn có thể viết các công cụ của riêng mình để tạo mã trong bộ vấn đề của bạn. Đây là cách lex và yacc lần đầu tiên bắt đầu. Bất kỳ loại ngôn ngữ cụ thể miền nào tồn tại vì lý do chính xác này. Bạn tạo một số khối xây dựng mô tả giải pháp của bạn để dễ hiểu mã hơn, gói các hoạt động phổ biến hoặc các phần phức tạp bằng các lệnh đơn giản. Bạn không tìm kiếm một giải pháp cho mọi vấn đề, chỉ là một định nghĩa dễ dàng hơn về vấn đề cụ thể mà bạn đang giải quyết.

Theo một nghĩa nào đó, mọi thứ bạn làm trên lớp nhị phân là tự động hóa mã.


Đó là một góc nhìn thực sự tốt đẹp. Tất cả trong tất cả chỉ là một phương pháp khác trong số nhiều phương pháp mà các lập trình viên cố gắng sử dụng để tạo thuận lợi cho hoạt động của họ và tập trung vào mức độ mã hóa cao hơn, thay vì chi tiết mã cú pháp.
Jose Faeti

1
@Jose Faeti Bài viết trên wikipedia en.wikipedia.org/wiki/Automatic_programming có liên kết đến nhiều công cụ khác nhau, nếu bạn quan tâm đến một số chi tiết. Tôi cũng khuyên bạn nên đọc lên lex và yacc, vì có thêm một chút tài liệu và mô tả cho những thứ đó.
Spencer Rathbun

Trong các ngôn ngữ đủ mạnh (ví dụ C ++ trái ngược với C), các công cụ bên ngoài như lex và yacc là không cần thiết.
kevin cline

YACC không viết "bất kỳ loại trình phân tích cú pháp" nào. Nó viết một loại trình phân tích cú pháp cụ thể (LALR) rất khó để lấy đúng nếu không có trợ giúp tự động. Có một loại trình phân tích cú pháp khác (gốc đệ quy) dễ viết và dễ đọc hơn, và tương ứng dễ đọc và hiểu những gì đang diễn ra.
Mason Wheeler

@MasonWheeler Loại trình phân tích cú pháp đã đề cập đến các ngữ pháp có thể được tạo để giải quyết các vấn đề, theo nghĩa rộng, không chính xác. Đọc nó một năm sau, nó không rõ ràng như tôi muốn. Tuy nhiên, tôi không chắc chắn rằng tôi đồng ý với bạn về trình phân tích cú pháp LL (*) để dễ viết và sử dụng hơn.
Spencer Rathbun

13

Lập trình siêu dữ liệu

Metaprogramming là một kỹ thuật gây tranh cãi trong nhiều cửa hàng. Lý do là, giống như bất kỳ công cụ mạnh mẽ nào, mức độ giúp đỡ hoặc tổn thương là rất lớn.

Ưu

  • Biểu cảm hơn, ít mã hơn để viết và duy trì (thường theo thứ tự cường độ trở lên)
  • Tính nhất quán, hành vi nhất quán hơn đối với lớp các vấn đề mà bạn giải quyết với mã
  • Năng suất, ít mã hơn cho một giải pháp cho một không gian vấn đề lớn hơn

Nhược điểm

  • Sự phức tạp, nó có thể rất phức tạp mặc dù có ít mã hơn
  • An toàn, đôi khi loại an toàn và phân tích tĩnh nói chung sẽ bị hy sinh
  • Lỗi ảnh hưởng nhiều hơn, lỗi nhỏ sẽ có tác động lớn hơn

Tôi là một fan hâm mộ lớn của siêu lập trình, nhưng tôi đã thực hiện nó trong một thời gian dài. Đối với tôi sự đánh đổi của kích thước mã giảm và hành vi nhất quán nhiều hơn là bù đắp cho những rủi ro. Ít mã hơn có nghĩa là ít lỗi hơn, ít mã hơn để duy trì và tôi thường có thể thêm các phần lớn chức năng rất nhanh.

Tuy nhiên, điều này không có nghĩa là tôi nghĩ rằng tất cả các lập trình viên nên tham gia vào nó. Tôi đã thấy và phải sửa các vấn đề lớn được tạo ra bằng siêu lập trình. Thông thường từ khi những người không hiểu khái niệm và đã cố gắng mở rộng chức năng hoặc chỉ sửa một lỗi. Nó cần một bộ tâm trí đặc biệt ít nhất là theo định hướng chi tiết. Câu hỏi để sử dụng các kỹ thuật siêu lập trình nên là một quyết định của nhóm . Nếu bạn có các thành viên trong nhóm không hiểu, không có khí chất cho điều đó hoặc chỉ chống lại điều đó, không ai trong nhóm nên sử dụng siêu lập trình.


Cảm ơn những cân nhắc hữu ích! Bạn có thể gợi ý cho tôi một nhiệm vụ cơ bản và đơn giản mà tôi có thể thực hiện bằng cách sử dụng siêu lập trình, điều này sẽ giúp tôi tiết kiệm thời gian hơn so với mã hóa thông thường, một ví dụ mã nhỏ?
Jose Faeti

haha làm cho tôi nhớ lại một lỗi mà tôi đã bị nghiêm trọng nhiều năm trước với GCC. 162 dòng để đặt thông báo lỗi trên màn hình của tôi. FTW đệ quy siêu lập trình!
deadalnix

6
Độ phức tạp của siêu lập trình được đánh giá cao. Hoàn toàn không có gì phức tạp trong đó, miễn là bạn đang sử dụng đúng công cụ. Và DSL dễ gỡ lỗi và bảo trì hơn nhiều so với mã soạn sẵn thông thường. Ngoài ra, tôi không thể hiểu tại sao người ta phải hy sinh loại an toàn - điều này hoàn toàn ngược lại, DSL cũng có thể có các hệ thống loại hiệu quả cao, đặc thù cho miền.
SK-logic

2
@ SK-logic: Không phải tất cả các ngôn ngữ đều hỗ trợ siêu lập trình tốt. Vì vậy, đôi khi những thứ như loại an toàn được hy sinh (ví dụ: C) . Ngoài ra siêu lập trình không chỉ là DSL. Nó bao gồm những thứ như lập trình kiểu điều phối, khái quát, currying, kiểm tra đối tượng, ứng dụng động, v.v ... Về độ phức tạp, tôi nghĩ thật dễ dàng cho chúng tôi (những người có kinh nghiệm lập trình siêu dữ liệu) nói rằng nó không phức tạp. Tôi đã thấy cuộc đấu tranh khác với việc hiểu tất cả các trường hợp mã sẽ được thực thi theo. Nó chủ yếu phụ thuộc vào kinh nghiệm của họ và kỹ thuật liên quan.
Dietbuddha

@dietbuddha, bạn có thể giải thích rõ hơn, tại sao người ta phải hy sinh loại an toàn của DSL của chính họ, bất kể nó được thực hiện như thế nào? Bạn có thể viết một trình thông dịch ad hoc trong C thuần túy với một hệ thống loại mạnh (xem ví dụ về Hugs). Bạn có thể viết một trình tạo mã nhắm mục tiêu C thực hiện tất cả các lỗi đánh máy, không dựa vào hệ thống loại ngôn ngữ đích. Đối với sự phức tạp: hầu hết mọi người đang thực hiện nó theo một cách phức tạp không cần thiết, trong khi tất cả các phương pháp thiết kế tương tự có thể được áp dụng cho việc tạo mã như trong lập trình "bình thường". Hầu như không có kiến ​​thức mới được yêu cầu.
SK-logic

9

Hầu hết các mã viết mã. Ví dụ mã php giúp viết html. Thư viện php pdo giúp viết các cuộc gọi SQL. Các hàm I / O tập tin viết mã để giao tiếp với HĐH. Ngay cả một lệnh gọi hàm thông thường là một tham chiếu đến một khối mã khác được thực thi. Vì vậy, các chức năng của bạn gọi là viết mã.

Theo nghĩa rộng, chúng ta có thể nghĩ về điện toán như viết mã viết mã theo cách đệ quy tạo thành một ngăn xếp chấm dứt khi nó chạy ngược với thực tế vật lý của mã được nối vào phần cứng.


3
Tôi sẽ không gọi html là ngôn ngữ lập trình. Đây là một cú pháp cho các tài liệu
Simon Bergot

3
@Simon nó là một điểm thú vị. Có tất cả các quyền hạn biểu cảm cho các mã khác nhau mà chúng tôi sử dụng. Mã có thể viết sang ngôn ngữ yếu hơn, ngôn ngữ mạnh hơn hoặc ngôn ngữ riêng.
Ben Haley

5

Làm thế nào bạn làm điều này thay đổi tùy thuộc vào yêu cầu của bạn. Giả sử bạn đang sử dụng tạo mã tĩnh, bạn có thể tự viết tất cả các cơ sở hạ tầng hoặc bạn có thể sử dụng một trình tạo hiện có như CodeSmith hoặc MyGeneration. Sử dụng chúng bạn chỉ cần viết các mẫu cần thiết.

Dự án cuối cùng của tôi liên quan đến điều này là một số màn hình ASP.NET CRUD cơ bản (tạo mã tốt cho việc này). Quá trình đã xác định các thực thể là siêu dữ liệu trong các tệp xml. Viết các mẫu để bao gồm các tạo phẩm khác nhau cần thiết (các lớp thực thể, kho lưu trữ, lớp dịch vụ, điều khiển asp.net, trang asp.net, v.v.). Chạy quá trình tạo và tạo kiểu đầu ra.

Có một số chi phí trong việc viết các mẫu nhưng chúng có thể được sử dụng lại cho các dự án tương tự tiếp theo. Các thay đổi tương tự đối với dữ liệu cơ bản được xử lý bằng cách thay đổi siêu dữ liệu và chạy lại việc tạo các thay đổi đơn giản hơn và nhanh hơn để thực hiện.

Như để thử nghiệm. Vì đây là một hệ thống khuôn mẫu, bạn sẽ cần dành một chút thời gian để xác nhận đầu ra của quy trình, nếu mẫu của bạn sai, tất cả đầu ra từ mẫu đó sẽ sai tương tự. Khi bạn hài lòng với điều này, bạn cũng có thể sử dụng trình tạo mã để tạo các thử nghiệm cơ bản từ siêu dữ liệu xml mà sau đó bạn có thể mở rộng để bao gồm các trường hợp đặc biệt. Tuy nhiên, hãy nhớ rằng bạn vẫn có thể cần phải kiểm tra mã tay để phục vụ cho những việc cụ thể, việc tạo mã làm giảm công việc của bạn, nó không loại bỏ hoàn toàn.


5

Tại công ty chúng tôi, chúng tôi sử dụng một số công cụ thực sự tạo ra các lớp C ++ hoặc C # với dữ liệu được tải xuống từ internet. Các lớp này là các thùng chứa dữ liệu và chứa một số lượng lớn các đối tượng trong danh sách.


Một cái gì đó giống như đoạn mã được tìm thấy trong một số IDE như Visual Studio chẳng hạn?
Jose Faeti

@Jose Công cụ của chúng tôi chỉ là một ứng dụng để chuyển đổi đầu ra HTML thành một lớp. Vì vậy, thay vì tải xuống dữ liệu mỗi khi ứng dụng khởi động, chúng tôi tải xuống một lần và tạo một lớp từ đó.
Holli

5

Metaprogramming đã là một phần của lập trình trong một thời gian dài. Hãy xem xét không chỉ các công cụ như SWIG, hoặc các nhà thiết kế WYSIWYG, những người tạo mã, mà cả các công cụ ngôn ngữ như bộ tiền xử lý của C, hoặc thậm chí các mẫu của C ++ và tổng quát của C # / Java - không đề cập đến Reflection.

Trong thực tế, bạn có thể lập luận rằng mọi trình biên dịch chỉ là một siêu dữ liệu khác - chúng có trong văn bản chương trình và máy đầu ra hoặc mã VM. Và, cuộc sống không có trình biên dịch? Owch.


Điều đó đúng, nhưng làm thế nào bạn thực sự có thể thực hiện nó bằng ngôn ngữ lập trình của riêng bạn để thực sự tăng năng suất của bạn? Đó là những gì tôi đang thiếu.
Jose Faeti

5

Đây là một ví dụ cụ thể từ quá khứ của tôi.

Tôi đã làm việc tại một trang web có khoảng 50 MB mã nguồn Delphi bằng BDE để truy cập dữ liệu. Họ muốn chuyển sang sử dụng Direct Oracle Access để cho phép nâng cấp Oracle qua phiên bản cao nhất được BDE hỗ trợ (8i nếu tôi nhớ lại chính xác).

Vì vậy, thay vì bắt một nhóm lập trình viên làm việc thông qua mọi biểu mẫu và mô đun dữ liệu thay đổi mọi thành phần theo cách thủ công, tôi đã viết một tập lệnh PERL rằng: -

  1. Phân tích cú pháp DFM (tệp biểu mẫu) và xác định tất cả các đối tượng TQuery, TTable, TStoredProcedure & TDatabase - lưu trữ các mục trong danh sách.

  2. Phân tích cú pháp PAS (mã) và xác định việc sử dụng các đối tượng - TQueries có đang cập nhật hoặc chọn không? Ngoài ra, nó đã xác định bất kỳ đối tượng nào được tạo trong mã thay vì thả vào một biểu mẫu trong IDE.

  3. Viết lại DFM & PAS thay đổi các loại đối tượng một cách thích hợp (ví dụ: TTable -> TOracleDataSet với thuộc tính SQL được đặt thành "select * from", v.v.) và các phương thức gọi. Ngoài ra, các cuộc gọi phương thức bổ sung đã được thêm vào nếu thích hợp để đóng, mở và đặt tham số.

Nói tóm lại, 3 tuần làm việc để điều chỉnh tập lệnh để hoạt động trên các ứng dụng khác nhau được viết bởi các nhóm khác nhau với các kiểu mã hóa khác nhau thay vì ước tính ban đầu của hơn 5 nhà phát triển làm việc trong 6 tháng.

Và lý do tôi thậm chí nghĩ đến việc sử dụng phương pháp đó là thông qua việc đọc Lập trình viên thực dụng


Thật tuyệt, giờ tôi đã vào Perl được vài ngày và tôi đã tạo ra một số công cụ năng suất để tạo các không gian làm việc cơ bản để phát triển web, với tất cả các thư mục, tệp, v.v. chỉ bằng cách gõ "tạo không gian làm việc"! :)
Jose Faeti

1
@Jose Đó là ý tưởng. Sử dụng các ngôn ngữ kịch bản để tự động hóa các công cụ lặp đi lặp lại. Nó có thể là một lần duy nhất khi bạn tăng năng suất 8 lần hoặc như trong trường hợp của bạn một cái gì đó tốn thời gian mà bạn sẽ làm lại & một lần nữa.
đánh dấu

4

Bạn hỏi ví dụ ....

Khi làm việc với SQL, bạn không nên thay đổi cơ sở dữ liệu trực tiếp mà thay vào đó được cho là đang thực thi các tập lệnh thực hiện bất kỳ thay đổi nào bạn muốn, bao gồm thay đổi cấu trúc cho cơ sở dữ liệu (thêm bảng, cột, khóa chính, ràng buộc, v.v.) . Rất thường xuyên, bạn sẽ cần phải thực hiện cùng một hành động đối với nhiều bảng hoặc cột cùng một lúc và thực hiện từng bước một sẽ rất tẻ nhạt, một tập lệnh ngắn tạo ra một tập lệnh lớn hơn làm những gì bạn muốn có thể là thật tiết kiệm thời gian.

Chẳng hạn, trước khi kiểu dữ liệu DATE được giới thiệu cho MS SQl Server, lựa chọn duy nhất cho cột ngày là DATETIME có phần thời gian - phần thời gian khiến việc xử lý dữ liệu khó hơn một chút. Khi nâng cấp lên phiên bản có loại dữ liệu Ngày, bạn có thể muốn cập nhật các cột trong đó thời gian luôn là 00:00. Trong cơ sở dữ liệu có hàng chục hoặc thậm chí hàng trăm cột DateTime, việc này sẽ khá tốn thời gian. Nhưng thật dễ dàng để viết một tập lệnh truy vấn tất cả các bảng, kiểm tra mỗi cột bằng kiểu dữ liệu của DATETIME để xem liệu đó có phải là thời gian không, trừ 00:00 và nếu không tạo câu lệnh ALTER để bảng / cột thay đổi kiểu dữ liệu thành NGÀY. Presto, mã mà viết mã.


3

Hãy xem Mac (Môi thường). Theo tôi đó là chính xác những gì bạn muốn. Môi là hoàn hảo trong siêu lập trình.

Ngoài ra, tôi đề nghị Nemerle nếu bạn muốn có quyền hạn .NET với sự hỗ trợ Metaprogramming hoàn hảo (bao gồm cả macro)

Nhưng nếu bạn muốn một công cụ tạo mã thực sự, hãy xem Apache tiết kiệm


3

Tôi chỉ đang làm việc trên một công cụ như vậy. Trong trường hợp cụ thể của chúng tôi, chúng tôi tạo mã VB.NET dựa trên Lớp dữ liệu trên chữ ký của các hàm trong cơ sở dữ liệu.

Bắt đầu làm việc với và tạo mã ban đầu rất khó vì bạn không biết nên tạo mã như thế nào, nhưng một khi bạn đã có một bộ quy tắc được thiết lập và mã phải được tạo luôn có thể được tạo dựa trên các quy tắc đó , làm việc với mã đó không phải là khó khăn. Tất nhiên, tùy thuộc vào sự phức tạp của việc tạo mã và vào số lượng quy tắc, nhiệm vụ có thể trở nên khó khăn hơn. Nhưng về bản chất, việc tạo mã tự động được sử dụng cho các nhiệm vụ mã hóa lặp đi lặp lại và không phải cho mã nâng cao thay đổi nhiều.

Kiểm tra đầu ra là gấp đôi. Trước tiên, bạn phải đảm bảo rằng mã biên dịch, và điều đó thật dễ dàng. Sau đó, bạn phải đảm bảo rằng đầu ra thực hiện những gì bạn muốn làm dựa trên các tham số được tạo trên .. và độ khó của nó thay đổi tùy theo độ phức tạp của mã bạn tạo.

Lời khuyên chân thành của tôi là nếu bạn cảm thấy như bạn viết mã theo cách lặp đi lặp lại và bạn có thể dành thời gian .. Hãy thử nghĩ xem những gì bạn đang làm không thể được thực hiện bằng mã được tạo. Và nếu vậy (nếu đó là mã lặp đi lặp lại gần như luôn luôn như vậy) hãy nghĩ bạn sẽ phải gia hạn bao nhiêu lần, sửa đổi một chút mã đó và bạn phải viết loại mã chính xác đó bao nhiêu lần. Nếu câu trả lời cho bất kỳ câu hỏi nào là "nhiều" thì bạn nên nghiêm túc xem xét việc tạo một trình tạo cho mã đó .

Hy vọng điều đó có ích,
IPP


Cảm ơn về câu trả lời! Làm thế nào là các quy tắc trong ví dụ của bạn thực hiện?
Jose Faeti

1
Tôi không thể nói cho bạn tất cả các quy tắc nhưng tôi có thể cho bạn một số ví dụ. Chúng tôi phân tích giao diện được hiển thị bởi một cơ sở dữ liệu oracle và chúng tôi xem xét chữ ký của các chức năng trong giao diện oracle. Dựa trên chữ ký, chúng ta tạo tên của hàm dữ liệu. chúng tôi biết rằng chúng tôi luôn nhận được từ db một bảng dữ liệu tiên tri do kết quả mà chúng tôi phân tích và lưu vào một mảng các loại đối tượng đặc biệt mà chúng tôi sử dụng để lưu trữ dữ liệu của mình. đồng thời, dựa trên các tham số đầu vào / đầu ra của chữ ký hàm db, chúng tôi thêm các tham số đầu vào và đầu ra tương ứng vào các hàm chúng tôi tạo và v.v.
Ioan Paul Pirau

3

Tôi có một mô-đun PHP xuất ra một trang web chứa mã JavaScript tạo HTML. Đó là ba lớp ngay tại đó. Cậu bé thật khó đọc!

Trong một lớp lập trình, chúng tôi phải viết một chương trình lấy chuỗi công thức từ người dùng và phân tích cú pháp và hiển thị giá trị. Trình giải ấn tượng nhất chỉ đơn giản là lấy đầu vào của người dùng, bọc nó trong hàm main () {printf ("% d", ...);} và chạy một tập lệnh để biên dịch, liên kết và chạy nó. Anh ấy đã không viết một trình phân tích cú pháp! Hôm nay bạn có thể làm điều đó trong một câu lệnh SQL SELECT.

Đây là một công cụ bạn nên chơi cùng, sau đó lưu trữ nó vào một ngày nào đó trong tương lai khi nó sẽ có ích.


Đó thực sự là điều tương tự mà tôi đã cố gắng thực hiện! :) Nhưng sau đó tôi đã quyết định viết mã bằng Perl ngoại tuyến và nó hoạt động rất tốt. Tôi có rất nhiều tính năng tôi đang nghĩ để thêm vào!
Jose Faeti

Tôi đang viết mã với tối đa 20 lớp ngôn ngữ để chuyển đổi ngôn ngữ, không có vấn đề gì cả. Nó không phức tạp hơn việc có độ sâu ngăn xếp cuộc gọi là 20 lớp. Vì vậy, tôi hoàn toàn không đồng ý rằng nó là một công cụ để " lưu trữ nó cho một ngày nào đó trong tương lai khi nó sẽ có ích " - việc tạo mã luôn tiện dụng.
SK-logic

3

Tôi đã phát triển các giải pháp lập trình meta gọn gàng với Prolog . Trong đó ứng dụng chính (trong C ++ nói) chuyển một định nghĩa trừu tượng về một vấn đề thành ứng dụng Prolog khi chạy, sau đó được ủy quyền. Thường thì việc viết chức năng tương đương trong C ++ sẽ mất mãi mãi.

Tôi nghĩ kịch bản này là một trường hợp xuất sắc ủng hộ đối số mã viết mã .


3

Bạn nghĩ gì về chủ đề này?

Lập trình siêu dữ liệu thường được kết hợp với các ngôn ngữ không động, vì có nhiều thời gian hơn để đạt được một số hành vi nhất định (chẳng hạn như thực hiện ORM) mà không có nhiều dòng mã không thông minh và không thông minh.

Nhưng ngay cả trong các ngôn ngữ năng động hơn như PHP, việc tạo mã có thể thực sự tiết kiệm và tăng năng suất với số lượng lớn. Trong các khung hiện đại, rất phổ biến khi có giàn giáo tạo ra hầu hết các mô hình, hình thức, thử nghiệm và hành động chung cho một đối tượng kinh doanh nhất định mà bạn tuyên bố. Đó là một trong những lý do tại sao các khung như symfony hoặc RoR có được rất nhiều thành công, những công cụ tạo mã này tạo ra mã nhất quán rất nhanh và tăng năng suất cho các lập trình viên.

Trong các trang web, hầu hết các tương tác đều xoay quanh bốn hành động chính:

  • Tạo một yếu tố
  • Lấy một tập hợp các phần tử (có thể lọc)
  • Cập nhật một yếu tố với các thuộc tính mới
  • Xóa một tập hợp các yếu tố

Ít nhất mọi thứ xoay quanh 4 hành động chính này đều có thể và IMHO NÊN đạt được bằng cách sử dụng các công cụ tạo mã để đạt được năng suất tối đa.

Trong công ty của tôi, chúng tôi sử dụng symfony và trình tạo quản trị viên của nó là một công cụ đặc biệt, thậm chí tạo mã trong thời gian chạy (và lưu trữ nó), có nghĩa là chúng tôi thậm chí không cần sử dụng bất kỳ loại tác vụ hoặc công cụ bên ngoài nào để tạo mã mới, chúng ta chỉ cần xóa bộ nhớ cache. Tôi thực sự khuyên bạn nên sử dụng loại công cụ này cho các hoạt động CRUD.

Nhưng, làm những gì mà những người đóng góp tuyệt vời của symfony đã làm, không phải là một nhiệm vụ dễ dàng. Tôi đã tự mình thực hiện một số tác vụ tạo mã và thực hiện một số thứ thực sự phù hợp và với việc triển khai rộng rãi để bao quát hầu hết các trường hợp góc là không dễ dàng.

Nó có phải là cái gì đó sẽ thực sự tăng năng suất của bạn?

Tôi tin rằng siêu lập trình là rất rất quan trọng trong các công việc cấp thấp hơn (khung, bộ đệm, trình biên dịch, v.v.) nhưng một cái gì đó mà chúng ta phải hết sức thận trọng nếu chúng ta làm việc trên tầng doanh nghiệp.

Sử dụng việc tạo mã là không có bất kỳ câu hỏi nào tăng cường năng suất chính. Việc triển khai các công cụ tạo mã của riêng bạn, không quá nhiều trừ khi bạn tự xây dựng một khung công tác.

Một số tài nguyên tốt về chủ đề này, trong số các cuốn sách, blog, trình chiếu, vv là gì?

Tài nguyên tốt nhất để hiểu lập trình luôn là mã nguồn tốt và được nhận xét tốt. Tôi muốn nói rằng việc xem xét các trình tạo quản trị viên RubyOnRailsSymfony là một ý tưởng tốt.


3

Mặc dù nhiều câu trả lời ở đây đề cập đến cái thường được gọi là lập trình meta, nhưng thực tế có một lĩnh vực liên quan đến AI được gọi là lập trình tự động là về hiểu biết chương trình hoặc tổng hợp chương trình [1].

Bất kỳ trình biên dịch nào (hoặc chương trình meta, trình tạo mã, trình dịch, hệ thống macro, ...) đều hoạt động với các phép biến đổi, tạo ra một đầu ra từ một đầu vào bằng cách thực hiện thuật toán chuyển đổi cố định của nó. Nhưng một trình biên dịch hoặc chương trình meta truyền thống không, đưa ra một định nghĩa, mô tả hoặc ví dụ về việc sắp xếp danh sách là gì (ví dụ: [5, 3, 9] => [3,5,9]), tạo ra một thuật toán sắp xếp. Những vấn đề như vậy mà sự quan tâm của lĩnh vực "lập trình tự động" này.

[1] - Báo cáo tiến độ về các hệ thống hiểu chương trình ftp://db.stanford.edu/pub/cstr/reports/cs/.../CS-TR-74-444.pdfShare


2

Lập trình meta có thể rất khó để duy trì. Thoạt nhìn có vẻ thanh lịch, nhưng khi bạn bắt đầu chạy vào các trường hợp góc, các lỗi được phát hiện muộn (trên mã đã được tạo) và toàn bộ điều này trở thành một cơn ác mộng khi sử dụng / gỡ lỗi.

Tôi chủ yếu viết mã python và theo kinh nghiệm lập trình meta của tôi luôn là một lựa chọn tồi với ngôn ngữ này. Bạn luôn có thể cấu trúc lại mọi thứ để làm điều đó với các tính năng ngôn ngữ thông thường nhàm chán. Kết quả là ít sôi nổi, nhưng dễ sống hơn.


bất kỳ loại mã nào cũng có thể rất khó bảo trì. Và có thể rất dễ dàng nếu được thực hiện đúng cách. Thực tế siêu lập trình có thể tăng khả năng bảo trì theo thứ tự độ lớn trong thực tế. Trải nghiệm trăn của bạn, rất có thể, không liên quan đến siêu lập trình thực sự, vì Python không phù hợp lắm với lối suy nghĩ này, với AST quá vụng về. Nhưng ngay cả với Python, tôi đã sử dụng thư viện Tempita với hiệu quả cao và không bao giờ có bất kỳ vấn đề bảo trì nào, ngay cả với một nhóm gần như không có kinh nghiệm về Python trước đây.
SK-logic

Tôi quan tâm đến quan điểm của bạn về AST python. Bạn đã sử dụng tempita cho mục đích lập trình meta?
Simon Bergot

này ( docs.python.org/library/ast.html ) là một AST quảng cáo hoc khá, và phân tích cú pháp cho một, cây overbloated unoptimised, mà làm cho việc phân tích vấn đề (đặc biệt là với việc thiếu mô hình đúng đắn phù hợp với bằng Python). Tạo AST như vậy cũng không thuận tiện lắm. Tôi đã sử dụng tempita để sản xuất cả mã Python và mã C (nghĩa là siêu lập trình dựa trên văn bản thuần túy), nó hoạt động tốt cho tác vụ cụ thể đó (tạo mã soạn sẵn). Tôi cũng thường sử dụng Python để tạo mã C từ một số mô tả cấp cao XML.
SK-logic

2

OP yêu cầu tài nguyên.

Bạn có thể thấy Bộ công cụ tái cấu trúc phần mềm DMS của chúng tôi thú vị. Nó là một công cụ siêu lập trình thuần túy, nhằm mục đích cho phép một người xây dựng các công cụ phân tích và chuyển đổi chương trình tùy chỉnh.

[Để theo dõi nhận xét cho câu hỏi của OP, khi được sử dụng để xây dựng một công cụ chuyển đổi cụ thể, DMS là một dòng sản phẩm viết mã, viết mã:]

DMS đạt được điều này bằng cách không tin tưởng (nhưng không độc lập) các làn lập trình mục tiêu. DMS cung cấp các dịch vụ tiêu chuẩn cần thiết cho nhiều loại nhiệm vụ siêu lập trình, giống như một hệ điều hành cung cấp nhiều dịch vụ khác nhau cho các nhiệm vụ lập trình tiêu chuẩn. Các dịch vụ này bao gồm phân tích cú pháp mạnh, tự động xây dựng các cây cú pháp kiêng, khớp mẫu và viết lại trên cây, các thư viện bảng biểu tượng dễ dàng quản lý các ngôn ngữ với các quy tắc phạm vi khó chịu như nhiều kế thừa, luồng điều khiển, luồng dữ liệu, điểm và cuộc gọi phân tích đồ thị. Không có gì trong số này là không có ý nghĩa trong việc không xử lý các ngôn ngữ cụ thể, vì vậy DMS chấp nhận các định nghĩa ngôn ngữ được gắn với các phần chung của máy móc này, mang lại phân tích cụ thể ngôn ngữ, xây dựng AST, khớp / viết lại mẫu ngôn ngữ cụ thể bằng cách sử dụng mục tiêu- cú pháp ngôn ngữ,

Và giống như một hệ điều hành, DMS được thiết kế để có rất ít ý kiến ​​hoặc ràng buộc về những chương trình (meta) nào bạn muốn viết, có nghĩa là nó có thể được sử dụng cho nhiều mục đích khác nhau: trích xuất số liệu, tìm mã chết, triển khai các khía cạnh, dịch thuật langauges, tạo mã từ DSL, nghiên cứu lại các ứng dụng lớn. (DMS đã được sử dụng cho tất cả các nhiệm vụ này).

Người ta cần định nghĩa ngôn ngữ mạnh mẽ nếu bạn không muốn dành thời gian mã hóa mọi thứ trong hướng dẫn tham khảo ngôn ngữ (nghĩ về ý nghĩa của điều này đối với Java và C ++). DMS giải quyết vấn đề này bằng cách có sẵn một thư viện các định nghĩa ngôn ngữ hoàn chỉnh. Sự tương tự ở đây giống như có một cơ sở dữ liệu sẵn có cho hệ điều hành của bạn; bạn không phải thực hiện một trong số chúng để bắt đầu viết ứng dụng tập trung vào cơ sở dữ liệu của bạn.


2

Xem vấn đề của Philip Greensasta, tập 4 từ MIT khóa 6,916: Kỹ thuật phần mềm về các dịch vụ web sáng tạo ( http : // philip.g Greensasta.com/teaching/psets/ps4/ps4.adp ).

Mục tiêu của nó nói, "Dạy cho sinh viên những ưu điểm của siêu dữ liệu. Cụ thể hơn, họ học cách thể hiện chính thức các yêu cầu của dịch vụ Web và sau đó xây dựng một chương trình máy tính để tạo ra các chương trình máy tính thực hiện dịch vụ đó."

Đây là một trong những vấn đề đặt ra những tân binh tiềm năng ArsDigita ( http://en.wikipedia.org/wiki/ArsDigita ) được yêu cầu giải quyết trong bong bóng đầu tiên.

Cuốn sách "SQL cho Web Nerds" Các tài liệu tham khảo Philip trong pset đã được chuyển đến ( http://philip.g Greensasta.com/sql/ ).


2

Vào khoảng năm 2001, tôi bắt đầu thực hiện một dự án sử dụng rộng rãi các đối tượng kinh doanh và đối tượng dữ liệu. Tôi đang xây dựng trang web mặt trước, nhưng bị treo ngón tay cái bởi vì lớp doanh nghiệp và lớp truy cập dữ liệu chưa được phát triển đầy đủ. Sau một vài tuần, tôi bắt đầu nhìn kỹ xem những lớp đó đang làm gì. Về cơ bản, họ đã phơi bày dữ liệu được trả về từ các thủ tục được lưu trữ dưới dạng tập hợp các đối tượng có thuộc tính tương ứng với các trường trong dữ liệu hoặc đang lấy tham số đầu vào và gửi chúng đến các thủ tục được lưu trữ để lưu vào bảng cơ sở dữ liệu. Có rất nhiều tuần tự hóa / giải tuần tự hóa diễn ra giữa hai lớp, có Máy chủ giao dịch Microsoft có liên quan, thư viện loại IDL / ODL ... nhưng tất cả đều phù hợp với một mẫu.

2 tuần sau, tôi đã có một trình tạo mã làm việc để loại bỏ IDL / ODL và cũng sẽ loại bỏ các đối tượng kinh doanh và dữ liệu. Anh chàng đã xây dựng các đối tượng lớp dữ liệu và kinh doanh trong 2 năm để đi đến điểm gỡ lỗi và thử nghiệm các đối tượng này. Trong 2 tuần, với việc tạo mã, chúng tôi có cùng một đầu ra, nhưng vì tất cả được tạo ra nên nó không có lỗi.

Trình tạo mã đó (công cụ CASE cấp thấp hơn) đã theo tôi xung quanh qua nhiều lần lặp khác nhau, trong khoảng 8 đến 10 năm, bởi vì nguyên tắc rất đơn giản: bạn đang làm một việc cần phải làm khi nói chuyện với cơ sở dữ liệu, thật tuyệt nhiều mã hóa lặp đi lặp lại, và một khi bạn hiểu đúng, bạn không phải lo lắng về nó nữa.

Vì vậy, có: sử dụng một trình tạo mã, đặc biệt khi mã hóa được lặp đi lặp lại và phù hợp với một mẫu được xác định rõ.

Tôi đã biết mọi người sử dụng macro RegX để làm những việc tương tự hoặc sử dụng các công thức Excel để làm những việc tương tự (tôi cũng làm điều này).


2

Một ví dụ siêu lập trình

Tôi có một thư viện ủy quyền của Ruby có tên là Author . Nó cho phép các nhà phát triển đặt câu hỏi trong ứng dụng của họ bằng các phương thức như current_user.can_read?(@post)@post.readable_by?(current_user). Những câu hỏi này được trả lời bởi các lớp ủy quyền tập trung.

Đây là phần cốt yếu: Chính quyền không biết nên xác định phương thức nào cho đến khi thấy cấu hình của người dùng . Cấu hình người dùng có thể chứa:

config.abilities =  {
  ...
  :read      => 'readable',
  :microwave => 'microwavable',  # user-defined
  ...
}

Trong trường hợp đó, cần phải có một phương pháp như thế nào current_user.can_microwave?(@post).

Metaprogramming làm cho điều này có thể: sau khi đọc cấu hình, tôi biết phương pháp nào cần xác định :

Authority.verbs.each do |verb|
  class_eval <<-RUBY, __FILE__, __LINE__ + 1 # allows for a nice bracktrace
    def can_#{verb}?(resource)
      resource.#{Authority.abilities[verb]}_by?(self)
    end
  RUBY
end
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.