Monday 28 November 2011

Functional composition, fluent programming and command line processing

We have a very repetitive and, to me, offensive piece of code which appears in several places throughout the codebase. The only variation between instances are the names of the parameters and the decision about which ones are mandatory. So I wrote some nice simple, functional code to do the heavy lifting, and now it's a one-liner, more or less!

            string defaultDate = DateTime.Today.ToShortDateString();
            const string defaultCheckType = "pnl";
            
            Dictionary<string, string> mandatoryArgs = Functional.array.toDict(new string[] { "filedir" });
            Dictionary<string, string> optionalArgs = Functional.array.toDict(new string[] {"interfaces", "filename", "reportingdate", "check"},
                                                                              new string[] { string.Empty, string.Empty, defaultDate, defaultCheckType });

            bool result = args > SplitArgsInto(mandatoryArgs, optionalArgs).Then(Validate(mandatoryArgs));

            return new Arguments(mandatoryArgs["filedir"], 
                                    optionalArgs["filename"],
                                    DateTime.ParseExact(optionalArgs["reportingdate"], "dd/MM/yyyy", CultureInfo.InvariantCulture),
                                    (CheckTypeEnum) Enum.Parse(typeof (CheckTypeEnum), optionalArgs["check"]), 
                                    optionalArgs["interfaces"]);

Lovely! Now the arguments are split into mandatory and optional, the mandatory arguments have all been validated and the program receives by return a structure containing the names and values that are relevant. Smashing!

In case you were wondering, the functional composition is hidden in the Then function, which is actually the composition operator in C# land. It takes Func<A,B>, Func<B,C> and returns Func<A,C>.

Tuesday 25 October 2011

F# - Active patterns

I like active patterns. I have yet to explore their possibilities completely but one pattern which crops up all the time in our code is checking whether a string is empty and acting accordingly.

In C# we have

if(!String.IsNullOrEmpty(myString))
{
    doSomethingWithTheString(myString);
}
else
{
    doSomethingInNullCase();
}

Clearly, the
doSomething...()
methods will usually be more than a simple procedure, often involving local variables and transformations thereof, but the essence of the pattern is captured above.

We could, of course, transliterate this directly into F# and that is the first step in the conversion process. Thus we have

if(not <| String.IsNullOrEmpty myString) then
    doSomethingWithTheString(myString)
else
    doSomethingInNullCase()

So what? I hear you say. Well, this is a step in the right direction. Functional programmers prefer pattern matching to indiscriminate use of the
if
statement though. The question, therefore, is what pattern can we match to achieve the end and how. Crucially, in F# one cannot match against a general function. Instead one uses what is known as an Active Pattern. There are three forms of Active Patterns: single-valued, partial and multi-valued. The names are mine but they are similar to the official names. I think of 'partial' active patterns as slightly different from the other two.

First, a single-valued active pattern:
let (|EmptyString|) str = String.IsNullOrEmpty str

which could be used in this manner:

match myString with | EmptyString true -> "Empty" | _ -> "Not empty"

I think the syntax for active patterns leaves a little to be desired so let me explain what is happening here. Clearly the match is being performed on
myString
. The match criterion first considered is
EmptyString
. All bar the final parameter (in this case, there are no additional parameters in the match criterion) are evaluated in the context of
myString
. The final parameter in the matching pattern is compared with the return value of the active pattern. In other words, the criterion is
EmptyString myString
which returns a
bool
against which we match
true
.

A multi-valued pattern is similar. For example:

let (|EmptyString|String|) str =
    if String.IsNullOrEmpty str then EmptyString else String(str)

Notice that this pattern looks much more like a discriminated union. Also, whilst it is not necessary to return a value in the 'constructor', if you will, in either case, we do so here for illustrative purposes. This pattern could be used as follows:

match String.Format("Is {0} empty?", myString) with
| EmptyString -> "It's empty"
| String str -> str

Thus
str
holds the string that was successfully matched.

Partial active patterns are a slight change again:

let (|NotEmpty|_|) s = if String.IsNullOrEmpty s then None else Some(s)

Note that I have changed the specified portion of the pattern to
NotEmpty
so that we can return the string that was matched successfully. Note also that this pattern returns an
option
type where the multi-valued pattern returns a
Choice
.

The partial pattern is used similarly:

match String.Format("Is {0} empty?", myString) with
| NotEmpty str -> str
| _ -> "It's empty"

