The hidden cost of C++

We must be talking across purposes. All I have been claiming is that A x B is the standard notation for vector cross product - which you seem to have agreed with.

I also claimed that A x B is usually “a * b” in programming languages and therefore “a * b” would be an obvious choice for overloading vector cross product (esp. since you can’t overload the ‘x’ character)

I also claimed that the ‘*’ multiplication operator when overloaded often inherits it’s programming language level precedence.

I also claimed that programming level precedence doesn’t always map correctly to various mathematical domains thereby creating a problem representing maths in code using operator overloading.

I don’t know why you’ve kept going on about inner / outer products, scalar/Vector multiplication or Vector multiplication OF ANY KIND. I’m not discussing any of those cases, I’m just discussing “A x B” with vectors, the cross product of A and B.

If you want to disagree with me, can you disagree with one of the points I actually made rather than making up straw men of your own?

regarding Mathematica: I asked you for a mathematical reference showing that A x B has a different precedence in the context of Vector maths than A + B, not a programming reference. It was a simple enough request I believe. All of your verbiage related to Mathematica is simply restating your intuitions - the very ones I asked for a reference for in the first place.

This is the reason I said in a previous thread about Java that I’d have preferred that the language didn’t have the primitive / type class split. It seems unnecessary given a smart enough compiler.

After more than a decade of work on the JIT, the (hotspot) compiler still isn’t smart enough to remove the overhead of objects. Every time the hotspot engineers promise optimisations in this regard, it’s like ‘Java2D all over again’: wildly varying performance, depending on a lot of unobvious factors. In realtime gaming (this is JGO after all) this is unacceptable.

WRT: No primitive types. I love smalltalk, but java having prims was the good choice IHMO. The problem that then the best option for promoting object wrappers of prims was tagged unions. Slows down performance and is an extra headache for the VM. The other option of boxing combined with AOT sugar of treating prims as objects is likewise a big pain (this is actually what I expect that they mean by “no more prims” in JDK10). However having said that, it seems like V8 does a pretty good job and it’s based on the strongtalk low-level…so I might be full of poop.

No question, here we’re in agreement.

Here’s where we start to disgree. I claim that in algebras the unique product ‘ab’ is represented in C-like programming languages as 'ab’ and that the cross product does not well agree with a unique product nor with any standard notion of properties one might expect from a product-like structure. (NOTE that a unique product does not indicate that other “products” do not exist). Of the various vector products the best one (in terms of structure/properties) is the Hadamard (component-wise) product which has little geometric meaning and is more useful if you’re treating vectors and tuples as one and the same (a la shaders and various SIMD ops). Now I’m sure that most people think that I’m a nut case, engaging in pure mathematical wankery or possibly both, however I don’t not consider this to be the case. In terms of operator overloading, defining the cross product as "" is pretty much an abitrary choice. Why not the dot or Hadamard products? These would be more logical as they are somewhat in agreement with multiplication by a scalar. The real problem with using “" as the cross product is that it leads to ambigous and therefore hard to read expressions, which is exactly contrary to the point of operator overloading in the first place. a(b×c) becomes: a*b*c = …I’ll pass. By naming convention the previous could be slightly cleaned-up, but simply not enough to interest me. I don’t see any issue with this. We use pow,floor,sqrt,etc mixed with operators for floating point and doing likewise over non-primitive types is more than reasonable. As such I use cross(a,b) and dot(a,b) respectively…problem solved as far as I’m concerned. None of this is intended to imply that anyone shouldn’t use "” as the cross product if that works for them (and potentially any “users”), because again, the point to get more correctly done in less time.

My “liking” of operator overloading is not a desire to have my code look like a LaTeX document. There exist languages in which this is possible. Operator overloading allows my high level language to NOT look assembly over a non-primitive types, therefore drastically increasing the read/write/maintainablity of my code…oh yeah, and I get things done faster.

This is all related to the choice of “*” as an operator for the cross product. It’s an arbitrary choice and not a logical one from a mathematical notation perspective. Addionally meanful computations require mixing of cross, dot and scalar products, so any choice of operators need to be readable…otherwise we’re simply using a language feature because it’s there and that’s naughty.

But really, talking about vectors in a discussion about operator overloading (when extended operators are not available) is a red herring as it’s an odd duck.

I think that fixed priority is a good choice for general purpose languages. Can you give any examples of fields which don’t agree with the standard order of operation? I seriously cannot think of any.

I’m seriously attempting to address your points (in my brain dump kind-a way). Am I missing any?

Yes indeed it’s a simple enough request. The thing is that I’m lazy and didn’t feel like doing a web-search for something that I’m certain to be correct about. Since you explicitly mentioned Wolfram in a previous post I made the assumption that you’d accept an output of Mathematica as a correct statement. I didn’t occur to me until later that vector identities implicitly contain the correct order of operation.

Has anyone seen any interesting testing about how well the backend is at scalar replacement? (This is on about page 20 for my “when I have spare time” list).

