I want to define global methods.
For that i define their signature under global unit.
What are the disadvantages of doing so ?
Why does it not recommended ?
One disadvantage of using global methods might be that they can be called without explicitly stating the object (just foo() rather than global.foo()), and this is error prone. For example, if your struct happens to have its own method with the same name, such a call is treated as a call to the struct method rather than the global method.
Speaking more generally, one of the principles in object oriented programming is that functions (methods) belong to some object/class rather than being global.
I recommend using sn_utils instead. It is also a singleton like global, but forces you to use its instance name: utils.foo().
You need to be aware not to pollute its namespace, e.g. use <evc-name>_foo() as method name.
Related
In swift, how is constants implemented?
I read this article, which says
In Swift, constants are generally implemented as (inlined) function calls.
I am not clear of this statement.
Does Swift use a special approach to make constants?
Could anyone explain?
Are you familiar with "getter" and "setter" methods from other languages, such as Java? If a variable is made public in a language like Java, it's exposed to other classes to access directly. In the future, if this variable has to be changed, there's no way to do so without changing all of the other classes dependent upon. With getter/setter methods, dummy implementations can be made that don't do anything besides read/write the value. In the case that a change needs to be made, the implementation of these methods can be changed without effecting the public API of the class.
Swift implements variables with "properties", which are like a backing private variable with public getter/setter methods that are automatically generated. In the future, you can replace a property with a computer property with a special getter/setter implementation, without effecting the public API of the class, just like before. The difference here is that you don't need to write all of the default getters/setters yourself.
For Sept 2015, here's exactly how you make a singleton in Swift:
public class Model
{
static let shared = Model()
// ( for ocd friends ... private init() {} )
func test()->Double { print("yo") }
}
then elsewhere...
blah blah
Model.shared.test()
No problem.
However. I add this little thing...
public let model = Model.shared
public class Model
{
static let shared = Model()
func test()->Double { print("yo") }
}
then, you can simply do the following project-wide:
blah blah
model.test()
Conventional idiom:
You see Model.shared.blah() everywhere in the code.
"My" idiom:
You see model.blah() everywhere in the code.
So, this results in everything looking pretty!
This then, is a "macro-like" idiom.
The only purpose of which is to make the code look pretty.
Simplifying appearances of ImportantSystem.SharedImportantSystem down to importantSystem. throughout the project.
Can anyone see any problems with this idiom?
Problems may be technical, stylistic, or any other category, so long as they are really deep.
As a random example, here's an "article in singletons in Swift" that happens to also suggest the idea: https://theswiftdev.com/swift-singleton-design-pattern/
Functionally, these are very similar, but I'd advise using the Model.shared syntax because that makes it absolutely clear, wherever you use it, that you're dealing with a singleton, whereas if you just have that model global floating out there, it's not clear what you're dealing with.
Also, with globals (esp with simple name like "model"), you risk of having some future class that has similarly named variables and accidentally reference the wrong one.
For a discussion about the general considerations regarding globals v singletons v other patterns, see Global Variables Are Bad which, despite the fairly leading title, presents a sober discussion, has some interesting links and presents alternatives.
By the way, for your "OCD friends" (within which I guess I must count myself, because I think it's best practice), not only would declare init to be private, but you'd probably declare the whole class to be final, to avoid subclassing (at which point it becomes ambiguous to what shared references).
There are a few things to look out for when using this approach:
The global variable
A global variable in itself is no big deal, but if you have quite some global variables, you might have trouble with autocompletion, because it will always suggest these global variables.
Another problem with global variables is that you could have another module in your application (written by you or otherwise) define the same global variable. This causes problems when using these 2 modules together. This can be solved by using a prefix, like the initials of your app.
Using global variables is generally considered bad practice.
The singleton pattern
A singleton is helpful when working with a controller, or a repository. It is once created, and it creates everything it depends on. There can be only one controller, and it opens only one connection to the database. This avoids a lot of trouble when working with resources or variables that need to be accessed from throughout your app.
There are downsides however, such as testability. When a class uses a singleton, that class' behaviour is now impacted by the singletons behaviour.
Another possible issue is thread safety. When accessing a singleton from different threads without locking, problems may arise that are difficult to debug.
Summary
You should watch out when defining global variables and working with singletons. With the appropriate care, not many problems should arise.
I can't see a single downside to this approach:
You can use different variables for different parts of the program (-> No namespace cramming if you don't like this I guess)
It's short, pretty, easy to use and makes sense when you read it. Model.shared.test() doesn't really make sense if you think about it, you just want to call test, why would I need to call shared when I just need a function.
It uses Swift's lazy global namespace: The class gets allocated and initialized when you use it the first time; if you never use it, it doesn't even get alloced/inited.
In general, setting aside the exact idiom under discussion, regarding the use of singletons:
Recall that, of course, instead of using static var shared = Model() as a kind of macro to a singleton, as suggested in this Q, you can just define let model = Model() which simply creates a normal global (unrelated to singletons).
With Swift singletons, there has been discussion that arguably you want to add a private init() {} to your class, so that it only gets initialized once (noting that init could still be called in the same file).
Of course in general, when considering use of a singleton, if you don't really need a state and the class instance itself, you can simply use static functions/properties instead. It's a common mistake to use a singleton (for say "calculation-like" functions) where all that is needed is a static method.
Racket's documentation only partially describe what augment and pubment do: augment makes a method that executes after the superclass's version of that method, while pubment makes a method that will implicitly have the augment property if it is defined in a child class.
The docs say absolutely nothing about overment and augride, and I can't guess what they would do based on their names. What are they, and what is the difference between them?
The relatively large family of inheritance functions for Racket's class system is, as you describe, a little confusing, and their somewhat cutesy names don't always help.
In order to understand this, Racket provides two separate mechanisms for method inheritance.
public methods correspond to the classical idea of public methods in other OO models. Methods declared with public may be overridden in subclasses, unless they're declared final, in which case they cannot.
pubment methods are similar, but they cannot be overridden, only augmented. Augmenting a method is similar to overriding it, but the dispatch calls the superclass's implementation instead of the subclass's.
To clarify the difference between overriding and augmentation, when an overridden method is called, the overriding implementation is executed, which may optionally call the superclass's implementation via inherit/super. In contrast, in an augmented method, the superclass's implementation receives control, and it may optionally call the subclass's implementation via inner.
Now, we're also provided public-final, override-final, and augment-final. These are pretty simple. Declaring a method with public-final means it can neither be augmented nor overridden. Using override-final overrides a superclass's public method, but it doesn't allow any further overriding. Finally, augment-final is similar, but for methods declared with pubment, not public.
So then, what about the two weird hybrids, overment and augride?
overment can be used to implement methods initially defined with public. This "converts" them to augmentable methods instead of overridable methods for all the class's subclasses.
augride goes in the opposite direction. It converts an augmentable method to one that is overridable, but the overriding implementations only replace the augmentation, not the original implementation.
To summarize:
public, pubment, and public-final all declare methods that do not exist in a superclass.
Then we have a family of forms for extending superclass methods:
override and augment extend methods declared with public and pubment, respectively, using the relevant behaviors.
override-final and augment-final do the same as their non-final counterparts, but prevent further overriding or augmentation.
overment and augride convert overridable methods to augmentable ones and vice-versa.
For another, fuller explanation, you might be interested in taking a look at the paper from which Racket's model was derived, which is quite readable and includes some helpful diagrams.
I just read that the init method can't be used as a value. Meaning:
var x = SomeClass.someClassFunction // ok
var y = SomeClass.init // error
Example found on Language reference
Why should it be like that? Is it a way to enforce language level that too dirty tricks come into place, because of some cohertion or maybe because it interferes with another feature?
Unlike Obj-C, where the init function can be called multiple times without problems, in Swift there actually is no method called init.
init is just a keyword meaning "the following is a constructor". The constructor is called always via MyClass() during the creation of a new instance. It's never called separately as a method myInstance.init(). You can't get a reference to the underlying function because it would be impossible to call it.
This is also connected with the fact that constructors cannot be inherited. Code
var y = SomeClass.init
would also break subtyping because the subtypes are not required to have the same initializers.
Why should it be like that?
init is a special member, not a regular method.
Beyond that, there's no reason that you'd ever need to store init in a variable. The only objects that could use that function in a valid way are instances of the class where that particular init is defined, and any such object will have already been initialized before you could possibly make the assignment.
Initializers don't have a return value. In order to assign it to something, it should be able to return something - and it doesn't.
Exactly what the topic title says,
In which cases would you prefer using public functions to change local variables over just defining that variable as public and modifying it directly?
Don't expose the data members directly: using opaque accessors means you can change the implementation at a later date without changing the interface.
I should know. I take the short cut from time-to-time, and have had occasion to regret it.
Obviously if you want changing the variable to have some other effect on the object's state (like recalculating some other property of the object) you must use a mutator function.
If it's possible to set the variable to something that places the object in an invalid state, you should probably also use a mutator function. This way you can throw an exception (or return an error, or just ignore) if something illegal is about to happen. This does wonders for debugging.
But if some variables can be modified with mutator functions, and others are public, the programmer needs to keep track of which is which. This is a waste of time and effort so in some cases it's easiest to just use mutator functions for everything.
If you look at an object purely in term of service, you realize that exposing a variable is not a good way to expose those services.
The API must reflect what the object is all about (for it to achieve a high cohesiveness), and if you define a setValue(...), it is not so much because you need a way to -- today -- changes a variable, but because it makes sense for the object to expose this service.
So:
Don't provide accessors or mutator function to every single member of every single class you write. Only provide accessors/mutator functions if the accessors/mutator methods are a sensible and useful part of the class's interface (API).
Don't think of these methods as accessors or mutators. Instead, think of them as methods that access or mutate a certain abstract property of the object that happens to be represented by a single member today, but may be computed in a more complex manner tomorrow.
You should mention what language you are dealing with, since that will affect the answer.
Your first thought should be about the API to your class. If you want to keep that API stable (and you should!), then consider how you might change today's simple variable into a full-blown method later.
In many languages, you can't change a variable to a method without changing the calling code. C, C++, and Java fall into this category. Never use public variables in these languages, because you won't have any wiggle room later.
In Python, you can change a variable to a property without changing the callers, so you don't have to worry up front: use public variables.
C# I believe has properties that can let you change variables to methods transparently, but I am not sure.
If you want to change a variable inside a class, your best doing it through Properties.
Its not good practice to have variable's modified on the outside.
Think of future development too. You could put some logic behind a Property without changing the whole program.