Re:A core Python committer's (very shallow) thoughts on Dart
by damncabbage on Monday May 14, 2012 @03:23AM
(#3969887)
Dart views types as helpful documentation and a way to help tools assist with things, period. I actually find it rather refreshing to have a language that treats types as just documentation since that is really what they are for the programmer
But, just like documentation, if it gets out of date you're really wonked.
I'd prefer something that is both useful as documentation and is used by the compiler (a la Haskell's type classes).
Re:A core Python committer's (very shallow) thoughts on Dart
by numbsafari on Monday May 14, 2012 @09:21AM
(#3970922)
I have to admit, there's some part of me that wants to think that "types as documentation" is a good idea. But I have to go with the OP on this one... I watched the Dart presentation from Lang.NEXT and laughed a bit to myself at one point because even in the presenter's example, the "type documentation" was already outdated. During his presentation it doesn't matter, because everyone watching is in the context of the code as part of his discussion. But if you put that code in front of somebody a year from now, out of context, would they immediately pick up on it? Or will they be frustrated by the fact that they expect the types to be what they say they are, but they aren't?
Are people really going to run in checked mode to verify their code? Or they going to do what they do with compiler warnings and turn them off as soon as they see one? I'm sure there will be a million blog posts titled "Dart Best Practices" that will say "do not use checked mode, it slows down execution and prints confusing messages". Of course, any bugs in checked mode will mean people will need to get their production systems working by ignoring checked mode.
I guess... my gut tells me that you should either have types, or not have types. Being in the middle creates too many opportunities for cognitive dissonance, too many opportunities for sneaky bugs, and too many opportunities to keep having this debate. It's one of those things that seems really smart and cool that, on a practical level, will probably turn out to be a complete waste of time and a total distraction.
Re:A core Python committer's (very shallow) thoughts on Dart
by nl on Monday May 14, 2012 @11:18AM
(#3971400)
I guess... my gut tells me that you should either have types, or not have types. Being in the middle creates too many opportunities for cognitive dissonance, too many opportunities for sneaky bugs, and too many opportunities to keep having this debate. It's one of those things that seems really smart and cool that, on a practical level, will probably turn out to be a complete waste of time and a total distraction.
The worlds collective programming experience doesn't really back that up. Almost every language drops (or makes optional) type support when constructs become too complicated, or they become so complicated no one can understand them.
Languages with the best type systems (OCaml) aren't particularly popular, while languages we think of as strongly typed (eg Java) have big backdoors to allow people to bypass the type system.
On the other side, weakly typed languages are adding typing-like features by integrating unit test facilities into the environment (which - optionally - catch many of the bugs typing can help with).
Like so many things, optional typing might seem impure, but often messy systems are the most robust.
Re:A core Python committer's (very shallow) thoughts on Dart
by pcwalton on Monday May 14, 2012 @11:34AM
(#3971470)
Dart's optional typing is not common in languages at all. What you're referring to is a combination of dynamic and static typing, which is not Dart-style optional typing. In statically-typed languages, the dynamically-typed values are clearly delimited in the source text and are not a compiler switch.
Re:A core Python committer's (very shallow) thoughts on Dart
by stcredzero on Monday May 14, 2012 @11:13AM
(#3971378)
even in the presenter's example, the "type documentation" was already outdated.
Yes, but it's not the same as outdated comments. A well featured optional type system will let you know that is happening. An out of date comment will just continue to deceive.
Or they going to do what they do with compiler warnings and turn them off as soon as they see one?
My advice, is not to work in such shops.
I guess... my gut tells me that you should either have types, or not have types. Being in the middle creates too many opportunities for cognitive dissonance
As if there's a lack of them on the ends of the spectrum compared to the middle. We will find out if it will be more of a mess, so many will have gut-calibration data.
Re:A core Python committer's (very shallow) thoughts on Dart
by fraserharris on Monday May 14, 2012 @05:07AM
(#3970122)
A message I received from a friend working at Google:
"New layers, more layers, bigger layers, better layers, abstract layers, injected layers, factory layers, module layers, AbstractFactoryFactoryModuleBuilderInjector layers, layers upon layers within layers wrapped in layers, a glorious spire of layers to reach the heavens and bring renown to Babylon! Hellelujah!"
Re:A core Python committer's (very shallow) thoughts on Dart
by nl on Monday May 14, 2012 @10:51AM
(#3971273)
There is no doubt that there is a culture of abstraction stupidity in Java (although it isn't as bad as it used to be), and yes, I agree that a FactoryFactory is a code smell.
Re:A core Python committer's (very shallow) thoughts on Dart
by masklinn on Monday May 14, 2012 @04:29AM
(#3970033)
> Maybe it's my Java background coming through, but I like the idea of Factory constructors.
Better languages don't special-case the constructor instead (no `new` operator), the constructor is just a class method. Bam, "factory method" constructors out of the box and problem solved.
Re:A core Python committer's (very shallow) thoughts on Dart
by nl on Monday May 14, 2012 @11:10AM
(#3971364)
Better is pretty subjective here.
Factories aren't common in Python, but they are used in exactly the same cases where they are used in Java (eg [1],[2],[3]). If you need to decide at runtime what object from an object hierarchy to create you use a factory. There's nothing inherently bad about that.
Re:A core Python committer's (very shallow) thoughts on Dart
by masklinn on Monday May 14, 2012 @01:23PM
(#3972052)
> Factories aren't common in Python
Factories are everywhere in Python because the default construction workflow goes through a bloody factory method.
> There's nothing inherently bad about that.
You may want to read my comment instead of inventing things I never wrote, because the comment you replied to didn't even remotely hint at factories being bad.
Oh, and the first two examples you provide are absolutely horrendous, it's not surprising they are used "in exactly the same cases where they are used in Java", because what you show there really is java code translated to Python.
Whereas the third one is something you can't do in Java: it factorizes the creation of a class through customization of the metaclass's standard creation protocol. The version in the comments overrides the creation of the instance (through, again, a completely standard override of Python's built in construction protocol), which is less efficient but doesn't require understanding metaobjects.
Re:A core Python committer's (very shallow) thoughts on Dart
by numbsafari on Monday May 14, 2012 @09:36AM
(#3970988)
It comes down to the fact that interfaces aren't classes.
To whit: let's say you want to have an interface for associative arrays. Let's call it Map. Now let's say you want to provide a static method to create an instance of the default Map implementation (call it, say, HashMap). So you'd think about doing something like this:
The only problem is that if you define Map as an abstract class instead of an interface, that means that all implementations of Map must extend Map. Given single inheritance, this means anything providing a Map-style interface can and must only extend from the base Map class.
So... Factory classes are there because of how Java treats interfaces and single inheritance.
Re:A core Python committer's (very shallow) thoughts on Dart
by generateui on Monday May 14, 2012 @07:11AM
(#3970443)
There does not need to be any knowledge of _any_ class. A factory method _still_ needs a class instance, you don't need them with factory constructors.
A classical, say Java or C# way will still need coupling to such a class. In dart, there is real decoupling going on.
Re:A core Python committer's (very shallow) thoughts on Dart
by masklinn on Monday May 14, 2012 @08:23AM
(#3970711)
> A factory method _still_ needs a class instance
Uh no it does not, it just needs a class. Unless what you mean by "a class instance" is "a class object". A factory method is a classmethod, not an instancemethod.
A factory method and a "factory constructor" need exactly the same thing: the class object.
> In dart, there is real decoupling going on.
In dart, there's mostly a bloody mess of 4 different constructors when all you need is a constructor and an initializer, as done in e.g. Ruby or Python. And these can be "regular" methods (respectively on the class and on the instance).
Conversely, you can also have an "overridden" constructor as in Javascript: an instance is built, the constructor function is called using the instance as its context, and if the constructor returns something that something is returned by `new` in stead of the original object.
Re:A core Python committer's (very shallow) thoughts on Dart
by generateui on Monday May 14, 2012 @10:44AM
(#3971252)
> A factory method is a classmethod, not an instancemethod.
This completely depends on your implementation. It's possible to implement it as instance method, or static method.
> Uh no it does not, it just needs a class.
Whether it be a static factory method or an instance method, fact is you need a reference to an implementation (class). In dart, you can do
List someListInstance = new List();
where List is an interface. There is none class needed in your consuming code, none. In C# or Java, this is impossible: You need _some_ class (whether it be a static method on it, or an instance method) to get a new instance of the interface.
Named constructors felt very liberating when working with Dart.
new List.from([instance1, instance1]);
delivers a lot of clarity, while offering the promised decoupling by the GoF:
> Define an interface for creating an object, but let the classes which implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses.
Re:A core Python committer's (very shallow) thoughts on Dart
by masklinn on Monday May 14, 2012 @01:09PM
(#3971961)
> It's possible to implement it as instance method
It makes no sense, if you're doing that you've switched to full-blown factories (abstracts or builders), you're not using factory methods anymore.
> Whether it be a static factory method or an instance method, fact is you need a reference to an implementation (class). In dart, you can do
> List someListInstance = new List();
> where List is an interface. There is none class needed in your consuming code, none.
That's got nothing to do with factories, or interfaces.
> You need _some_ class (whether it be a static method on it, or an instance method) to get a new instance of the interface.
You always need a class, even in Dart there has to be a default List implementation of some sort which can be called (and has to be specified on the interface, it's not like you can even provide your own default implementation of a third party's interface). As to the calling code needing to know about that one concrete implementation:
abstract class Foo {
public static Foo foo() {
return new FooImpl();
}
public abstract void printFoo();
}
class FooImpl extends Foo {
public void printFoo() {
System.out.println("I am FooImpl");
}
}
class Main {
public static void main(String[] args) {
Foo foo = Foo.foo();
foo.printFoo();
}
}
Oh look at that, the calling code does not know anything about FooImpl.
> Named constructors felt very liberating when working with Dart.
Re:A core Python committer's (very shallow) thoughts on Dart
by generateui on Monday May 14, 2012 @04:27PM
(#3973073)
Your consuming code is tied to Foo. In dart, the consuming code only needs tying up to the interface.
> You always need a class
Nope. That's the whole point which I am trying to communicate: you do not need a reference to a class to get the instance of the interface from, as you confirm later on:
> As to the calling code needing to know about that one concrete implementation:
My personal feeling of liberation comes from the fact that the code is simpler and more clear. The non-coupling is nice, but can be achieved with dependency injection too: the point is the transfer of characters into a mental model which is more efficient with the named constructors/factory constructors.
Re:A core Python committer's (very shallow) thoughts on Dart
by masklinn on Tuesday May 15, 2012 @12:56AM
(#3974966)
> Your consuming code is tied to Foo. In dart, the consuming code only needs tying up to the interface.
Foo is an abstract class, which is the exact same thing.
> Nope. That's the whole point which I am trying to communicate: you do not need a reference to a class to get the instance of the interface from
Neither do you in the code I posted, can you bloody read?
> My personal feeling of liberation comes from the fact that the code is simpler and more clear.
You'll have to give actual examples of that, because I've not seen it so far.
> the point is the transfer of characters into a mental model which is more efficient with the named constructors/factory constructors.
This phrase doesn't even make sense, what "transfer of characters" are you talking about, and how is it more efficient for the user to type more? (named constructors only add ceremony to factory methods) (I'm not even going to talk about factory constructors again, they're a band-aid on the self-inflicted wound of stupid java-style constructors)
Re:A core Python committer's (very shallow) thoughts on Dart
by tomp on Monday May 14, 2012 @08:22AM
(#3970709)
Just a bit more expressive, actually. Make classes first-class entities, and make them callable, and you can easily do what Python does, but in a statically-typed manner.
Re:A core Python committer's (very shallow) thoughts on Dart
by numbsafari on Monday May 14, 2012 @09:24AM
(#3970932)
You can implement multiple interfaces on a single class, but only "inherit" from a single implementation.
Or, perhaps more specifically, you can implement an interface without extending its default implementation.
As the article states, the default implementations are there more so that you can say "m = new Map()", instead of having to remember about this other thing called "HashMap".
Re:A core Python committer's (very shallow) thoughts on Dart
by stcredzero on Monday May 14, 2012 @03:46PM
(#3972811)
Have you seen some of the early Bittorrent code? Code with lots and lots of this[n:-3] or this[1,:,:] sprinkled around in the same piece of code starts to get like regexp or Perl. It's a cool operator to have to get stuff specified in a few keystrokes, but that makes it quite terse, so high density use of it is hard to read.
Re:A core Python committer's (very shallow) thoughts on Dart
by stcredzero on Monday May 14, 2012 @11:07AM
(#3971352)
...have done toy examples now in 18 languages...this is actually usually enough for me to grasp the inspirations for a language and thus understand its essence.
Usually is the dangerous word here. (Dangerous as in, "a little knowledge.")
Re:A core Python committer's (very shallow) thoughts on Dart
by madhadron on Monday May 14, 2012 @11:21AM
(#3971413)
Actually, that's the point when I stopped taking him seriously (though why anyone in core Python should be taken seriously as a language designer I don't know). 18? Come on. I've deployed projects in that many languages.
Re:A core Python committer's (very shallow) thoughts on Dart
by stcredzero on Monday May 14, 2012 @12:48PM
(#3971849)
My point is more that in-depth knowledge in a number of languages is also vital. The 18 toy examples is completely unimportant. Competency in core Python is. I would look for such depth in one or two other languages.
But, just like documentation, if it gets out of date you're really wonked.
I'd prefer something that is both useful as documentation and is used by the compiler (a la Haskell's type classes).
Are people really going to run in checked mode to verify their code? Or they going to do what they do with compiler warnings and turn them off as soon as they see one? I'm sure there will be a million blog posts titled "Dart Best Practices" that will say "do not use checked mode, it slows down execution and prints confusing messages". Of course, any bugs in checked mode will mean people will need to get their production systems working by ignoring checked mode.
I guess... my gut tells me that you should either have types, or not have types. Being in the middle creates too many opportunities for cognitive dissonance, too many opportunities for sneaky bugs, and too many opportunities to keep having this debate. It's one of those things that seems really smart and cool that, on a practical level, will probably turn out to be a complete waste of time and a total distraction.
The worlds collective programming experience doesn't really back that up. Almost every language drops (or makes optional) type support when constructs become too complicated, or they become so complicated no one can understand them.
Languages with the best type systems (OCaml) aren't particularly popular, while languages we think of as strongly typed (eg Java) have big backdoors to allow people to bypass the type system.
On the other side, weakly typed languages are adding typing-like features by integrating unit test facilities into the environment (which - optionally - catch many of the bugs typing can help with).
Like so many things, optional typing might seem impure, but often messy systems are the most robust.
Summary
Gilad Bracha discusses Dart, its type system, interfaces, generics, ADTs without types, built-in factory support.
http://www.infoq.com/presentations/A-Quick-Tour-of-Dart
Yes, but it's not the same as outdated comments. A well featured optional type system will let you know that is happening. An out of date comment will just continue to deceive.
Or they going to do what they do with compiler warnings and turn them off as soon as they see one?
My advice, is not to work in such shops.
I guess... my gut tells me that you should either have types, or not have types. Being in the middle creates too many opportunities for cognitive dissonance
As if there's a lack of them on the ends of the spectrum compared to the middle. We will find out if it will be more of a mess, so many will have gut-calibration data.
(I'm genuinely curious.)
Maybe it's my Java background coming through, but I like the idea of Factory constructors.
http://discuss.joelonsoftware.com/default.asp?joel.3.219431
NB Factories are one of these things that seem like a good idea in theory, but often seem to end up with crazy levels of abstraction in practice.
"New layers, more layers, bigger layers, better layers, abstract layers, injected layers, factory layers, module layers, AbstractFactoryFactoryModuleBuilderInjector layers, layers upon layers within layers wrapped in layers, a glorious spire of layers to reach the heavens and bring renown to Babylon! Hellelujah!"
That doesn't make factories bad.
Essentially closures, curried functions, partial evaluated is the same thing: code that generate code.
I'm not a java developer
Better languages don't special-case the constructor instead (no `new` operator), the constructor is just a class method. Bam, "factory method" constructors out of the box and problem solved.
Factories aren't common in Python, but they are used in exactly the same cases where they are used in Java (eg [1],[2],[3]). If you need to decide at runtime what object from an object hierarchy to create you use a factory. There's nothing inherently bad about that.
[1] http://www.linuxtopia.org/online_books/programming_books/pyt...
[2] http://stackoverflow.com/questions/8129018/factory-method-in...
[3] http://eikke.com/python-factory-like-type-instances/ (though I prefer the version in the comments here)
Factories are everywhere in Python because the default construction workflow goes through a bloody factory method.
> There's nothing inherently bad about that.
You may want to read my comment instead of inventing things I never wrote, because the comment you replied to didn't even remotely hint at factories being bad.
Oh, and the first two examples you provide are absolutely horrendous, it's not surprising they are used "in exactly the same cases where they are used in Java", because what you show there really is java code translated to Python.
Whereas the third one is something you can't do in Java: it factorizes the creation of a class through customization of the metaclass's standard creation protocol. The version in the comments overrides the creation of the instance (through, again, a completely standard override of Python's built in construction protocol), which is less efficient but doesn't require understanding metaobjects.
Does Python do that too?
To whit: let's say you want to have an interface for associative arrays. Let's call it Map. Now let's say you want to provide a static method to create an instance of the default Map implementation (call it, say, HashMap). So you'd think about doing something like this:
interface Map { ... static defaultImpl() { .... } }
Except, interfaces can't have implementation in them. That would imply multiple inheritance (which languages like Dart and Java don't support).
Okay, so one workaround: use an abstract class:
abstract class Map { ... static defaultImpl() { .... } }
The only problem is that if you define Map as an abstract class instead of an interface, that means that all implementations of Map must extend Map. Given single inheritance, this means anything providing a Map-style interface can and must only extend from the base Map class.
So... Factory classes are there because of how Java treats interfaces and single inheritance.
DI Frameworks were originally created to provide an alternative to Factories.
A classical, say Java or C# way will still need coupling to such a class. In dart, there is real decoupling going on.
Uh no it does not, it just needs a class. Unless what you mean by "a class instance" is "a class object". A factory method is a classmethod, not an instancemethod.
A factory method and a "factory constructor" need exactly the same thing: the class object.
> In dart, there is real decoupling going on.
In dart, there's mostly a bloody mess of 4 different constructors when all you need is a constructor and an initializer, as done in e.g. Ruby or Python. And these can be "regular" methods (respectively on the class and on the instance).
Conversely, you can also have an "overridden" constructor as in Javascript: an instance is built, the constructor function is called using the instance as its context, and if the constructor returns something that something is returned by `new` in stead of the original object.
This completely depends on your implementation. It's possible to implement it as instance method, or static method.
> Uh no it does not, it just needs a class.
Whether it be a static factory method or an instance method, fact is you need a reference to an implementation (class). In dart, you can do
where List is an interface. There is none class needed in your consuming code, none. In C# or Java, this is impossible: You need _some_ class (whether it be a static method on it, or an instance method) to get a new instance of the interface.Named constructors felt very liberating when working with Dart.
delivers a lot of clarity, while offering the promised decoupling by the GoF:> Define an interface for creating an object, but let the classes which implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses.
It makes no sense, if you're doing that you've switched to full-blown factories (abstracts or builders), you're not using factory methods anymore.
> Whether it be a static factory method or an instance method, fact is you need a reference to an implementation (class). In dart, you can do
> List someListInstance = new List();
> where List is an interface. There is none class needed in your consuming code, none.
That's got nothing to do with factories, or interfaces.
> You need _some_ class (whether it be a static method on it, or an instance method) to get a new instance of the interface.
You always need a class, even in Dart there has to be a default List implementation of some sort which can be called (and has to be specified on the interface, it's not like you can even provide your own default implementation of a third party's interface). As to the calling code needing to know about that one concrete implementation:
Oh look at that, the calling code does not know anything about FooImpl.> Named constructors felt very liberating when working with Dart.
Yeah, that's so much more liberating than:
Wait, no it's not.> You always need a class
Nope. That's the whole point which I am trying to communicate: you do not need a reference to a class to get the instance of the interface from, as you confirm later on:
> As to the calling code needing to know about that one concrete implementation:
My personal feeling of liberation comes from the fact that the code is simpler and more clear. The non-coupling is nice, but can be achieved with dependency injection too: the point is the transfer of characters into a mental model which is more efficient with the named constructors/factory constructors.
Foo is an abstract class, which is the exact same thing.
> Nope. That's the whole point which I am trying to communicate: you do not need a reference to a class to get the instance of the interface from
Neither do you in the code I posted, can you bloody read?
> My personal feeling of liberation comes from the fact that the code is simpler and more clear.
You'll have to give actual examples of that, because I've not seen it so far.
> the point is the transfer of characters into a mental model which is more efficient with the named constructors/factory constructors.
This phrase doesn't even make sense, what "transfer of characters" are you talking about, and how is it more efficient for the user to type more? (named constructors only add ceremony to factory methods) (I'm not even going to talk about factory constructors again, they're a band-aid on the self-inflicted wound of stupid java-style constructors)
(I don't know Dart, though)
Or, perhaps more specifically, you can implement an interface without extending its default implementation.
As the article states, the default implementations are there more so that you can say "m = new Map()", instead of having to remember about this other thing called "HashMap".
A last method is much more intention revealing and easier to scan for me than negative indexes.
Usually is the dangerous word here. (Dangerous as in, "a little knowledge.")