www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is this strange alias syntax?

reply Andrej Mitrovic <none none.none> writes:
Taken from the docs:

alias int func(int);
void main()
{
    if ( is(func[]) )               // not satisfied because arrays of
        writeln("satisfied");    // functions are not allowed
    else
        writeln("not satisfied");
}

It will print not satisfied. But I'm not sure what func is supposed to be? An
alias.. to what? I can't declare variables of its type:
    func x;
    error:  variable test.main.x cannot be declared to be a function

Of course if you write the alias the usual way it will print 'satisfied'.
Nothing strange about having an array of functions in D:

alias int function(int) func;
void main()
{
    if ( is(func[]) )
        writeln("satisfied");
    else
        writeln("not satisfied");
}
May 20 2011
next sibling parent Jesse Phillips <jessekphillips+D gmail.com> writes:
Andrej Mitrovic Wrote:

 Taken from the docs:
 
 alias int func(int);
 void main()
 {
     if ( is(func[]) )               // not satisfied because arrays of
         writeln("satisfied");    // functions are not allowed
     else
         writeln("not satisfied");
 }
 
 It will print not satisfied. But I'm not sure what func is supposed to be? An
alias.. to what? I can't declare variables of its type:
     func x;
     error:  variable test.main.x cannot be declared to be a function
 
 Of course if you write the alias the usual way it will print 'satisfied'.
Nothing strange about having an array of functions in D:
 
 alias int function(int) func;
 void main()
 {
     if ( is(func[]) )
         writeln("satisfied");
     else
         writeln("not satisfied");
 }

Well, I have no idea. File a bug maybe.
May 20 2011
prev sibling next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Sat, 21 May 2011 05:12:20 +0200, Andrej Mitrovic <none none.none> wrote:

 Taken from the docs:

 alias int func(int);
 void main()
 {
     if ( is(func[]) )               // not satisfied because arrays of
         writeln("satisfied");    // functions are not allowed
     else
         writeln("not satisfied");
 }

 It will print not satisfied. But I'm not sure what func is supposed to  
 be? An alias.. to what? I can't declare variables of its type:
     func x;
     error:  variable test.main.x cannot be declared to be a function

 Of course if you write the alias the usual way it will print  
 'satisfied'. Nothing strange about having an array of functions in D:

 alias int function(int) func;
 void main()
 {
     if ( is(func[]) )
         writeln("satisfied");
     else
         writeln("not satisfied");
 }

It's the old C syntax for defining function pointers. Well, without the pointer. And that last part is important, because the latter example is an array of function pointers, with which D has no issue. -- Simen
May 21 2011
next sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 21/05/2011 10:15, Simen Kjaeraas wrote:
 On Sat, 21 May 2011 05:12:20 +0200, Andrej Mitrovic <none none.none> wrote:

 Taken from the docs:

 alias int func(int);


 It's the old C syntax for defining function pointers.

Functions, not function pointers. The C syntax for declaring function pointers is int (*func)(int); In C (with "typedef" instead of "alias"), what you're effectively doing is declaring a type that you can't use directly, but can declare pointers to. But why does this exist in D? Stewart.
May 22 2011
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 22/05/2011 11:57, Steven Schveighoffer wrote:
 On Sat, 21 May 2011 05:15:32 -0400, Simen Kjaeraas <simen.kjaras gmail.com>
wrote:

 It's the old C syntax for defining function pointers. Well, without the
 pointer. And that last part is important, because the latter example is
 an array of function pointers, with which D has no issue.

Yes, and I thought we were killing that syntax because of how horrible it is?

Indeed, that D has this notion of immediate function types is absurd: - it's mostly undocumented; indeed, no mention of it on type.html - there's no native D syntax for it, only the kludgy syntax inherited from C - it seems silly to have a type that you can't declare variables of and that (unlike void) has no obvious practical reason for its existence - it leads to such corner cases as http://d.puremagic.com/issues/show_bug.cgi?id=3650 Stewart.
May 22 2011
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
Andrej Mitrovic wrote:
 Should I file a bug report to kill this syntax?

