With a bit of fiddeling you can use every kind of bracket to basically make function calls in c++

Here are the links to the snippets, all compile and run

Rust: https://godbolt.org/z/bM3d7bG14

OCaml: https://godbolt.org/z/17oMv83zx

C++: https://godbolt.org/z/9Y3WfoE1W

all 42 comments

sorted by: hot top controversial new old
[–] 48 points 1 week ago (16 children)

cpp and their operator overloads are also insane. It makes understanding cpp code impossible. A "+" could actually do something completely different or have insane side-effects. Truly superior language for spreading confusion.

  • source
  • hideshow 16 child comments
  • [–] 29 points 1 week ago (7 children)

    Operator overloads is something that sounds like a good idea until you experience them firsthand. Just properly name your functions for fuck’s sake.

  • source
  • parent
  • hideshow 7 child comments
  • [–] 14 points 1 week ago

    Operator overloading is awesome in a functional language. Haskell allows for a lot of creative stuff with operators, but since they can't have side effects, must conform to predictable types, and have specific requirements they are somewhat understandable. Idris is also very ergonomic when it comes to operators.

    C++ allowing a library to override the + operator with system("rm -rf /") is a lot less awesome.

  • source
  • parent
  • [–] 8 points 1 week ago

    Every time I use a language that doesn’t have operator overloading I wish I was using C++. It’s absolutely maddening to have to read and write things like “end.subtract(start)”.

  • source
  • parent
  • [–] 7 points 1 week ago (1 child)

    As a computational physicist, I appreciate operator overloading IF used properly.
    Example of a good use: + for matrix addition
    Example of a bad use: left shift operator << as a pipe
    I still don't understand who's in the C++ committee that they would choose this garbage over a function

  • source
  • parent
  • hideshow 1 child comment
  • [–] 3 points 1 week ago*

    My theory is that they came up with the concept of operator overloading (or copied it elsewhere and were exited) and decided the best place to demonstrate and sell the concept is in the most used console input and output standard functions.

    Edit: I realize my contempt for this decision is not evident here, so let me add that it was a terrible choice in their part indeed.

  • source
  • parent
  • [–] 6 points 1 week ago* (-1 children)

    Honestly, I'm glad to have them, it can make a number of things simpler. For instance, a program I wrote had a number of duration fields that had to be stored in XML files and updated every once in a while. It was something that had to occur very often in the code: add a value to the duration, set that value in the XML data, and save the XML file. So I created a class that stored the date/time value and a pointer the XML element (it could be assumed that nothing else would be changing the value in the XML file and if it did, then that change should be overwritten) and overloaded the += operator (among others), so then all I needed was to create the DurationField object, and then I could go durationFieldX += time2 - time1 for instance. I could abstract all the logic away and make it very clear and easy to write. Could I have made it so that I have to to durationFieldX.add(time2 - time1)? Of course I could have. But IMO that variant is less neat and less readable.

  • source
  • parent
  • hideshow -1 child comments
  • load more comments (-1 replies)
  • [–] 3 points 1 week ago*

    Like all of the footguns in C++, it's only a problem if the codebase uses it wrong. When used correctly (i.e. only when behaviours mimic built-in types, and without side effects), it helps makes code more readable

    Don't do what numpy does, which is to define * for two arrays. Without learning the library, you wouldn't know whether this performs element-wise multiplication, matrix multiplication, dot product or cross product. Worse yet, it behaves differently to Python's built-in * for lists (which is also bad), which concatenates N copies of the list

  • source
  • parent
  • [–] 7 points 1 week ago (4 children)

    When I was an intern, I was tasked with writing a file converter for 3D geometry files. There was an official cpp library to read the source files, so I was using that to read the data, restructure and transform it as needed, then write it to the output file format. Near the end, I was having a problem where I was SURE that my math was correct for the transform coordinates, but the resulting file would load in the viewer with all the correct looking pieces but all in the wrong locations. The senior guy there helped me debug it since I wasn't super familiar with cpp at the time, and we found that the library I was using had overloaded the multiply (*) operator specifically for the objects I was using it on, and it was actually multiplying and saving the result directly to the first variable used in the multiplication. I assume it was done for memory efficiency or something, but I had no idea it would behave that way, so I was accidentally changing the values of variables I didn't intend to.

    Example: I was doing something a = b * c, which caused the value of b to be changed (to b * c). Which screwed things up when I needed the original value of b later.

  • source
  • parent
  • hideshow 4 child comments
  • [–] 7 points 1 week ago (3 children)

    This is the type of shit that haunts me. Imagine overloading ">>" for piping and hiding threading behind that. The idea was to create an async pipe, but nowhere are you aware of async or threading or whatever was chosen. You look at the code and think "of it's like piping to stdout" or whatever, only to find out that the method immediately returns.

    Tracking down what the hell is happening with code that has such hidden side effects is a nightmare.

    Are you still in the C++ world?

  • source
  • parent
  • hideshow 3 child comments
  • [–] 4 points 1 week ago (2 children)

    That is WILD lol. No, after that, I did a bunch of backend server apps for a few years mostly in C#, and then I got put onto some web app stuff after that. For better or worse. I do enjoy it and appreciate the abstraction, and I have found that I do love frontend dev a lot, but I do sometimes miss the lower level languages haha.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 3 points 1 week ago* (last edited 1 week ago) (1 child)

    I talked to a frontender recently who said they had less pleasure writing frontend, because AI could make it look as good as they wanted in a fraction of the time. Has AI changed anything for you?

    I was "encouraged" to use AI at work for frontend and while it output functional stuff, lifting the hood on the how, terrified me. 😅

  • source
  • parent
  • hideshow 1 child comment
  • [–] 3 points 1 week ago

    Yeah, in my experience, it's very hit or miss with frontend code architecture (I primarily work with React). And I am very particular about keeping code clean and maintainable, so that can be a challenge sometimes for sure. It's not bad for smaller one-off tasks, but I still do a majority of my larger tasks by hand because I typically already know what I need and how to do it correctly.

  • source
  • parent
  • [–] 23 points 1 week ago* (2 children)

    Funny that you put rust as the "uses parenthesis for function calls". When in rust you can use any bracket for macro invocations:

    let v1 = vec!(1,2,3);
    let v2 = vec![1,2,3];
    let v3 = vec!{1,2,3};
    

    These are valid and have the exact same meaning.

  • source
  • hideshow 2 child comments
  • [–] 3 points 1 week ago (1 child)

    That's always funny to me. In a language that's so particular about different syntax features, they let macros of all things have a little bit of arbitrariness.

  • source
  • parent
  • hideshow 1 child comment
  • [–] 1 point 1 week ago

    Yeah, I always wonder, if it was an intentional decision or just some first draft that stayed in.

    Because I do think, it's kind of smart. Some macros make sense to call with either () or {}, depending on if you pass a code snippet that's multi-line or not.
    So, you could come up with a complicated syntax to define which bracket types are acceptable, or you could just not bother. 🙃

  • source
  • parent
  • [–] 18 points 1 week ago (3 children)

    I have honestly never seen parentheses called "round brackets" before. It totally makes sense, I have no idea why it's not used more often.

  • source
  • hideshow 3 child comments
  • [–] 16 points 1 week ago (1 child)

    Ehh, who needs functions anyways, you got one big one and thats your whole codebase.

  • source
  • hideshow 1 child comment
  • [–] 10 points 1 week ago (2 children)

    Good meme, but I'm really not sure why you wrapped everything in asserts which kind of ruins the aesthetics. IMO would have worked better as e.g.:

    x = sum(1, 2, 3); // x = 6
    
  • source
  • hideshow 2 child comments
  • [–] 8 points 1 week ago (3 children)

    I haven't kept up to date with C++ development in the last 16 years, I only recognize the first two of those four.

  • source
  • hideshow 3 child comments
  • [–] [S] 7 points 1 week ago (1 child)

    You can overload the indexing operazor "[]" (std::vector does this for example), and since c++23 this operator can have more than one argument.

    The last one is a constructor call with an overloaded conversion operator. The {} syntax is possible since c++11 I think. The conversion operator was already available before that

  • source
  • parent
  • hideshow 1 child comment
  • [–] 4 points 1 week ago

    Weird opinion: I like square brackets, angle brackets are neat, curly braces range from neat to ok.

    But I just don't like the look of parentheses compared to the others. They especially look ugly and clunky when you need a bunch of them in a row, in a way that's not true for the others.

    I can't think of a reason why I feel this way apart from the fact they tend to be very clunky in math too. They're also the ugliest one when handwritten despite being the arguably simplest shape.

    All that said it annoys me how parentheses are the most used bracket type in programming.

  • source
  • [–] 4 points 1 week ago

    No time for arguments, pipelines go brrrr

  • source
  • [–] 3 points 1 week ago

    You can do most if not all of this in Perl if you're twisted enough. Some hoop jumping may be required*, but I can think of ways to do something that looks like each of these.

    *: The braces are especially tricky if warnings are turned on. I'd probably abuse the deprecated multidimensional syntax and tie a hash to the actual function.

  • source
  • [–] 2 points 1 week ago*
    (best-syntax? '(lisp clojure))
    ;; => true
    
  • source
  • [–] 2 points 1 week ago (3 children)

    I asked the other day in another thread about hating on C++ what makes C++ so bad and never got an answer.

  • source
  • hideshow 3 child comments
  • [–] 7 points 1 week ago

    There are lots of ways to write C++ code that looks perfectly reasonable but introduces horrible undefined behaviour. You need to be aware of lots of edge cases all the time and you will still make mistakes that can introduce difficult to trace bugs. One of my personal favourites is object slicing.

    class A {
       int foo;
    };
    
    class B : public A {
       int bar;
    };
    
    B b;
    A a = b;
    

    Looks OK? Well, a now only contains the A part of the object. The field bar is lost in the assignment. There are reasons for this behaviour but its a sharp edge nonetheless.

    These kinds of problems are numerous and you have to keep them in mind while programming C++. Some people don't mind it but many do. Static analysis tools that can catch many of these errors exist, but I understand people who say they don't want to deal with that and rather use a language where these kind of errors are not possible. Personally, I would also discourage people from starting new C++ projects today if they can avoid it.

  • source
  • parent
  • [–] [S] 2 points 1 week ago

    I don't really know myself, probably the many footguns and complexities. Like taking a reference to a value in a vector and then resizing the vector, boom undefined behaviour. There a re a lot of things like this. Maybe also the verbosity and multie ways to do things. Look at the linked code, there is a lot of overhead to the function definitions, sure there is a point to all of it and I put it there for a reason, but to people less familiar to the language it is probably quite offputting.

    Personally I like the language, second only to rust for me

  • source
  • parent