As you can see, the construct is powerful and I haven't demonstrated how to pass additional parameters or match multiple values. Check Wikibooks for further information and then try the broader t'internet.

Friday 14 October 2011

Reflection - the perils

I've been struggling with Reflection. I want to create an object from a dynamically loaded assembly. In general, this is a simple problem. Just use Type.InvokeMember, easy!

However, the problem comes when the constructor does other stuff, particularly when it loads yet more objects by reflection from dynamically loaded libraries. When it doesn't work, it can be really difficult to diagnose.

The upshot of this is that it would be so much better if the constuctor did the minimum amount and all the initialisation came later, once the object had been created etc.

Just a thought.

Wednesday 12 October 2011

Creating a class with multiple constructors in F#

Using the implicit type syntax couldn't be easier. For example:


type A (a,b) as this =
let c = "sum"
do printfn "The sum is " (a+b)


Easy! But class A only has one constructor. Suppose we want another? The obvious guess would be


type B (a,b) as this =
let c = "sum"
do printfn "The sum is " (a+b)
new (d) = B(a,0)


but this doesn't work for a number of reasons. You can't have let or do sections in your type if you have multiple constructors. So this means that a, b and c have to be defined in the new function. This means, of course, that you need to use explicit class syntax. The action can then follow the initialisation in a then clause.


type C =
val a :float
val b :int
val c :string
new (_a,_b) = { a=_a; b=_b; c="sum"} then printfn "The sum is " (a+(float b))
new (_a) = { a=_a; b=0; (* Yes, you have to initialise all the class members *) c="sum"} then printfn "The sum is " (a+(float b))


Whew! Complicated! And repetitive, potentially! It is possible to call functions in the then clause but you still have to initialise all the members in the record clause.

It's more fiddly in the presence of inheritance unfortunately. In this case the record initialiser has to include inherit Cbase(a).

Here's one I've used in production code, anonymised...


type drv = class
inherit bse

val _parser : Parser
val _columnExtractors : List

new (configuration:ExpConfig ) as x =
{inherit bse(configuration); _parser = new Parser(configuration); _columnExtractors = new List()}
then x.Init()
new (configuration:ExpConfig, parser:Parser) as this =
{inherit bse(configuration); _parser = parser; _columnExtractors = new List()}
then this.Init()

member private x.Init() =
printfn "blah blah blah"
end

Monday 3 October 2011

F# - Abstract class

It's possible to create an abstract class, but it's not obvious how to do it. You need to create a type, as normal. Then place an abstract method declaration within. At this point, though, the compiler still grumbles. Now you have to tag the type with [<AbstractClass>].

First attempt:


> type C =
inherit Exception
new () = {inherit Exception()}
abstract print : unit -> unit
;;

type C =
-----^

stdin(14,6): error FS0365: No implementation was given for 'abstract member C.print : unit -> unit'


Now apply the annotation and, hey presto, the compiler responds with:


type C =
class
inherit Exception
new : unit -> C
abstract member print : unit -> unit
end


But why the compiler can't work it out for itself I don't know.

Overloaded constructors and inheritance - F#

I've been struggling vainly to create my own Exception class but the obvious fails to compile:


type MyException1 () =
inherit Exception ()
new (msg:string) = {inherit Exception(msg)}


with the following error message:

      new (msg:string) = {inherit Exception(msg)}
  -----------------------^^^^^^^^^^^^^^^^^^^^^^^^

stdin(9,24): error FS0762: Constructors for the type 'MyException1' must directly or indirectly call its implicit object constructor. Use a call to the implicit object constructor instead of a record expression.

After some head-scratching, I guessed that the problem might be the default constructor, and lo, this works.


type MyException =
inherit Exception
new () = {inherit Exception()}
new (msg:string) = {inherit Exception(msg)}


It's not clear to me why I need to explicitly define the default constructor, but the compiler has stopped complaining now.

Tuesday 27 September 2011

Null coalescing operator in F#

I'm converting some C# code into F# and I was wondering where the lovely ?? operator from C# had gone. In C# we have ?? as a binary infix operator meaning

if left is null then right else left

My first crack at (re-)implementing this in F# gave me compiler headaches and so a quick trawl on the web revealed that F# interprets operators starting with (or containing, not sure at the moment) a question mark as unary operators. Aha! That would explain it. So then I defined

let inline (/??) x y = if x = null then y else x