No. It is perfectly valid, see grammar: http://www.digitalmars.com/d/2.0/declaration.html What is strange about this syntax in particular? int i; //declares i of type "int" alias int i; //defines i as type "int" int func(int); //declares func of type "function that takes int and returns int" alias int func(int); //defines func as type "function that takes int and returns int" It is perfectly consistent with other uses of alias. It is the way alias works (taken from typedef), and function declarations work (also taken from c) that are somewhat strange, not this particular case. Timon
May 22 2011
next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 22/05/2011 16:20, Timon Gehr wrote:
 Andrej Mitrovic wrote:
 Should I file a bug report to kill this syntax?

No. It is perfectly valid, see grammar: http://www.digitalmars.com/d/2.0/declaration.html

Grammar states only that it's syntactically valid, and makes no comment on semantic validity. I suspect what Andrej actually meant is to kill treating function signatures as types in this way. And possibly "enhancement request" rather than "bug".
 What is strange about this syntax in particular?

 int i; //declares i of type "int"
 alias int i; //defines i as type "int"

 int func(int); //declares func of type "function that takes int and returns
int"

True, if you use "type" in a broad sense. But it doesn't declare a variable of that type, and you can't use it as a type as such. Really, function signatures and data types are distinct entities and ought not to be interchangeable.
 alias int func(int); //defines func as type "function that takes int and
returns int"

 It is perfectly consistent with other uses of alias.

I wouldn't say consistent. The essence of an alias is that you can use it where you would use what it's an alias of. But in that case, you should be able to do: alias int func(); func main { return 0; } Stewart.
May 22 2011
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
 On 22/05/2011 16:20, Timon Gehr wrote:
 Andrej Mitrovic wrote:
 Should I file a bug report to kill this syntax?

No. It is perfectly valid, see grammar: http://www.digitalmars.com/d/2.0/declaration.html

Grammar states only that it's syntactically valid, and makes no comment on

 I suspect what Andrej actually meant is to kill treating function signatures as

 this way.  And possibly "enhancement request" rather than "bug".

It is the opposite of an enhancement request. It means removing a feature that cannot be meaningfully substituted by other features. (also, removing it increases the inconsistency of the language and makes the compiler more complex).
 What is strange about this syntax in particular?

 int i; //declares i of type "int"
 alias int i; //defines i as type "int"

 int func(int); //declares func of type "function that takes int and returns
int"

True, if you use "type" in a broad sense. But it doesn't declare a variable of

 and you can't use it as a type as such.  Really, function signatures and data

 distinct entities and ought not to be interchangeable.

You can alias any symbol. Data types and other symbols are distinct entities too. By your arguments, this is a bad thing to have. Also, a function signature, while not a data type is still a _type_ (the "broad sense" is the D sense. You can do typeof(some_function)).
 alias int func(int); //defines func as type "function that takes int and


 It is perfectly consistent with other uses of alias.

I wouldn't say consistent. The essence of an alias is that you can use it where

 use what it's an alias of.  But in that case, you should be able to do:

 alias int func();

 func main {
      return 0;
 }

