www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - x.sizeof vs typeid(x)

reply Sergey Gromov <snake.scaly gmail.com> writes:
I wonder why .sizeof is implemented as a property while typeof() and
typeid() are functions.  I can see no reasons for such inconsistency.
It's not that obvious for typeof() because it yields a type instead
of a value, but even then, why not ?
Feb 05 2008
next sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
I believe there are plans afoot to remove the distinction, so that
f(x) and x.f are, in general, interchangable. If and when that day
comes, perhaps we'll be able to write sizeof(x) and x.typeid as well?

On 06/02/2008, Sergey Gromov <snake.scaly gmail.com> wrote:
 I wonder why .sizeof is implemented as a property while typeof() and
 typeid() are functions.  I can see no reasons for such inconsistency.
 It's not that obvious for typeof() because it yields a type instead
 of a value, but even then, why not ?

Feb 05 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Are you sure this is to the better ?  I'm not quite fond of D's freedom
in syntax.  It already allows to write an unreadable code like this:

use(context) in (GL gl) {draw(gl);}

auto GetEven = stackthread = (int delegate() read, void delegate(int) yield)
{...}

Less typing is often => less maintainable.  And Perl's slogan, "there is
more than one way to do things," is exactly what makes Perl
a write-only language.

SnakE

Janice Caron Wrote:
 I believe there are plans afoot to remove the distinction, so that
 f(x) and x.f are, in general, interchangable. If and when that day
 comes, perhaps we'll be able to write sizeof(x) and x.typeid as well?
 
 On 06/02/2008, Sergey Gromov <snake.scaly gmail.com> wrote:
 I wonder why .sizeof is implemented as a property while typeof() and
 typeid() are functions.  I can see no reasons for such inconsistency.
 It's not that obvious for typeof() because it yields a type instead
 of a value, but even then, why not ?


Feb 06 2008
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Sergey Gromov:
 Less typing is often => less maintainable.

But that may be false if you take lot of care of keeping the language tidy, quite ergonomic. Python is quite maintainable, and it's far from being verbose. Haskell too is readable enough, if you know it, despite its programs being quite short. In this regard, one of the things I don't like of D syntax is that it allows to call functions without the final () if they take no arguments. It may be useful for properties, but when you see something like: foo = bar; Is it a function call? I am learning to always put the () there to be explicit: foo = bar(); To improve code readability I think it may be better to remove this feature from the language (and later that may be used to simplify the object instantiation syntax). Bye, bearophile
Feb 06 2008
next sibling parent reply Matti Niemenmaa <see_signature for.real.address> writes:
bearophile wrote:
 In this regard, one of the things I don't like of D syntax is that it allows
 to call functions without the final () if they take no arguments. It may be
 useful for properties, but when you see something like:
 
 foo = bar;
 
 Is it a function call? I am learning to always put the () there to be
 explicit:
 
 foo = bar();
 
 To improve code readability I think it may be better to remove this feature
 from the language (and later that may be used to simplify the object
 instantiation syntax).

The point is that it shouldn't matter. If you want to change it later to a function, you have to change all the points where you use it as well. Canonical example with classes: class Vector { Point a, b; double distance; this(...) {...} } Now, if you want to save memory by changing distance to a method instead: class Vector { Point a, b; this(...) {...} double distance() {...} } You would have to change all uses of distance, whether inside or outside the class, to be distance() instead of distance. Except that D does give us the ability to always use just distance and not care about whether it's a function or not. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Feb 06 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
Matti Niemenmaa:
 You would have to change all uses of distance, whether inside or outside the 
 class, to be distance() instead of distance.
 
 Except that D does give us the ability to always use just distance and not
care 
 about whether it's a function or not.

I was talking about free functions. I think for methods/properties the syntax without () can be kept... Bye, bearophile
Feb 06 2008
parent Matti Niemenmaa <see_signature for.real.address> writes:
bearophile wrote:
 I was talking about free functions. I think for methods/properties the syntax
 without () can be kept...

