edA-qa | 3 Oct 10:35

Revisit synonyms and references / typing

I would like to revist Slawek's example from before of the invoker series:

template<class T> void InvokerA( T^ fun )
{ fun.doSomething(); }

template<class T> void InvokerB( T^ fun )
{ InvokerA( fun ); }

...
T local;
T^ shared = new T();
InvokerB( local );
InvokerB( shared );

I believe this meets the requirements of no copying of the parameters 
without needing a reference.  Here's why, and it has to do with typing, 
an issue that has been somewhat ignored.

In my previous statemtn about references and instances, I am of the 
opinion, that in the way C2 works, the reference type has nothing to do 
with the actual instance type.  Therefore:

T local;
T^ sharedRef = new T();
T local^ localRef = @local;
T* ptr = /*something*/;

Unlike C/C++, in C2 all of the above references are used in the same 
fashion:
	local.func();
	sharedRef.func();
	localRef.func();
	ptr.func();

This is implying that the standard operators, and function calls, are 
working not on the reference, but on the instance.  In which case, all 
of the above have these types:
	local;	//object type T, locality: stack, ref type: value
	sharedRef;	//object type T, locality: heap, ref type: shared
	localRef;	//object type: T, locality: stack
	ptr;	//object type: T, locality: unknown, ref type: pointer

Now, given a function signature:
	template<typename Q> void func( Q any^ ref )

How does type resolution work?  In the above case it is requesting any 
reference to Q, thus the object type is of most importance, so it works 
with the object type, not reference type, thus:

func( local ):
	matches object type, to which a reference can be made:	
		T local^ tempRef @= local;
		ref @= tempRef;

func( sharedRef ):
	matches object type, to which a reference can be made:
		T shared^ tempRef @= sharedRef;
		ref @= tempRef;

This is based on an observation of the following.

Given a variable:
	T any^ ref;
The following statements are possible, and yield a reference to the object:

	ref @= local;
	ref @= sharedRef;
	ref @= localRef;
	ref @= ptr;

Thus, there is no reason that our invoker would yield a T^^, as the 
first conversion checked above, works fine.

This comes around to the synonym notation (&), which may be needed 
elsewhere, but to meet Slawek's requirements, is not needed.

(Note: This is difficult to explain the above, so I may have to redo it. 
In any case it leaves a lot of open questions about automatic conversions.)

--

-- 
edA-qa mort-ora-y
Idea Architect
http://disemia.com/

-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl

Re: Revisit synonyms and references / typing

edA-qa wrote:
> In my previous statemtn about references and instances, I am of the 
> opinion, that in the way C2 works, the reference type has nothing to do 
> with the actual instance type. 

For clarification, an instance is characterized by a duet of type and 
locality. Locality in turn determines types of references that are 
allowed to refer to that instance. The relationship between a reference 
type and locality of an instance is at the center of the C2 referencing 
model.

An object shall only be accessed via a reference (or less safely via a 
pointer). This is also true for value-types. Consider this example:

T localT;

Here, `localT' is a const reference to a stack object T (`localT' cannot 
be rebound). Object T will be destroyed deterministically, that is, when 
the `localT' reference goes out of scope.

T& st = localT;  // error, there cannot be a synonym to a (value) type,
                  //   only to a reference.

T local^& st = localT; // st: ok, synonym to reference to local T

One may think that the indexing operator brakes the "no synonym to 
value-type" rule:

[]<T> ar[5](); // array of 5 Ts initialized with default constructor

?? = ar[0]; // what does ar[0] return?

Here `ar' is a const reference to a local array of 5 (contiguous in 
memory) initialized elements of type T. operator[] returns a synonym to 
a const reference to local T. Elements of the array can be assigned to 
references to local T or to any T. Array will be destroyed when the `ar' 
reference goes out of scope.

> T local;
> T^ sharedRef = new T();
> T local^ localRef = @local;

T local^ localRef = local; // initialization of a reference
                            //   is binding. No `@'.

> T* ptr = /*something*/;
> 
> Unlike C/C++, in C2 all of the above references are used in the same 
> fashion:
>     local.func();
>     sharedRef.func();
>     localRef.func();
>     ptr.func();
> 

Pointers do not act like references. Consider,

T* p1;        // pointer to T

p1 = @sharedRef;

p1 -> func(); // invokes func on object pointed
               //   by p1.

++p1;         // increments pointer, returns pointer
++(*p1)       // calls T.operator++(), returns reference
               //   to any T

