# Tag Info

## Hot answers tagged meta-programming

93

What this answer is and is not To avoid some confusion and misunderstanding, let me state right away what is the intended status of this answer. This answer is not A tutorial to the subject A systematic, or complete, introduction to the subject An authoritative answer putting the final word on the subject This answer hopefully is An (subjective!) ...

31

Use pure functions (Function) and "InlineExternalDefinitions" -> True: g = #^2 &; f = # + 1 &; compiledFunction = Compile[{{x, _Real, 0}}, f@g[x], CompilationOptions -> {"InlineExternalDefinitions" -> True}]; CompilePrint[compiledFunction] 1 argument 1 Integer register 4 Real registers Underflow ...

27

Yes there is a way to use functions that use external non compiled functions. It uses the step function of Mr.Wizard defined in the post How do I evaluate only one step of an expression?, in order to recursively expand the code that we want to compile until it uses only functions that Mathematica can compile. The technique discussed in the post How to ...

20

There are a lot of commands! One way to get a list is to use Name["*"], which will return all the symbols Mathematica knows. Since commands start with capital letters, you can gain more control over the list by asking for only a subset. For example, all = {"A*", "B*", "C*"}; Names[#] & /@ all provides a list of all commands that start with A, B, or C....

18

This is a tricky case indeed, because what you basically ask for is compile-time evaluation (macro-style). Generally, the answer is to use meta-programming, to assemble the compiled expression at run-time. The reason your attempt did not work is that the expression you want to evaluate is too deep for Evaluate to be effective. Solution using in-place ...

18

That's an interesting first question. Welcome. :-) From a simplistic perspective this should work, but as you observe there are evaluation properties that are more complex. Here is a reference for most (but not all) behavior: The Standard Evaluation Sequence Let's follow those steps for your example. Heads are evaluated first Evaluate the head h of ...

18

The trick is thinking about list structural operations, not indexes like you would do in common procedural languages. The following does the same as your code, but is terser and easier to follow lint = {3, 2, 2}; lx = {a, b, c}; idx = Tuples[Range[0, #] & /@ lint]; dd = BIF[p[#][lx (1 - Unitize[lint - #])], Transpose@{lx, lint - #}] & /@ idx /...

17

Implementation The following implementation is based on expression serialization and SequenceAlignment built-in function. The idea is to break expressions into constituent parts, then align these part sequences, and then determine the positions where the expressions are different. The auxiliary heads we will need are inert heads diff and myHold, the latter ...

14

Ok, what you have here is some classic example of what is called "Evaluation leaks". So, first, the corrected code: ClearAll[capture] SetAttributes[capture, HoldAllComplete]; capture[expr_ /; AtomQ[Unevaluated[expr]]] := {Head[Unevaluated[expr]], expr}; capture[head_[args___]] := {head, capture /@ Unevaluated[{args}]}; Now, you can inspect it and ...

14

Here I offer the safe version of Get that can be used successively to collect all the source files and contexts of packages without polluting the memory (too much). What it does I have practically reverse-engineered all the necessary functions (Get, Needs, BeginPackage, Begin, EndPackage and End) so that I could inject the monitoring code for introspection....

13

I am not really familiar with LISP macros but from what little I think I know these do not appear to be strongly related. Rather they appear to be utility functions for function authors; it seems that a number of recently added internal top-level definitions use them. Some of them clearly do use meta-programming type expansions so perhaps they are closer ...

12

Your situation can be solved by Evaluate. According to the documentation of Compile You can use Compile[...,Evaluate[expr]] to specify that expr should be evaluated symbolically before compilation. F[x_] := x + 2; G[x_] := x; ff = Compile[{x}, Evaluate@F[G[x]]]; <<CompiledFunctionTools CompilePrint@ff result 1 argument 1 ...

12

Get the full list of Mathematica functions here: myFunctionList = Import["http://reference.wolfram.com/language/guide/\ AlphabeticalListing.html"]; Strip the list of header and footer material, and select a random element: RandomChoice[StringSplit[StringTake[myFunctionList, {3245, -1225}]]] Or, based on the approach of bill s: RandomChoice@Flatten[...

11

If your definitions are exactly like you show, every time, you can use belisarius's method, slightly refined: g[x_Integer] := x + 1 g[s_String] := s <> "!!!" (DownValues@g)[[All, 1, 1, 1, 2, 1]] {Integer, String} However this is fragile in that it will fail if your definitions are different, e.g.: g[r_ /; Head[r] === Real] := r + Pi g[a_List?...

11

You may already have discovered that something like g[#]& doesn't work - this is because Function has the HoldAll Attribute, so its argument (g[#] in this case) doesn't get evaluated. The solution is to force g[#] to evaluate. Rasher showed what one way to do that, by using Evaluate, whose specific purpose is to force evaluation of arguments that would ...

10

Here is a functional approach: Narciss[x_] := With[{num = IntegerDigits[x]}, Total[num^Length[num]] == x] Here is a compiled version of the above function: NarcissC = Compile[{{x, _Integer}}, With[{num = IntegerDigits[x]}, Total[num^Length[num]] == x], Parallelization -> True, CompilationTarget -> "C", RuntimeAttributes -> Listable, ...

10

With this helper function: SetAttributes[partThread, HoldAll]; partThread[l___, rhs_] := Join @@ Replace[ MapIndexed[Append[#, First@#2] &, Thread[Hold[{l}]]], Hold[s_, i_] :> Hold[s = rhs[[i]]], {1}]; The following modification of LetL seems to work according to your specs: ClearAll[Let, let]; SetAttributes[{Let, let}, HoldAll]; ...

9

Not an answer per se, but two clarifications (which are too long for the comment box): 1) The Wiki definition you have linked to for a narcissistic number is not really apt. The Wiki page is actually describing the definition for an Armstrong Number, also known as pluperfect digital invariants, or m-narcissistic numbers, such as: $$407 = 4^3 + 0^3 + 7^3$$ ...

9

Here's a piece of code that lets you see random Wolfram Language code snippets, rather than just command names. RandomExample[] := Module[{dir, file, inputs, output, cap, i = 0, j = 1, in}, dir = DirectoryName[FindFile["ExamplePages/CreateMolecularGraphs.nb"]]; file = RandomChoice[FileNames["*", dir]]; output = Import[file, {"Cells", "Output"}][[...

8

Please be gentle with me - this is my first ever post to stackexchange. Firstly, I'd like to say that I found Faysal's post both fascinating and outstandingly useful (I would upvote it if I could, but I have insufficient reputation). It introduces techniques I'm sure I shall use a great deal. However, it doesn't, quite, cater for all use cases. Where a ...

8

Ad Hoc Programming: Notebooks It is very common for programming problems to be solved completely without leaving the confines of a single notebook. A notebook can contain any combination of function definitions and expressions that use those functions. See, for example, the Function Definitions section of the Fast Introduction For Programmers. The nicest ...

8

ClearAll[ruleToFunction, f1, f2]; ruleToFunction[func_] := Function[, Evaluate@func[Slot[1]]]; g[x_] := Piecewise[{{0, x < 8.}, {2.5, 8. <= x < 18}, {0, x > 18}}] f1 = ruleToFunction[g] ClearAll[g]; f1@10 f[x_] := x Sin[x^2] f2 = ruleToFunction[f] ClearAll[f]; f2@10

7

If you can convert expressions to text form, there's a possible answer here. I sometimes use it to compare notebooks: notebook1 = StringJoin[ Import["/tmp/freaky-illusion.nb", "Plaintext"]]; notebook2 = StringJoin[ Import["/tmp/freaky-illusion-1.nb", "Plaintext"]]; SystemDump`showStringDiff[notebook1, notebook2]

7

I'm not sure what you're trying to do here and most probably Nasser's admonition rings true, but perhaps you want something like this?: Do[ CellPrint @ Cell[BoxData[RowBox[{RowBox[{"r", "[", i, "]"}], "="}]], "Input"], {i, 5} ] Alternatively you might make use of \[Placeholder] and Defer: Do[CellPrint @ ExpressionCell[Defer[r[#] = \[Placeholder]], "...

7

This also works: getHeads[g_] := DownValues[g][[All, 1, 1, 1]] /. Verbatim[Pattern][_, k_] :> k[[1]] Then: getHeads[g] {Integer, String}

6

I'm not to present any thorough analysis if metaprogramming is viable, but I could give a hint towards this issue. I don't think there is any fundamental barrier for metaprogramming in Mathematica, but I doubt we could develop this way anything really powerful. To point out a practical obstacle (though by any means not a no-go theorem) I suggest to take a ...

6

nar[m_] := ToExpression[ "Compile[{\$},Do[With[{n=0" <> StringJoin[ Table["+1" <> Array["0" &, m - 1 - i, 1, StringJoin] <> "a" <> ToString[m - 1 - i], {i, 0, m - 1}]] <> ",n2=0" <> Table["+a" <> ToString[m - 1 - i] <> "^" <> ToString[m], {i, 0, m - 1}] <> "},...

6

The only official information about the Macro functions I am aware of can be found in a short segment in this presentation, which describes the "Macro System" as an essential part of the next compiler generation. However, the CreateMExpr shown there isn't included in Mathematica 10.4.1. (But maybe someone can find parts of it digging deeper into it?) ...

5

Dynamically generated Do loops:) cnar = With[{n = 7}, With[{var = Array[Unique["x"] &, n]}, With[{n1 = FromDigits@var, n2 = Total[var^n]}, Compile[{Null}, Do[If[n1 == n2, Sow@n1], ##], RuntimeOptions -> "Speed", CompilationTarget -> "C" ] & @@ MapAt[1 &, Thread[{var, 0, 9}], {1, 2}] ] ] ]; ...

5

From a cold start, I would have written it like this: findNarc = Compile[{{stop, _Integer}, {pow, _Integer}}, Do[ If[Total[IntegerDigits[n]^pow] == n, Sow[n]] , {n, 1, stop} ] , RuntimeOptions -> "Speed", CompilationTarget -> "C"]; However, it is slower than your function (which takes 0.326 seconds on my machine) Reap[findNarc[...

Only top voted, non community-wiki answers of a minimum length are eligible