As I said in another post, that which applies to properties applies equally well to free functions, due to global variables. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Feb 06 2008
prev sibling next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
bearophile wrote:
 Sergey Gromov:
 Less typing is often => less maintainable.

But that may be false if you take lot of care of keeping the language tidy, quite ergonomic. Python is quite maintainable, and it's far from being verbose. Haskell too is readable enough, if you know it, despite its programs being quite short. In this regard, one of the things I don't like of D syntax is that it allows to call functions without the final () if they take no arguments. It may be useful for properties, but when you see something like: foo = bar; Is it a function call? I am learning to always put the () there to be explicit: foo = bar(); To improve code readability I think it may be better to remove this feature from the language (and later that may be used to simplify the object instantiation syntax). Bye, bearophile

I agree with you on that particular syntax. I think when it's a member of some sort, that syntax should be allowed, though (to allow a property syntax), but for free functions it's a bad idea.
Feb 06 2008
parent reply Matti Niemenmaa <see_signature for.real.address> writes:
Robert Fraser wrote:
 I agree with you on that particular syntax. I think when it's a member 
 of some sort, that syntax should be allowed, though (to allow a property 
 syntax), but for free functions it's a bad idea.

The argument for class properties applies equally well to global variables. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Feb 06 2008
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Matti Niemenmaa wrote:
 Robert Fraser wrote:
 I agree with you on that particular syntax. I think when it's a member 
 of some sort, that syntax should be allowed, though (to allow a 
 property syntax), but for free functions it's a bad idea.

The argument for class properties applies equally well to global variables.

Oops, forgot about those... alright, well I guess then people just need to be careful with this syntax.
Feb 06 2008
parent torhu <no spam.invalid> writes:
Robert Fraser wrote:
 Matti Niemenmaa wrote:
 Robert Fraser wrote:
 I agree with you on that particular syntax. I think when it's a member 
 of some sort, that syntax should be allowed, though (to allow a 
 property syntax), but for free functions it's a bad idea.

The argument for class properties applies equally well to global variables.

Oops, forgot about those... alright, well I guess then people just need to be careful with this syntax.

I've actually used that when making bindings for a C library which has got some volatile globals. Just property wrappers with volatile statements in them. At least it made the examples easier to port. Whether this syntax is good or bad in general, I'm not sure.
Feb 06 2008
prev sibling parent reply Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> writes:
 It may be useful for properties, but when you see something like:
 
 foo = bar;
 
 Is it a function call?
 I am learning to always put the () there to be explicit:
 
 foo = bar();

It really gets odd when foo is a function as well: void foo(int i); int bar(); foo = bar; // same as foo(bar()); I think property syntax is nice, but should only be valid where it makes sense (or only where the user explicitly allowed it). Christian Kamm
Feb 06 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Christian Kamm wrote:
 It really gets odd when foo is a function as well:
 
 void foo(int i);
 int bar();
 
 foo = bar; // same as foo(bar());
 
 I think property syntax is nice, but should only be valid where it makes
 sense (or only where the user explicitly allowed it).

Agree. If there were, say, an attribute `property', so that you can write: foo(double x) {...} property double distance() {return ...} foo(distance); // OK foo(distance()); // OK foo = distance; // error it'd be much safer. SnakE
Feb 06 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Sergey Gromov <snake.scaly gmail.com> wrote:
 foo(double x) {...}
 property double distance() {return ...}
 
 foo(distance);   // OK
 foo(distance()); // OK
 foo = distance;  // error

Or even forbid to use the `double()' syntax for properties, and forbid to overload properties with non-property functions. In other words: foo(distance()); // error, can't use call syntax for properties double distance(int precision) {...} // error, can't overload a property -- SnakE
Feb 06 2008
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Sergey Gromov wrote:
 Sergey Gromov <snake.scaly gmail.com> wrote:
 foo(double x) {...}
 property double distance() {return ...}

 foo(distance);   // OK
 foo(distance()); // OK
 foo = distance;  // error

