← Back to team overview

ooc-dev team mailing list archive

Re: Singletons?

 


I agree about the "nothing prevents" stuff. Indeed I don't really
care about it (if someone would be so dumb as to initialize a class
starting with a '_' himself, doesn't he deserve his changes to be
ignored - because everyone else would refer to the previously unique
instance anyway?) - but it could probably be solved with compiler
plugins and annotations in an ideal world. 

About the "not clear /
messy / not obvious" well nothing prevents you from adding a lil'
comment, ie. "// Singleton instance of MySingleton" before the
definition so that there's no doubt left. 

There are two things of
interest: is it not clear because it clearly is a sucky way of doing
singletons - or is it not clear/obvious because it's not familiar to you
(or any of us for that matter)? Afaik, Java's way of doing singletons
sucks bigtime, and *nothing* in the code gives you the slightest hint
that it is, indeed, a singleton. The hints that make it clear it's a
singleton when reading the Java code are: 'the presence of a private
static field named 'instance'', and 'the presence of a static method
named 'get''. (And also maybe a private constructor for the really picky
Java programmers - which is ridiculous imho.) 

For my proposed method,
the hints are somehow better, if you consider this:


_LocalizationSingleton: class {
 init: func { /* ... */
}
}
Localization := _LocalizationSingleton new()

1) class starts with a
'_' (hint: don't touch/ don't instanciate) and ends with 'Singleton'
(hint: it's a singleton, dude.)
2) global variable with a capital,
that's unusual, probably because... it's a singleton, ie. we treat its
methods/ivars as if they were static. 

So by my book this doesn't look
*too* bad and it's just one underscore, one suffix, and one vardecl line
longer than a non-singleton class. 

ndd 

On Wed, 29 Sep 2010 20:09:05
-0300, Damian  wrote:  

I always forget to hit Reply all :P 

Yes,
surely your way to make a singleton will work. What I don´t like is : 
*
it's not clear... it's kind of mesy, and looking at a class you wouldn't
notice at first sight that's a singleton. 
* The same as with a lot
other things: nothing prevents you from subclassing / instantiating more
tan once. 
I know that protecting the developer from himself is not
something ooc cares about... we have no privates, so maybe that 2nd
point means nothing to you. 

On the other hand, if I use namespaced
imports, I would be solving the problem of someone subclasing /
instanciatint the "singleton", and it would really act as a Singleton,
right? The initialization code I write in a file, outside any class,
will be executed only once. 

But again, I don't like that I can import
normally that file and use the funcitionality of my "singleton" in a non
object-oriented-like way. Also I don't like that namespaced imports are
not for that. 

I think I'll end up doing it the way you described
anyway. 

On Wed, Sep 29, 2010 at 7:40 PM,  wrote:

Well, my goal isn't
to prevent you from using singletons or anything, I was just sharing my
point of view. 

(About your Localization singleton - I'd expect a
language change to be something done *to* the localization object (e.g.
method call on it that changes some of its data), not it to be a
completely different instance) 

As you have probably seen already, in
ooc we prefer to implement patterns from existing syntax - it is imho
the sign of a powerful and expressive language that we can then keep
small. Scala has a *lot* of syntax (very much like C++0x), not all of
which is necessary imho. Lisp is quite extreme in its minimalist, but I
like to think that ooc is somehow a middle ground. 

That said - doesn't
the last way I suggested to do singletons satisfy you? It basically
takes an underscore and one line to turn a class into a kinda-singleton,
usable a-la scala (ie. without get()), e.g. MySingleton doStuff(). (And
yes I forgot to tell - you can do stuff like MySingleton := _MySingleton
new() at the module level, it'll just be a global) 

ndd 

P.S: Don't
forget to hit "Reply all". No reason to keep this discussion personal :)


On Wed, 29 Sep 2010 18:49:25 -0300, Damian  wrote:  

Yes I know about
the "singleton is evil" thing. I disagree. 
I would never pass around an
instance everywhere. Imagine a Localization singleton that it's main
function is to take a key and return the respective string in the
correct language. In certain applications that singleton will be used
*everywhere* in the code. How can you replace a singleton by passing
around an instance? 
At the first link you provide, there's a list of
the problems a singleton causes: 
a) Says nothing  
b and c) memory leak
// not with gc 
d) syntactic noise because most languages don't support
it // I think this is the only problem 
c) problems when subclassing //
If the language supports singletons, it should not allow subclassing.
Why would you do it?! 
f) says someting about static methods that makes
no sense to me. 
It also says that the main problem using singletons is
that it's against OO design. But I don't see how. 
I agree with your
point about wanting several resource managers, and maybe in that case
the best option is storing an instance in an instance variable, or a
static instance on a class. But why are you going to mess your code like
that when you know there can/will be just one instance of a
resourceManager / userManager / Localizator / etc. 
Anyway, I'm just
writing my thought about the topic, I'm not requesting a feature. 
With
the time I will get more used to code in ooc and maybe that's the whole
thing. 
Damian 

On Wed, Sep 29, 2010 at 5:43 PM,  wrote:

Ahah, but
that's where we disagree. Believe me, I fully grasp the seduction
potential of singletons, and I'm guilty of having used them much in the
past.. 

Others have said it before, and much better than me: 

 	*
http://sites.google.com/site/steveyegge2/singleton-considered-stupid
[4]
 	*