and it seemed to work. That is, it seemed to work until I tried values slightly more complex than strings for x and y.

let y () = printfn "test" ; 2 ;;

Ho hum! Now evaluating the new operator reveals a subtlety. F# evaluates both parameters, which is unlike the if .. then .. else implementation.


"334" /?? y();;
test
val it : string = "334"


Hmmm. How should this be handled? Clearly the parameters could be wrapped in lambda functions but I'm not sure about that.... More thought required. Call back later to check.

P.S. I found another implementation, but it shares the same issue (although there are other interesting operators provided as well) unfortunately

Friday 29 July 2011

The perils of 'ref' parameters

Arrghh! ref parameters! Don't you just love them? At least C# requires that you place the keyword ref in the calling code as well as the receiving code but even so ...

I had a nice one today. A swap object was passed as a ref parameter into a function which then called Clone_API. Now, under normal circumstances this works fine but this was a new swap and the code had been set by our code to zero. The Clone_API call did not, however, recognise the zero code and replaced it with the sicovam of the original instrument from which our working swap was cloned. Arrrghhh! Luckily our code fell over when it tried to save the instrument!

Lesson? Don't use ref parameters if at all possible and certainly not when it would be so easy to return the cloned object from the function and then explicitly reassign it in the calling code.

Thursday 28 July 2011

Beware the yield'd iterator

In C# there are two types of iterator (as far as I know). One is an iterator into a container which is created by something akin to List<T>.GetEnumerator(). The other is the yield'd iterator and this is created by a function which yield returns each element in the sequence.

The issue is that the former can be reset but the latter cannot. Therefore, if you are using the latter you need to be very sure that it is only used the once. If a second loop through the sequence will be required then store the iterator in a list comme ca


List<T> l = new List<T>(myIterator);


and then use l instead.

Monday 27 June 2011

newCSRTransaction - returns null on error ... or does it?

Well, the documentation states that CSMTransaction.newCSRTransaction returns null if the function fails, ie if the transaction sought is invalid. Perhaps this is true in some cases but it certainly isn't true all the time, as we have observed.

Mysteriously our code was failing and a MNoSuchDealException was being thrown. Where was it coming from? Guess what? It came from CSMTransaction.newCSRTransaction! So those null checks we had were pretty useless in this instance, although I suppose they might be necessary, there's no real way of telling until a null is returned (like the docs state should be the case).

Ho hum, so now we have another wrapper:


public static OptionType<CSMTransaction> NewCSRTransaction(int transactionId, short version)
{
try
{
return CSMTransaction.newCSRTransaction(transactionId, version);
}
catch (MNoSuchDealException)
{
return OptionType<CSMTransaction>.Null;
}
}

Friday 20 May 2011

Checking for null in generic methods