Or even forbid to use the `double()' syntax for properties, and forbid to overload properties with non-property functions. In other words: foo(distance()); // error, can't use call syntax for properties double distance(int precision) {...} // error, can't overload a property

From my limited experience with C#, I know there's some kind of special property syntax. Maybe something like this would be a better solution? private double myDistance; public property distance { double __get { return myDistance; } void __set(double val) { myDistance= val; } double* __addressOf { return &myDistance; } } double x = distance; // x = distance.__get(); distance = 50.0; // distance.__set(50.0); double* p = &distance; // p = distance.__addressOf(); And maybe add more property-properties as needed. This would make them first-class, fully interchangeable with variables.
Feb 06 2008
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Robert Fraser:
  From my limited experience with C#, I know there's some kind of special 
 property syntax. Maybe something like this would be a better solution?

If you take a look at my last post of notes (the 4th) you can see I suggested something even better, coming from C# 3.x ;-) Bye, bearophile
Feb 06 2008
prev sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
Robert Fraser <fraserofthenight gmail.com> wrote:
  From my limited experience with C#, I know there's some kind of special 
 property syntax. Maybe something like this would be a better solution?
 
 private double myDistance;
 public property distance
 {
     double __get { return myDistance; }
     void __set(double val) { myDistance= val; }
     double* __addressOf { return &myDistance; }
 }
 
 double x = distance;    // x = distance.__get();
 distance = 50.0;        // distance.__set(50.0);
 double* p = &distance;  // p = distance.__addressOf();
 
 And maybe add more property-properties as needed. This would make them 
 first-class, fully interchangeable with variables.

Yes, this would be far more consistent of course. I've just tried to keep to the current syntax and semantics as close as possible. -- SnakE
Feb 06 2008
prev sibling next sibling parent downs <default_357-line yahoo.de> writes:
Sergey Gromov wrote:
 Are you sure this is to the better ?  I'm not quite fond of D's freedom
 in syntax.  It already allows to write an unreadable code like this:
 
 use(context) in (GL gl) {draw(gl);}
 
 auto GetEven = stackthread = (int delegate() read, void delegate(int) yield)
{...}
 

I just don't like "});". The less closing parens the better. :) Semantically, read it as "auto GetEven = stackthread = (int delegate() read, void delegate(int) yield) { ... };]". --downs
Feb 06 2008
prev sibling parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Sergey Gromov wrote:
 Are you sure this is to the better ?  I'm not quite fond of D's freedom
 in syntax.  It already allows to write an unreadable code like this:
 
 use(context) in (GL gl) {draw(gl);}

And when I actually asked for comments about that syntax, no one stated that it was unreadable ... thanks for the (mislocated) feedback. As for the exact form of that use() in .. statement, I made it so with the sole purpose of it being *readable*. It may be new to you; it usually makes people think that the construct is built into D, resulting in some confusion ("did I miss anything in the spec?"). Yet ultimately using the language's features to write code which looks built-in makes code easier to read. If my statement is false, then using AST macros in lisp makes the code less readable as well. -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Feb 07 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:
 Sergey Gromov wrote:
 Are you sure this is to the better ?  I'm not quite fond of D's freedom
 in syntax.  It already allows to write an unreadable code like this:
 
 use(context) in (GL gl) {draw(gl);}

And when I actually asked for comments about that syntax, no one stated that it was unreadable ... thanks for the (mislocated) feedback.

I don't know where or when you have asked for this. It's not my job to read through years of discussions, and I'm not obligated to read every single post even though I do monitor the group. Someone has cited this code in D.learn asking what it does. That's exactly what I mean.
 As for the exact form of that use() in .. statement, I made it so with 
 the sole purpose of it being *readable*. It may be new to you; it 
 usually makes people think that the construct is built into D, resulting 
 in some confusion ("did I miss anything in the spec?"). Yet ultimately 
 using the language's features to write code which looks built-in makes 
 code easier to read. If my statement is false, then using AST macros in 
 lisp makes the code less readable as well.

I'm not familiar with Lisp. Anyway, when I say 'readable,' I mean that I can look into an unfamiliar code written by other person and understand, in general, what's happening. This class is having this method called with these arguments. That template is instantiated with those types. Basically, it should be enough to read language specification to understand the code. In your case you're inventing a construct which doesn't quite fit into specs, which in turn causes confusion. -- SnakE
Feb 07 2008
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Sergey Gromov wrote:
 I don't know where or when you have asked for this.  It's not my job to 
 read through years of discussions, and I'm not obligated to read every 
 single post even though I do monitor the group.
 
 Someone has cited this code in D.learn asking what it does.  That's 
 exactly what I mean.

Ah, fine then, I thought you saw me pasting a more complete example on IRC on #d :) Anyway, here it is, so maybe it makes some more sense this time: http://paste.dprogramming.com/dpn66vhk It's an example from an unreleased OpenGL wrapper. The ext/use(...) in {}; constructs actually play an important role in its functioning, restricting access to the resource to a controlled region, executing special code before and after it, and in the case of 'ext', allowing an extra parameter after a variadic one.
 I'm not familiar with Lisp.  Anyway, when I say 'readable,' I mean that 
 I can look into an unfamiliar code written by other person and 
 understand, in general, what's happening.  This class is having this 
 method called with these arguments.  That template is instantiated with 
 those types.  Basically, it should be enough to read language 
 specification to understand the code.  In your case you're inventing a 
 construct which doesn't quite fit into specs, which in turn causes 
 confusion.

Doesn't fit into the specs? How so? It's not like I'm preprocessing D. I've talked with a few folks who have been coding in D for a while, and they immediately recognized the constructs. The func call, proxy object, opIn and the inline delegate. It's not a surprise that fancy D code may cause confusion in D.learn, since well, it's an NG for beginners... Let's take another example. For someone coming from Java, operator overloads might be unreadable code because when they see a + b, they can't know what's happening. But it's normal for D code. Someone coming from C would see any OO stuff unreadable. D is a relatively new language and there really isn't a common understanding of how 'readable' D code should look like. It's got its very own feel and syntax, to which programmers must get used and perhaps notice that some things can be implemented in a much different way than in their old favorite language. -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Feb 07 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:
 Sergey Gromov wrote:
 I'm not familiar with Lisp.  Anyway, when I say 'readable,' I mean that 
 I can look into an unfamiliar code written by other person and 
 understand, in general, what's happening.  This class is having this 
 method called with these arguments.  That template is instantiated with 
 those types.  Basically, it should be enough to read language 
 specification to understand the code.  In your case you're inventing a 
 construct which doesn't quite fit into specs, which in turn causes 
 confusion.

Doesn't fit into the specs? How so? It's not like I'm preprocessing D. I've talked with a few folks who have been coding in D for a while, and they immediately recognized the constructs. The func call, proxy object, opIn and the inline delegate. It's not a surprise that fancy D code may cause confusion in D.learn, since well, it's an NG for beginners...

OK so I'm new to D, too. It's a part of a problem. I have quite strong C/C++/Java background, and I do like the strictness of Java. But anyway. opIn has a distinct default semantics in the language. It's "check if," not an "apply to." The ability to overload is here to mimic the default semantics for non-ordinary types. It's a bad practice IMO to completely change operator semantics. That's exactly why a concatenation operator is added to D: to ensure that what you think is being done is actually what is done, at least conceptually. That's also the reason I didn't like the luabind library for C++. Here's a piece of C++ code: module(L) [ def("greet", &greet) ]; What it does, God knows. -- SnakE
Feb 07 2008
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Sergey Gromov wrote:
 opIn has a distinct default semantics in the language.  It's 
 "check if," not an "apply to."  The ability to overload is here to mimic 
 the default semantics for non-ordinary types.  It's a bad practice IMO 
 to completely change operator semantics.

Well then, the whole C++ committee is following bad practice as well, by making << and >> work with streams. Following semantics is one thing - sure. It's crucial when you're making your own Map container to support it in exactly the same way as the built-in AAs do. But if you can make your code more natural to write by abusing the operators a little - opIn, operator<<, etc, then it's not a very bad practice IMHO. In fact, anyone defining opMul for their matrix class/struct is breaking semantics. The spec states that opMul is commutative.
 That's exactly why a 
 concatenation operator is added to D: to ensure that what you think is 
 being done is actually what is done, at least conceptually.

Wrong. As far as I know, it was added because D was supposed to have array operations, so you could say [1, 2] + [10, 10] and have [11, 12], not the concatenation.
 That's also the reason I didn't like the luabind library for C++. Here's 
 a piece of C++ code:
 
     module(L)
     [
         def("greet", &greet)
     ];
 
 What it does, God knows.

It doesn't really matter. Would you actually know without looking at the implementation? It's easy to read, the language features used can be figured out rather easily. What matters is that it's really easy to use. It's actually a very nice example of a DSL (Domain Specific Language) within C++. Would you rather write 4 times this much, in order just to have it look like the rest of C++ code? Because then, there's the low level C API... -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Feb 07 2008
next sibling parent reply Sergey Gromov <snake.scaly gmail.com> writes:
What can I say.  I do not agree.  C++ committee is not the best 
exemplar.  Looking into implementation should be required to learn the 
details, not to understand what the hell is going on.  Creating the DSLs 
should be a privilege of scripting languages, that's what they are for, 
after all.

Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:
 Sergey Gromov wrote:
 opIn has a distinct default semantics in the language.  It's 
 "check if," not an "apply to."  The ability to overload is here to mimic 
 the default semantics for non-ordinary types.  It's a bad practice IMO 
 to completely change operator semantics.

Well then, the whole C++ committee is following bad practice as well, by making << and >> work with streams. Following semantics is one thing - sure. It's crucial when you're making your own Map container to support it in exactly the same way as the built-in AAs do. But if you can make your code more natural to write by abusing the operators a little - opIn, operator<<, etc, then it's not a very bad practice IMHO. In fact, anyone defining opMul for their matrix class/struct is breaking semantics. The spec states that opMul is commutative.
 That's exactly why a 
 concatenation operator is added to D: to ensure that what you think is 
 being done is actually what is done, at least conceptually.

Wrong. As far as I know, it was added because D was supposed to have array operations, so you could say [1, 2] + [10, 10] and have [11, 12], not the concatenation.
 That's also the reason I didn't like the luabind library for C++. Here's 
 a piece of C++ code:
 
     module(L)
     [
         def("greet", &greet)
     ];
 
 What it does, God knows.

It doesn't really matter. Would you actually know without looking at the implementation? It's easy to read, the language features used can be figured out rather easily. What matters is that it's really easy to use. It's actually a very nice example of a DSL (Domain Specific Language) within C++. Would you rather write 4 times this much, in order just to have it look like the rest of C++ code? Because then, there's the low level C API...

-- SnakE
Feb 07 2008
next sibling parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Sergey Gromov wrote:
 What can I say.  I do not agree.  C++ committee is not the best 
 exemplar.  Looking into implementation should be required to learn the 
 details, not to understand what the hell is going on.  Creating the DSLs 
 should be a privilege of scripting languages, that's what they are for, 
 after all.

As long as you understand the language, you should understand more or less 'what the hell is going on'. Doesn't make much difference for comprehension, whether it's written using syntax sugar or not. Yet it may be more pleasant to read when it's *with* sugar. As for your argument with scripting languages? Do you suggest that the binding to Lua from C++ should be done... with a scripting language? That wouldn't make much sense. And yet, the folks have managed to create a very nice DSL within C++ that makes the code look really nice. Or should my GL wrapper *for D* be running through a scripting language? What can I say. I do not agree. Scripting languages have their uses, but when the 'main' language is powerful enough, you don't need them that much. -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Feb 07 2008
prev sibling parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Anders Bergh <anders1 gmail.com> wrote:
 On Feb 8, 2008 3:20 AM, Sergey Gromov <snake.scaly gmail.com> wrote:
 What can I say.  I do not agree.  C++ committee is not the best
 exemplar.  Looking into implementation should be required to learn the
 details, not to understand what the hell is going on.  Creating the DSLs
 should be a privilege of scripting languages, that's what they are for,
 after all.

How is this different from other code? You have to look in any implementation code to figure out what's going on internally, be it with syntax sugar or not.

If there is a bug, and I know it's /not/ in the OpenGL sub-system, and I can tell that OpenGL sub-system from the rest of the code, then I don't need to look into it. On the other hand, if I can't recognize the code, I automatically consider it error prone due to its non-obvious nature. I just have to look into it, to make sure it works. -- SnakE
Feb 08 2008
parent reply Alexander Panek <alexander.panek brainsware.org> writes:
Sergey Gromov wrote:
 If there is a bug, and I know it's /not/ in the OpenGL sub-system, and I 
 can tell that OpenGL sub-system from the rest of the code, then I don't 
 need to look into it.  On the other hand, if I can't recognize the code, 
 I automatically consider it error prone due to its non-obvious nature.  
 I just have to look into it, to make sure it works.
 

Uhm.. you consider code error-prone because you can't parse it in your head? Wow. Then there's lots of error-prone code out there in other languages I don't know! They're all bad and error-prone languages!
Feb 08 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Alexander Panek <alexander.panek brainsware.org> wrote:
 Sergey Gromov wrote:
 If there is a bug, and I know it's /not/ in the OpenGL sub-system, and I 
 can tell that OpenGL sub-system from the rest of the code, then I don't 
 need to look into it.  On the other hand, if I can't recognize the code, 
 I automatically consider it error prone due to its non-obvious nature.  
 I just have to look into it, to make sure it works.

Uhm.. you consider code error-prone because you can't parse it in your head? Wow. Then there's lots of error-prone code out there in other languages I don't know! They're all bad and error-prone languages!

Don't you see the difference between "it is" and "I consider" ? If I'm searching for a bug, and I don't understand some code, I *must* check it. -- SnakE
Feb 08 2008
parent Alexander Panek <alexander.panek brainsware.org> writes:
Sergey Gromov wrote:
 Alexander Panek <alexander.panek brainsware.org> wrote:
 Sergey Gromov wrote:
 If there is a bug, and I know it's /not/ in the OpenGL sub-system, and I 
 can tell that OpenGL sub-system from the rest of the code, then I don't 
 need to look into it.  On the other hand, if I can't recognize the code, 
 I automatically consider it error prone due to its non-obvious nature.  
 I just have to look into it, to make sure it works.

head? Wow. Then there's lots of error-prone code out there in other languages I don't know! They're all bad and error-prone languages!

Don't you see the difference between "it is" and "I consider" ? If I'm searching for a bug, and I don't understand some code, I *must* check it.

Are there bugs in there?
Feb 08 2008
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Tom S Wrote:
 Well then, the whole C++ committee is following bad practice as well, by 
 making << and >> work with streams.

Right, a committee too can take bad choices, that operator usage is very unnatural, and it will always be for a C-based language. Operator overloading is useful, but like with all the situations where you have more power, you need more control too (this will become very clear when D will have macros. They will require a very strong self-discipline from the programmer, otherwise they will lead to big problems, mostly at the level of *language community*, and not at the level of single program. I have explained this in my 4th post of notes). So you have to use them avoiding to change their original semantics too much. Otherwise code becomes a jungle that a different programmer can't read well. As far as I know Java outlaws operator overloading essentially to avoid that class of problems. Java success comes from it being good for the *community* of Java programmers, and not just for the single programmer. Making the language simple and regular allows everyone to understand code written by others, and modify it, share it, etc. It also allows firms to take young programmers and use them to manage legacy Java code, etc, it allows to *lot* of less good programmers to use the language, like most of the people that today are using Processing, a graphics processing language that is essentially Java with few libs and some added sugar. You can also read this section, it says right things: http://en.wikipedia.org/wiki/Operator_overloading#Criticisms Other languages don't outlaw it, like Python (despite giving less possibilities of op overload to help keep things more tidy). But you have to remember that generally even if something isn't outlawed it doesn't mean it's better for everyone to use it all the time. You don't have to use op overload *too much*. And you need some programming experience to know what "too much" means in a specific context. In this context program readability is more important that reducing the code to 2 lines instead of 4 without too much op overload. Note that DSL (Domain Specific Language) isn't something mostly for scripting languages, they come from Lisp (and Forth too, probably) that can be compiled into a normal executable. D with macros will be fit for that too. Bye, bearophile
Feb 08 2008
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
bearophile wrote:
 Tom S Wrote:
 Well then, the whole C++ committee is following bad practice as well, by 
 making << and >> work with streams.

Right, a committee too can take bad choices, that operator usage is very unnatural, and it will always be for a C-based language.

But perhaps there was no way to make it look better?
 Operator overloading is useful, but like with all the situations where you
have more power, you need more control too (this will become very clear when D
will have macros. They will require a very strong self-discipline from the
programmer, otherwise they will lead to big problems, mostly at the level of
*language community*, and not at the level of single program. I have explained
this in my 4th post of notes).So you have to use them avoiding to change their
original semantics too much. Otherwise code becomes a jungle that a different
programmer can't read well.

You've also stated that the programmer doesn't have to understand what's going on inside a standard lib (as long as it reads well and is consistent across its span). The code of mine which spawned this discussion is to be used like a standard lib for interfacing with OpenGL. Same situation. And it doesn't abuse operator overloading 'too much'. It's just one specific construct.
 As far as I know Java outlaws operator overloading essentially to avoid that
class of problems. Java success comes from it being good for the *community* of
Java programmers, and not just for the single programmer. Making the language
simple and regular allows everyone to understand code written by others, and
modify it, share it, etc.

Disclaimer: I don't like Java. // It also is a total PITA to write.
 It also allows firms to take young programmers and use them to manage legacy
Java code, etc,

// I'm grateful for that. Otherwise thedailywtf.com would lose half of its sources.
 it allows to *lot* of less good programmers to use the language, like most of
the people that today are using Processing, a graphics processing language that
is essentially Java with few libs and some added sugar.

If Java was so great, why did Processing need the extra sugar? Similarly, I don't want to use something different from D to write my code because just I feel like having more sugar. D can provide it as well.
 You can also read this section, it says right things:
 http://en.wikipedia.org/wiki/Operator_overloading#Criticisms

It also highlights that there are two sides in the debate. And it doesn't seem like the discussion ever ends, so I'd rather leave this thread as is and not let it turn into a complete flame war ;)
 Note that DSL (Domain Specific Language) isn't something mostly for scripting
languages, they come from Lisp (and Forth too, probably) that can be compiled
into a normal executable. D with macros will be fit for that too.

That was also my point -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Feb 08 2008
parent bearophile <bearophileHUGS lycos.com> writes:
Tomasz Stachowiak:
You've also stated that the programmer doesn't have to understand what's going
on inside a standard lib (as long as it reads well and is consistent across its
span).<

I think all I have said was "I agree" :-) So I can explain a bit better. I like to understand what's inside the std lib, because I think that if you want to use a system well, you have to know something about the layer just below the one you are using (C if you use Python, assembly/CPU if you use C, the GC and the std Lib and the assembly/CPU if you use D, etc). I have found problems in using D (to built some collection data structures) because I have yet to understand how the heck the Phobos GC actually behaves. Some kinds of languages (and their communities) like Java think that having opaque objects is better. Other languages like Python think that's not always a good thing, and the usual coding style is different. I think both views of the situation have their merits and disadvantages, I like both styles, and I think they are fit for the languages they are used in, and the typical situations they are used in. If you want I can offer more details. Bye, bearophile
Feb 08 2008
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Sergey Gromov wrote:
 I wonder why .sizeof is implemented as a property while typeof() and
 typeid() are functions.  I can see no reasons for such inconsistency.
 It's not that obvious for typeof() because it yields a type instead
 of a value, but even then, why not ?

Because expression.identifier always yields an expression, whereas typeof() always yields a type. It makes parsing easier and more consistent.
Feb 06 2008
next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Walter Bright wrote:
 Sergey Gromov wrote:
 I wonder why .sizeof is implemented as a property while typeof() and
 typeid() are functions.  I can see no reasons for such inconsistency.
 It's not that obvious for typeof() because it yields a type instead
 of a value, but even then, why not ?

Because expression.identifier always yields an expression, whereas typeof() always yields a type. It makes parsing easier and more consistent.

typeid yeilds an expression...
Feb 06 2008
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Robert Fraser wrote:
 Walter Bright wrote:
 Sergey Gromov wrote:
 I wonder why .sizeof is implemented as a property while typeof() and
 typeid() are functions.  I can see no reasons for such inconsistency.
 It's not that obvious for typeof() because it yields a type instead
 of a value, but even then, why not ?

Because expression.identifier always yields an expression, whereas typeof() always yields a type. It makes parsing easier and more consistent.

typeid yeilds an expression...

The subject says typeid, the post says typeof ! typeid(type) looks for a type between the parentheses, and a type has a different grammar than an expression.
Feb 06 2008
parent reply Christopher Wright <dhasenan gmail.com> writes:
Walter Bright wrote:
 Robert Fraser wrote:
 typeid yeilds an expression...

The subject says typeid, the post says typeof ! typeid(type) looks for a type between the parentheses, and a type has a different grammar than an expression.

real.nan?
Feb 07 2008
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Christopher Wright wrote:
 Walter Bright wrote:
 Robert Fraser wrote:
 typeid yeilds an expression...

The subject says typeid, the post says typeof ! typeid(type) looks for a type between the parentheses, and a type has a different grammar than an expression.

real.nan?

Yields an expression, not a type.
Feb 07 2008
parent Christopher Wright <dhasenan gmail.com> writes:
Walter Bright wrote:
 Christopher Wright wrote:
 Walter Bright wrote:
 Robert Fraser wrote:
 typeid yeilds an expression...

The subject says typeid, the post says typeof ! typeid(type) looks for a type between the parentheses, and a type has a different grammar than an expression.

real.nan?

Yields an expression, not a type.

typeid yields an expression, not a type.
Feb 08 2008
prev sibling parent Moritz Warning <moritzwarning _nospam_web.de> writes:
On Wed, 06 Feb 2008 18:51:49 -0800, Walter Bright wrote:

 Sergey Gromov wrote:
 I wonder why .sizeof is implemented as a property while typeof() and
 typeid() are functions.  I can see no reasons for such inconsistency.
 It's not that obvious for typeof() because it yields a type instead of
 a value, but even then, why not ?

Because expression.identifier always yields an expression, whereas typeof() always yields a type. It makes parsing easier and more consistent.

From a users perspective, my first thought is always that it should be used similar to a type alias in a struct/class. .typeof feels also more consistent with .length, .sizeof or .stringof. typeof() looks like a build-in compile time function, but the feeling to access the AST is definitely nicer. Thought, I don't know if typeof() is worth the gains on the parsing side.
Feb 06 2008
prev sibling parent "Anders Bergh" <anders1 gmail.com> writes:
On Feb 8, 2008 3:20 AM, Sergey Gromov <snake.scaly gmail.com> wrote:
 What can I say.  I do not agree.  C++ committee is not the best
 exemplar.  Looking into implementation should be required to learn the
 details, not to understand what the hell is going on.  Creating the DSLs
 should be a privilege of scripting languages, that's what they are for,
 after all.

How is this different from other code? You have to look in any implementation code to figure out what's going on internally, be it with syntax sugar or not. Anders
Feb 07 2008