"const" In Objective-C and Cocos2D: Is It Me, Or Does It Seem To Be Taboo? - ios

I'm not sure if this is the right place to ask this, since it's not really a technical question but more a question of style and coding practices...
I've always ben a fan of using "const" to define variables that will not be changing throughout their lifetime, most especially when they are parameters to functions/methods. This probably stems from my history with C++, where objects could be passed by reference rather than by pointer, but you wanted to ensure that the original value wasn't accidentally altered, either by you or by someone else on your team who was working on the same code snippet.
When looking through the headers for both Objective-C in general and Cocos2d specifically, I've noticed that there is a noticeable lack of use of this item. Now, I'm not against developing code as quickly as possible, and leaving off constraints such as these leave the developer the option to modify values as their code develops and evolves, but there are some instances where I believe that this laxity does not belong.
For example, in Cocos2D/UIKit, the "UIFont fontWithName" method takes "(NSString *)" as the parameter for the font name: does this method really need to reserve the right to alter the original string that was passed in? I personally like to define constant strings as "const" items, and I don't like the necessity of casting these as non-"const" when calling these methods.
Enough proselytizing: My question - Is the direction now moving towards less well-defined interfaces and more towards "lazy references" (which I do not consider to be a derogative term)?
Thanks in advance for any feedback....

Const wouldn't mean anything for Objective C class pointers, because it would have to be overloaded in a very confusing way for Objective C types. This is because there's no way to mark a method as const, as there is in C++, so the compiler could never enforce it.
That said, at my old company, we did declare global string constants using something like:
NSString* const kMyCoolString = #"Hello, world!";
The point being that it at least couldn't be reassigned to something else.
The closest analog in Objective C/Cocoa/Foundation are mutable/immutable versions of data structures, which doesn't really help your case.

Related

Why is using final, with no type, considered good practice in Dart? ie `final foo = config.foo;`?

I see this recommended in the dart style guide, and copied in tons of tutorials and flutter source.
final foo = config.foo;
I don't understand it, how is this considered best practice when the readability is so poor? I have no clue what foo is here, surely final String foo = config.foo is preferable if we really want to use final?
This seems the equivalent to using var, which many consider a bad practice because it prevents the compiler from spotting errors and is less readable.
Where am I wrong?
In a lot of cases is does not really matter what type you are using as long the specific type can be statically determined by the compiler. When you are using var/final in Dart it is not that Dart does not know the type, it will just figure it out automatically based on the context. But the type must still be defined when the program are compiled so the types will never be dynamic based on runtime behavior. If you want truly dynamic types, you can use the dynamic keyword where you tell Dart "trust me, I know what I am doing with this types".
So types should still be defined where it matter most. This is e.g. for return and argument types for methods and class variables. The common factor for this types is that they are used to define the interface for using the method or class.
But when you are writing code inside a method, you are often not that interested in the specific types of variables used inside the method. Instead the focus should be the logic itself and you can often make it even more clear by using good describing variable names. As long the Dart analyzer can figure out the type, you will get autocomplete from your IDE and you can even still see the specific type from your IDE by e.g. Ctrl+Q in IntelliJ on the variable if you ends up in a situation where you want to know the type.
This is in particular the case when we are talking about the use of generics where it can be really tiresome to write the full specific type. Especially if you are using multiple generics inside each other like e.g. Map<String, List<String>>.
In my experience, Dart is really good to figure out very specific types and will complain loudly if your code cannot be determined statically. In the coming future, Dart will introduce non-null by default, which will make the Dart compiler and analyzer even more powerful since it will make sure your variable cannot be null unless this is something you specifically want and will make sure you are going to test for null when using methods which are specified to not expecting null.
About "Where am I wrong?". Well, a lot of languages have similar feature of var/final like Dart with the same design principle about the type should still be statically determined by a compiler or runtime. And even Java has introducing this feature. As a experienced Java and Dart programmer I have come to the conclusion for myself that typing inside methods are really not that important in a lot of cases as long I can still easily figure out the specific type by using an IDE when it really matters.
But it does make it more important to name your variables so they are clearly defining the purpose. But I am hoping you already are doing that. :)

Using #properties for all instance variables coding standards