http://www.ibm.com/developerworks/webservices/library/co-single.html
[5]
 	*
http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
[6]

Concerning your example, what if you want several resource managers
that have different options? (ie. memory quotas/timeout before freeing
old unreferenced stuff, different loading paths, maybe disable the cache
completely one of the managers for debugging? different levels of
logging and destination of logging message, etc.) 

When your brain
thinks of singletons, it automatically becomes stupid - and misses
opportunities to make your code more flexible, easier to maintain and
debug, and more natural. 

Passing around an instance isn't *that* bad
of an idea, and storing an instance in an instance variable isn't too
bad either. 

If you really really want to emulate the Scala way I guess
this would work marvelously: 

// -- cut

_MySingle: class {
 //
instance vars
 init: func {
 // initialize
 }
}

MySingle := _MySingle
new()

// -- cut 

Then, MySingle would be the instance, as in Scala,
and nobody in his right mine will go instanciate _MySingle directly (the
underscore is usually a convention of "don't touch or I'll bite your
balls off" in ooc land - aka "pseudo-protected". It's not impossible
that at some point in the future, a compiler switch is implemented to
enforce the encapsulation of such attributes.) 

ndd 

On Wed, 29 Sep
2010 17:13:08 -0300, Damian  wrote:  

Well, I don't know; it's one of
the features I love from scala. 
I find singletons useful *a lot* of
times. It's just an object that there will be only one instance in the
app and that can be accessed from anywhere in the code.  
To me it's
useful for example to create a manager of resources, that has internal
cache, and where I can ask for a resource and the manager will look for
it in the cache or load it, process it, and chache it, and that kind of
stuff. 
I hate the pattern as you describe it too, because MySingle
should be the instance, not a class, and I should be abble to do
something like: 
Resources getResource("nana") 
instead of 
Resource
getInstance() getResource("nana") 
I think that the namespaced imports
are more suitable... Though I don't like it too much to be honest. But
well, ooc is not 100% object oriented and maybe it's just that I'm not
used to that.  

By the way, is there any documentation about namespaced
imports?

On Wed, Sep 29, 2010 at 3:58 PM,  wrote:

 Well singletons are
more than namespaces, although I kinda hate this
 pattern, here it
goes:

 you can choose to implement 'new' as your get method:


MySingle: class {

 _instance := static alloc() as This
 new: static
func -> This { _instance }

 }

 if you dislike this (because 'new'
sortof implies that it's a new
 instance..) just use 'get' instead of
'new', there's not really a
 convention here yet

 also, there's no
special syntax like Scala's object: I actually dislike
 this bit of
Scala's syntax, it's mostly useful for the main class in
 Scala anyway..
(correct me if I'm wrong).

 ndd

 On Wed, 29 Sep 2010 14:33:01 -0400,
Oddity007 
 wrote:

> Easy: Don't.
 >
 > ooc != Java
 >
 > If you want a
namespace sort of effect, just use namespaced imports:
 >
 > import
Source/Path/Foo into Foo
 >
 > Foo doSomeStuff(10)
 >
 > If you can't
use namespaced imports (for one-file-monsters), use a
 > cover's static
methods.
 >
 > Foo: cover{
 > doSomeStuff: static func(argument: Int)
 >
}
 >
 > Foo doSomeStuff(10)
 >
 > On Sep 28, 2010, at 1:16 PM, Damian 
wrote:
 >
 >> What's the proper or preferred way to create a singleton
in ooc? Is > there something specific to do so? (like 'object' in scala,
for > example)
 >> Thanks!
 >>
 >>
_______________________________________________
 >> Mailing list:
https://launchpad.net/~ooc-dev [11]
 >> Post to :
ooc-dev@xxxxxxxxxxxxxxxxxxx [12]
 >> Unsubscribe :
https://launchpad.net/~ooc-dev [13]
 >> More help :
https://help.launchpad.net/ListHelp [14]
 >
 >
_______________________________________________
 > Mailing list:
https://launchpad.net/~ooc-dev [15]
 > Post to :
ooc-dev@xxxxxxxxxxxxxxxxxxx [16]
 > Unsubscribe :
https://launchpad.net/~ooc-dev [17]
 > More help :
https://help.launchpad.net/ListHelp [18]

                 


Links:
------
[1] mailto:ndd@xxxxxxxxxx
[2]
mailto:damian.pop@xxxxxxxxx
[3] mailto:ndd@xxxxxxxxxx
[4]
http://sites.google.com/site/steveyegge2/singleton-considered-stupid
[5]
http://www.ibm.com/developerworks/webservices/library/co-single.html
[6]
http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
[7]
mailto:damian.pop@xxxxxxxxx
[8] mailto:ndd@xxxxxxxxxx
[9]
mailto:oddity007@xxxxxxxxx
[10] mailto:damian.pop@xxxxxxxxx
[11]
https://launchpad.net/~ooc-dev
[12]
mailto:ooc-dev@xxxxxxxxxxxxxxxxxxx
[13]
https://launchpad.net/~ooc-dev
[14]
https://help.launchpad.net/ListHelp
[15]
https://launchpad.net/~ooc-dev
[16]
mailto:ooc-dev@xxxxxxxxxxxxxxxxxxx
[17]
https://launchpad.net/~ooc-dev
[18] https://help.launchpad.net/ListHelp

References