Do we really need typedef?

789 views
Skip to first unread message

Sean Eagan

unread,
Apr 23, 2013, 12:35:41 PM4/23/13
to General Dart Discussion
I'm probably missing something, but I believe the following:

typedef C A(B b);
typedef X = Object with Y, Z;

can be written as:

class A {
  C call(B b);
}
class X extends Object with Y, Z {}

So is typedef worth it?  What benefit does it provide over the equivalent class declarations?

Cheers,
Sean Eagan

James Wendel

unread,
Apr 23, 2013, 1:15:30 PM4/23/13
to mi...@dartlang.org
typedefs are still needed for functional programming (no classes involved).  You can create a typedef for a function definition, then use that typedef as the parameter to another function.  Then any function that matches that typedef can be used.

typedef void A(B b);

void call(B b) {};
void doStuff(A a) {};

main
() {
    doStuff
(call);
}


Sean Eagan

unread,
Apr 23, 2013, 1:37:32 PM4/23/13
to General Dart Discussion
Thanks James!  I forgot that function typedefs are structural as opposed to nominal, which is confusing since it's not the case for the other form of typedefs (mixin applications).  I still don't think we need sugar for mixin applications (other than possibly removing the requirement for "extends Object").  And then for function typedefs, why not avoid the extra keyword (typedef), and just declare them as top-level abstract methods using either of:

abstract C A(B b);
C A(B b);

Cheers,
Sean Eagan




--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
 
 

Ladislav Thon

unread,
Apr 23, 2013, 2:31:50 PM4/23/13
to mi...@dartlang.org
I still don't think we need sugar for mixin applications (other than possibly removing the requirement for "extends Object").  And then for function typedefs, why not avoid the extra keyword (typedef), and just declare them as top-level abstract methods using either of:

I'd personaly prefer removing typedef completely. For mixin application, I think it's superfluous, and for function types, I'd rather have a special syntax.

LT

Lasse R.H. Nielsen

unread,
Apr 23, 2013, 3:01:16 PM4/23/13
to mi...@dartlang.org
On Tue, Apr 23, 2013 at 6:35 PM, Sean Eagan <seane...@gmail.com> wrote:
I'm probably missing something, but I believe the following:
... 
typedef X = Object with Y, Z;

can be written as:
 ...
class X extends Object with Y, Z {}

There is a difference between the two. The later extends "Object with Y,Z" with ... an implicit constructor.
For this code there is no real visible difference, but take this example:

class C {
   final int x;
   C() : x = 0;
   C.x(this.x);
}

class X {
  void print() { print("something"); }
}

class D1 extends C with X {}
typedef D2 = C with X;

then D1 has only one constructor, the default implicit constructor, which delegates to "C with X"'s unnamed constructor, which again delegates to C's constructor C(), but D2 has two constructors.
You can write "new D2.x(4)", but not "new D1.x(4)".

D1 is really equivalent to
  class D1 extends D2 {}
not just to D2.

/L 'useful difference? Who knows, but it's a difference!'
-- 
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

Simon Pai

unread,
Apr 23, 2013, 11:51:39 PM4/23/13
to mi...@dartlang.org
On Wednesday, April 24, 2013 1:37:32 AM UTC+8, Sean Eagan wrote:

abstract C A(B b);
C A(B b);


If you think it as an abstract method, that would implies a method of name A, not a type of name A, which is a different thing.

Cheers,
Simon

Ladislav Thon

unread,
Apr 24, 2013, 4:20:53 AM4/24/13
to mi...@dartlang.org
I'm probably missing something, but I believe the following:
... 
typedef X = Object with Y, Z;

can be written as:
 ...
class X extends Object with Y, Z {}

There is a difference between the two. The later extends "Object with Y,Z" with ... an implicit constructor.
For this code there is no real visible difference, but take this example:

class C {
   final int x;
   C() : x = 0;
   C.x(this.x);
}

class X {
  void print() { print("something"); }
}

class D1 extends C with X {}
typedef D2 = C with X;

then D1 has only one constructor, the default implicit constructor, which delegates to "C with X"'s unnamed constructor, which again delegates to C's constructor C(), but D2 has two constructors.
You can write "new D2.x(4)", but not "new D1.x(4)".

Really? The spec says that "mixin application has forwarding constructors for all superclass constructors". This is actually a quote from the changelog in the spec, but looking at 9.1, I don't see how this only applies to a mixin application in the form of a type alias. If I read correctly, new D1.x(4) should be possible here. Where am I mistaken?

LT

Lasse R.H. Nielsen

unread,
Apr 24, 2013, 7:11:08 AM4/24/13
to mi...@dartlang.org
The trick is that D1 is not itself a mixin application. It is a class that extends a mixin application. 

The extending adds the members in the class body to D1 (in this case there are none) along with a default constructor (because no constructor is specified either), just as any other class defined by extension. It is the same as "class Foo extends Object {}".

The superclass of D1 is "C with X", and that is a mixin application and has two generated constructors.

There is currently a bug in the VM (9683) where "typedef C = X with Y" adds an extra layer on top of  "X with Y", so for "typedef C = Object with X;", C doesn't extend Object directly and can't be used again as a mixin (which you may or may not have any practical use for). 

/L
-- 