My OptionType<T> class indicates whether the underlying reference type is null or not whilst retaining all the good type information and forcing the hand of the developer to think about checking for null, at the very least (unfortunately the C# compiler won't let me force the check :-( ). But this didn't work very well for string types because string.Empty is also considered as a null value in many circles, including this one, hence the prevalence of string.IsNullOrEmpty checks all over our codebase.

Now the problem arose when I had an OptionType<string> which was used to represent string.Empty. The simple check I had in place was nothing more than an equality check with null which was clearly unsatisfactory here. What I needed was to check using string.IsNullOrEmpty, but only when T is a string.

The obvious way to approach this would be to abstract out the null checking behaviour, not into a separate parameter because that would be nasty but into a set of functions from which the compiler would make the appropriate selection. Mind you, non-generic calling code worked just fine! Typical!

And so I introduced


public static class Check
{
public static bool IsNull(string s)
{
return string.IsNullOrEmpty(s);
}

public static bool IsNotNull(string s)
{
return !IsNull(s);
}

public static bool IsNull(T t) where T : class
{
return t == null;
}

public static bool IsNotNull(T t) where T : class
{
return !IsNull(t);
}
}


To my dismay, however, the call to Check always selected the generic method, even when the generic type was actually a string. Argh! And so we end up with


public static class Check
{
public static bool IsNull(string s)
{
return string.IsNullOrEmpty(s);
}

public static bool IsNotNull(string s)
{
return !IsNull(s);
}

public static bool IsNull(T t) where T : class
{
return t == null;
}

public static bool IsNotNull(T t) where T : class
{
return !IsNull(t);
}

// We need these two because OptionType cannot call IsNull(string), it can only call IsNull(string)
public static bool IsNullString(string s)
{
return IsNull(s);
}
public static bool IsNotNullString(string s)
{
return IsNotNull(s);
}
}


which is called from the OptionType constructor in the following manner:


if ((typeof(T) == typeof(string) && Check.IsNotNullString(t as string)) || (typeof(T) != typeof(string) && Check.IsNotNull(t)))
{
_t = t;
_isEmpty = false;
}


Not pretty, but it does work. Let me know if you come up with a neater way to achieve this.

Wednesday 18 May 2011

Null values in dictionaries

Eeek! Why on Earth would someone insert null values into a dictionary? Especially when one sees code like


Dictionary<A,B> d = new Dictionary<A,B>();


blah


TryGetValue( key, out value);
if(value==null) throw new Exception();


That is to say that the return value from TryGetValue is routinely ignored and instead the null-ness of the output value is used to indicate failure. Clearly this has been written because the original author didn't want to wrap dictionary access in try ... catch(), which is understandable, but ...

So I propose that null indicates failure. With this in mind, we can rewrite TryGetValue as follows:


public static Nullable<V> TryGetValue(Dictionary<K,V> d, K key)
{
V v;
bool s = d.TryGetValue(key, out v);
return s ? v : (Nullable<V>)null;
}


This is, of course, absolutely spiffing because now TryGetValue is a function which returns the sought value and so lends itself to a declarative programming style.

Also, with the parameters in the order key then dictionary we allow ourselves the possibility of function pipelining.

Monday 9 May 2011

Overriding the database access in CSMApi

Sophis' CSMApi class provides the method GetDBAccess(CMString). At first blush this is not going to help because the CMString is passed in and not out of the method. However, the CMString is a tricky class, and it has the method SetString() which allows you to change the underlying string representation even if the object itself has all the appearances of being constant, or at least non-modifiable. Another good reason to avoid CMString.

Anyway, the upshot is that you can override GetDBAccess to provide your own connection details. Interestingly, it turns out that if your CSMApi derivative is in the exe this all works fine but if it is in a dll then, oh dear, it doesn't work. I don't know why at this point, but I assume that there are statics in CSMApi which have some evil order-dependencies...

I'll let you know if I find out what's going on.

Wednesday 20 April 2011

Curried functions in C# 2.0

This wasn't as difficult as I thought it might have been. Below I reproduce two examples of currying in C#. Easy!

        bool fn<B, C>(B b, C c) { return b.Equals(c); }
        Functional.fn<C, bool> curried_fn<B, C>(B b)
        {
            return delegate(C c) { return fn(b, c); };
        }

        [Test]
        public void CurriedFnTest1()
        {
            bool test1a = fn(1, 2);
            bool test1b = curried_fn<int, int>(1)(2);
            Assert.AreEqual(test1a, test1b);
        }

        Functional.fn<int, int> curried_adder_int(int c)
        {
            return delegate(int p) { return FunctionalHelpers.adder_int(c, p); };
        }

        [Test]
        public void CurriedFnTest2()
        {
            int[] a = { 1, 2, 3, 4, 5 };
            List<int> b = Functional.map<int, int>(delegate(int a1) { return FunctionalHelpers.adder_int(2, a1); }, a);
            List<int> c = Functional.map<int, int>(curried_adder_int(2), a);
            Assert.IsTrue(CollectionComparer.SetEqual(b, c));
        }

Monday 28 March 2011

C# 2.0 - Functional composition and closures

Sadly, it seems that anonymous functions / delegates cannot hold state so although we can imitate closures if the delegate is defined inline, we cannot do the below:

int diff = 2;
Functional.filter2_fn<int, int> f = delegate(int a, int b) { return Math.Abs(a - b) > diff; };
diff = 3;
bool retval = Functional.forAll2(f, l, m);

because, by the time we come to use
f
, the value stored in
diff
has changed to 3.

C# 2.0 - Functional composition

Yes! It's possible, just! Get your thinking gear around this!

        public static filter_fn<A> not<A>(filter_fn<A> f)
        {
            return delegate(A a) { return !f(a); };
        }

        public static bool forAll<A>(filter_fn<A> f, IEnumerable<A> input)
        {
            return !exists(not(f), input);
        }


and an example:

        public void CompositionTest1()
        {
            int[] i = { 1, 2, 3, 45, 56, 6 };

            bool allOdd = Functional.forAll(Functional.dIsOdd, i);
            bool notAllOdd = Functional.exists(Functional.not(Functional.dIsOdd), i);

            Assert.IsFalse(allOdd);
            Assert.IsTrue(notAllOdd);
        }

Thursday 24 March 2011

C# is soooo verbose

I have this:
List<ReportItem2> value = new List<ReportItem2>();
IEnumerable<MComponentDetails> components = SwapUtils.GetBasketComponents(swap);
foreach (MComponentDetails detail in components)
{
    string sedol = InstrumentUtils.GetSedol(detail.fSicovam);
    string instrName = InstrumentUtils.GetInstrName(detail.fSicovam);
    value.Add(new ReportItem2(sedol, instrName, columnConfig));
}

and I'd like to have this:
List<ReportItem2> value = new List<ReportItem2>();
IEnumerable<MComponentDetails> components = SwapUtils.GetBasketComponents(swap);
value.AddRange(Functional.map(sec(columnConfig), components));

but there are two problems. One is that the code required in order to build
sec
and enable it to take a parameter (instead of simply being a delegate) is far too much; the second is that, unbelievably, the compiler will not implicitly cast from
IEnumerable<MComponentDetails>
to
IEnumerable<object>
Unbelievable!

By way of illustrating the verbosity of C#, here is my preliminary version of the loop innards:

private class sec
{
    private static ExportColumnConfiguration _config;
    public static Functional.fn f(ExportColumnConfiguration config)
    {
        _config = config;
        return sec_func;
    }

    private static Functional.fn sec_func = CreateReportItem2FromSecurity;
    private static ReportItem2 CreateReportItem2FromSecurity(MComponentDetails detail)
    {
        string sedol = InstrumentUtils.GetSedol(detail.fSicovam);
        string instrName = InstrumentUtils.GetInstrName(detail.fSicovam);
        return new ReportItem2(sedol, instrName, _config);
    }
}


Aha, but I discover that C# 2.0 supports anonymous delegates which are, effectively, lambdas and closures.

Splendid!

Wednesday 16 March 2011

CSMInstrument creation

Although it's obvious really, you should avoid doing this:

CSMInstrument i = new CSMInstrument(sicovam);
CSMSwap s = i;

and you should instead do this:

CSMInstrument i = CSMInstrument.GetInstance(sicovam);
CSMSwap s = i;

The CSMInstrument constructor should not be used. It should not be public; it really ought to be protected at the very least.

What the first example does is create an instance of the base class. Now, clearly, even if the sicovam is that of a derived class, the additional fields will not be populated. So use the factory. That's what it's there for! This is particularly pertinent given that one tends to pass around CSMInstrument references and utilise the implicit cast, as shown above, which will unaccountably fail.

In fact, as I think about it, CSMInstrument ought to be an abstract class. Ho hum!

Thanks for listening.

Tuesday 15 March 2011

CSMTransactionVector and Flat View Positions

Ack! I forgot that Flat View positions do not exist per se in the database. Therefore the code which queries histomvts using mvtident returns a different dataset compared to CSMPosition.GetTransactions()

Interestingly, CSMTransactionVector(string sql) can be used for Flat View positions as well. Beware!

Thursday 3 March 2011

CSMPortfolio loading and the corruption of already loaded CSMPositions

You know, of course, that CSMPortfolio objects are cached because they are expensive to load and compute. You also know, of course, that a user preference is 'Do not load portfolios'. Well, did you know that if you load some CSMPositions (and put them in a container for safe keeping) and then load portfolios, the CSMPositions will almost certainly be corrupted! And this is doubly surprising since, obviously, the portfolio corresponding to the position object has to be loaded already in order to build said position object.

All of which is a long-winded way of saying not to load portfolios in the middle of your app! You have been warned.

Wednesday 2 March 2011

CMString - lifetime and ownership

So, you have a CMString and you've noticed that it is IDisposable. But you're passing it in and out of functions. What is the lifetime of your CMString? Which reference has ownership, especially as Sophis have implemented their own reference counting class?

Here we have it then:

use CMString.ToString, CMString.GetString or the implicit cast operator to System.String and testing would suggest that this is safe. These three functions appear to perform copies.

assign another CMString to your first CMString and then Dispose the first one. Miraculously this works too! Even though it can be clearly seen that both CMStrings are in fact referring to the selfsame underlying data! Hurrah!

Nevertheless, don't rely on the CMString because of the unmanaged aspect. Always convert to System.String!

Monday 28 February 2011

N-tone equal temperament vs Just Intonation

Some swift number-crunching later and I have several tables of relative pitches (relative to the octave) for N-tone equal temperament scales where 12<=N<=35 and Just Intonation. What surprises me the most is how closely to Just Intonation 12-Tone Equal Temperament actually is! The average difference between the ratios of the notes to the octave in 12-TET and JI is 0.006157 to 6dp. Contrast this with 13-TET having 0.014749, the second-least closely fitting scale in of those considered. In fact, the next nearest reasonable scale in 19-TET, closely followed by 22-TET.

Specifically, 12-TET differs by 0.006157, 32-TET by 0.005659, 35-TET by 0.005402, 19-TET by 0.005342, 33-TET by 0.005320, 22-TET by 0.004979, 31-TET by 0.003342 and 34-TET by 0.002679.

You don't want to see the rest of them; they're worse fits than 12-TET and so of little value.

Proof, if any were needed or wanted, that floating point arithmetic is not exact

Well, well, I replaced CSMTransactionVector throughout the codebase with System.Collections.Generic.List and ran the entire suite of system and unit tests. One of the test (just one, out of ~360) failed! And do you know why? It failed because the test was comparing expected floating point results with actual floating point results and we all know that floating point numbers should not be compared.

Anyway, the system test was comparing the following derived values (be amazed at the expected precision!)

Assert.AreEqual(-7347, pos.Quantity);
Assert.AreEqual(64.966093643663939, pos.AveragePrice);
Assert.AreEqual(-477305.88999999897, pos.GrossAmount);
Assert.AreEqual(-477297.82353045908, pos.NetAmount);

and all but the last were succeeding. The last test, the net amount test, was different by 15E-10!! Dunno about you but I'd normally say that they were the same LoL.

Interestingly, though, the upshot of this is that the CSMTransactionVector appears to store its contents in reverse, in the manner of a functional list, I suppose. Reversing my List after loading the data and running all the tests again meets with SUCCESS!!! Well, well, as I said at the beginning of this post!

This makes me ponder on the internals of the CSMTransactionVector. We have already determined that accessing the vector using an enumerator leads to unexpected results, but this means that using the random-access [] operator does some magic too. I wonder what happens when elements are added to the CSMTransactionVector in mid-flow?

Wednesday 23 February 2011

IDisposable and Collections

Ah, joy! The .NET collections don't clean up their contained objects if said objects are IDisposable! Boo! So, if the collection contains IDisposable then these objects need to be Disposed individually before the collection itself is discarded. Some swift googling revealed that others had experienced this issue (see stackoverflow, for example).

Snipped from stackoverflow:

public class DisposableList : List, IDisposable where T : IDisposable
{
#region IDisposable Members

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

public virtual void Dispose(bool disposing)
{
if (disposing)
{
foreach (T type in this)
{
try
{
type.Dispose();
}
finally {/* In case of ObjectDisposedException*/}
}
}
}
#endregion
}

Investigation reveals that CSMInstrument implements IDisposable! Bah! How many of them are scattered throughout the code, also being held in collections?

Tuesday 22 February 2011

chord progressions

I'm wondering if anyone has looked at the mathematics behind chord progressions. I have a list of frequencies in excel....

Dominant - the perfect fifth

Well, I had wondered why, using the standard Western 12-tone scale, that the perfect fifth is, one, so called and, two, such a nice (in a harmonic sense) fit. All can now be revealed.

CSRInstrument::SetModelName

When modifying instruments using the Sophis API, one would normally expect to call Clone_API() first and then modify the instrument accordingly. This is because the instruments are cached locally and to edit them directly is to change them in the cache in a non-thread safe (this is Sophis, remember) way. So, use Clone_API() first.

However, the documentation for SetModelName() says to call Clone afterwards!

Mysteriously, calling Clone after SetModelName resets the modified flag in the object to false. I suppose it's not that mysterious really. Anyway, the upshot of this is that it would appear to be necessary to manually set the modified flag using SetModified(true). Then Save() will actually persist the updated model name to titres!

Note, however, that it is still necessary to call Clone before SetModelName as well! Goodness gracious!

Failure to call Clone after SetModelName results in an exception being thrown from the depths of the Sophis toolkit bearing a message which politely informs one of the need to use Clone afterwards. Just so that you know.