comp.lang.ada
 help / color / mirror / Atom feed
* What is your opinion on Global Objects?
@ 2014-11-18  1:36 Hubert
  2014-11-18  2:52 ` Jeffrey Carter
                   ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Hubert @ 2014-11-18  1:36 UTC (permalink / raw)


This is not an Ada matter per se, but since I see such a vigorous 
discussion about the OOP topic in this forum I thought I'd ask this 
question here which has kept me thinking for a while and I wasn't able 
to find a satisfying canonical statement on this. Some say this and 
others say that, so I think I'd ask for opinions here so that perhaps I 
can form my own at the end.

Here is the question. Assume you have a large software system. Let's 
take the system for instance that I am involved in now as part of my 
work which is a multiplayer Client Server game. It is written in C++ but 
that shouldn't matter for the purpose of this topic.

There are "entities" on the server side that need to be accessed nearly 
everywhere. These entities best fit the Singleton Pattern because there 
is really only one instance of them, ever. For instance the class that 
handles the internet access and all client connections. Or the Ram based 
database that holds all the game objects. There is also the 
representation of the 3D world on the server side which is used for 
position check and all sort of 3D information.

These entities must be accessible from many locations in the code, 
although the region where access is needed can be somewhat restricted 
for instance the internet channel must be accessible for all player 
initiated actions but also by the User Agents that handle open windows 
on the player client and so on.

So my question is basically, is it OK to make these entities available 
through global access variables, or should they all be passed as 
arguments to function calls? We all know global objects are bad (not to 
mention that theorists heftily denounce the Singleton Pattern as bad, 
but, hey there is only one way to the internet and only one database, 
I'm sorry) but we also know that it is bad to carry "tramp data" through 
multiple levels of function calls when the functions do nothing with 
that data but pass it on to lower functions.

Global access can not really be tested in unit tests because they can 
not be passed as parameters. That's my greatest objection with the 
global concept but I dont want to pass 3, 4 or 5 parameters to every 
single function because a function called 5 levels below that call level 
might need access to those objects.

I don't think there is a silver bullet here but I would really love to 
hear what others think about this problem, specifically in an 
environment and with the examples I have shown here.

Thanks

---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18  1:36 What is your opinion on Global Objects? Hubert
@ 2014-11-18  2:52 ` Jeffrey Carter
  2014-11-18  3:08   ` Hubert
  2014-11-19 10:11   ` Jacob Sparre Andersen
  2014-11-18  8:54 ` Dmitry A. Kazakov
  2014-11-20 20:33 ` sbelmont700
  2 siblings, 2 replies; 27+ messages in thread
From: Jeffrey Carter @ 2014-11-18  2:52 UTC (permalink / raw)