Ladislav Thon

unread,
Apr 24, 2013, 7:22:21 AM4/24/13
to mi...@dartlang.org
Really? The spec says that "mixin application has forwarding constructors for all superclass constructors". This is actually a quote from the changelog in the spec, but looking at 9.1, I don't see how this only applies to a mixin application in the form of a type alias. If I read correctly, new D1.x(4) should be possible here. Where am I mistaken?

The trick is that D1 is not itself a mixin application. It is a class that extends a mixin application. 

Ha! Gotcha. Thanks :-)

LT

Sean Eagan

unread,
Apr 24, 2013, 9:41:39 AM4/24/13
to General Dart Discussion
But an abstract method is not the same as a concrete method.  It only consists of a name and a signature, not an implementation, which matches up with what the current function typedefs define.  Also, declaring them as abstract methods could make a lot of sense if we ever want to have first class libraries.  There is one incompatibility though, which is that dart doesn't (yet) have generic methods, but at the same time does have generic function typedefs.

Cheers,
Sean Eagan

David Bernard

unread,
Apr 24, 2013, 10:55:56 AM4/24/13
to mi...@dartlang.org
May be, I did a wrong usage of typedef, but I used it as a workaround to define type of attribute as a method.

typedef int myFunc(int a, int b);

class Xxxx {
  myFunc f
;

 
Xxxx(this.f);
}

I used this pattern  a lot to define "micro strategy" to apply later (on demand, as part of bigger flow, ...)

Its a workaround because inside class Xxxx (a concrete class) I can write (anonymous function def)

class Xxxx {
 
int f(int a, int b);

 
Xxxx(this.f);
}


If someone know a better solution, I take it, but currenlty I need typedef.

[troll]
something that didn't happen with type info after ':' like in scala
class Xxxx {
 
var f : (a : int, b : int) => int
}

[/troll]

Sean Eagan

unread,
Apr 24, 2013, 11:24:54 AM4/24/13
to General Dart Discussion
David,

I believe you want to star http://dartbug.com/1616 (methods as function properties), which is unforunately marked as WontFix, but I don't see why it couldn't be introduced post dart 1.0.

Cheers,
Sean Eagan


Ladislav Thon

unread,
Apr 24, 2013, 11:27:17 AM4/24/13
to General Dart Discussion


> May be, I did a wrong usage of typedef, but I used it as a workaround to define type of attribute as a method.

It's not a workaround, it's the only way to do that.

> class Xxxx {
>   int f(int a, int b);
>
>   Xxxx(this.f);
> }

You actually can't, as here, f is an abstract method. This discrepancy between parameter types and variable types is exactly why I'm longing for a special syntax for function types. I've actually sent an email about this exact thing to the list a long time ago, but I've never created a bug report. Today, it's probably already too late.

LT

Fabio Kaminski

unread,
Apr 24, 2013, 6:59:48 PM4/24/13
to General Dart Discussion
typedefs are one of those features you use just a few times, but when you use it is very handy.. 
dont know the dart case, but in c, c++ and go.. its very conforting know that its there when you need it.. 

there are two special cases i findo very handy when doing c/c++:

for externally managed objects:
Ex : 
  1) kernel objects: linux use ints all around.. but if you would want to annotate the int for diferent types of objects
      eg: 
             typedef int file_t; 
             typedef int sock_t;
     then you use it in you func declarations:
            sock_t sock_open();
                 instead of opaque
            int sock_open();

you see that since ints are also used to see if theres and error when you see a func where the object id is also a int
how can you know, if its not a status value returning? 
   
  2) sugar for function callbacks .. typedef void(...) mycallback ;
      
  now if you dont have a typedef and you have a function/method with this callback as a parameters (maybe more than once)
 you are doomed.. :) 
 







--

Ladislav Thon

unread,
Apr 25, 2013, 12:34:05 AM4/25/13
to General Dart Discussion


>   1) kernel objects: linux use ints all around.. but if you would want to annotate the int for diferent types of objects
>       eg: 
>              typedef int file_t; 
>              typedef int sock_t;
>      then you use it in you func declarations:
>             sock_t sock_open();
>                  instead of opaque
>             int sock_open();

Except that you can't do this in Dart. You are supposed to define new types by defining new classes.

>   2) sugar for function callbacks .. typedef void(...) mycallback ;
>       
>   now if you dont have a typedef and you have a function/method with this callback as a parameters (maybe more than once)
>  you are doomed.. :)

Funny, because people are declaring callbacks as parameters all the time in Dart, and they usually don't use typedefs for that. Just look at Future.then or Stream.listen (but there is a ton of other examples).

But yes, this is doable, and I'm doing it sometimes too. Usually when I want to store the callback into a variable and I want that variable to have a type annotation. For that, there's no other way. If we had a syntax for function types, I wouldn't use typedefs at all.

LT

Simon Pai

unread,
Apr 25, 2013, 11:18:47 PM4/25/13
to mi...@dartlang.org

 I see your point. I assume you mean we can borrow the syntax of abstract function declaration in static scope to define a type. Personally I do not enjoy the idea though, as it only save one keyword, at a cost of introducing semantic confusion.

Cheers,
Simon
Reply all
Reply to author
Forward
0 new messages