Re: To :D or not to :D
> * Patrick R. Michaud (pmich...@pobox.com) [151013 01:05]: >> On Tue, Oct 13, 2015 at 12:32:01AM +0200, Mark Overmeer wrote: >>> Yes, that what I started realizing when I saw all the pain Perl6 goes to >>> ignore the existence of a real "undef" in the language. (I follow Perl6 >>> from a short distance since its start, read all original designs, but >>> this penny did not drop before, sorry) >> Actually, it's the other way around. Perl 6 is not trying to ignore >> the existence of an "undef", it's recognizing that there are in fact >> many different kinds of undef. It's the languages that think there's >> only one "real undef" that are confused. :) > Yes, I like the typed undef... as real undef. Let's call it "Car:undef" > when it fits in a Car typed variable which is not used yet. Easy to > understand for Perl5 people. Why do we need to add an adverb on a type to talk about the type? If you want to pass a class around for example, do you alsway want to but an ":undef" on it? Then somebody would ask: "What do I get when I dont put said :undef on it?" - And the answer might be "Well, you get basically the same." Also please keep in mind that Perl 6 does not have to be seen from a Perl 5 perspective. There are more valid views. >>> my Car $a; my Car $b; Now I have two different types. >> Not really, you have two variables, both of which have been >> initialized to the same (undefined) Car object. It's not >> much different than >> >>my Int $a; my Int $b; $a = $b = 1; >> >> where $a and $b end up being variables that contain the same >> Int object. > This is a different view on the syntax layer: implementor vs programmer. > As programmer, knowing of optimizations of this kind adds to the > confusion, not to the understanding. As long as >my Int $a; my Int $b; $a = $b = 1; $b = 2; $a.say, $b.say > produces 1\n2\n, I'm fine with any implementation. I don't want to know > how it is done internally. No, rot really. You stated that you have two dirrenent types there, but it really is the very same type. It is just so that two variables containing it. >> I think Self would be the (pardon the pun) prototypical example, and >> it's also a common feature of JavaScript. As to whether there is >> precedence in other "successful" programming languages > I use it in JavaScript. I reread a few tutorials about OO/prototype > in Javascript yesterday. They smoothly speak about adding methods to > objects etc. They speak about types and objects in a very natural way. > They don't speak about undef objects to contain types, which are used > as object factory. I have not found the need for :U there. I've also not used :U in Perl 6 yet. There might be scenarios where you want to accept, say, class definitions only but these cases are rare I'd say. More often you call a construction on a type, or smartmatch a value agains a type. And this really happens regularly in idomatic Perl 6 code. >> Perl 6 still has classes and instances, but Perl 6 also adds the >> ability to represent undefined instances of a type (or, rephrased, >> to have typed "undefs"). Perl 6 then binds the commonly-used >> identifier (e.g., C) to an undefined instance rather than the >> class object that defines the instances. Once you accept that model, >> it seems to work out very well in practice. > Trying to reformulate this without spoilers of internal details: > > Perl6 has classes, instances, and prototypes. Commonly used > types, like Int, are prototypes based on classes. Therefore, > they can easily absorb features via Roles and Mixins. > > Note about the internals: we are not keeping a separate > administration of type features, but keep that inside the > instantiated objects. As all prototype-based languages do. > > Acceptable? > >> If Research refers instead to the class definition, then the >> method namespaces for instances and classes begin to clash, and >> we have to introduce all sorts of disambiguation for that. > Yes, disambiguation either via a keyword (class method/instance method) > or via the invocant (being a type :T or instance... multi methods to > the rescue) > > For me, prototypes in JavaScript work well, because all graphical > elements on the screen are slightly different in behavior. I am a bit > afraid to get into swamps when programs are large, where it is already > hard to keep track on all the cleanly organized classes. > > So... my hessitation seems to be limited to the explanation and name > of the flag :U, which tell me that a type is an undef. Type defining > features are loaded into a base object which does not carry a value: yes. > Via specialization you get objects which carry a value. > > Maybe this comes back to the distiction between implicit and explicit > undefinedness.
Re: To :D or not to :D
Hi Patrick, thank you for your thoughts. I needed a bit more time for the response ;-) * Patrick R. Michaud (pmich...@pobox.com) [151013 01:05]: > On Tue, Oct 13, 2015 at 12:32:01AM +0200, Mark Overmeer wrote: > > Yes, that what I started realizing when I saw all the pain Perl6 goes to > > ignore the existence of a real "undef" in the language. (I follow Perl6 > > from a short distance since its start, read all original designs, but > > this penny did not drop before, sorry) > > Actually, it's the other way around. Perl 6 is not trying to ignore > the existence of an "undef", it's recognizing that there are in fact > many different kinds of undef. It's the languages that think there's > only one "real undef" that are confused. :) Yes, I like the typed undef... as real undef. Let's call it "Car:undef" when it fits in a Car typed variable which is not used yet. Easy to understand for Perl5 people. > > my Car $a; my Car $b; Now I have two different types. > > Not really, you have two variables, both of which have been > initialized to the same (undefined) Car object. It's not > much different than > >my Int $a; my Int $b; $a = $b = 1; > > where $a and $b end up being variables that contain the same > Int object. This is a different view on the syntax layer: implementor vs programmer. As programmer, knowing of optimizations of this kind adds to the confusion, not to the understanding. As long as my Int $a; my Int $b; $a = $b = 1; $b = 2; $a.say, $b.say produces 1\n2\n, I'm fine with any implementation. I don't want to know how it is done internally. > I think Self would be the (pardon the pun) prototypical example, and > it's also a common feature of JavaScript. As to whether there is > precedence in other "successful" programming languages I use it in JavaScript. I reread a few tutorials about OO/prototype in Javascript yesterday. They smoothly speak about adding methods to objects etc. They speak about types and objects in a very natural way. They don't speak about undef objects to contain types, which are used as object factory. I have not found the need for :U there. > Perl 6 still has classes and instances, but Perl 6 also adds the > ability to represent undefined instances of a type (or, rephrased, > to have typed "undefs"). Perl 6 then binds the commonly-used > identifier (e.g., C) to an undefined instance rather than the > class object that defines the instances. Once you accept that model, > it seems to work out very well in practice. Trying to reformulate this without spoilers of internal details: Perl6 has classes, instances, and prototypes. Commonly used types, like Int, are prototypes based on classes. Therefore, they can easily absorb features via Roles and Mixins. Note about the internals: we are not keeping a separate administration of type features, but keep that inside the instantiated objects. As all prototype-based languages do. Acceptable? > If Research refers instead to the class definition, then the > method namespaces for instances and classes begin to clash, and > we have to introduce all sorts of disambiguation for that. Yes, disambiguation either via a keyword (class method/instance method) or via the invocant (being a type :T or instance... multi methods to the rescue) For me, prototypes in JavaScript work well, because all graphical elements on the screen are slightly different in behavior. I am a bit afraid to get into swamps when programs are large, where it is already hard to keep track on all the cleanly organized classes. So... my hessitation seems to be limited to the explanation and name of the flag :U, which tell me that a type is an undef. Type defining features are loaded into a base object which does not carry a value: yes. Via specialization you get objects which carry a value. Maybe this comes back to the distiction between implicit and explicit undefinedness. -- MarkOv Mark Overmeer MScMARKOV Solutions m...@overmeer.net soluti...@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Re: To :D or not to :D
* Moritz Lenz (mor...@faui2k3.org) [151013 07:18]: > >In Perl5, you get slower code when you test for definedness... in Perl6 > >you get faster (better optimized) code. That's a big difference. > > Do you? Did you actually measure that? For Perl6? Well, Liz tells us that it can be optimized better (you limit the range of choices) Whether this is already the case does not really matter here. And at least it produces the error at the side of the caller, not inside your function. > >How can de invocant not be defined? > > Well, if you call a constructor, you call it on the type object. Hence the > type object is the class, and not defined. Yes, that's the other thread which emerged from my :D question. When you call .new, the type is well defined (maybe Any). Trickery links that type to some missing value "undef". And then the programmer is expected to understand that :U actually means "it's a class method". I would be able to understand it better if that whole type==undef stayed hidden from the story told to the programmer. For instance, by calling this flag :T (from Type) The freed up flag :U may say "non-defined for positional allowed", and :D can become the default. > >There shouldn't be a problem making :D a superfluous option. Of swiftly > >add "use parameters $_;" to all modules. > > Why shouldn't this be a problem? If you make :D the default behavior, then adding "use parameters $_;" to existing code would avoid the urgency to scan through all code to see what needs to be changed. > >>> . :D looks really ugly, don't you think? Try to explain to students > >>> to add this smiley everywhere. > >> > >>It's not uglier than a 'die "Must be defined" unless defined $x' > >Much too expensive in Perl5. > > Then don't do in Perl 6 either. If you can argue away the need for safety > based on the need for performance, you can also argue away the need for > safety based on the need for cleaner code. Remember that I only ask for :D to be the default. That's an generic request which does not depend on my personal programming style. For my personal Perl5 code, no: I do not check the definedness of all parameters because it is a lot of work to code and slows-down all subs. I have the intention to use the definedness checks on all parameters in Perl6 because the brievety of ":D" gives me the impression that it is fast, produces a standardized clean message, and easy to use. So, my code would look like Tux's work: cluttered with :D Within a code block, variables are often temporary undefined. But as positional parameters of functions that's rarely useful. For named parameters, the situation is different. In their case, you want to choose between: "undef value means missing parameter", "undef value means illegal value" (:D), "undef value is allowed". For my coding style, the first case is usually true. I am not sure, but probably Perl6 makes do difference between missing existence and undefinedness of named parameters... where hashes and XML (minOccurs=0/nillable) do. So probably merged to "undef value is allowed". Moritz, Patrick, thanks for your patience and detailed answers! -- Regards, MarkOv Mark Overmeer MScMARKOV Solutions m...@overmeer.net soluti...@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Re: To :D or not to :D
On 10/12/2015 09:51 PM, Mark Overmeer wrote: * Moritz Lenz (mor...@faui2k3.org) [151012 15:32]: . are they using :D correctly? Yes, though not everybody uses :D as much as they do. Do you check that all the parameters that your Perl 5 methods/subs receive are defined? If not, you wouldn't use :D in Perl 6 either. In Perl5, you get slower code when you test for definedness... in Perl6 you get faster (better optimized) code. That's a big difference. Do you? Did you actually measure that? FWIW you can now (as of a few days ago) control the default with use invocant :D; How can de invocant not be defined? Well, if you call a constructor, you call it on the type object. Hence the type object is the class, and not defined. use parameters :D; The new "use warnings"/"use strict"... which means all those :D annotations can go away, and you have to use :_ explicitly if you want to allow all. Oh, use :U for that. Ehhh already in use. :U means "undefined", :_ means "defined or undefined, I don't care" And I don't know if we can change it now without creating a huge havoc in the existing ecosystem. There shouldn't be a problem making :D a superfluous option. Of swiftly add "use parameters $_;" to all modules. Why shouldn't this be a problem? And there still quite a number of other crucial changes going in anyway... But hopefully none of them breaking backwards compatibility on such a large scale. The last few backwards incompatible changes still cause pain in the ecosystem. We have 390+ modules, and hand-waving away all trouble of maintaining them seems a bit lofty. . :D looks really ugly, don't you think? Try to explain to students to add this smiley everywhere. It's not uglier than a 'die "Must be defined" unless defined $x' Much too expensive in Perl5. Then don't do in Perl 6 either. If you can argue away the need for safety based on the need for performance, you can also argue away the need for safety based on the need for cleaner code. Cheers, Moritz
Re: To :D or not to :D
On Tue, Oct 13, 2015 at 12:32:01AM +0200, Mark Overmeer wrote: > Yes, that what I started realizing when I saw all the pain Perl6 goes to > ignore the existence of a real "undef" in the language. (I follow Perl6 > from a short distance since its start, read all original designs, but > this penny did not drop before, sorry) Actually, it's the other way around. Perl 6 is not trying to ignore the existence of an "undef", it's recognizing that there are in fact many different kinds of undef. It's the languages that think there's only one "real undef" that are confused. :) > The reasoning behind the output of > my $a; $a.say; $a = 1; $a.saybeing (Any) \n 1 \n > Which actually means > "unstantiated (Any)" versus "instantiated (Int) value=1" > for me personally painfully imbalanced. > > my Car $a; my Car $b; Now I have two different types. Not really, you have two variables, both of which have been initialized to the same (undefined) Car object. It's not much different than my Int $a; my Int $b; $a = $b = 1; where $a and $b end up being variables that contain the same Int object. > Is there any precedence in a succesful programming language where types > and values get mixed-up this way? I think Self would be the (pardon the pun) prototypical example, and it's also a common feature of JavaScript. As to whether there is precedence in other "successful" programming languages -- to me part of Perl's legacy has always been that it offers exotic (at the time) features that other "successful" languages didn't provide. Perl has often been the tip of the spear in making "exotic" features commonplace. :) Larry and the other OO experts can probably comment on this in more detail; but this construction of types allows Perl 6 to incorporate a lot more features of prototype-based languages than the traditional class-based model. I suspect it's also related to a proper implementation of mixins and roles. > For me, a "Car" is not "a vehicle which is not yet there", but is a > featural and functional template of a thing. The template describes the > interface of a car, not the instance of a car. A type is scientific, > an object is dull facts. Is that an old-fashioned, traditional idea > to be abandoned? Perl 6 still has classes and instances, but Perl 6 also adds the ability to represent undefined instances of a type (or, rephrased, to have typed "undefs"). Perl 6 then binds the commonly-used identifier (e.g., C) to an undefined instance rather than the class object that defines the instances. Once you accept that model, it seems to work out very well in practice. When we need to communicate with the class definition (rather than an instance), there's a convenient .^foo syntax that allows us to accomplish this, which works on any instance (defined or undefined). That becomes important when you want to do something like: my Research $a; say $a.methods(); # invoke "methods" defined by Research say Research.methods(); # same as above say $a.^methods(); # return a list of methods for Research objects If Research refers instead to the class definition, then the method namespaces for instances and classes begin to clash, and we have to introduce all sorts of disambiguation for that. Pm
Re: To :D or not to :D
* Patrick R. Michaud (pmich...@pobox.com) [151012 20:25]: > > > method new(MyClassHere:U: *@args) { ... } > Keep in mind that what Perl 6 calls a "type object" isn't quite the > same as class objects in other languages -- a Perl 6 typename is > really an undefined instance of a class. In other words, the > identifiers C, C, C etc. refer to instances of > those classes just like the literals C<3>, C<4/5>, and C<[1,2,3]> are > instances of those classes. They share the same method spaces. Yes, that what I started realizing when I saw all the pain Perl6 goes to ignore the existence of a real "undef" in the language. (I follow Perl6 from a short distance since its start, read all original designs, but this penny did not drop before, sorry) The reasoning behind the output of my $a; $a.say; $a = 1; $a.saybeing (Any) \n 1 \n Which actually means "unstantiated (Any)" versus "instantiated (Int) value=1" for me personally painfully imbalanced. my Car $a; my Car $b; Now I have two different types. Eh, wait they are both Cars. No, not the same because types are real objects. Or maybe a bit the same, because $a===$b is made to work. Ehhh... Confused. Is there any precedence in a succesful programming language where types and values get mixed-up this way? There must be a hidden advantange, which I do not see. Of course, syntactically this works, but Why? For me, a "Car" is not "a vehicle which is not yet there", but is a featural and functional template of a thing. The template describes the interface of a car, not the instance of a car. A type is scientific, an object is dull facts. Is that an old-fashioned, traditional idea to be abandoned? -- Regards, MarkOv Mark Overmeer MScMARKOV Solutions m...@overmeer.net soluti...@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Re: To :D or not to :D
On 2015-10-12 1:25 PM, Patrick R. Michaud wrote: On Mon, Oct 12, 2015 at 09:51:13PM +0200, Mark Overmeer wrote: Can you give me an example? Many other languages are capable to live without undef and have first class type objects. Keep in mind that what Perl 6 calls a "type object" isn't quite the same as class objects in other languages -- a Perl 6 typename is really an undefined instance of a class. In other words, the identifiers C, C, C etc. refer to instances of those classes just like the literals C<3>, C<4/5>, and C<[1,2,3]> are instances of those classes. They share the same method spaces. Hey, that sounds like a nice elegant design, I learned something new. -- Darren Duncan
Re: To :D or not to :D
On Mon, Oct 12, 2015 at 09:51:13PM +0200, Mark Overmeer wrote: > > method new(MyClassHere:U: *@args) { ... } > > > > in the constructor, which would be quite hostile to newbies. It's still > > not clear to me how to avoid that. > > It is also unclear to me what this means. It is a method which requires > and undef parameter? Because of the second colon, it's a method accepting an undef invocant. This is what would be needed in order for MyClassHere.new(...) to work the way you expect (since MyClassHere is undefined). > > Another concern is that if "everything" defaults to :D, then classes > > (and other type objects) aren't really first class objects anymore, > > which is a really neat thing to have. > > Can you give me an example? Many other languages are capable to live > without undef and have first class type objects. Keep in mind that what Perl 6 calls a "type object" isn't quite the same as class objects in other languages -- a Perl 6 typename is really an undefined instance of a class. In other words, the identifiers C, C, C etc. refer to instances of those classes just like the literals C<3>, C<4/5>, and C<[1,2,3]> are instances of those classes. They share the same method spaces. Pm
Re: To :D or not to :D
* Moritz Lenz (mor...@faui2k3.org) [151012 15:32]: > > . are they using :D correctly? > > Yes, though not everybody uses :D as much as they do. Do you check that > all the parameters that your Perl 5 methods/subs receive are defined? If > not, you wouldn't use :D in Perl 6 either. In Perl5, you get slower code when you test for definedness... in Perl6 you get faster (better optimized) code. That's a big difference. > FWIW you can now (as of a few days ago) control the default with > use invocant :D; How can de invocant not be defined? > use parameters :D; The new "use warnings"/"use strict"... > which means all those :D annotations can go away, and you have to use :_ > explicitly if you want to allow all. Oh, use :U for that. Ehhh already in use. > That said, I agree that it's the wrong default. And the design documents > even mandate a default to :D, though at the time it was written, it > wasn't clear how to switch off that default, nor how to avoid having to > write > > method new(MyClassHere:U: *@args) { ... } > > in the constructor, which would be quite hostile to newbies. It's still > not clear to me how to avoid that. It is also unclear to me what this means. It is a method which requires and undef parameter? > And I don't know if we can change it now without creating a huge havoc > in the existing ecosystem. There shouldn't be a problem making :D a superfluous option. Of swiftly add "use parameters $_;" to all modules. And there still quite a number of other crucial changes going in anyway... > Another concern is that if "everything" defaults to :D, then classes > (and other type objects) aren't really first class objects anymore, > which is a really neat thing to have. Can you give me an example? Many other languages are capable to live without undef and have first class type objects. In the old days, I had to implement the Algol68 style during compile construction course ;-) > > . :D looks really ugly, don't you think? Try to explain to students > > to add this smiley everywhere. > > It's not uglier than a 'die "Must be defined" unless defined $x' Much too expensive in Perl5. -- Regards, MarkOv Mark Overmeer MScMARKOV Solutions m...@overmeer.net soluti...@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Re: To :D or not to :D
Hi, On 10/12/2015 03:41 PM, Mark Overmeer wrote: > > Hi all, > > Liz and Tux demonstrate powerful Perl6 code at each monthly meeting of > our Mongers in Amsterdam. Looking at their examples, I collected a few > questions of which I want to discuss the first one in this thread. > > > When I look at Merijns (Tux') code, I see a huge number of :D attributes. > https://github.com/Tux/CSV/blob/master/lib/Text/CSV.pm > > Close to all scalar positional parameter (51x) carry the :D flag. I count > only 3 where the parameter does accept undef and the method is able to > handle it. I count another 3 where the :D is missing, but the method is > not able the handle it. > > The same for examples Liz shows us in our core code: most scalar > positional parameters have :D. > > Writing a sub which is able to handle undef is usually more work than > implementing "I expect sane values for all of the parameters". > > > Questions: > . are they using :D correctly? Yes, though not everybody uses :D as much as they do. Do you check that all the parameters that your Perl 5 methods/subs receive are defined? If not, you wouldn't use :D in Perl 6 either. > . the simpelest code does not handle the undef case... but now needs > the more complex prototype to be correct. > . it feels like the wrong default: usually you have to do something > extra for the unusual cases, not the 90%+ usual cases. FWIW you can now (as of a few days ago) control the default with use invocant :D; and use parameters :D; which means all those :D annotations can go away, and you have to use :_ explicitly if you want to allow all. That said, I agree that it's the wrong default. And the design documents even mandate a default to :D, though at the time it was written, it wasn't clear how to switch off that default, nor how to avoid having to write method new(MyClassHere:U: *@args) { ... } in the constructor, which would be quite hostile to newbies. It's still not clear to me how to avoid that. And I don't know if we can change it now without creating a huge havoc in the existing ecosystem. Another concern is that if "everything" defaults to :D, then classes (and other type objects) aren't really first class objects anymore, which is a really neat thing to have. > . :D looks really ugly, don't you think? Try to explain to students > to add this smiley everywhere. It's not uglier than a 'die "Must be defined" unless defined $x' Cheers, Moritz