Going to the Google's walled garden with Go



  • @JBert They aren’t gonna be able to sell Asure subscriptions for long. It has become embarrassingly easy these days to see Azure is complete shit! Fuck it in the ass with a cactus with all serrated thorns.



  • @Gribnit said in Going to the Google's walled garden with Go:

    @Arantor said in Going to the Google's walled garden with Go:

    Don’t discount the amount of stuff written in PHP…

    You expect it to sell at market price somehow :wtf:

    I sell it at above market price because I am better than the competition 😉


  • Considered Harmful

    @Arantor works for Chivas Regal.


  • Notification Spam Recipient

    @topspin said in Going to the Google's walled garden with Go:

    @DogsB still, you haven’t pointed out how “does absolutely retarded thing in overloaded operator” is any different from “does absolutely retarded thing in overloaded method”.

    The analogy with the alphabet not work well? If == can't be overloaded by the user then that bit of the language will always be understood by everyone regardless of user doing stupid things with method names and their contents. If you want to overload operators like that you're welcome to that insanity. I’ll have a like ready for your story about it in a couple years.

    Except that typing .equals, .less, .add gets really annoying..

    You're a typist by trade...


  • Notification Spam Recipient

    @Bulb what languages that support operator overloading could prevent a developer from throwing a range check into an overloaded ==?



  • @DogsB said in Going to the Google's walled garden with Go:

    You're taking a fundamental part of the language and understanding code and allowing them to fuck with it.

    "Those" people are going to fuck things up whether they have operator overloading or not.



  • @stillwater said in Going to the Google's walled garden with Go:

    @JBert They aren’t gonna be able to sell Asure subscriptions for long. It has become embarrassingly easy these days to see Azure is complete shit! Fuck it in the ass with a cactus with all serrated thorns.

    So, the same as everything else? Or is it extra enterprisey?



  • @Carnage Yes



  • @DogsB said in Going to the Google's walled garden with Go:

    @topspin said in Going to the Google's walled garden with Go:

    @DogsB still, you haven’t pointed out how “does absolutely retarded thing in overloaded operator” is any different from “does absolutely retarded thing in overloaded method”.

    The analogy with the alphabet not work well? If == can't be overloaded by the user then that bit of the language will always be understood by everyone regardless of user doing stupid things with method names and their contents.

    It will, however, be irrelevant that it will be understood, because it won't be even usable in the cases where there could be a problem. Instead the equals (or whatever) method will be used and will have exactly the same capacity for surprising behavior.

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb what languages that support operator overloading could prevent a developer from throwing a range check into an overloaded ==?

    Haskell¹, for example. Well, you can still bottom on it, but there is no way to make that a useful behaviour there.

    But then, does Java prevent developer from throwing a range check in the override of Object.equals()? And if not, how is that less of a problem?

    Keep in mind that no language with a userbase to speak of allows overriding operators for types that already have it. The programmer can't mess with the == for int or string or whatever built-in type. Only provide a broken one for types that wouldn't otherwise have it.


    ¹ Also, when I'm mentioning Haskell, Haskell got this right. In Haskell

    • every function with at least two arguments can be used as a binary operator (wrap the name in backticks),
    • and vice versa (ditto),
    • and you can even define new operators (identifiers composed of interpunction)
    • but you can't define related operators independently, because they are defined together in typeclasses and you can't overload an identifier, you can only define the typeclass for another type.
    • Oh, and you can derive the common typeclasses, so e.g. a structure composed of comparable items can automatically become comparable via lexical ordering without giving you opportunity to make a mistake writing it by hand.


  • @Bulb said in Going to the Google's walled garden with Go:

    no language with a userbase to speak of allows overriding operators for types that already have it

    Hm, thinking about it, the ones with overzealous implicit conversions like Perl¹ probably do. Good riddance.

    Statically typed languages (like C++, C#, Haskell, Rust) don't allow that though. There you can define operators only on types that don't otherwise have it.


    ¹ In Perl you can overload operators, but if you don't, the objects will be converted to something (string, probably) and compare that².

    ² Which in turn applies even to languages like JavaScript that don't support operator overloading, but do support overloading the implicit conversions, which can still give you really funky results.


  • Considered Harmful

    @Bulb said in Going to the Google's walled garden with Go:

    Haskell got this right

    Ah, so it's impossible in practice.


  • BINNED

    @Bulb how the fuck did that happen:

    49634CD0-CA25-4DB7-B9AC-9FD856C9AA76.jpeg

    Filed under: markdumb


  • Notification Spam Recipient

    @Bulb said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    @topspin said in Going to the Google's walled garden with Go:

    @DogsB still, you haven’t pointed out how “does absolutely retarded thing in overloaded operator” is any different from “does absolutely retarded thing in overloaded method”.

    The analogy with the alphabet not work well? If == can't be overloaded by the user then that bit of the language will always be understood by everyone regardless of user doing stupid things with method names and their contents.

    It will, however, be irrelevant that it will be understood, because it won't be even usable in the cases where there could be a problem. Instead the equals (or whatever) method will be used and will have exactly the same capacity for surprising behavior.

    If it can't be understood then it's worse than useless and won't be used so I have nothing to worry about. I won't have too much of a problem with methods having surprising behaviour so long as the basic axioms remain unmolested.

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb what languages that support operator overloading could prevent a developer from throwing a range check into an overloaded ==?

    Haskell¹, for example. Well, you can still bottom on it, but there is no way to make that a useful behaviour there.

    But then, does Java prevent developer from throwing a range check in the override of Object.equals()? And if not, how is that less of a problem?

    If someone has overridden an equals to do that as part of it's implementation, while annoying, is fine once the symbols that make it up isn't a local dialect that's subject to change on a whim.



  • @DogsB said in Going to the Google's walled garden with Go:

    @Bulb said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    @topspin said in Going to the Google's walled garden with Go:

    @DogsB still, you haven’t pointed out how “does absolutely retarded thing in overloaded operator” is any different from “does absolutely retarded thing in overloaded method”.

    The analogy with the alphabet not work well? If == can't be overloaded by the user then that bit of the language will always be understood by everyone regardless of user doing stupid things with method names and their contents.

    It will, however, be irrelevant that it will be understood, because it won't be even usable in the cases where there could be a problem. Instead the equals (or whatever) method will be used and will have exactly the same capacity for surprising behavior.

    If it can't be understood then it's worse than useless and won't be used so I have nothing to worry about. I won't have too much of a problem with methods having surprising behaviour so long as the basic axioms remain unmolested.

    Why does it make such a huge difference to you whether the operation is called x.equals(y) or x.operator ==(y)? Or whether it's called x == y or x `equals` y? To me those differences are completely superficial.

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb what languages that support operator overloading could prevent a developer from throwing a range check into an overloaded ==?

    Haskell¹, for example. Well, you can still bottom on it, but there is no way to make that a useful behaviour there.

    But then, does Java prevent developer from throwing a range check in the override of Object.equals()? And if not, how is that less of a problem?

    If someone has overridden an equals to do that as part of it's implementation, while annoying, is fine once the symbols that make it up isn't a local dialect that's subject to change on a whim.

    It is a local dialect that is subject to change on exactly the same whim as the operator ==. They are both just methods, and both defined by the language standard, just the first one has identifier composed of letters and the second has identifiers composed of special symbols.


  • Considered Harmful

    @Bulb I recall settling this for myself as a conflict between the assumptions natural to algebra and those natural to programming.


  • Notification Spam Recipient

    @Bulb said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    @topspin said in Going to the Google's walled garden with Go:

    @DogsB still, you haven’t pointed out how “does absolutely retarded thing in overloaded operator” is any different from “does absolutely retarded thing in overloaded method”.

    The analogy with the alphabet not work well? If == can't be overloaded by the user then that bit of the language will always be understood by everyone regardless of user doing stupid things with method names and their contents.

    It will, however, be irrelevant that it will be understood, because it won't be even usable in the cases where there could be a problem. Instead the equals (or whatever) method will be used and will have exactly the same capacity for surprising behavior.

    If it can't be understood then it's worse than useless and won't be used so I have nothing to worry about. I won't have too much of a problem with methods having surprising behaviour so long as the basic axioms remain unmolested.

    Why does it make such a huge difference to you whether the operation is called x.equals(y) or x.operator ==(y)? Or whether it's called x == y or x `equals` y? To me those differences are completely superficial.

    Why do you want to redefine what == does in every class? I’ll be hungover and just assign the bug to you then. Not wonder if == now includes a range check.

    Also, where I'm from x==y is very different to x.equals(y).

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb what languages that support operator overloading could prevent a developer from throwing a range check into an overloaded ==?

    Haskell¹, for example. Well, you can still bottom on it, but there is no way to make that a useful behaviour there.

    But then, does Java prevent developer from throwing a range check in the override of Object.equals()? And if not, how is that less of a problem?

    If someone has overridden an equals to do that as part of it's implementation, while annoying, is fine once the symbols that make it up isn't a local dialect that's subject to change on a whim.

    It is a local dialect that is subject to change on exactly the same whim as the operator ==. They are both just methods, and both defined by the language standard, just the first one has identifier composed of letters and the second has identifiers composed of special symbols.

    Before this gets even more circular. So do you see operators ()[]<>== as the same as methods or as distinct from methods ? I see operators as immutable actions while I see methods as mutable collections of actions. Do you preceive everything as a method?



  • Again JavaScript comes heroically to the rescue with at least one library I've seen checking that a thing is a number with a dual check against isNaN but also coercing to a string and validating that the string version is not [object Object] because someone modified the prototype of it.

    That might as well be 'let's rip up the rule book' when you can't trust a number to be a number without exotic testing against other idiots' idiocy.



  • @Gribnit Having some background in abstract algebra for me those assumptions match quite well. For me, addition is just the operation of a monoid (the set part corresponds to type in programming) and the only requirement there is that there exists a ‘zero’ element. String concatenation satisfies that definition, so does list concatenation, set addition, logical xor and a bunch of other things. Hell, Darcs documentation used to even define patch algebra that was a bona fide algebra.



  • @Arantor Which library is this? I wanna see the code and experience this awesomeness firsthand



  • @stillwater I don't think it exists any more. It was in an era where so much bad stuff got written. Not that now is any better.

    I will however direct you to what I did find just now in the spirit of the thing, a JS library for 'is this a string'.

    Complete with literal check against coercing the thing under investigation to a string and verifying that the type cast gets you the correct [object String] line.



  • @Arantor That's messed up. Nobody bats an eye only cos it is JS. If it was Java or C# or something everyone will already be ready with their pitchforks.



  • @stillwater even PHP isn't this awful.



  • @DogsB said in Going to the Google's walled garden with Go:

    @Bulb said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    @topspin said in Going to the Google's walled garden with Go:

    @DogsB still, you haven’t pointed out how “does absolutely retarded thing in overloaded operator” is any different from “does absolutely retarded thing in overloaded method”.

    The analogy with the alphabet not work well? If == can't be overloaded by the user then that bit of the language will always be understood by everyone regardless of user doing stupid things with method names and their contents.

    It will, however, be irrelevant that it will be understood, because it won't be even usable in the cases where there could be a problem. Instead the equals (or whatever) method will be used and will have exactly the same capacity for surprising behavior.

    If it can't be understood then it's worse than useless and won't be used so I have nothing to worry about. I won't have too much of a problem with methods having surprising behaviour so long as the basic axioms remain unmolested.

    Why does it make such a huge difference to you whether the operation is called x.equals(y) or x.operator ==(y)? Or whether it's called x == y or x `equals` y? To me those differences are completely superficial.

    Why do you want to redefine what == does in every class?

    Not every class. Just every class that needs to be equality comparable.

    I’ll be hungover and just assign the bug to you then. Not wonder if == now includes a range check.

    If for class C it includes a range check, and that range check does make sense for class C, then it's fine. If it does not make sense for it, then whoever implemented class C was probably a moron.

    Also, where I'm from x==y is very different to x.equals(y).

    Java manages to make a pretty big mess of this, because for primitive types == compares values, but for reference types (java.lang.Object and anything derived from it) it compares the reference identity, and you get java.lang.Object#equals for value comparison. Which really does not play well with auto-boxing as you compare int with ==, but when it's for whatever reason promoted to java.lang.Integer, you have to switch to .equals. With == appearing to still work if you test it on small numbers.

    While in most other languages, == is always intended to compare values, and there is a separate operator for reference equality if some types are inherently references. So in C++ you take addresses and compare those, C#, recognizing it's actually rare thing to want, has System.Object.ReferenceEquals static method (to handle nulls), Python has is, IIRC PHP has ===. But == is the thing that compares by value, for both value and reference types.

    And that is what I came to expect of a language properly geared for building abstractions. == compares values, and for types I define I get to also define what that means. Java uses it differently, so in Java the thing I get to define is java.lang.Object.equals. But for all practical purposes those are the same things that I am comparing, except the later has uglier syntax.

    @DogsB said in Going to the Google's walled garden with Go:
    Before this gets even more circular. So do you see operators ()[]<>== as the same as methods or as distinct from methods ? I see operators as immutable actions while I see methods as mutable collections of actions. Do you preceive everything as a method?

    All those operators are just special kinds of methods, yes. Though maybe method isn't the right word here, but either way they are definitely the same kind of thing to me: operations defined in type-dependent manner.

    The [] are defined for arrays as indexing by offset, but in many languages they are also defined for associative arrays indexing by whatever key there is and that is a different type for different type of associative arrays. So clearly type-dependent.

    The <, > and ==, even if we stick to primitive types, NaN != NaN and neither Nan < Nan nor Nan > Nan, so for floats they are not even a total order, but they are a total order on integers.

    And since these days basically all languages got function objects, the function/method call () are an operation defined differently for each function type.

    Only the grouping () are a special thing because those only control the parse tree and don't denote any operation of their own. But all the operators are just operations and methods or functions or whatever are just operations, and all are defined in a type-dependent way. Is-just-a principle.


  • BINNED

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    @topspin said in Going to the Google's walled garden with Go:

    @DogsB still, you haven’t pointed out how “does absolutely retarded thing in overloaded operator” is any different from “does absolutely retarded thing in overloaded method”.

    The analogy with the alphabet not work well? If == can't be overloaded by the user then that bit of the language will always be understood by everyone regardless of user doing stupid things with method names and their contents.

    It will, however, be irrelevant that it will be understood, because it won't be even usable in the cases where there could be a problem. Instead the equals (or whatever) method will be used and will have exactly the same capacity for surprising behavior.

    If it can't be understood then it's worse than useless and won't be used so I have nothing to worry about. I won't have too much of a problem with methods having surprising behaviour so long as the basic axioms remain unmolested.

    Why does it make such a huge difference to you whether the operation is called x.equals(y) or x.operator ==(y)? Or whether it's called x == y or x `equals` y? To me those differences are completely superficial.

    Why do you want to redefine what == does in every class? I’ll be hungover and just assign the bug to you then. Not wonder if == now includes a range check.

    You don’t want to redefine it in every class. You want to redefine it in exactly the same cases you’d otherwise redefine .equals.

    Also, where I'm from x==y is very different to x.equals(y).

    But it’s not. It’s just a different, more idiomatic name.
    (INB4 “it’s not in the specific language I’m using that doesn’t have operator overloading to begin with.”)

    @DogsB said in Going to the Google's walled garden with Go:

    @Bulb what languages that support operator overloading could prevent a developer from throwing a range check into an overloaded ==?

    Haskell¹, for example. Well, you can still bottom on it, but there is no way to make that a useful behaviour there.

    But then, does Java prevent developer from throwing a range check in the override of Object.equals()? And if not, how is that less of a problem?

    If someone has overridden an equals to do that as part of it's implementation, while annoying, is fine once the symbols that make it up isn't a local dialect that's subject to change on a whim.

    It is a local dialect that is subject to change on exactly the same whim as the operator ==. They are both just methods, and both defined by the language standard, just the first one has identifier composed of letters and the second has identifiers composed of special symbols.

    Before this gets even more circular. So do you see operators ()[]<>== as the same as methods or as distinct from methods ? I see operators as immutable actions while I see methods as mutable collections of actions. Do you preceive everything as a method?

    Yes, that’s the point. Operators are just functions with a special syntax (usually symbols instead of letters and infix instead of prefix), nothing else.

    You can’t overload the existing meaning of + for integers. You can overload the meaning of + for your own vector class, which wouldn’t even have such an operator otherwise, so there’s no conflict. And naming that + is more idiomatic than .add. What’s the “immutable action” of adding two vectors using + in your user-defined class if you’re not allowed to define +?

    Or if you write a set container, you can compare sets for equality with == instead of .equals. Either way you write the same function, either way it’s an overload of a name that’s already used with other types, just that you’re using the name of an operator.



  • @Arantor said in Going to the Google's walled garden with Go:

    Again JavaScript comes heroically to the rescue with at least one library I've seen checking that a thing is a number with a dual check against isNaN but also coercing to a string and validating that the string version is not [object Object] because someone modified the prototype of it.

    That might as well be 'let's rip up the rule book' when you can't trust a number to be a number without exotic testing against other idiots' idiocy.

    And that language even does not have operator overloading! Though, well, the coercions, which are called cast operators in many languages, can be customized, so partially it does.


  • Notification Spam Recipient

    @Bulb @topspin so when ye specify operator overloading ye don't mean that preexisting operators for prexisting types can be arbitrarily overloaded by developers working in the language? I couldn't just decide += for strings can now add a “\n” for kicks and giggles.


  • BINNED

    @DogsB no. It just means that you as the author of a custom class can equip it with functionality the same way as the language/library authors can. Not change existing stuff willy nilly.

    That sounds more like monkey patching in fully dynamic languages.



  • @DogsB said in Going to the Google's walled garden with Go:

    @Bulb @topspin so when ye specify operator overloading ye don't mean that preexisting operators for prexisting types can be arbitrarily overloaded by developers working in the language? I couldn't just decide += for strings can now add a “\n” for kicks and giggles.

    Of course not! That would be stupid. Operator overloading is the same thing as function overloading: you get to define them for new types and/or new combinations of types.

    Well, some dynamic languages can be ‘monkey-patched’ that way, but then doing that to methods of existing types is just as bad—though sometimes you just do it to work around a bug in some library.



  • @Bulb said in Going to the Google's walled garden with Go:

    @Steve_The_Cynic said in Going to the Google's walled garden with Go:

    @topspin said in Going to the Google's walled garden with Go:

    @DogsB said in Going to the Google's walled garden with Go:

    I’ll give it a read

    Go not letting you do operator overloading, harkening back to the Java days where a == b isn't the same as a.equals(b)

    No. That is a point in every language’s favour. Overloading an operator just makes a new maintainer’s life a misery.

    Operators are just functions with a special name. Having to write a.equals(b) is stupid when the language has an equality operator.

    This has my vote.

    But then either:

    • The primitive types also have that method so generic containers can use it (either using dynamic or static polymorphism (generics)).
    • Any generic container has to have separate implementation for primitive types, and those probably can't be covered by generics or interfaces.
    • There are no generic containers.

    In the first case, why is the operator even there? And in the other two, you are significantly restricting ability to build abstraction.

    Or it all implements a constexpr bool operator ==(const Thing &this_thing, const Thing &that_thing) const and everything just works, including primitives where the operators are implied. (Well, also operator < so you can use them as keys in std::map, but you get the idea.)

    Sorry. My main ride these days is C++17, where overriding operators is a bit ordinary. (And yes, I do know about std::less, and I want nothing to do with it, thanks, unless it's for actual raw pointers :vomit: .)



  • @Steve_The_Cynic said in Going to the Google's walled garden with Go:

    Sorry. My main ride these days is C++17, where overriding operators is a bit ordinary. (And yes, I do know about std::less, and I want nothing to do with it, thanks, unless it's for actual raw pointers :vomit: .)

    std::less<T> is basically just a shortcut for approximately &bool operator <(const T&, const T&>) (with the benefit it encodes the function pointer in the type and so is zero-sized to the extent things can be zero-sized in C++ (they can't, but may be eligible for elision in places).



  • @Steve_The_Cynic It looks like I actually misread your post last time.

    I agree that operators are indeed just functions with special names. C++ does it mostly right except it lacks (or until recently lacked; I stopped at C++17 in the last project I used it) good helpers for defining the consistent sets of operators. That is for equality comparable define == and get != as !(x == y), for comparable define < and get ==, !=, <=, >= and >, for + and unary - get binary - etc. I know those exist in boost, but I don't know whether they got added to the standard yet.


  • Considered Harmful

    @Bulb said in Going to the Google's walled garden with Go:

    @Bulb said in Going to the Google's walled garden with Go:

    no language with a userbase to speak of allows overriding operators for types that already have it

    Hm, thinking about it, the ones with overzealous implicit conversions like Perl¹ probably do. Good riddance.

    Perl only allows it on objects, and while you can use those with all operators, most of them (everything but method call, list operators and isa) are meaningless. Integer operators work as if the pointer values were cast to uintptr_t, string operators use the even less useful reference-as-string representation.
    That said, of course it lets you do pretty much any evil fuckery you can think of. Nothing forces you to return a boolean from a boolean operator or a number from a mathematical one for instance :tro-pop:

    use overload
        "!" => sub{ 42 },
        sin => sub{ "repent!" };
    


  • @LaoC My point was that perl allows it on objects, but if you don't define them, they do weird things. Specifically the == defaults to conversion to numbers and comparing those (and since most objects will convert to 0, most objects are ==-equal) and eq defaults to conversion to strings and comparing those (and objects default to coverting to string representation of the pointer IIRC, so it would end up as approximately reference identity).

    … and it does these even for the inequalities. IIRC in contrast python made this stricter and going to version 3 it made objects of different types unordered by default, i.e. trying to sort mixed-type collection raises an exception.


  • BINNED

    @Bulb C++20 got the spaceship operator and can synthesize default comparisons. Haven’t used it, so I’m not sure how it works in detail.
    Apparently early drafts synthesized everything from <=>, but that sucks for performance. They addressed that, though. (As usual, rust got it right by having separate Eq and Ord)


  • Considered Harmful

    @Bulb said in Going to the Google's walled garden with Go:

    @LaoC My point was that perl allows it on objects, but if you don't define them, they do weird things. Specifically the == defaults to conversion to numbers and comparing those (and since most objects will convert to 0, most objects are ==-equal) and eq defaults to conversion to strings and comparing those (and objects default to coverting to string representation of the pointer IIRC, so it would end up as approximately reference identity).

    If you don't do anything to prevent it, objects always convert to their address:

    Using a string or number as a reference produces a symbolic reference, as explained above. Using a reference as a number produces an integer representing its storage location in memory. The only useful thing to be done with this is to compare two references numerically to see whether they refer to the same location.

               if ($ref1 == $ref2) {  # cheap numeric compare of references
                   print "refs 1 and 2 refer to the same thing\n";
               }
    


  • @LaoC Ok, my memory is a bit faded. I stopped working with perl some 15 years ago.



  • @Bulb said in Going to the Google's walled garden with Go:

    @Steve_The_Cynic said in Going to the Google's walled garden with Go:

    Sorry. My main ride these days is C++17, where overriding operators is a bit ordinary. (And yes, I do know about std::less, and I want nothing to do with it, thanks, unless it's for actual raw pointers :vomit: .)

    std::less<T> is basically just a shortcut for approximately &bool operator <(const T&, const T&>) (with the benefit it encodes the function pointer in the type and so is zero-sized to the extent things can be zero-sized in C++ (they can't, but may be eligible for elision in places).

    Yup. Been there, done that, ugly T-shirt. More specifically, alternative deleters for std::unique_ptr<T>. Writing a functor object for the deleter embeds the deleter in the type (std::unique_ptr<T,MyDeleterForT>) instead of in the unique_ptr (std::unique_ptr<T,decltype(some_function_that_deletes_T)> and always remembering to pass the right function to the constructor...). Violently ugly.



  • @Steve_The_Cynic As new techniques get discovered, and features get bolted on to the existing mess, a lot of C++ is violently ugly.



  • @Bulb You're not wrong, but I was thinking specifically of the "using a function pointer" version of std::unique_ptr, which is ugly from a maintainability point of view.


  • BINNED

    From the article:

    Okay. Let's talk about what makes Go compelling.

    Go is a pretty good async runtime, with opinionated defaults, a state-of-the-art garbage collector with two knobs, and tooling that would make C developers jealous, if they bothered looking outside their bubble.

    40qhlp.png



  • @topspin By the way, I've been wondering why the async runtime is such a big deal.

    An async system call is still a system call, so you still get the entry and exit context switches, and then you have to make an additional system call to poll for the result, with it's own entry and exit context switches, and deal with the work queue handling.

    But a sync system call has the entry and then schedule() gets called and some other thread that can make progress gets to run instead and the sync syscall only returns when its ready and this thread gets a turn again. So you only have one pair of context switches in this thread, and they are not more expensive when they are still to the same process (as is the case with multi-dreaded servers).

    And schedule(), at least the Linux one, has had the bejeesus optimized out of it and is O(1). So what makes the complicated M-to-N dread mapping so popular over keeping it simple by throwing the synchronous code to system-level dreads and calling it a fortnight?



  • @topspin said in Going to the Google's walled garden with Go:

    @Bulb how the fuck did that happen:

    49634CD0-CA25-4DB7-B9AC-9FD856C9AA76.jpeg

    Filed under: markdumb

    Well, obviously, Haskell got that right...



  • @Steve_The_Cynic said in Going to the Google's walled garden with Go:

    @Bulb You're not wrong, but I was thinking specifically of the "using a function pointer" version of std::unique_ptr, which is ugly from a maintainability point of view.

    The non-ugly way is to explicitly specialize the std::default_delete. If you want to always use the same function for given type, which you usually do.



  • @Bulb said in Going to the Google's walled garden with Go:

    @Steve_The_Cynic said in Going to the Google's walled garden with Go:

    @Bulb You're not wrong, but I was thinking specifically of the "using a function pointer" version of std::unique_ptr, which is ugly from a maintainability point of view.

    The non-ugly way is to explicitly specialize the std::default_delete. If you want to always use the same function for given type, which you usually do.

    Except that in our case, where some non-delete[] things are char * deleted with free() and some are char * deleted with e.g. OpenSSL_free(), that doesn't work well.

    ((:wtf: terrority: some things have "non-deleting deleters" (custom deleter object that does not actually free the thing it's given) so as to avoid having naked raw pointers to strings returned by OpenSSL that are parts of larger allocations(1) and therefore must not be deleted. Managing them like that rather than leaving the naked pointers was not my idea.))

    (1) Some OpenSSL strings are not allocated separately, so if it gives you one of these, you must not free it in any way.



  • @Steve_The_Cynic Yeah, that takes custom functors to do. Writing the struct openssl_deleter { void operator()(…) { … }} boilerplate is almost muscle memory, and then I'd do something like using openssl_charp = std::unique_ptr<char, openssl_deleter> to avoid having to spell it out all the time. Verbose but otherwise not too bad.



  • @Bulb said in Going to the Google's walled garden with Go:

    @Steve_The_Cynic Yeah, that takes custom functors to do. Writing the struct openssl_deleter { void operator()(…) { … }} boilerplate is almost muscle memory, and then I'd do something like using openssl_charp = std::unique_ptr<char, openssl_deleter> to avoid having to spell it out all the time. Verbose but otherwise not too bad.

    Exactly what I did. 👍


  • Considered Harmful

    @DogsB said in Going to the Google's walled garden with Go:

    Do you preceive everything as a method?

    As an expression, actually.


  • Discourse touched me in a no-no place

    @Bulb said in Going to the Google's walled garden with Go:

    It only got bad name because C++ and C# standard libraries abused operators for things that isn't appropriate.

    Yes, but that means that everyone who uses those languages gets exposed to the stupid annoyances. (C++ operator abuse also allows for some extremely surprising behaviour when mixed with overloading. Languages should not be made out of landmines.)



  • @dkf said in Going to the Google's walled garden with Go:

    @Bulb said in Going to the Google's walled garden with Go:

    It only got bad name because C++ and C# standard libraries abused operators for things that isn't appropriate.

    Yes, but that means that everyone who uses those languages gets exposed to the stupid annoyances. (C++ operator abuse also allows for some extremely surprising behaviour when mixed with overloading. Languages should not be made out of landmines.)

    Personally, I have found that stupid annoyances are intrinsic to programming.


  • Discourse touched me in a no-no place

    @Carnage said in Going to the Google's walled garden with Go:

    golang seems to be getting more popular and for some reason being hot shit in startups

    Burnt out ex-googlers.


Log in to reply