This does not make sense. The problem is, that currently there is no other way than alias to even _refer_ to a function signature. alias int func(); int main(){ static assert(is(typeof(main)==func); return 0; } I do not get why anybody would want to remove the possibility to refer to function signatures. It can be handy for template constraining. I agree that the way to do it is somewhat strange, but it is easy for the compiler to handle.
 Stewart.

What I consider strange is that: import std.stdio; int main(){ writeln(typeof(main).stringof); } Will print "int()()", which is still the C way of referring to function types. In D, this looks more like the type of a function template. It gets even more strange: alias int func(); template tt(func a){ enum tt=a.stringof; } Error: variable ttt.a cannot be declared to be a function Error: arithmetic/string type expected for value-parameter, not int() Note how it is only "int()" now. I think C function pointer syntax was maybe deprecated too early, because all other function type-related stuff is still very near to how C does it. This should be solved. But I cannot think of any reasonable solution that would not break easy parsing. Any ideas? Timon
May 22 2011
next sibling parent reply David Nadlinger <see klickverbot.at> writes:
On 5/23/11 8:41 AM, Andrej Mitrovic wrote:
 On 5/22/11, Timon Gehr<timon.gehr gmx.ch>  wrote:
 The problem is, that currently there is no other
 I do not get why anybody would want to remove the possibility to refer to
 function
 signatures.

What's wrong with using this: alias void function(int, int) funcAlias;

It's a function pointer type, not a function type. David
May 22 2011
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 23/05/2011 07:43, David Nadlinger wrote:
 On 5/23/11 8:41 AM, Andrej Mitrovic wrote:

 What's wrong with using this:

 alias void function(int, int) funcAlias;

It's a function pointer type, not a function type.

How is that something wrong with it? I.e. what can you do with a function type that you cannot possibly do by using the function pointer type instead? Stewart.
May 23 2011
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 22/05/2011 21:51, Timon Gehr wrote:
<snip>
 I suspect what Andrej actually meant is to kill treating function
 signatures as types in this way.  And possibly "enhancement
 request" rather than "bug".

It is the opposite of an enhancement request. It means removing a feature that cannot be meaningfully substituted by other features.

Unless you know a use case I've never heard of, it's no more "a feature that cannot be meaningfully substituted by other features" than the C preprocessor.
 (also, removing it increases the inconsistency of the language and
 makes the compiler more complex).

I disagree. My point is that function types and data types have practically nothing in common. So your argument seems to me like claiming that D is inconsistent because classes and functions aren't interchangeable. <snip>
 True, if you use "type" in a broad sense.  But it doesn't declare
 a variable of that type, and you can't use it as a type as such.
 Really, function signatures and data types are distinct entities
 and ought not to be interchangeable.

You can alias any symbol. Data types and other symbols are distinct entities too. By your arguments, this is a bad thing to have.

But do function signatures count as symbols? I'm not sure.
 Also, a function signature, while not a data type is still a _type_
 (the "broad sense" is the D sense.  You can do
 typeof(some_function)).

And do what _with_ it, let alone that cannot be done by any other means? <snip>
 alias int func();

 int main(){
      static assert(is(typeof(main)==func);

alias int function() func; static assert (is(typeof(&main) == func));
      return 0;
 }

 I do not get why anybody would want to remove the possibility to
 refer to function signatures.  It can be handy for template
 constraining.

Can you give an example? Stewart.
May 23 2011
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
Steven Schveighoffer wrote:
 It is not perfectly consistent.  The function type syntax is useless,
 because you can only use it if you use the pointer modifier with it.  If
 you want to declare a function pointer, there are other (better) ways.

Yes, other ways of declaring a function pointer are better. But there is no other way than alias for referring to a function type... It is not useless, see below.
 Yes, removing it would be a "special case" for the compiler, but it's
 syntax and usages are so bizzare, nobody would miss it.

I would. For the usages part, not the syntax part.
 it's akin to
 making:

 if(x);

 invalid. Yes, it's valid syntax, but it's almost certainly not what the
 user wanted.  It's special cased for failure, to aid the developer in
 writing less buggy programs.  This would be a similar change, and I
 actually thought it was already in the compiler.

It is in the compiler. It is actually not valid syntax anymore (disallowed by grammar and caught by the parser). And it is not similar to removing function type alias. You can write if(x){} as a replacement if you need it. There is currently no alternative for the alias.
 I'll throw it back at you, do you see a good use case for it?  And no,
 porting C code isn't a good use case.

 -Steve

There are no alias in C code. I actually gave one: Timon Gehr wrote:
 alias int func();

 int main(){
     static assert(is(typeof(main)==func);
     return 0;
 }

You can use something similar to this to constrain templates. I do not say this syntax is good. But at the moment we have nothing better than that. How DMD handles function types is closer to how C does it than me or you would like, see my other post. BTW: writeln(typeid(int function(int))); //int()* wtf? Timon
May 23 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
Steven Schveighoffer wrote:
 On Mon, 23 May 2011 10:50:11 -0400, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 Since &main can't be a template value argument, maybe he meant this use
 case:

 alias int func();

 void foo(alias T)()
 {

 }

 int main()
 {
     foo!main;
     return 0;
 }


Oh, I am sorry. I did not realize that D does not allow overloading the address-of operator. (C++ does, but D is quite restrictive, I have to get used to that) Therefore, this solution works of course unambiguously. Well, you could kill alias R func(T); in that case, but still, it makes the compiler more complicated. :) Maybe you even want to kill typeof(some_function) then? I think that, without being able to refer to function types per alias, this could often be a bug. Timon
May 23 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 21 May 2011 05:15:32 -0400, Simen Kjaeraas  
<simen.kjaras gmail.com> wrote:

 On Sat, 21 May 2011 05:12:20 +0200, Andrej Mitrovic <none none.none>  
 wrote:

 Taken from the docs:

 alias int func(int);
 void main()
 {
     if ( is(func[]) )               // not satisfied because arrays of
         writeln("satisfied");    // functions are not allowed
     else
         writeln("not satisfied");
 }

 It will print not satisfied. But I'm not sure what func is supposed to  
 be? An alias.. to what? I can't declare variables of its type:
     func x;
     error:  variable test.main.x cannot be declared to be a function

 Of course if you write the alias the usual way it will print  
 'satisfied'. Nothing strange about having an array of functions in D:

 alias int function(int) func;
 void main()
 {
     if ( is(func[]) )
         writeln("satisfied");
     else
         writeln("not satisfied");
 }

It's the old C syntax for defining function pointers. Well, without the pointer. And that last part is important, because the latter example is an array of function pointers, with which D has no issue.

Yes, and I thought we were killing that syntax because of how horrible it is? -Steve
May 22 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Should I file a bug report to kill this syntax?
May 22 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 5/22/11, Timon Gehr <timon.gehr gmx.ch> wrote:
 The problem is, that currently there is no other
 I do not get why anybody would want to remove the possibility to refer to
 function
 signatures.

What's wrong with using this: alias void function(int, int) funcAlias;
May 22 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Ah ok.

Hey if it's used for something useful I won't steal it from you. ;)
May 22 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 22 May 2011 11:20:15 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:

 Andrej Mitrovic wrote:
 Should I file a bug report to kill this syntax?

No. It is perfectly valid, see grammar: http://www.digitalmars.com/d/2.0/declaration.html What is strange about this syntax in particular? int i; //declares i of type "int" alias int i; //defines i as type "int" int func(int); //declares func of type "function that takes int and returns int" alias int func(int); //defines func as type "function that takes int and returns int" It is perfectly consistent with other uses of alias.

It is not perfectly consistent. The function type syntax is useless, because you can only use it if you use the pointer modifier with it. If you want to declare a function pointer, there are other (better) ways. Yes, removing it would be a "special case" for the compiler, but it's syntax and usages are so bizzare, nobody would miss it. it's akin to making: if(x); invalid. Yes, it's valid syntax, but it's almost certainly not what the user wanted. It's special cased for failure, to aid the developer in writing less buggy programs. This would be a similar change, and I actually thought it was already in the compiler. I'll throw it back at you, do you see a good use case for it? And no, porting C code isn't a good use case. -Steve
May 23 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 5/23/11, Timon Gehr <timon.gehr gmx.ch> wrote:
 BTW:

 writeln(typeid(int function(int))); //int()*

 wtf?

Yeah, typeid generally seems to be bad for these things. typeof.stringof to the rescue: writeln((int function(int)).stringof); // int function(int)
May 23 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Well if there's no better way to do it and it's useful, we should do a
feature request for a better syntax, no?
May 23 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 23 May 2011 09:32:47 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:

 Steven Schveighoffer wrote:
 it's akin to
 making:

 if(x);

 invalid. Yes, it's valid syntax, but it's almost certainly not what the
 user wanted.  It's special cased for failure, to aid the developer in
 writing less buggy programs.  This would be a similar change, and I
 actually thought it was already in the compiler.

It is in the compiler. It is actually not valid syntax anymore (disallowed by grammar and caught by the parser).

When I said I thought it was already in the compiler, I meant the bizarro function type declaration, not the empty if statement.
 And it is not similar to removing function type
 alias. You can write if(x){} as a replacement if you need it.

 There is currently no alternative for the alias.

But why do you need a function type vs. a function pointer type? Especially since the function pointer type is easily built from the function type, and you can't actually use the function type until you turn it into a function pointer.
 I'll throw it back at you, do you see a good use case for it?  And no,
 porting C code isn't a good use case.

There are no alias in C code. I actually gave one: Timon Gehr wrote:
 alias int func();

 int main(){
     static assert(is(typeof(main)==func);
     return 0;
 }


static assert(is(typeof(&main) == int function()); More straightforward and descriptive.
 BTW:

 writeln(typeid(int function(int))); //int()*

 wtf?

That needs to be fixed, the runtime's TypeInfo.toString methods are not always accurate (I think this warrants a bugzilla report). -Steve
May 23 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 23 May 2011 09:59:01 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Mon, 23 May 2011 09:32:47 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:

 Steven Schveighoffer wrote:
 it's akin to
 making:

 if(x);

 invalid. Yes, it's valid syntax, but it's almost certainly not what the
 user wanted.  It's special cased for failure, to aid the developer in
 writing less buggy programs.  This would be a similar change, and I
 actually thought it was already in the compiler.

It is in the compiler. It is actually not valid syntax anymore (disallowed by grammar and caught by the parser).

When I said I thought it was already in the compiler, I meant the bizarro function type declaration, not the empty if statement.

I should clarify once again :) I meant the *change to remove* the bizarro function type declaration. I thought that was already decided and in the compiler (Don had a whole thread on this). -Steve
May 23 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Since &main can't be a template value argument, maybe he meant this use case:

alias int func();

void foo(alias T)()
{
    static assert(is(typeof(T) == func));
}

int main()
{
    foo!main;
    return 0;
}
May 23 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 23 May 2011 10:50:11 -0400, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 Since &main can't be a template value argument, maybe he meant this use  
 case:

 alias int func();

 void foo(alias T)()
 {

 }

 int main()
 {
     foo!main;
     return 0;
 }

May 23 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Nice.
May 23 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 23 May 2011 14:06:31 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:

 Steven Schveighoffer wrote:
 On Mon, 23 May 2011 10:50:11 -0400, Andrej Mitrovic
 <andrej.mitrovich gmail.com> wrote:

 Since &main can't be a template value argument, maybe he meant this use
 case:

 alias int func();

 void foo(alias T)()
 {

 }

 int main()
 {
     foo!main;
     return 0;
 }


Oh, I am sorry. I did not realize that D does not allow overloading the address-of operator. (C++ does, but D is quite restrictive, I have to get used to that) Therefore, this solution works of course unambiguously. Well, you could kill alias R func(T); in that case, but still, it makes the compiler more complicated. :)

I went to Don's thread to give you a good case of why it's worth it, and I realized that his example looks nothing like what yours does, and in fact, is disallowed in the latest compiler. So we have been talking about two completely different problems. The issue was for C-style function type declarations: int x; x(y); // declare a function type y which returns an x, but looks like a function call. Here was the bug report: http://d.puremagic.com/issues/show_bug.cgi?id=4987 So although I think the alias function syntax is horrible, it's not nearly as bad as I thought. I also still don't see much use for it, it seems much more straightforward to use function pointers as types instead. I'd favor removing it, but I was wrong that it was already scheduled to be removed. -Steve
May 23 2011