Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

It is possible to define my own With construct where each local constant can depend on the previous defined local constants?

I wish to replace something like this

With[{m=10},
  With[{h=1/m},
    Table[{i h}, {i, 0, m}]
  ]
]

with something like this

WithMany[{m=10, h=1/m},
    Table[{i h}, {i, 0, m}]
]

The very basic idea is to use Fold:

Attributes[WithMany] := {HoldAll};
WithMany[{vars___}, body_] := Fold[With[{#2}, #1] &, body, {vars}]

but we need to properly evaluate the argumens in a non-standard way, possibly using Hold and related constructs. I'm not so fluent with this.

An improvement would be to use the minimum number of With constructs depending on the dependencies between variables.

Any help will be appreciated.

EDIT As several people pointed out the original question has already been answered. This solve my immediate needs but I'm still interested to other implementation.

@Leonid Shifrin think the referred answer already use the best approach, the simplest, the most elegant, the most efficient and so, but, even if true, I consider an interesting programming exercise to try different approach, like the one in my original question, using functional programming and Fold

The sketch of a possible implementation is the following:

Attributes[WithMany] := {HoldAll};
WithMany[vars : {__}, body_] :=
 Block[{With},
  Attributes[With] = {HoldAll};
  ReleaseHold@Fold[
    With[{#2}, #1] &,
    Hold[body],
    Reverse@Thread@Hold@vars
    ]
  ]

I don't understand if there is some limit or issue with this implementation, or if it is fully equivalent to the one in the referred answer and to nested With costruct (after adding Syntax coloring and handling SetDelayed)?

At a first sight I like more my approach (if it works properly of course) and I think is cleaner. It also appears slightly faster, according to some very basic tests. But I recognize that some people might prefer a different approach.

share|improve this question
    
I don't fully understand the referred answer, but, apparently we make use of a recursive definition. There is a way to avoid and make a one-time direct replacement? –  unlikely Jul 2 at 16:52
1  
Yes, there is, but this will be less natural / harder / less elegant. Since the resulting code expansion is a nested With, recursion is IMO the most natural road to proceed here. –  Leonid Shifrin Jul 2 at 16:55
    
Fold is a construct for implementing recursion without the need of spreading the definition of a construct across multiple rules. IMO, if usable here, is better. So I edited the question to investigate this approach... –  unlikely Jul 2 at 22:57
1  
This is not a simple recursion, it is combined with evaluation control. In other words, it is recursive code generation, and you have to think about evaluation. I see absolutely no advantage in using Fold here, but at the point where you start being interested not in just having a solution to the problem, but having it in a specific way, it all becomes speculative. So, in this new formulation I'd consider this either opinion-based, or too narrow. Technically, I don't see here anything deeper than just another exercise in evaluation control. But may be I am wrong. Let's see what others think. –  Leonid Shifrin Jul 2 at 23:03
    
Also, technically, Fold does not implement recursion. It actually does the opposite - it kills it, for a rather small subset of all cases where recursion can be used. There are lots of more complex cases where recursion can not be reduced to Fold. And I personally view recursion cleaner and more idiomatic, in lots of cases. And, as I said, strictly more powerful than Fold. This is not to say that I don't appreciate Fold - if you look at the code I posted on this site, you'll see that I use Fold rather frequently. –  Leonid Shifrin Jul 2 at 23:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.