My coding team has chosen implement a coding standard of using #property's for all instance ivars. For publicly facing things, we of course define them in our .h files, but for our private things, we define them in the .m file in an interface above our implementation.
Does it matter if I refer to them as self.myvar = whatever or as [self setMyvar:whatever]? It doesn't seem to matter at all to me, and there seems to be a great deal of mixing one way or the other in our code base.
self.myvar = whatever
is syntactic sugar for
[self setMyvar:whatever]
They're exactly the same thing. No difference at all.
As others have indicated, foo.bar and [foo bar] are equivalent (save for the additional type requirements on the former, but that is minor).
FWIW, our team decided to eschew the dot syntax completely. The motivation is to avoid ambiguity; a message send always looks like a message send and .s are always used to access structure members.
We also limit our use of #{} and #[] to the creation of collections only. All accesses are done via indexOfObject:, objectForKey:, etc...
As well, we use ARC everywhere save for a couple of border files that sit between ObjC and C++. And we have the static analyzer turned on for all DEBUG builds and all warnings are treated as hard errors. We've also turned on just about every compiler warning that is practical (there are some that simply aren't practical to use).
There is plenty of similar questions.
In our coding standards, we don't care about using dot notation or method to access the property. We even sometimes use dot notation for methods which are not formally declared as property because with library methods it's sometimes hard to know without checking the docs and it doesn't make a difference.
It never makes sense to forbid direct method calls (hard to enforce).
I saw coding standards forbidding the dot notation.
In general I tend to prefer dot notation because it enables me to split assignments into visually separated parts, e.g.
self.a = x;
against
[self setA:x];
The second just seems less readable to me but it's a matter of personal taste.
On the other hand, sometimes it's easier to use the method directly, e.g. when you have the object as an id and you would have to cast to use the dot notation.
I think that mixing both is a good solution. Choose the one that will increase the readibility at the given place.
self.myVar = x is actually compiled to [self setMyVar: x];. There's no run-time difference.
However; for ease of code readability, I'd advise sticking with one scheme or the other. If you've already had properties enforced, it'd be better to leave everything in the dot notation - if for no other reason than because this allows your code to be more easily searched.

Change this to use auto_ptr?

