2014-12-09 14 views
6

Tôi đã làm việc với ngôn ngữ Scala trong một vài tháng và tôi đã tạo vài dự án ở Scala. Tôi đã tìm thấy Scala REPL (ít nhất là triển khai bảng tính IntelliJ) khá thuận tiện cho việc phát triển nhanh chóng. Tôi có thể viết mã, xem nó làm gì và nó đẹp. Nhưng tôi làm thủ tục chỉ cho các chức năng (không phải toàn bộ chương trình). Tôi không thể khởi động ứng dụng của mình và thay đổi nó ngay lập tức. Hoặc ít nhất tôi không biết làm thế nào (vì vậy nếu bạn biết bạn được chào đón để cho tôi lời khuyên).Sự khác nhau giữa Clojure REPL và Scala REPL là gì?

Một vài ngày trước, cộng tác viên của tôi đã nói với tôi về Clojure REPL. Anh ấy sử dụng Emacs cho quá trình phát triển và anh ấy có thể thay đổi mã tại chỗ và xem kết quả mà không cần khởi động lại. Ví dụ, ông bắt đầu quá trình và nếu ông thay đổi thực hiện một chức năng, mã của ông sẽ thay đổi hành vi của mình mà không cần khởi động lại. Tôi muốn có điều tương tự với ngôn ngữ Scala.

P.S. Tôi muốn thảo luận về ngôn ngữ nào tốt hơn cũng như không lập trình chức năng tốt hơn ngôn ngữ hướng đối tượng. Tôi muốn tìm một giải pháp tốt. Nếu Clojure là ngôn ngữ tốt hơn cho nhiệm vụ, hãy để nó được.

+2

Được sử dụng để viết Clojure, người còn lại viết Scala. Ngoài ra: http://stackoverflow.com/questions/2471947/is-there-an-easy-way-to-get-the-scala-repl-to-reload-a-class-or-package – vptheron

+0

Hơi khó để tôi biết câu trả lời đúng sẽ như thế nào? Bạn có thể hỏi nếu Scala REPL có thể xác định lại các chức năng trong một chương trình đang chạy không? –

+0

Sự tò mò, câu hỏi là tốt, nhưng tiêu đề thì không. – Mars

Trả lời

18

Câu trả lời ngắn gọn là Clojure được thiết kế để sử dụng trình biên dịch một lần rất đơn giản, đọc và biên dịch một biểu thức hoặc biểu mẫu duy nhất tại một thời điểm. Đối với tốt hơn hoặc tồi tệ hơn không có thông tin kiểu toàn cục, không có suy luận kiểu toàn cục và không có phân tích hoặc tối ưu toàn cầu. Clojure sử dụng các trường hợp clojure.lang.Var để tạo các liên kết toàn cầu thông qua một loạt các hashmaps từ các ký hiệu văn bản đến các giá trị giao dịch. def tạo tất cả các ràng buộc tạo ra phạm vi toàn cầu trong bản đồ ràng buộc toàn cầu này. Vì vậy, trong Scala một "hàm" (phương pháp) sẽ được giải quyết cho một cá thể hoặc phương thức tĩnh trên một lớp JVM cụ thể, trong Clojure, một "hàm" (def) thực sự chỉ là một tham chiếu đến một mục trong bảng kết buộc var. Khi một hàm được gọi, không có một liên kết tĩnh đến một lớp khác, thay vì var là tham chiếu theo tên biểu tượng, sau đó dereferenced để có được một thể hiện của một đối tượng clojure.lang.IFn mà sau đó được gọi.

Lớp gián tiếp này có nghĩa là có thể đánh giá lại chỉ một định nghĩa duy nhất tại một thời điểm và việc đánh giá lại trở nên rõ ràng cho tất cả các khách hàng của var được xác định lại.

Để so sánh, khi định nghĩa trong thay đổi Scala, scalac phải tải lại tệp đã thay đổi, macroexpand, nhập infer, gõ check và biên dịch. Sau đó, do ngữ nghĩa của việc nạp lớp trên JVM, scalac cũng phải tải lại tất cả các lớp phụ thuộc vào các phương thức trong lớp đã thay đổi. Ngoài ra tất cả các giá trị là trường hợp của lớp đã thay đổi trở thành thùng rác.

Cả hai phương pháp đều có điểm mạnh và điểm yếu. Rõ ràng cách tiếp cận của Clojure đơn giản hơn để thực hiện, tuy nhiên nó trả một chi phí liên tục về hiệu suất do các hoạt động tra cứu chức năng liên tục quên các mối quan tâm chính xác do thiếu các loại tĩnh và những gì có bạn. Điều này được cho là thích hợp cho các bối cảnh trong đó nhiều thay đổi đang diễn ra trong một khung thời gian ngắn (phát triển tương tác) nhưng ít phù hợp hơn với ngữ cảnh khi mã chủ yếu là tĩnh (triển khai, do đó Oxcart). some work I did gợi ý rằng sự chậm chạp của các chương trình Clojure do thiếu liên kết phương pháp tĩnh là theo thứ tự từ 16-25%. Đây không phải là để gọi Clojure chậm hoặc Scala nhanh, họ chỉ có những ưu tiên khác nhau. Scala chọn làm nhiều công việc hơn để ứng dụng được biên dịch sẽ hoạt động tốt hơn, được cho là phù hợp hơn cho triển khai ứng dụng khi ít hoặc không tải lại sẽ diễn ra, nhưng chứng tỏ sự kéo khi bạn muốn thực hiện nhiều thay đổi nhỏ .

Một số tài liệu tôi có trong tay về việc biên dịch mã Clojure nhiều hay ít theo thứ tự thời gian theo thứ tự xuất bản vì Nicholas ảnh hưởng đến GSoC của tôi rất nhiều.

Mà tôi cho rằng lá tôi trong nơi không hài lòng khi nói đơn giản "Tôi xin lỗi, Scala không được thiết kế cho cách C Lojure là "liên quan đến trao đổi mã nóng.

+1

Gilad Bracha và các ngôi sao sáng khác từ thế giới Smalltalk và Lisp có câu thần chú này là "Các kiểu tĩnh là khớp nối", và đây là một ví dụ khác về điều đó. Đó là - ít nhất với kiến ​​thức hiện tại của chúng ta - đơn giản là không thể thực hiện môi trường sống động cho một ngôn ngữ tĩnh, trong khi các ngôn ngữ động có môi trường sống động * cực kỳ mạnh mẽ, hãy xem máy MIT Lisp, Squeak/Pharo Smalltalk , Báo chí, hạt nhân sống động của Dan Ingall hoặc tự thế giới. –

+0

Cảm ơn tất cả các bạn rất nhiều! – Curiosity

+0

@ JörgWMittag Nó luôn luôn là một sự cân bằng giữa năng động và được kiểm tra tĩnh. Đôi khi bạn muốn một, đôi khi bạn muốn khác. Tôi có xu hướng dựa vào phía gõ tĩnh - chủ yếu là vì tôi đã nhìn thấy khá một vài lỗi xảy ra ngay cả trong Java vì hệ thống kiểu của nó quá khoan dung. Đó không phải là để loại bỏ những lợi thế của đánh máy năng động, đối với tôi những lợi thế của gõ tĩnh chỉ đơn giản là cân nhắc nhiều hơn. YMMV – Cubic

Các vấn đề liên quan