On 11/17/2014 06:36 PM, Hubert wrote:
> 
> So my question is basically, is it OK to make these entities available through
> global access variables, or should they all be passed as arguments to function
> calls? We all know global objects are bad (not to mention that theorists heftily
> denounce the Singleton Pattern as bad, but, hey there is only one way to the
> internet and only one database, I'm sorry) but we also know that it is bad to
> carry "tramp data" through multiple levels of function calls when the functions
> do nothing with that data but pass it on to lower functions.

This is only a problem in poorly designed languages. In Ada these "singletons"
should be packages. No global variables needed. No access types needed, much
less global access variables.

-- 
Jeff Carter
"So if I understand 'The Matrix Reloaded' correctly, the Matrix is
basically a Microsoft operating system--it runs for a while and
then crashes and reboots. By design, no less. Neo is just a
memory leak that's too hard to fix, so they left him in ... The
users don't complain because they're packed in slush and kept
sedated."
Marin D. Condic
65

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18  2:52 ` Jeffrey Carter
@ 2014-11-18  3:08   ` Hubert
  2014-11-18  3:16     ` Shark8
                       ` (2 more replies)
  2014-11-19 10:11   ` Jacob Sparre Andersen
  1 sibling, 3 replies; 27+ messages in thread
From: Hubert @ 2014-11-18  3:08 UTC (permalink / raw)


> This is only a problem in poorly designed languages. In Ada these "singletons"
> should be packages. No global variables needed. No access types needed, much
> less global access variables.
>
Perhaps I didn't make myself clear enough. I am talking about something like

class A
{
	void function1();
	......
}

A s_object_a;


and then other code being able to access the object like
s_object.a.function1();

I guess in Ada you could have a package with a type and a variable in 
the body but you would still need a way to access that variable somehow 
in other packages, either through a parameter or globally and that's my 
question. What is the best way to access such an object


---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18  3:08   ` Hubert
@ 2014-11-18  3:16     ` Shark8
  2014-11-18  5:09     ` Jeffrey Carter
  2014-11-18 11:23     ` Brian Drummond
  2 siblings, 0 replies; 27+ messages in thread
From: Shark8 @ 2014-11-18  3:16 UTC (permalink / raw)


On 17-Nov-14 20:08, Hubert wrote:
> I guess in Ada you could have a package with a type and a variable in
> the body but you would still need a way to access that variable somehow
> in other packages, either through a parameter or globally and that's my
> question. What is the best way to access such an object

Generics?
You could have everything that depends on that singleton have its 
package (or accessor-function) passed in as a parameter.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18  3:08   ` Hubert
  2014-11-18  3:16     ` Shark8
@ 2014-11-18  5:09     ` Jeffrey Carter
  2014-11-18 11:23     ` Brian Drummond
  2 siblings, 0 replies; 27+ messages in thread
From: Jeffrey Carter @ 2014-11-18  5:09 UTC (permalink / raw)


On 11/17/2014 08:08 PM, Hubert wrote:
>>
> Perhaps I didn't make myself clear enough. I am talking about something like
> 
> class A
> {
>     void function1();
>     ......
> }
> 
> A s_object_a;
> 
> 
> and then other code being able to access the object like
> s_object.a.function1();

That may be necessary in C++, but not in Ada.

> I guess in Ada you could have a package with a type and a variable in the body
> but you would still need a way to access that variable somehow in other
> packages, either through a parameter or globally and that's my question. What is
> the best way to access such an object

Through the operations exported by the package. This is a very common Ada paradigm.

-- 
Jeff Carter
"So if I understand 'The Matrix Reloaded' correctly, the Matrix is
basically a Microsoft operating system--it runs for a while and
then crashes and reboots. By design, no less. Neo is just a
memory leak that's too hard to fix, so they left him in ... The
users don't complain because they're packed in slush and kept
sedated."
Marin D. Condic
65

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18  1:36 What is your opinion on Global Objects? Hubert
  2014-11-18  2:52 ` Jeffrey Carter
@ 2014-11-18  8:54 ` Dmitry A. Kazakov
  2014-11-20 20:33 ` sbelmont700
  2 siblings, 0 replies; 27+ messages in thread
From: Dmitry A. Kazakov @ 2014-11-18  8:54 UTC (permalink / raw)


On Mon, 17 Nov 2014 17:36:44 -0800, Hubert wrote:

[...]
> So my question is basically, is it OK to make these entities available 
> through global access variables, or should they all be passed as 
> arguments to function calls?

You would have some "Context" or "World" object and pass it along.

> We all know global objects are bad (not to 
> mention that theorists heftily denounce the Singleton Pattern as bad,

Yes, if misused for unrelated purposes, like module initialization etc.

And I doubt that "World" object is really a singleton. It is always better
to expose all stateful parameters rather than hiding them. E.g.

   Put_Line (Standard_Output, ...);

vs.

   Put_Line (...);

Later you might decide to use a different file for the output.
 
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18  3:08   ` Hubert
  2014-11-18  3:16     ` Shark8
  2014-11-18  5:09     ` Jeffrey Carter
@ 2014-11-18 11:23     ` Brian Drummond
  2014-11-19  2:50       ` Hubert
  2 siblings, 1 reply; 27+ messages in thread
From: Brian Drummond @ 2014-11-18 11:23 UTC (permalink / raw)


On Mon, 17 Nov 2014 19:08:03 -0800, Hubert wrote:

>> This is only a problem in poorly designed languages. In Ada these
>> "singletons"
>> should be packages. 

>  What is the best way to access such an object

Through the accessor subprograms supplied by the package.

- Brian


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18 11:23     ` Brian Drummond
@ 2014-11-19  2:50       ` Hubert
  2014-11-19  3:03         ` Jeffrey Carter
  2014-11-20 16:34         ` Stephen Leake
  0 siblings, 2 replies; 27+ messages in thread
From: Hubert @ 2014-11-19  2:50 UTC (permalink / raw)


On 11/18/2014 3:23 AM, Brian Drummond wrote:
> On Mon, 17 Nov 2014 19:08:03 -0800, Hubert wrote:
>
>>> This is only a problem in poorly designed languages. In Ada these
>>> "singletons"
>>> should be packages.
>
>>   What is the best way to access such an object
>
> Through the accessor subprograms supplied by the package.
>
> - Brian
>
That basically is a vote for global objects. Whether they are accessed 
through a global variable or some sort of getter function that returns 
access, it means bypassing the parameters. Well from what I read here, 
there are no strong opinions for either concept. Strange, I wasn't able 
to find good arguments for or against the two concepts anywhere, I guess 
they are just used interchangeably in applications.

Personally I am for global objects since they keep the interfaces 
smaller and avoid tramp data, the problem I see is just the unit test 
setup. Subprograms with side effect are hard to test automatically


---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-19  2:50       ` Hubert
@ 2014-11-19  3:03         ` Jeffrey Carter
  2014-11-19  9:13           ` Hubert
  2014-11-20 16:34         ` Stephen Leake
  1 sibling, 1 reply; 27+ messages in thread
From: Jeffrey Carter @ 2014-11-19  3:03 UTC (permalink / raw)


On 11/18/2014 07:50 PM, Hubert wrote:
> That basically is a vote for global objects. Whether they are accessed through a
> global variable or some sort of getter function that returns access

Most of us on here are talking about how to do it in Ada. However you do it in
C++ will be different, because C++ lacks modules. In Ada, there would be no
functions that return access.

At some point you have some requirements for your game, and somewhere in them is
something along the lines of "the game will keep track of this, that, and the
other".

In the design you make from these reqs you decide to meet this req with a DB
object. It allows you to add new (Key, Value) pairs, update the value for a key,
retrieve the value for a key, and delete the pair for a key.

In the Ada implementation, you implement this object as a package:

package Game.DB is
   procedure Add (Key : in Key_Value; Value : in Data_Value);

   procedure Update (Key : in Key_Value; Value : in Data_Value);

   function Value (Key : in Key_Value) return Data_Value;

   procedure Delete (Key : in Key_Value);
end Game.DB;

[I'm sure the reality is more complicated. No doubt there are many different
kinds of (Key, Value) pairs.]

This pkg would be part of a low-level layer in your S/W architecture. Anything
in higher layers that needs to access the DB can with the pkg and call its
subprograms.

This is the "Package as Object" pattern in Ada.

-- 
Jeff Carter
"You empty-headed animal-food-trough wiper."
Monty Python & the Holy Grail
04

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-19  3:03         ` Jeffrey Carter
@ 2014-11-19  9:13           ` Hubert
  2014-11-19 10:22             ` J-P. Rosen
  2014-11-19 17:37             ` Jeffrey Carter
  0 siblings, 2 replies; 27+ messages in thread
From: Hubert @ 2014-11-19  9:13 UTC (permalink / raw)


On 11/18/2014 19:03 PM, Jeffrey Carter wrote:
> On 11/18/2014 07:50 PM, Hubert wrote:
>> That basically is a vote for global objects. Whether they are accessed through a
>> global variable or some sort of getter function that returns access
>
> Most of us on here are talking about how to do it in Ada. However you do it in
> C++ will be different, because C++ lacks modules. In Ada, there would be no
> functions that return access.
>
> At some point you have some requirements for your game, and somewhere in them is
> something along the lines of "the game will keep track of this, that, and the
> other".
>
> In the design you make from these reqs you decide to meet this req with a DB
> object. It allows you to add new (Key, Value) pairs, update the value for a key,
> retrieve the value for a key, and delete the pair for a key.
>
> In the Ada implementation, you implement this object as a package:
>
> package Game.DB is
>     procedure Add (Key : in Key_Value; Value : in Data_Value);
>
>     procedure Update (Key : in Key_Value; Value : in Data_Value);
>
>     function Value (Key : in Key_Value) return Data_Value;
>
>     procedure Delete (Key : in Key_Value);
> end Game.DB;
>
> [I'm sure the reality is more complicated. No doubt there are many different
> kinds of (Key, Value) pairs.]
>
> This pkg would be part of a low-level layer in your S/W architecture. Anything
> in higher layers that needs to access the DB can with the pkg and call its
> subprograms.
>
> This is the "Package as Object" pattern in Ada.
>

Ok this is still an access of the global object directly from a 
subprogram. The subprogram then accesses the variable with the data 
ijnternally which is the same as accessing a global object. The data 
object itself is not passed through the parameters of the subprogram 
that uses it.

Sounds like most people are in favor of that method


---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18  2:52 ` Jeffrey Carter
  2014-11-18  3:08   ` Hubert
@ 2014-11-19 10:11   ` Jacob Sparre Andersen
  2014-11-20  6:21     ` Hubert
  1 sibling, 1 reply; 27+ messages in thread
From: Jacob Sparre Andersen @ 2014-11-19 10:11 UTC (permalink / raw)


Jeffrey Carter wrote:

> This is only a problem in poorly designed languages. In Ada these
> "singletons" should be packages.

A simple, untested example:

package Counter is
   procedure Reset;
   procedure Increment;
   function Value return Natural;
end Counter;

package body Counter is
   State : Natural := 0;

   procedure Reset is
   begin
      State := 0;
   end Reset;

   procedure Increment is
   begin
      State := State + 1;
   end Increment;

   function Value return Natural is
   begin
      return State;
   end Value;
end Counter;

Greetings,

Jacob
-- 
Photo of the day:
                    http://billeder.sparre-andersen.dk/dagens/2014-11-10

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-19  9:13           ` Hubert
@ 2014-11-19 10:22             ` J-P. Rosen
  2014-11-19 17:37             ` Jeffrey Carter
  1 sibling, 0 replies; 27+ messages in thread
From: J-P. Rosen @ 2014-11-19 10:22 UTC (permalink / raw)


Le 19/11/2014 10:13, Hubert a écrit :
> Ok this is still an access of the global object directly from a
> subprogram. The subprogram then accesses the variable with the data
> ijnternally which is the same as accessing a global object. The data
> object itself is not passed through the parameters of the subprogram
> that uses it.
<Plug>
Note that AdaControl (rule Directly_Accessed_Globals) can enforce that
this pattern is used safely. From the User's Guide:

"this rule enforces that all global variables are accessed by dedicated
access subprograms, and that only those subprograms access the variables
directly. If given with the keyword “protected” and/or “accept”, it
enforces that global variables are accessed only by dedicated protected
subprograms or tasks, ensuring that no race condition is possible"
</Plug>

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-19  9:13           ` Hubert
  2014-11-19 10:22             ` J-P. Rosen
@ 2014-11-19 17:37             ` Jeffrey Carter
  1 sibling, 0 replies; 27+ messages in thread
From: Jeffrey Carter @ 2014-11-19 17:37 UTC (permalink / raw)


On 11/19/2014 02:13 AM, Hubert wrote:
> 
> Ok this is still an access of the global object directly from a subprogram. The
> subprogram then accesses the variable with the data ijnternally which is the
> same as accessing a global object. The data object itself is not passed through
> the parameters of the subprogram that uses it.

The package represents the object ("object" being a design concept). The
variables in the pkg body represent the state of the object, same as the private
fields of an object represented by an instance of a tagged type (or a "class"
type in some other languages). Note the use of State for the hidden variable in
Andersen's example, and the SPARK "state" annotations for such packages.

-- 
Jeff Carter
"How'd you like to hide the egg and gurgitate
a few saucers of mocha java?"
Never Give a Sucker an Even Break
101


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-19 10:11   ` Jacob Sparre Andersen
@ 2014-11-20  6:21     ` Hubert
  0 siblings, 0 replies; 27+ messages in thread
From: Hubert @ 2014-11-20  6:21 UTC (permalink / raw)


Yes, I guess if something like that is called by a module or subprogram,
one has to make sure that this package is unit tested before the ones 
that use it are unit tested. I guess in the end there is no big 
difference whether you pass this sort of entity as a parameter or call 
it through these access functions. In the end, there are status 
variables maintained in a separate package, so I guess when you look at 
it this way, it doesn't really matter which way you chose, teh package 
must have been tested before it is used either way in other unit tests



---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-19  2:50       ` Hubert
  2014-11-19  3:03         ` Jeffrey Carter
@ 2014-11-20 16:34         ` Stephen Leake
  2014-11-20 21:11           ` Adam Beneschan
                             ` (2 more replies)
  1 sibling, 3 replies; 27+ messages in thread
From: Stephen Leake @ 2014-11-20 16:34 UTC (permalink / raw)


Hubert <herrdoktor@fumanchu.com> writes:

> That basically is a vote for global objects. Whether they are accessed
> through a global variable or some sort of getter function that returns
> access, it means bypassing the parameters. Well from what I read here,
> there are no strong opinions for either concept. Strange, I wasn't
> able to find good arguments for or against the two concepts anywhere,

If you can really, truly, absolutely guarrantee that you will _never_
need two different copies of the data structure, then the singleton
pattern makes sense (data in a single variable in a package body).

If you ever need two different copies of the data structure, then you
need to pass it around in parameters.

The symbol table for a compiler is a good candidate for a singleton.

A database connection is not; you will need to copy the database from
one object to another when you change the schema or move to a new
backend in the future.

-- 
-- Stephe


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-18  1:36 What is your opinion on Global Objects? Hubert
  2014-11-18  2:52 ` Jeffrey Carter
  2014-11-18  8:54 ` Dmitry A. Kazakov
@ 2014-11-20 20:33 ` sbelmont700
  2014-11-20 21:35   ` J-P. Rosen
  2 siblings, 1 reply; 27+ messages in thread
From: sbelmont700 @ 2014-11-20 20:33 UTC (permalink / raw)


For what it's worth, I'm in the "pass everything as an argument" camp (and really functional programming in general), and loathe the 'hidden state' setup, for the following reasons:
1. You are hardcoded to a particular implementation (i.e. no dispatching)
2. You always end up needing a second object, no matter much you think you don't think you will.
3. The majority of the program becomes impure
4. Things that access global objects are way more complex to try and test
5. Everything is compile-time constant (i.e. no creating or deleting things dynamically).

-sb



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-20 16:34         ` Stephen Leake
@ 2014-11-20 21:11           ` Adam Beneschan
  2014-11-21 15:25             ` Stephen Leake
  2014-11-21 21:53             ` Randy Brukardt
  2014-11-21  1:25           ` Hubert
  2014-11-21  3:00           ` Brad Moore
  2 siblings, 2 replies; 27+ messages in thread
From: Adam Beneschan @ 2014-11-20 21:11 UTC (permalink / raw)


On Thursday, November 20, 2014 8:34:31 AM UTC-8, Stephen Leake wrote:
> 
> > That basically is a vote for global objects. Whether they are accessed
> > through a global variable or some sort of getter function that returns
> > access, it means bypassing the parameters. Well from what I read here,
> > there are no strong opinions for either concept. Strange, I wasn't
> > able to find good arguments for or against the two concepts anywhere,
> 
> If you can really, truly, absolutely guarrantee that you will _never_
> need two different copies of the data structure, then the singleton
> pattern makes sense (data in a single variable in a package body).
> 
> If you ever need two different copies of the data structure, then you
> need to pass it around in parameters.
> 
> The symbol table for a compiler is a good candidate for a singleton.

This doesn't seem right to me.  

I haven't followed the whole discussion closely, so I might have missed something...  But in the case of a symbol table, an Ada compiler that implements generics by "macro instantiation" is an example of why a symbol table should *not* be a singleton.  If the compiler rescans the text of the generic, the entire context (i.e. what symbols are visible) will change while the generic is being instantiated, and then it will change back at the end.  And of course the generic can instantiate another generic.

This doesn't mean that any data structures are being copied.  The "symbol table" could be implemented as a single access object, or as a smallish record that contains an access object that points to the root of the symbol table and has some other housekeeping info.  But it still wouldn't be a singleton.  Making it a singleton (or global) would mean that any time the context has to change, some subprogram has to save the global value into a local, change the global value, call whatever other subprogram will be using the new context, then restore the global value from the local.  I've worked with this kind of arrangement and have suffered from numerous migraines as a result.  (That's one of the reasons I try not to use singleton objects in general; there have been too many times when it's seemed clear that there needs to be only one instance of something, and it's come back to bite me.)

In any case, though, I don't know what it has to do with "copies of a data structure".  That seems to be the wrong criterion, especially in a case like a compiler symbol table.  Perhaps I just view the world too differently from you, or you're just used to working with different examples than I am.

                                -- Adam


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-20 20:33 ` sbelmont700
@ 2014-11-20 21:35   ` J-P. Rosen
  2014-11-21  1:02     ` sbelmont700
  2014-11-21  9:01     ` Dmitry A. Kazakov
  0 siblings, 2 replies; 27+ messages in thread
From: J-P. Rosen @ 2014-11-20 21:35 UTC (permalink / raw)


Le 20/11/2014 21:33, sbelmont700@gmail.com a écrit :
> For what it's worth, I'm in the "pass everything as an argument" camp
> (and really functional programming in general), and loathe the
> 'hidden state' setup, for the following reasons:
Let's see what the other camp has to respond...

> 1. You are hardcoded to a particular implementation (i.e. no dispatching)
Yes, it is more static, therefore safer and more easily provable.
Dispatching is a very powerful tool, but only when you really need it.

> 2. You always end up needing a second object, no matter much you think you don't think you will.
Doesn't meet my experience. Knowing that by design there can be only one
object simplifies understanding and provability. You don't have to worry
about which object you are dealing with - there is only one.

> 3. The majority of the program becomes impure
??? Please explain you notion of "purity".

> 4. Things that access global objects are way more complex to try and test
Yes, when accessing in uncontrolled ways global variables from multiple
places. No with proper encapsulation (like here) with accessors and
selectors that can control exclusive access if necessary.

> 5. Everything is compile-time constant (i.e. no creating or deleting things dynamically).
I would regard this as a huge benefit - dynamicity has always been
opposed to simplicity and provability.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-20 21:35   ` J-P. Rosen
@ 2014-11-21  1:02     ` sbelmont700
  2014-11-21  1:31       ` Hubert
  2014-11-21  9:01     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 27+ messages in thread
From: sbelmont700 @ 2014-11-21  1:02 UTC (permalink / raw)


On Thursday, November 20, 2014 4:35:20 PM UTC-5, J-P. Rosen wrote:
>
> Let's see what the other camp has to respond...
> 

As you have pointed out, either way is a double-edged sword; one programmers rigid and inflexible code is another programmers safe and reliable code, and all engineering is compromise.  That being said, in my experiences, the only proven way to know when the customer is going to change the requirements is when he says they are never going to change the requirements.  For something like a game, assuming a fixed number (especially one) of anything is a surefire way to incur massive rework.  Suppose, for instance, the game evolves to a multiplayer version; a server might need to host a dynamic and always changing number of game engines.

>
> ??? Please explain you notion of "purity".
> 

I guess generally I mean "referentially transparent", but more practically I mean "pragma Pure".

-sb

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-20 16:34         ` Stephen Leake
  2014-11-20 21:11           ` Adam Beneschan
@ 2014-11-21  1:25           ` Hubert
  2014-11-21  3:00           ` Brad Moore
  2 siblings, 0 replies; 27+ messages in thread
From: Hubert @ 2014-11-21  1:25 UTC (permalink / raw)


> A database connection is not; you will need to copy the database from
> one object to another when you change the schema or move to a new
> backend in the future.
>
Yes my application is a little different from what most of you probably 
work on. Like I said, I am working on a multiplayer game and the things 
that are implemented as singletons here exist absolutely only once.

The reason for my question was not so much for my actual work but for 
future subprojects we will be doing where we want to attempt a different 
approach to the design, with more upfront planning and a scheme that is 
more like Structured Design, but with elements that allow for OOP 
elements, so we can't just take the old books by Yourdon et al and apply 
their technique, since we can't deny that there is value in small scale 
inheritance sometimes yet the techniques and diagrams for Structured 
Design don't take that into account since they are mostly from the 70s 
and 80s.

Anyway thanks a lot everybody for the input, I didn't think of global 
objects as subprogram calls with internal status variables before since 
I am kind of preoccupied with C++ thinking and look at most everything 
as a self sufficient object, so it's good to get a different perspective.


---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-21  1:02     ` sbelmont700
@ 2014-11-21  1:31       ` Hubert
  0 siblings, 0 replies; 27+ messages in thread
From: Hubert @ 2014-11-21  1:31 UTC (permalink / raw)



> As you have pointed out, either way is a double-edged sword; one programmers rigid and inflexible code is another programmers safe and reliable code, and all engineering is compromise.  That being said, in my experiences, the only proven way to know when the customer is going to change the requirements is when he says they are never going to change the requirements.  For something like a game, assuming a fixed number (especially one) of anything is a surefire way to incur massive rework.  Suppose, for instance, the game evolves to a multiplayer version; a server might need to host a dynamic and always changing number of game engines.



Our game is already a multiplayer game and although your a=point about 
customers changing their mind is generally true, in a scenario like ours 
it is not since we are customers, designers and programmers in one team, 
so there is no need to consider outside people or rather people with 
little understanding of how their ideas look when being realized in 
software and thus be likely to change their minds once they see the result.

Also, our software world does not so much consist of active objects or 
whatever is used in web or phone apps these days. Think of it more like 
an old fashioned mainframe system. Once it runs there will be changes 
for upgrades of course but nothing that requires a quick implementation 
or rapid reaction to changing demands, so the "inflexible" argument does 
not affect our case, although it may be important to consider in other 
scenarios.


---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-20 16:34         ` Stephen Leake
  2014-11-20 21:11           ` Adam Beneschan
  2014-11-21  1:25           ` Hubert
@ 2014-11-21  3:00           ` Brad Moore
  2 siblings, 0 replies; 27+ messages in thread
From: Brad Moore @ 2014-11-21  3:00 UTC (permalink / raw)


On 2014-11-20 9:34 AM, Stephen Leake wrote:
> If you can really, truly, absolutely guarrantee that you will _never_
> need two different copies of the data structure, then the singleton
> pattern makes sense (data in a single variable in a package body).
>
> If you ever need two different copies of the data structure, then you
> need to pass it around in parameters.

Not entirely true. Another possibility is to use generic packages.
Each instantiation of the generic could contain an independent copy of 
the data structure. One can select which object to operate on by 
selecting and using the generic instantiation of interest.

I think that generally this is not a good design, but I have seen it 
used in a fair bit in practice. For this case, I generally prefer to see 
a type declared in the visible part of the package that can is passed as 
a parameter to the subprograms declared in the package.

This is generally more flexible. One can use the object as a component 
in a larger record structure, or protect access to certain objects, by 
wrapping them in a protected object.

Otherwise, if the singleton is buried in a package body without any 
protection around the object, if someone wants to use the instantiation 
from multiple tasks, the usage can be unsafe or error prone and messy,
and the object does not have composability.

However, there are probably certain abstractions where that approach 
makes sense.

For the singleton case, I tend to prefer the object inside the body of 
the package approach though.

Brad


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-20 21:35   ` J-P. Rosen
  2014-11-21  1:02     ` sbelmont700
@ 2014-11-21  9:01     ` Dmitry A. Kazakov
  2014-11-22  7:46       ` J-P. Rosen
  1 sibling, 1 reply; 27+ messages in thread
From: Dmitry A. Kazakov @ 2014-11-21  9:01 UTC (permalink / raw)


On Thu, 20 Nov 2014 22:35:16 +0100, J-P. Rosen wrote:

> Le 20/11/2014 21:33, sbelmont700@gmail.com a écrit :
>> For what it's worth, I'm in the "pass everything as an argument" camp
>> (and really functional programming in general), and loathe the
>> 'hidden state' setup, for the following reasons:
> Let's see what the other camp has to respond...
> 
>> 1. You are hardcoded to a particular implementation (i.e. no dispatching)
> Yes, it is more static, therefore safer and more easily provable.

This is a bit contradictory. Proofs as such are always against some stated
things. That already presumes several instances. Some instances may
withstand the proof some don't. Thus the idea of proving an inherent
singleton looks somewhat dubious. Singleton is only in the usage not a
property.

Anyway proving things about a type (singleton-object) might be easier than
doing this for an ad-hoc package.

> Dispatching is a very powerful tool, but only when you really need it.

Dispatching does not make sense for singletons, but Ada won't do any
dispatch anyway since the object's type is not class-wide.

>> 2. You always end up needing a second object, no matter much you think you
>> don't think you will.
> Doesn't meet my experience. Knowing that by design there can be only one
> object simplifies understanding and provability. You don't have to worry
> about which object you are dealing with - there is only one.

But the design may change and maintaining changes on the client side is
easier when the object is properly typed rather than when it is implicit,
in an assorted sets of subprograms stuffed into a package.

And you forgot about reuse. A singleton implementation may use some other
types implementations or provide its implementation for reuse.

>> 3. The majority of the program becomes impure
> ??? Please explain you notion of "purity".

I understood it as:

Pure = the only side effect is on the mutable arguments and/or the result.

>> 5. Everything is compile-time constant (i.e. no creating or deleting things dynamically).
> I would regard this as a huge benefit - dynamicity has always been
> opposed to simplicity and provability.

Huh, that reminds me of a relatively fresh discussion about termination of
a library-level task in Ada. A typical singleton, isn't it? Yet impossible
to terminate on application exit! Making it an access type (=not a
singleton) or moving out of the library level solved the problem.

Ego, it is not simple to have things static, though most things aren't any
static anyway, not even keeping them at the library level is simple.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-20 21:11           ` Adam Beneschan
@ 2014-11-21 15:25             ` Stephen Leake
  2014-11-21 21:53             ` Randy Brukardt
  1 sibling, 0 replies; 27+ messages in thread
From: Stephen Leake @ 2014-11-21 15:25 UTC (permalink / raw)


Adam Beneschan <adambeneschan@gmail.com> writes:

> On Thursday, November 20, 2014 8:34:31 AM UTC-8, Stephen Leake wrote:
>> 
>> > That basically is a vote for global objects. Whether they are accessed
>> > through a global variable or some sort of getter function that returns
>> > access, it means bypassing the parameters. Well from what I read here,
>> > there are no strong opinions for either concept. Strange, I wasn't
>> > able to find good arguments for or against the two concepts anywhere,
>> 
>> If you can really, truly, absolutely guarrantee that you will _never_
>> need two different copies of the data structure, then the singleton
>> pattern makes sense (data in a single variable in a package body).
>> 
>> If you ever need two different copies of the data structure, then you
>> need to pass it around in parameters.
>> 
>> The symbol table for a compiler is a good candidate for a singleton.
>
> This doesn't seem right to me.  
>
> I haven't followed the whole discussion closely, so I might have
> missed something... But in the case of a symbol table, an Ada compiler
> that implements generics by "macro instantiation" is an example of why
> a symbol table should *not* be a singleton. If the compiler rescans
> the text of the generic, the entire context (i.e. what symbols are
> visible) 

That's not the _entire_ symbol table, just one subtree.

I've never implemented a compiler, but I have implemented an
interpreter; it has a singleton symbol table.

I imagine "context" is a pointer into the symbol table, showing what is
visible at the current code position.

It certainly depends on how the compiler uses the symbol table.

-- 
-- Stephe


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-20 21:11           ` Adam Beneschan
  2014-11-21 15:25             ` Stephen Leake
@ 2014-11-21 21:53             ` Randy Brukardt
  1 sibling, 0 replies; 27+ messages in thread
From: Randy Brukardt @ 2014-11-21 21:53 UTC (permalink / raw)


"Adam Beneschan" <adambeneschan@gmail.com> wrote in message 
news:65f2470c-0828-4f97-9f0e-f11966896c06@googlegroups.com...
...
>> The symbol table for a compiler is a good candidate for a singleton.
>
>This doesn't seem right to me.

It does to me. :-)

>I haven't followed the whole discussion closely, so I might have missed 
>something...  But
>in the case of a symbol table, an Ada compiler that implements generics by 
>"macro
>instantiation" is an example of why a symbol table should *not* be a 
>singleton.  If the
>compiler rescans the text of the generic, the entire context (i.e. what 
>symbols are visible)
>will change while the generic is being instantiated, and then it will 
>change back at the end.
>And of course the generic can instantiate another generic.

This makes no sense whatsoever. First of all, you can't instantiate a 
generic by rescanning the text, because all of the objects are bound when 
they are initially compiled. Most likely, everything would resolve wrong. 
Trying to make that work would be an absolute nightmare.

Our symboltable is purely a singleton; it reflects exactly the declarations 
available to the program at the current point in the compilation. (Our 
compiler is syntax-driven, so for most purposes it can be considered one 
pass -- we never go backwards in the source or symbols). Every change in the 
code changes the symboltable. (Initially, we deleted declarations as they 
went out of scope, but that always seemed to leave dangling pointers and was 
just a lot more complex than marking things as invisble.) That's why 
implementing ASIS is impractical in our compiler -- we don't ever have a 
view of the compilation as a whole to work from.

Generic instantiations are implemented by copying the symboltable for the 
generic unit and making the changes required by the instantiation. We don't 
do macro expansion, but if we did, we'd do it by duplicating a tree form of 
the unit (in which all of the symbols are already bound). Trying to work 
from the text is madness (especially as our parser is also a singleton)!

Now, I'm well aware that anything done in someone else's compiler is totally 
weird -- the things that other ARG members consider hard (or easy for that 
matter) often make little sense to me. I could imagine structuring a symbol 
table as a set of units (which would not be a singleton). [I can't imagine 
the Rational compiler, which supposely doesn't have a symbol table at all. 
But whatever.]

Anyway, I think the main point is that there really is no rules. Sometimes a 
singleton package is the best design. Sometimes a bunch of global spagetti 
is about all that would ever work (that's probably the best description of 
the symbol table in Janus/Ada)! [We couldn't afford the code that 
encapsulation would have cost back on CP/M and MS-DOS -- indeed, we use 
jumps, not calls for elaboration because we saved the call setup code *200 
units -- which was enough to make a big difference when getting code to fit 
into 64K RAM.]

                                           Randy.





^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-21  9:01     ` Dmitry A. Kazakov
@ 2014-11-22  7:46       ` J-P. Rosen
  2014-11-22  9:02         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 27+ messages in thread
From: J-P. Rosen @ 2014-11-22  7:46 UTC (permalink / raw)


Le 21/11/2014 10:01, Dmitry A. Kazakov a écrit :
> On Thu, 20 Nov 2014 22:35:16 +0100, J-P. Rosen wrote:
> 
>>> 1. You are hardcoded to a particular implementation (i.e. no dispatching)
>> Yes, it is more static, therefore safer and more easily provable.
> 
> This is a bit contradictory. Proofs as such are always against some stated
> things. That already presumes several instances. Some instances may
> withstand the proof some don't. Thus the idea of proving an inherent
> singleton looks somewhat dubious. Singleton is only in the usage not a
> property.
Not at all. Where we differ is that you are thinking in terms of classes
first, then instances. You see the properties at class level, and then a
singleton (a class with a single instance) makes little sense.

I am thinking in terms of objects first. Objects have properties. If
several objects share a common behaviour, then I group them into
"equivalence classes", and the common properties of the objects become
the properties of the class. If you think objects first, singletons make
perfect sense.

> And you forgot about reuse. A singleton implementation may use some other
> types implementations or provide its implementation for reuse.
You implicitely think of reuse by inheritance. I favor reuse by composition.

> 
>>> 3. The majority of the program becomes impure
Not really. If your problem requires a global state, then it is
"impure". Whether you use global variables in a package or a global
object gathering the data that you pass to subprograms does not change
anything.

>>> 5. Everything is compile-time constant (i.e. no creating or deleting things dynamically).
>> I would regard this as a huge benefit - dynamicity has always been
>> opposed to simplicity and provability.
> 
> Huh, that reminds me of a relatively fresh discussion about termination of
> a library-level task in Ada. A typical singleton, isn't it? Yet impossible
> to terminate on application exit! 
??? Select ... or terminate works perfectly well for library tasks. I do
that all the time.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: What is your opinion on Global Objects?
  2014-11-22  7:46       ` J-P. Rosen
@ 2014-11-22  9:02         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 27+ messages in thread
From: Dmitry A. Kazakov @ 2014-11-22  9:02 UTC (permalink / raw)


On Sat, 22 Nov 2014 08:46:36 +0100, J-P. Rosen wrote:

> Le 21/11/2014 10:01, Dmitry A. Kazakov a écrit :
>> On Thu, 20 Nov 2014 22:35:16 +0100, J-P. Rosen wrote:
>> 
>>>> 1. You are hardcoded to a particular implementation (i.e. no dispatching)
>>> Yes, it is more static, therefore safer and more easily provable.
>> 
>> This is a bit contradictory. Proofs as such are always against some stated
>> things. That already presumes several instances. Some instances may
>> withstand the proof some don't. Thus the idea of proving an inherent
>> singleton looks somewhat dubious. Singleton is only in the usage not a
>> property.
> Not at all. Where we differ is that you are thinking in terms of classes
> first, then instances. You see the properties at class level, and then a
> singleton (a class with a single instance) makes little sense.

Correction: not classes, types. An instance, an object has a type.
Instances of types form a class.

Classes are relevant only when reuse comes in question.

> I am thinking in terms of objects first. Objects have properties. If
> several objects share a common behaviour, then I group them into
> "equivalence classes", and the common properties of the objects become
> the properties of the class. If you think objects first, singletons make
> perfect sense.

Yes. That is what OOA/D say. I don't believe in OOA/D in software design.
To me it is ad hocery and, worse, untyped.

>> And you forgot about reuse. A singleton implementation may use some other
>> types implementations or provide its implementation for reuse.
> You implicitely think of reuse by inheritance. I favor reuse by composition.

So what? You could find useful to reuse parts of the singleton
implementation per composition as well.

>>>> 3. The majority of the program becomes impure
> Not really. If your problem requires a global state, then it is
> "impure". Whether you use global variables in a package or a global
> object gathering the data that you pass to subprograms does not change
> anything.

It does for the clients because it clearly defines the context the client
is allowed to update. The origin of the context if it is global or not,
plays no role to the client. In particular, the functionality of the client
does not depend on whether the context is a singleton. One constraint less
to be aware of, safer is the design.

>>>> 5. Everything is compile-time constant (i.e. no creating or deleting things dynamically).
>>> I would regard this as a huge benefit - dynamicity has always been
>>> opposed to simplicity and provability.
>> 
>> Huh, that reminds me of a relatively fresh discussion about termination of
>> a library-level task in Ada. A typical singleton, isn't it? Yet impossible
>> to terminate on application exit! 
> ??? Select ... or terminate works perfectly well for library tasks. I do
> that all the time.

It was not possible to have terminate alternative (in practice it is almost
always so).

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2014-11-22  9:02 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-18  1:36 What is your opinion on Global Objects? Hubert
2014-11-18  2:52 ` Jeffrey Carter
2014-11-18  3:08   ` Hubert
2014-11-18  3:16     ` Shark8
2014-11-18  5:09     ` Jeffrey Carter
2014-11-18 11:23     ` Brian Drummond
2014-11-19  2:50       ` Hubert
2014-11-19  3:03         ` Jeffrey Carter
2014-11-19  9:13           ` Hubert
2014-11-19 10:22             ` J-P. Rosen
2014-11-19 17:37             ` Jeffrey Carter
2014-11-20 16:34         ` Stephen Leake
2014-11-20 21:11           ` Adam Beneschan
2014-11-21 15:25             ` Stephen Leake
2014-11-21 21:53             ` Randy Brukardt
2014-11-21  1:25           ` Hubert
2014-11-21  3:00           ` Brad Moore
2014-11-19 10:11   ` Jacob Sparre Andersen
2014-11-20  6:21     ` Hubert
2014-11-18  8:54 ` Dmitry A. Kazakov
2014-11-20 20:33 ` sbelmont700
2014-11-20 21:35   ` J-P. Rosen
2014-11-21  1:02     ` sbelmont700
2014-11-21  1:31       ` Hubert
2014-11-21  9:01     ` Dmitry A. Kazakov
2014-11-22  7:46       ` J-P. Rosen
2014-11-22  9:02         ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox