News for hackers. Stuff that matters.
Re:PyTorch 1.0 is out by usgroup on Friday December 07, 2018 @05:03PM (#18632114)
i picked up c++ for some gpu stuff with the arrayfire api... felt the same. firstly, modern c++ takes no time to learn if you come from java / c/ c# / etc. secondly, things like operator overloading and type inference make for pretty seamless apis. E.g. want to add matrices? auto C = A + B.

A lot of things suck (closures, generator functions, first order functions all suck in c++), but oh my does it all run fast when you get it working; plus wrapping it with Rcpp or Lua is easy as pie.

Re:PyTorch 1.0 is out by umvi on Friday December 07, 2018 @05:25PM (#18632253)
I'm not sure how I feel about operator overloading. It starts out simple enough, but can lead to extremely confusing code.

Take this snippet of an API call[1] that parses ISO strings to chrono::time_point using date[2]:

    std::istringstream in(iso_string);
    in >> date::parse("%FT%TZ", tp);
At first glace my brain cannot comprehend the second statement. Why is there an input stream going into a function? Is that even valid C++? Why not just pass `in` as a function parameter and return time_point as the return value?? When you actually dig into the source, it's a namespace overloaded operator and it's extremely heavily templated to be generic. So now if I think of `>>` as simply a second function call using the result of `date::parse` it makes sense, but... I still don't understand all of the technical reasons behind that decision. I assume they're valid reasons though since Howard Hinnant is the c++ datetime expert.

[1] https://stackoverflow.com/a/33438989/2516916

[2] https://github.com/HowardHinnant/date

Re:PyTorch 1.0 is out by nwallin on Friday December 07, 2018 @07:13PM (#18632857)
> Why is there an input stream going into a function?

The function is constructing a temporary object and reading into that object. The object includes a reference to a named tp object, and the temporary parser object is parsing from the input stream, which writes the data into the tp object.

> but... I still don't understand all of the technical reasons behind that decision.

Because he wants to support input from an istream, and inputting from a istream necessarily means overloading '>>'. That's just how things are done in C++; if you want to support reading from or writing to an istream/ostream, you overload the '>>' and '<<' operators.

It's a trade off; he could have designed it so that the constructor of tp simply accepts the format string and the istream as parameters. But that has the downside of not looking like idiomatic istream code.

I personally think that the way iostreams are implemented in C++ was a mistake. (because I don't like the way idiomatic istream looks, and I think friend functions are generally smelly.) Unfortunately, it's something like 35 years too late to correct it. (I'm aware that C++ is only 33 years old; iostream.h and cout << "blah" << endl; and cin >> foo; preexist C++) But here's the thing: it's badly designed iostreams that make the linked code confusing, not operator overloading.

Re:PyTorch 1.0 is out by pjmlp on Saturday December 08, 2018 @05:57AM (#18634739)
Maybe because my background coming into C++ was Turbo Pascal, and I already knew OOP from 5.5 and 6.0, including a nice experience with Turbo Vision and its stream framework, introduced with Turbo Pascal 6.0.

I never grasped the hate iostreams get, as they are type safe and composable in ways that FILE will never be.

Sure they might be a couple of ms slower than stdio calls, but unless I would be writing a HPC trading application communicating over stdio, I hardly see the relevance.

And for the operators, oh well, as long as they are consistent.

Then again, it might just be my biased background as I got introduced to them.

Re:PyTorch 1.0 is out by Fede_V on Saturday December 08, 2018 @12:29AM (#18634073)
Thanks for explaining that design logic a lot more clearly. I figured out what the code did, but understanding the why was very helpful.
Re:PyTorch 1.0 is out by irishcoffee on Friday December 07, 2018 @07:58PM (#18633117)
I recently encountered code (at work no less) that overloaded the == operator.

a.) It was not a const overload. b.) Inside said overload, it modified FOUR member variables. c.) The 'new' keyword was used twice inside said == overload. d.) I learned when gdb fails, to grep the codebase for the 'operator' keyword.

I am not a fan of operator overloading. If the SW enginner in question had instead written a equals(<type> rhs) function, I'd have saved myself a lot of headache.

Re:PyTorch 1.0 is out by logicchains on Friday December 07, 2018 @08:16PM (#18633194)
Sounds like operator overloading isn't the real problem here. An function equals(T rhs) -> bool that calls new and modifies member variables still sounds pretty terrible; changing "==" to "equals" doesn't fix the problem.
Re:PyTorch 1.0 is out by sgrove on Saturday December 08, 2018 @02:09AM (#18634258)
The difference is in the time it takes to track down the aberrant behavior, and the learning opportunities available.

In the named case, it's obvious the other programmer may be doing something nefarious.

In the operator case, you learn much more, like how to grep, really work gdb, etc.

Re:PyTorch 1.0 is out by emmelaich on Friday December 07, 2018 @09:53PM (#18633590)
But you're familiar with cin/cout right?

Same thing. Weird at first every C++ programmer should be familiar with it now.

I pronounce << and >> as 'goes to' and 'comes from' or something similar.

Re:PyTorch 1.0 is out by umvi on Friday December 07, 2018 @11:06PM (#18633858)
Of course. But what I'm not used to is seeing something like this:

   cin >> foo(x);
Re:PyTorch 1.0 is out by cercatrova on Monday December 10, 2018 @07:25AM (#18647359)
This is common in many functional languages, and even in the shell. Think of pipes such as input | sed ... | grep ..., or in F#, xs |> List.map (fun x -> x.Value). Basically, each input goes into the function and is piped through to get to the output.
Re:PyTorch 1.0 is out by shaklee3 on Friday December 07, 2018 @07:54PM (#18633099)
Why do closures suck? What are they missing?
Re:PyTorch 1.0 is out by grandmczeb on Friday December 07, 2018 @10:33PM (#18633749)
I’m confused about that too - closures are one of the nicer parts of C++ imo.
Re:PyTorch 1.0 is out by usgroup on Saturday December 08, 2018 @04:16AM (#18634552)
I like to pass closures as return values or as function parameters. In my experience this is folly in c++.
Re:PyTorch 1.0 is out by grandmczeb on Saturday December 08, 2018 @11:06AM (#18635841)
Here's an example of doing both:

  $ cat test.cpp
  #include <iostream>
  #include <string>

  template <typename F>
  auto pass_func(F func) {
    return func();
  }

  auto return_func() {
    std::string test = "Hello World!";
    return [=](){ return test; };
  }

  int main() {
    auto func = return_func();
    std::cout << pass_func(func) << std::endl;
  }

  $ clang test.cpp -lstdc++ -std=c++14 -o test
  $ ./test
  "Hello World!"
What's hard about it?
Re:PyTorch 1.0 is out by black-tea on Sunday December 09, 2018 @03:47AM (#18640003)
You didn't pass a function to std::cout, you called it and passed its return value.
Re:PyTorch 1.0 is out by grandmczeb on Sunday December 09, 2018 @12:50PM (#18642161)
The way I interpret the GP, they're talking about passing closures as a function argument. In the example I pass func (a closure) to pass_func. Not sure what std::cout has to do with it?
Re:PyTorch 1.0 is out by black-tea on Sunday December 09, 2018 @03:31PM (#18643086)
Sorry, I misread the code.