# Changing DownValues of a function when calling

## General problem

I am looking for a possibility to store information in parallel for a function and change the information when a function is called.

## Idea

It seems possible to solve this problem by using DownValues of a function. Imagine I use

makeFileCache[stream_, cacheSize_] := fileCache[OpenRead[stream], cacheSize];
fileCache[stream_, cacheSize_]["Size"] := cacheSize;
fileCache[stream_, cacheSize_][newCacheSize_]:= ???;
f = makeFileCache[STREAM, 12]; (* use arbitrary STREAM here. *)


This way I could for example

f["Size"]


in order to get the DownValue of the cache size. But is there a possibility to set it directly when calling? I know it is possible to manipulate it directly, this is not what I ask for. I look for a possibility to replace the question marks and directly work on the function f and change its underlying parameters.

As I didn't know what exactly to look for it might be possible (and probable) that this question is a duplicate. Hints are appreciated.

• I'm not sure exactly what you mean. Do you mean you want to call f[n_] and have that reset the cache size? Also have you seen Associations? They were introduced in 10.0 and will probably make your life easier. – b3m2a1 Mar 14 '17 at 20:00

So if I understand you correctly, you want f to work in an oop like manner. There are a few things you could do here. One if go full OOP:

$cacheStore = <||>; makeFileCache[stream_, cacheSize_] := With[{fcUUID = CreateUUID["FileCache-"]},$cacheStore[fcUUID] = <|
"Size" -> cacheSize,
|>;
fileCache[fcUUID]
];

fileCache[uuid_]["Size"] :=
$cacheStore[uuid, "Size"]; fileCache[uuid_]["Stream"] :=$cacheStore[uuid, "Stream"];
fileCache[uuid_][
newCacheSize_Integer] :=
($cacheStore[uuid, "Stream"] = newCacheSize);  But this is overkill and you'll have to clear that $cacheStore yourself.

Cleanest is probably a setCacheSize function:

setCacheSize[fileCache[stream_, size_], newsize_] :=

fileCache[stream, newsize];
setCacheSize[s_Symbol?(MatchQ[_fileCache]), size_] :=

s = fileCache[First@s, size];
setCacheSize~SetAttributes~HoldFirst;


These are the two most reasonable routes, I think, but obviously I could be wrong. There's a universe of stuff discussing object-oriented programming in Mathematica. See for instance the first two results I got by searching for "OOP" How can I implement object oriented programming in Mathematica?, Struct equivalent in Mathematica?, and then for completeness there's this: Which Object-oriented paradigm approach to use in Mathematica?

• This is indeed exactly what I was looking for. Sometimes Mathematica's way of thinking drives me crazy coming from other languages. Thanks a lot :-) – pbx Mar 14 '17 at 21:40
• It's a lot to get a handle on if you're an oop person, like I am. But the language is powerful and the unified symbolic nature of the language is actually a real pleasure once you get a handle on it. In any case I'm hoping real(ish) OOP framework built on a UUIDs and Associations will make it into the language at some point. I doubt it though. – b3m2a1 Mar 14 '17 at 21:43