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.

I am trying to make a function with an optional argument that may change but mathematica caches the value when the function is defined.

Here is an example where the optional time variable is set when the function is defined.

Remove[CurrentTime]
CurrentTime[time_: DateList[]] := {time, DateList[]};
Pause[1]
CurrentTime[]

The output is split by 1 second

{{2013, 6, 4, 13, 57, 46.149504}, {2013, 6, 4, 13, 57, 47.150726}}

Is there a way to tell it its a delayed set, or to just read the function each time?

share|improve this question
    
...what sort of behavior were you expecting? –  J. M. Jun 4 '13 at 4:34
    
I want the time argument to default to the current time in this case, ie, they should show the same time. –  Richard Jun 4 '13 at 4:40
    
Well, the problem is that you're effectively evaluating {DateList[], DateList[]}; it stands to reason that some amount of time should have to pass in between the two times you call DateList[]... –  J. M. Jun 4 '13 at 4:45
    
That is by design to illustrate the problem, there is a pause of 1 second to show that the default value for time is set once and never changed. I would like to make a function in which you can pass in the time, but if you dont it defaults to the current time. –  Richard Jun 4 '13 at 4:49
    
Well, you might be interested in CurrentTime[OptionsPattern[{"Time" :> DateList[]}]] := {OptionValue["Time"], DateList[]}. One could either do CurrentTime[] or CurrentTime["Time" -> {2013, 6, 4, 12, 0, 0}]... –  J. M. Jun 4 '13 at 4:52
show 1 more comment

1 Answer

CurrentTime[time_: Hold[DateList[]]] := {ReleaseHold@time, DateList[]};
Pause[1]
CurrentTime[]

{{2013, 6, 4, 8, 29, 34.8437500}, {2013, 6, 4, 8, 29, 34.8437500}}

Edit

This works too:

Remove[CurrentTime]
SetAttributes[CurrentTime, HoldAll]
CurrentTime[time_: DateList[]] := {time, DateList[]};
share|improve this answer
    
Ah, it was the Attributes[]... I do think your second solution is much better than the first. –  J. M. Jun 4 '13 at 6:42
    
@0x4A4D It is more elegant but if, for example, You have 3 arguments with Hold and 4 without and only HoldAll, HoldRest, HoldFirst Attributes avalible then the first is useful. –  Kuba Jun 4 '13 at 6:49
add comment

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.