Điều bạn yêu cầu là khó khăn. Đây là một công việc cho các macro, như đã được những người khác tiếp xúc. Tôi sẽ khám phá một khả năng khác nhau - để sử dụng các biểu tượng giống nhau nhưng đặt một số hàm bao quanh mã bạn muốn viết. Ưu điểm của kỹ thuật này là mã được chuyển đổi "lexically" và tại "compile-time", thay vì ở thời gian chạy (như trong các câu trả lời khác). Điều này thường nhanh hơn và dễ gỡ lỗi hơn.
Vì vậy, đây là một chức năng mà sẽ chuyển đổi With
với cú pháp đề xuất của bạn:
Clear[expandWith];
expandWith[heldCode_Hold] :=
Module[{with},
heldCode /. With -> with //. {
HoldPattern[with[{{} = {}, rest___}, body_]] :>
with[{rest}, body],
HoldPattern[
with[{
Set[{var_Symbol, otherVars___Symbol}, {val_, otherVals___}], rest___},
body_]] :>
with[{{otherVars} = {otherVals}, var = val, rest}, body]
} /. with -> With]
Lưu ý rằng điều này hoạt động trên mã được tổ chức. Điều này có lợi thế là chúng ta không phải lo lắng về việc đánh giá khả thi o mã không phải lúc đầu hoặc khi expandWith
hoàn tất. Dưới đây là cách hoạt động:
In[46]:= [email protected][With[{{x1,x2,x3}={a,b,c}},x+x1+x2+x3]]
Out[46]= Hold[With[{x3=c,x2=b,x1=a},x+x1+x2+x3]]
Điều này, tuy nhiên, không thuận tiện khi sử dụng.Đây là một chức năng thuận tiện để đơn giản hóa này:
ew = Function[code, [email protected]@[email protected], HoldAll]
Chúng ta có thể sử dụng nó bây giờ như:
In[47]:= [email protected][{{x1,x2}={a,b}},x+x1+x2]
Out[47]= a+b+x
Vì vậy, để thực hiện việc mở rộng xảy ra trong các mã, chỉ cần quấn ew
xung quanh nó. Đây là trường hợp của bạn cho định nghĩa của hàm:
Remove[f];
ew[f[x_] := With[{{x1, x2} = {a, b}}, x + x1 + x2]]
Bây giờ chúng ta kiểm tra và thấy rằng những gì chúng ta nhận được là một định nghĩa mở rộng:
?f
Global`f
f[x_]:=With[{x2=b,x1=a},x+x1+x2]
Ưu điểm của phương pháp này là bạn có thể quấn ew
xung quanh một tùy ý đoạn mã lớn của bạn. Điều gì xảy ra là đầu tiên, mã mở rộng được tạo ra từ nó, như thể bạn sẽ tự viết nó, và sau đó mã đó được thực hiện. Đối với trường hợp các định nghĩa của hàm, như là f
ở trên, chúng ta có thể tin rằng việc tạo mã xảy ra tại "thời gian biên dịch", vì vậy bạn tránh được bất kỳ thời gian chạy nào khi sử dụng hàm này sau này, có thể đáng kể nếu hàm này được gọi thường xuyên.
Một ưu điểm khác của phương pháp này là tính tương thích của nó: bạn có thể đưa ra nhiều cú pháp mở rộng, và cho mỗi người trong số họ viết một hàm tương tự như ew
. Sau đó, với điều kiện các hàm chuyển đổi mã tùy chỉnh này không giao dịch với nhau, bạn có thể chỉ cần soạn (lồng) chúng, để có được hiệu ứng tích lũy. Theo cách này, bạn tạo một trình tạo mã tùy chỉnh để tạo ra mã Mathematica hợp lệ từ một số biểu thức Mathematica biểu diễn các chương trình trong sự hao mòn tùy chỉnh của bạn, mà bạn có thể tạo trong Mathematica bằng các phương tiện này.
EDIT
Trong văn bản expandWith
, tôi sử dụng ứng dụng quy tắc lặp đi lặp lại để tránh đối phó với sự kiểm soát đánh giá, có thể là một mớ hỗn độn. Tuy nhiên, đối với những người quan tâm, đây là một phiên bản thực hiện một số công việc rõ ràng với các đoạn mã chưa được đánh giá.
Clear[expandWithAlt];
expandWithAlt[heldCode_Hold] :=
Module[{myHold},
SetAttributes[myHold, HoldAll];
heldCode //. HoldPattern[With[{Set[{vars__}, {vals__}]}, body_]] :>
With[{eval =
(Thread[Unevaluated[Hold[vars] = Hold[vals]], Hold] /.
Hold[decl___] :> myHold[With[{decl}, body]])},
eval /; True] //. myHold[x_] :> x]
Tôi thấy nó phức tạp hơn nhiều so với lần đầu tiên.
Tôi thường cân nhắc các lựa chọn thiết kế như vậy và thỉnh thoảng tôi đăng các câu hỏi như vậy ở đây. Thật không may, hiếm khi những điều đó được giải thích. Tôi đã tự bào chữa với thực tế là With/Block/Module chỉ hoạt động khác nhau và 'Set' trong đối số đầu tiên không thực sự thực hiện thao tác' Set' nhưng thay vào đó là cú pháp. –
Từ việc đọc tài liệu thông báo lỗi (phần được trích dẫn ở cuối Q), có vẻ như tôi có một số mẫu đơn giản khớp với hành vi hiện tại --- nghĩa là chấp nhận các mẫu có Danh sách đầu, chứa chỉ các phần tử đánh giá thành True cho một thứ như MatchQ [Giữ [Set [x, 1]], Giữ [Đặt [Symbol_, _]]]. Nếu đây là trường hợp, ít nhất là trong thế giới nhỏ cận thị của tôi, dường như có thể tinh chỉnh mô hình phù hợp/thử nghiệm để cho phép hành vi tôi tìm kiếm, và tài liệu trên Set dường như ngụ ý sẽ hoạt động (dưới dạng biểu mẫu hợp lệ của bài tập). – telefunkenvf14
Tôi không đồng ý, nhưng tôi biết không có cách nào để thực hiện thay đổi đó. –