# Elegant transformation of various rules to strings, {f[z_] -> y} becomes “f = @(z) y”

Assume that I have some function for transformation mathematica expressions to strings. For simplicity, just assume it is an identity:

mytostring[e_] := ToString[e]; (* In reality, much more complicated... *)


What I want to take various permutations of variadic rules syntax and apply this function to create a string for the function. e.g. assume my basic test is:

rulestostring[rule_????] := ???
testrules = {f[x,y] -> x, f[x_,y_] -> x, f[x,y] :> x, f[x_,y_] :> x};

(* Create a function rulestostring where all of these give the same output as a string:
==>    "f = @(x,y) x"
Where the f is actually generated from mytostring[f], x is from mytostring[x], etc.
*)


I need it to support variadic arguments and a few other things:

otherrules = {f[x_] -> x, f[x[bar]] -> x[bar]};
(* ==>   {"f = @(x) x", "f = @(x[bar]) x[bar]"
where in reality both x[bar] would be transformed by mytostring
*)


(you can probably guess that what I am doing is extending the http://library.wolfram.com/infocenter/MathSource/577/ package to generate matlab functions. If anyone has an updated version of this package it would be appreciated)

-
What is your end goal? To just convert to MATLAB expressions or to actually be able to inter-operate between MATLAB and Mathematica? – R. M. Sep 27 '13 at 3:08
I want to generate functions that can be used in matlab (copy-paste). – jlperla Sep 27 '13 at 5:05
I read your question a second time after posting my answer. I think I'm missing something regarding mytostring. What is mytostring supposed to do? – Mr.Wizard Sep 27 '13 at 8:15

ruleToString[(Rule | RuleDelayed)[h_[a__], rhs_]] :=
ToString @ Row[{h, " = @(", Row[{a} /. Pattern -> (# &), ","], ") ", rhs}]


Test:

ruleToString /@ testrules // Union

{"f = @(x,y) x"}

ruleToString /@ otherrules

{"f = @(x) x", "f = @(x[bar]) x[bar]"}


Based on communication in comments I propose this as a more complete solution:

Options[ruleToString] = {Format -> mytostring};

ruleToString[(Rule | RuleDelayed)[h_[a__], rhs_], OptionsPattern[]] :=
With[{fn = OptionValue[Format]},
ToString@Row[{fn@h, " = @(", Row[fn /@ ({a} /. Pattern -> (# &)), ","], ") ", fn@rhs}]
]


You can then change the function that is used to convert elements by using SetOptions, or by providing the option Format -> function directly in ruleToString.

-
Thank you, this seems very close. mytostring will actually be the ToMatlab function that walks the expression tree to generate a matlab expression from that package I referenced, I just wanted to set things up in a minimal way. For now, lets set: mytostring[e_] := "_" <> ToString[e]; just so we can see that a transform has been applied. – jlperla Sep 27 '13 at 16:30
With that def of mytostring, when I change your function to be: ruleToString[(Rule | RuleDelayed)[h_[a__], rhs_]] := ToString@Row[{mytostring[h], " = @(", Row[mytostring /@ {a} /. Pattern -> (# &), ","], ") ", mytostring[rhs]}]; it seems to do what I want? – jlperla Sep 27 '13 at 16:33
@jlperla Yes, that should do it if I understand your requirement. You may want to do the Pattern replacement before mapping mytostring, i.e.: Row[mytostring /@ ({a} /. Pattern -> (# &)), ","] but it's hard to say without seeing the function proper. – Mr.Wizard Sep 27 '13 at 17:15
@mr-wizard Thanks, I believe that is preferable and completes my requirements. Consider editing your answer if you think it is more complete. – jlperla Sep 27 '13 at 17:26
Also, how do you copy/paste in the output from mathematica into SE? as you did above? – jlperla Sep 27 '13 at 17:27