Aaahh! Ok, thanks for the clarification - I get where we diverge now - mainly around the use of the ‘*’ character. I guess the larger issue here is that we don’t have a number of characters available to use for overloading which means that we’re always compromising somewhat. It’s this element of compromise which always disappoints me with operator overloading.

Indeed. More operators makes overloading much more generally useful. And in the context of Java (and JVM based language) which already support UNICODE it would be perfectly reasonable to support the wealth of UNICODE defined operators. This brings up a tooling issue which, again, in my opinion is a minor issue. As mentioned previously, I think that overloaded operators should be rendered differently than their built-in equivalent as then it’s immediately obvious that it’s overloaded. Likewise an IDE could have a default ‘font’ for operators which it could use if the current font doesn’t contain the character in question. That leaves the outstanding issue of input which I’ll defer to UI specialists :slight_smile:

But extended operators aside, just the default set of operators would cover the major of peoples needs. Examples:

  • R representations all work as well as built-in floating point (multiprecision flavors, double-double & double-quad, non-standard fixed width floats, IEEE: (binary16, binary128, decimal32, decimal64, decimal128), rational (Q), fixed-point
  • Z variants: same thing.
  • Ranges/Intervals over an ordered type: error bound analysis, range analysis
  • Dual Numbers over an ordered type: automatic differentiation
  • C over Reals: Yeah, you have inner & outer products, conjugate and some other operators…but again, not everything has be an overloaded operator (before anyone asks: 2D geom/physics, electrical engineering, physics…including light modeling.

These barely scratch the surface…and beyond that is the “biggy”: linear algebra (over many types). Again LA has a ton of operators, but the basics cover a great deal of territory. Practical LA need very many implementations of the same things for different specialized use-cases. And yeah, I’ve seen many bloody awful LA libraries which use overloaded operators. That’s not a problem. The issue is the ability to create a reasonably well written library which isn’t awful.

@Roquen

I was confused over who you were addressing. There were multiple disconnected conversations going on. I thought you were addressing one of my posts about retrofitting Objects to behave like numerical types. (I said something I thought that you thought I meant using C++ as a model for Java…) How much of this post did you see and to what extent were you addressing that post vs the other people? I’ll respond to parts of your response to try to make some sense of this.

You wrote “Most of the stuff about operator overloading must do this and that under the hood is compete bunk.” In general, you absolutely should care what happens under the hood. Operator overloading included. I think you absolutely agree that language features ought to have smart implementations. Without that, the entire language suffers in terms of utility more so than if the feature did not exist at all. I’m against adding (arithmetic) operator overloading without making other updates to the language first (structs/improved generics), but only because no one put forth a proposal that does not involve plain Objects.

[quote]Sure, as long as performance and spending twice the required memory is of no concern.
[/quote]
Right. The same can be said for operator overloading. If speed and memory are concerns (and consistency with primitive types, simplicity, and predictability, too) then like it or not a good implementation of operator overloading in Java would probably look more like C++ under the hood than a Java Object. Not because someone used C++ as a model, but simply because C++ coincidentally implements operator overloading on by-value types (if only because all C++ types behave that way). There are merits to that method over more complicated methods, even if C++ did it first.

[quote]Personally I could care less if Java ever gets operator overloading, but I’m able to look beyond my own bellybutton to the needs of other programmers. I can implement operators exactly as I would like them to work.
[/quote]
I disagree. Under the hypothetical situation that one person here had a magic wand to make a change to the language, I would be worried if Java got a bad implementation of operator overloading. Most people can’t see for themselves that a change would have a snowball effect to the rest of the language. A struct-like type is probably the only practical way that would be most universally useful. I disagree with sentiments like “Just use annotations!” or “Just put add, subtract, multiply, divide in an interface!” or “Well I would make a really really really really smart compiler.” That’s the same crime, but has worse consequences than requiring programmers work within an existing framework until the design can be worked out.

As for the rest of your post, I’m not sure what you’re arguing. Are you saying you would use a struct-like data type? A contract system? JIT Compiler magic? Syntax sugar like auto-boxing? Or what? (BTW, where did the JDK 10 thing come from? Is it a rumor or a roadmap I don’t know about?)

First off:

  1. If you think that operations over non-primitive types looking like macro-assembly is not a problem…stop reading, you’re wasting your time.
  2. I strongly suspect that most people whom cry: “OMG! The calling overhead! OMG! The object creation overhead!!” were to read some other post on a topic which included optimizations which yields greater cycle reductions then these introduce would cry: “OMG! Premature optimization!” If you feel you might fit in this category…stop reading, you’re wasting your time.

Indeed. On the whole I’m only talking about operator overloading in an imperative language. I see no strong reason to retrofit anything.

Saw all of it…but, forget C++…like the creators of Java did. There’s nothing to learn about high-level language design other than counter-examples. (And again: C++ is a very useful language. It’s feature set is more than reasonable…it’s problems are design related, or rather the lack thereof. Oh and structural. Oh and I hate multiple inheritance of state) Are there any specific issues you’d like me to comment on from that post?

Agreed. That wasn’t my point. Operator overload doesn’t not require naive direct translation of the expression tree into a method sequence. Also since the exact sequence is not mandated by the programmer (unlike method calls) the compiler is given more flexibility in reordering. Nor does it require one-to-one translation of operator to method. Nor is where data is stored in the sub-expression mandated, yet again giving the compiler more wiggle room. If you allow for rewrite rules (which isn’t operator specific) then more advanced transformations are allowed, likewise for contracts, etc. etc. Someone asked a question like: how many object does this long expression require? In every DSL I’ve thrown together, the answer (assuming type is backed by an object) would have been: either zero or one…it depends on the call-site. In general you can run a trivial live variable analysis pass which (the vast majority of the time) will tell it the exact number of temporary data chunks required. This is just one example of something the programmer must currently manually perform that and will often get “wrong” (as in non-minimal) and the compiler can easily (most of the time) get it exactly right. But we could babble forever about compiler techniques and bore everyone to tears. Also I don’t really feel like it. All of this ties back to my comment about assembly programmers. Really you want to get things done as quickly as possible and hopefully your chosen language is helping you with that. This free up time spent better somewhere else. If anyone really want to micro-manage their codebase, then please…write in C. It’s a nice clean language designed for that kind of thing.

Again I don’t care about overloaded operators in Java. I can solve that problem myself. Conversely structs is a huge deal to me…esp combined with concrete arrays of structs. This is a problem I cannot solve for myself. BTW: Structs were mentioned recently on the dev mailing list. There seems to be no plan other than “gosh, we should do this.”. But there’s no real problem with objects if that doesn’t happen. The only real gotcha exists for both structs & object: aliasing.

Forget everything about C++. Think functional which generates imperative.

I disagree. Under the hypothetical situation that one person here had a magic wand to make a change to the language, I would be worried if Java got a bad implementation of operator overloading. Most people can’t see for themselves that a change would have a snowball effect to the rest of the language.
[/quote]
Having written many DSLs I’m well aware how insanely difficult it is to design languages. So we’re in agreement here. Good design is uber important. In the context of Java there’s no concern…all features are painfully over-thought. The up side is it’s a nice clean language. But really there’s little concern here (other than potentially adding more operators, which IHMO would be a good thing). No syntax pollution…and the “real-estate” (if you will) remains the same.

I disagree. There’s no real additional problem with objects. Also note that struct only tosses out quite a bit of things, notably many LA formulations. Sure VM aware structs/value-types are slightly easier, but not really by much. Give me structs/value-types/tuples and support-em all! Interfaces is in IHMO a very silly idea. “really xN time smart compiler” isn’t needed…the analysis/transforms are easy. Annotations are the way to go. Meta-data is awesome. Look at the LLVM mailing-list archive and you’ll see tons of discussion about meta-data, because it’s awesome. One of the biggest problems is providing compilers with too little information. I’m sure that annotations in Java seem like a PITA and/or bordering on useless to most java programmers but because of how the’re used. The java “system” doesn’t really use annotations in any meaningful way. And that’s too bad. Oh yeah, and contracts are awesome…because they’re meta-data…which is awesome…which provides more info to the system…which is double awesome!

I’m not arguing for anything specific. I’m arguing that operator overloading is much more than minor sugar. Without operators over non-prim types you’re stuck programming in a macro assembler which blows chunks. I’m also attempting to point out that what most people think-of as operator overloading is far from the only implementation possible.

This presentation. Which is basically: Hey, this is some stuff that we’re thinking about…well at least for the future stuff.

What are Operator Overloads even used for? ???

They are critically important so that everyone can use their own randomly chosen set of ascii symbols to write their own mathematical vector library. Some intrepid programmers also like to overload the new and delete operators to make up for C++ shortcomings in the garbage collection department.

Cas :slight_smile:

Indeed. The wealth of Java mathematics libraries speaks for itself (I’ll leave off qualifiers like full-featured, useful, high-performance and over non-primitive types off…no reason to be TOO demanding).

I always overload new/delete and it has nothing to do with GC…I promise!

Why is that helpful? ???

How did you manage to turn C++ into dinosaurs? (Not that they’re not cool ;D)

Tell here what are the worst things about C and C++ (In your opinion ;D)
I’m trying to tell everyone that C++ is BAD!!!
EDIT: I wasn’t thinking to clearly. I just want your opinions. ;D Sorry :-X

It comes after the A and B. Nuff said.

Merged ::slight_smile:

But its not, you can still do great stuff with it. Its the developers that abuse it who suck.

Like HotSpot! :wink: I guess @masteryoom better steer clear of Java too. :yawn:

The language that a VM is written in has no really bearing on language(s) which run on it.

Talking about what’s “bad” about C & C++ is like talking about what’s bad about Java and Objective-C (or Self, strongtalk, smalltalk, forth)

If you’re asking about new/delete…then the compiler provided manager is a single heap (thread-safe if multi-threaded app). On the whole that doesn’t match allocations in the real world. But it’s fine if you don’t care about performance.

In C++, this is not valid:

vector<vector<vector<double>>> myVec;

This is valid ???:

vector<vector<vector<double> > > myVec;