I have been reading up on the c++ auto_ptr and unique_ptr and stuff and thought to try and use them in a class I am playing with... but I was having trouble getting it to work...
How would I convert these pointers to auto pointers or some equivalent so the deletion of the pointers is handled automatically?
Header - http://ideone.com/Z9bc5
Body - http://ideone.com/WfwBY
At the moment it is working using normal pointers but I sometimes get a access violation error. I am pretty sure I know what it causing it.. but the "best" way might be to use the automatic deletion stuff recently added to c++11?
Thanks in advance.
Don't use auto_ptr. Try one of unique_ptr or shared_ptr. Here's Sutter explaining when to use which:
When in doubt, prefer unique_ptr by default, and you can always later move-convert to shared_ptr if you need it. If you know from the start you need shared ownership, however, go directly to shared_ptr via make_shared (see #2 below).
Also from his blog-post:
3. What’s the deal with auto_ptr?
auto_ptr is most charitably characterized as a valiant attempt to
create a unique_ptr before C++ had move semantics.
auto_ptr is now deprecated, and should not be used in new code. When
you get a chance, try doing a global search-and-replace of auto_ptr to
unique_ptr in your code base; the vast majority of uses will work the
same, and it might expose (as a compile-time error) or fix (silently)
a bug or two you didn’t know you had.
So, your member declarations change from:
sf::Texture * tSpriteSheet;
to:
std::unique_ptr<sf::Texture> tSpriteSheet;
As for member functions which return a raw pointer you have but the obvious choice: You cannot return a unique_ptr if the class is not movable. So, you can either:
Keep the signature as-is
Return a const& unique_ptr<T>
Return a reference to the object
Choose the one that suits your needs the best.

F# Instance Methods... should they return a new instance instead of altering the current object?

The problem is whether an instance method should in anyway alter the object that contains the method or should it return a new instance? I'm new to F# and the concept of full mmutability that is suggested for F#.
Just using psuedo code for now unless I need to be more specific.
First thought is just add the message to the message list on the object:
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
_messages.Add(message)
Second is to construct a new list that joins the old list and the new message. Then I would create a new instance altogther and send back.
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
newMessageList = _messages.Join(message)
return new Something(newMessageList)
Am I overthinking immutability?
In my opinion, the answer depends on your requirements. The immutable style is probably more idiomatic, and would be a sensible default. However, one nice thing about F# is that you can choose what to do based on your needs; there's nothing inherently wrong with code that uses mutation. Here are some things to consider:
Sometimes the mutable approach leads to better performance, particularly when used in a single-threaded context (but make sure to measure realistic scenarios to be sure!)
Sometimes the immutable approach lends itself better to use in multi-threaded scenarios
Sometimes you want to interface with libraries that are easier to use with imperitave code (e.g. an API taking a System.Action<_>).
Are you working on a team? If so, are they experienced C# developers? Experienced F# developers? What kind of code would they find easiest to read (perhaps the mutable style)? What kind of code will you find easiest to maintain (probably the immutable style)?
Are you just doing this as an exercise? Then practicing the immutable style may be worthwhile.
Stepping back even further, there are a few other points to consider:
Do you really even need an instance method? Often, using a let-bound function in a module is more idiomatic.
Do you really even need a new nominal type for what you're doing? If it's just a thin wrapper around a list, you might consider just using lists directly.
As you are doing "class based" programming which is one of the way (rather unfortunate) to do object oriented programming, you would be doing in place state modification rather than returning a new state (as that's what would be expected when you are doing OO).
In case you really want to go towards immutability then I would suggest you need to use more FP concepts like Modules, Functions (not methods which have you have in class based programming), recursive data types etc.
My answer is way too general and the appropriate answer lies in the fact that how this class of your will fit in the big picture of your application design.

Delphi : Handling the fact that Strings are not Objects

I am trying to write a function that takes any TList and returns a String representation of all the elements of the TList.
I tried a function like so
function ListToString(list:TList<TObject>):String;
This works fine, except you can't pass a TList<String> to it.
E2010 Incompatible types: 'TList<System.TObject>' and 'TList<System.string>'
In Delphi, a String is not an Object. To solve this, I've written a second function:
function StringListToString(list:TList<string>):String;
Is this the only solution? Are there other ways to treat a String as more 'object-like'?
In a similar vein, I also wanted to write an 'equals' function to compare two TLists. Again I run into the same problem
function AreListsEqual(list1:TList<TObject>; list2:TList<TObject>):boolean;
Is there any way to write this function (perhaps using generics?) so it can also handle a TList<String>? Are there any other tricks or 'best practises' I should know about when trying to create code that handles both Strings and Objects? Or do I just create two versions of every function? Can generics help?
I am from a Java background but now work in Delphi. It seems they are lately adding a lot of things to Delphi from the Java world (or perhaps the C# world, which copied them from Java). Like adding equals() and hashcode() to TObject, and creating a generic Collections framework etc. I'm wondering if these additions are very practical if you can't use Strings with them.
[edit: Someone mentioned TStringList. I've used that up till now, but I'm asking about TList. I'm trying to work out if using TList for everything (including Strings) is a cleaner way to go.]
Your problem isn't that string and TObject are incompatible types, (though they are,) it's that TList<x> and TList<y> are incompatible types, even if x and y themselves are not. The reasons why are complicated, but basically, it goes like this.
Imagine your function accepted a TList<TObject>, and you passed in a TList<TMyObject> and it worked. But then in your function you added a TIncompatibleObject to the list. Since the function signature only knows it's working with a list of TObjects, then that works, and suddenly you've violated an invariant, and when you try to enumerate over that list and use the TMyObject instances inside, something's likely to explode.
If the Delphi team added support for covariance and contravariance on generic types then you'd be able to do something like this safely, but unfortunately they haven't gotten around to it yet. Hopefully we'll see it soon.
But to get back to your original question, if you want to compare a list of strings, there's no need to use generics; Delphi has a specific list-of-strings class called TStringList, found in the Classes unit, which you can use. It has a lot of built-in functionality for string handling, including three ways to concatenate all the strings into a single string: the Text, CommaText and DelimitedText properties.
Although it is far from optimal, you can create string wrapper class, possibly containing some additional useful functions which operate on strings. Here is example class, which should be possibly enhanced to make the memory management easier, for example by using these methods.
I am only suggesting a solution to your problem, I don't agree that consistency for the sake of consistency will make the code better. If you need it, Delphi object pascal might not be the language of choice.
It's not cleaner. It's worse. It's a fundamentally BAD idea to use a TList<String> instead of TStringList.
It's not cleaner to say "I use generics everywhere". In fact, if you want to be consistent, use them Nowhere. Avoid them, like most delphi developers avoid them, like the plague.
All "lists" of strings in the VCL are of type TStringList. Most collections of objects in most delphi apps use TObjectList, instead of templated types.
It is not cleaner and more consistent to be LESS consistent with the entire Delphi platform, and to pick on some odd thing, and standardize on it, when it will be you, and you alone, doing this oddball thing.
In fact, I'm still not sure that generics are safe to use heavily.
If you start using TList you won't be able to copy it cleanly to your Memo.Lines which is a TStringList, and you will have created a type incompatibility, for nothing, plus you will have lost the extra functionality in TStringList. And instead of using TStringList.Text you have to invent that for yourself. You also lose LoadFromFile and SaveToFile, and lots more. Arrays of strings are an ubiquitous thing in Delphi, and they are almost always a TStringList. TList<String> is lame.

Resources