Iterators will overload operators (->, *T, ++) to imitate pointers
[ptr->func(), *ptr, ++ptr]. Operator dot `.' cannot be overloaded.

Pointer to void will be used for compatibility with C and in the
implementation of an Any type --safe, generic container for single
values of different value types, provided by C2 std. library [Note:
references to void are not allowed].

> This is implying that the standard operators, and function calls, are 
> working not on the reference, but on the instance.  

Except for pointers.

> Thus, there is no reason that our invoker would yield a T^^, as the 
> first conversion checked above, works fine.

I agree.

--

-- 
Slawomir Lisznianski
C2 Language Group Principal (http://c2-lang.org)

-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
Rajesh Walkay | 30 Sep 22:16
Favicon

main function signature?

If pointers are second class citizens in C2, what would be the main 
function signature? (-:

-Rajesh

-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl

Re: main function signature?


Rajesh Walkay wrote: > If pointers are second class citizens in C2, what would be the main > function signature? (-:
It depends on what type is str of in the following expression: T str = "What am I"; Knowing the answer to the above will help us determine the signature of the main function. In C++, T is of type: const char* <- pointer to const characters In C2, T might be of type: []<char const> local^ <- reference to local array of const characters Since argv in C++ is a pointer to pointers to const chars, C2 argv would be declared as a reference to array of references to arrays of const characters. Our main function would then have a signature: int Main(int, []<[]<char const> any^> any^); I can just imagine your disappointment-- it surely looks easy to make a mistake. The easiest way to make it shorter would be to declare a typedef in some standard header: // file: System.h2 namespace System { typedef int RtCode; typedef int Argc; typedef []<[]<char const> any^> any^ Argv; typedef []<[]<char const> any^> any^ Env; // ... } We would then write: // file: UserMain.c2 #include <System.h2> using namespace System; RtCode Main(Argc, Argv) { } Using plain arrays is not a convenient method of dealing with sequences of characters. Arrays do not resize nor support encoding schemes (UTF, ASCII...) to name a few deficiencies. Instead, String class should be used by passing an array of const characters to its constructor: template <typename Ty, typename Enc, ...> class String { public: String([]<Ty const> any^ str); // ... }; // and somewhere else we might have: typedef String<char, AsciiEncoding<char>, ...> AsciiString; typedef String<char, UtfEncoding<char>, ...> Utf8String; typedef String<short, UtfEncoding<short>, ...> Utf16String; typedef String<int, UtfEncoding<int>, ...> Utf32String; // ... We could then write something like: using namespace System; RtCode Main(Argc argc, Argv argv) { AsciiString programName = argv[0]; // ... return skSuccessCode; } -- -- Slawomir Lisznianski C2 Language Group Principal (http://c2-lang.org) ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal Use IT products in your business? Tell us what you think of them. Give us Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more http://productguide.itmanagersjournal.com/guidepromo.tmpl
edA-qa | 30 Sep 19:43

const references and synonyms

This is a recall of a previous constant discussion.  I would like to 
differentiate between const instances and const references.

//the following is a shared reference to a const heap instance
T const ^ ref;	

//the following is a const shared reference to a heap instance
T ^ const ref;

//const references disallow rebinding, ro conversion to non-const
//references
ref @= otherRef;	//error, cannot rebind

void func( T^ param );
func( ref );	//error, cannot conver to non-const reference

This then needs to be extended to synonyms in the function call syntax. 
  To show why, here is an example of what bad happens without:

template<typename T>
void beNice( T& ref ) {
	ref @= somethingElse;
}

The callers of this function have no guarantee that their shared 
references aren't being rebound -- while sometimes they may want this, 
other times clearly not.  So:

template<typename T>
void beNice( T const& ) {
	ref @= somethingElse;	//fails, cannot rebind const reference
}

This of course requires a "^ const" to have meaning, which I've define 
above.

--

-- 
edA-qa mort-ora-y
Idea Architect
http://disemia.com/

-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
Slawomir Lisznianski | 30 Sep 20:47

Re: const references and synonyms


edA-qa wrote: > This is a recall of a previous constant discussion. I would like to > differentiate between const instances and const references.
Everything you stated looks fine to me. -- -- Slawomir Lisznianski C2 Language Group Principal (http://c2-lang.org) ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal Use IT products in your business? Tell us what you think of them. Give us Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more http://productguide.itmanagersjournal.com/guidepromo.tmpl
edA-qa | 30 Sep 19:16

Clarified references, shortcut notation

Okay, looking at the types more and more I get a clear picture of how 
they all related to each other and their usage.  I will try to give that 
picture here.

Firstly, in C2 all variables comprise two parts, the instance and the 
reference (I intentionally use this word).

Instances can exist:
	-on the stack
	-in the heap
	-elsewhere (not yet defined)

References are of the types:
	-shared ref to instance in heap
	-local ref to instance on stack
	-value ref to instance on stack
	-ref to instance anywhere

Notes:
-when all shared refs to items in the heap go out of scope, the instance 
is marked for removal/deleted
-when stack space for a stack instance goes out of scope, the instance 
is removed/deleted
-a value ref is the same as a local ref, except that it may not be 
rebound (this limitation is to prevent the losing of an instance)
-in this discussion, a pointer is being ignored, as I believe it can be 
implemented as a non-fundamental type

Notation:

//creates an instance in heap, and returns a shared reference
new T();

//declares a shared reference, uninitialized bound to null (the 
following are all the same)
T^ sharedRef;	
T shared^ sharedRef;
T^ sharedRef = null;

//binds a heap instance
sharedRef @= otherSharedRef;

//creates an instance on the stack, and a value reference which is bound 
to this instance
T value;

//declares a local reference (unitialized bound to null)
T local^ localRef;
T local^ localRef = null;

//binds a local ref to a stack instance
localRef @= value;
localRef @= otherLocalRef;

//declares an any reference (unitiialized bound to null)
T any^ anyRef;
T any^ anyRef = null;

//binds an any ref to a stack instance, and heap instance
anyRef @= value;
anyRef @= localRef;
anyRef @= sharedRef;

--

-- 
edA-qa mort-ora-y
Idea Architect
http://disemia.com/

-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
Slawomir Lisznianski | 30 Sep 20:35

Re: Clarified references, shortcut notation


edA-qa wrote: > Okay, looking at the types more and more I get a clear picture of how > they all related to each other and their usage. I will try to give that > picture here.
Looks good. Only one question.. If we followed the C++ rules of initialization of local objects, then any uninitialized, non-static, local references would not be bound to null. For example: void fun() { T static^ t0; T^ t1 = null; T^ t2; if ( @t0 || @t1 ) // ok: evaluates to false if ( @t2 ) // undefined: t2 used but uninitialized } Above, t0 and t1 are bound to null. t2 reference is of indeterminate initial value. -- -- Slawomir Lisznianski C2 Language Group Principal (http://c2-lang.org) ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal Use IT products in your business? Tell us what you think of them. Give us Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more http://productguide.itmanagersjournal.com/guidepromo.tmpl
edA-qa | 1 Oct 18:07

Re: Clarified references, shortcut notation


Slawomir Lisznianski wrote: > T static^ t0; > T^ t1 = null; > T^ t2; > Above, t0 and t1 are bound to null. t2 reference is of indeterminate > initial value.
C++ is confused when it comes to default construction and initialization. I have the opinion that unless stated otherwise, all objects should be default initialized and all references should be null initialized. Meaning t2 about starts as null. This makes sense since it is the *normal* case in programming. For those people that need to make fine-tine optimizations you could introduce this syntax: T^ t2 = uninit; Even with performance in mind it is rare that one would specifically want to leave a value unitialized (an optimizer will remove the redundant initialization should it not be needed). -- -- edA-qa mort-ora-y Idea Architect http://disemia.com/ ------------------------------------------------------- This SF.net email is sponsored by: IT Product Guide on ITManagersJournal Use IT products in your business? Tell us what you think of them. Give us Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more http://productguide.itmanagersjournal.com/guidepromo.tmpl

Re: Clarified references, shortcut notation

edA-qa wrote:
> C++ is confused when it comes to default construction and 
> initialization.  I have the opinion that unless stated otherwise, all 
> objects should be default initialized and all references should be null 
> initialized.

I agree.

> Even with performance in mind it is rare that one would specifically 
> want to leave a value unitialized (an optimizer will remove the 
> redundant initialization should it not be needed).

Arrays are an exception and their initialization should be optional. 
Containers, such as Vector, will be implemented using a combination of 
uninitialized arrays and a placement new. Below is the proposed syntax 
for array initialization per Declarators document:

[]<int> a1[10](-1); // array of 10 integers initialized with -1

[]<int> a2[10];     // array of 10 uninitialized integers;
                     //   memory is aligned for constructing objects
                     //   of type int

[]<int> a3[10]();   // array of 10 zero-initialized integers

struct A {
   A();
   A(int);
};

[]<A> b1[10](12);  // array of 10 instances of `A' constructed
                    //    using A(int)

[]<A> b2[10];      // array of 10 uninitialized entities of A;
                    //   memory is aligned for constructing objects
                    //   of type `A'

new (@b3[0])(12);  // constructs an `A' object at location 0 using
                    //    A(int)

new (@b3[1])();    // constructs an `A' object at location 1 using
                    //    A()

[]<A> b4[10]();    // array of 10 instances of `A' constructed
                    //    using A()

--

-- 
Slawomir Lisznianski
C2 Language Group Principal (http://c2-lang.org)

-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
Rajesh Walkay | 29 Sep 22:57
Favicon

references to shared objects - too much typing...

Isn't T shared^ too much typing? If C2 makes heap my primary store why 
not defaulting references to refer to objects on shared store only? In 
such a case reference to any-store object would be a special case (being 
less safe and all that) and expect users to be explicit. For example,

T^ myT1 = new T(); /// myT1: reference to shared T
T any^ myT2 = myT; /// myT2: reference to any-store T
myT1 @= myT2; /// error... cannot rebind from any-store

I used "any" for the lack of better name (-:

Constructors would then typically be written as:

struct X {
   X(X const any^ rhs) /// rhs: reference to any-store const X
   {...}
};

About references to local objects..., what's the use of explicitly 
specifying "local"? Won't shared and any-store qualifiers suffice?

-Rajesh

-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl

Gmane