Live data from Hacker News

My favorite Rust function

blog.jabid.in

191–197 of 197 posts

Re: My favorite Rust function

#191
post #116

Earlier quoted context omitted.

I’m mostly working with Rust, and I really like it, and I can even understand why WRITING Golang can be frustrating at times, but it should be clear to everyone that Golang is the best language to READ.

I completely disagree, coming from a Java and C# background. There are nice aspects to reading Go, but any function which does some kind of error-prone operation is so hard to grok, it gets tiring - the actual purpose is constantly interrupted by 'if err := nil' so much. And gods help you if there is some actual non-trivial error handling going on, as you've generally learned to gloss over and can easily miss that on…

> I completely disagree, coming from a Java

I'm sorry but I couldn't read past this.

Re: My favorite Rust function

#192

Earlier quoted context omitted.

It may be an unnecessary dig, but the author may indeed be familiar with Go and still think it's unacceptably crippled for all their use cases. The whole post is just their opinion.

Using the word "crippled" is not in keeping with the Rust Code of Conduct. https://www.rust-lang.org/policies/code-of-conduct Hey @dang -- why do you and Hacker News think it's ok to make comments at the expense of the differently-abled, and when I call you on it, the post gets flagged? That's NOT OK.

[deleted]

Re: My favorite Rust function

#193
post #97

Earlier quoted context omitted.

I work with Rust only these days, it’s really an awesome language and I wish everyone working with system languages would switch to Rust. Yet, I find Golang to be a much clearer language to read (and I read a shit ton of code). I hope they don’t add generics, but I wish they would options, results, sum types in general, redeclaring variables, the ? Operator, etc.

How would Option , Result , and sum types work without generics?

Native support is the answer.

Re: My favorite Rust function

#194

can someone elaborate on this passage: The beauty of programming language design is not building the most complex edifice like Scala or making the language unacceptably crippled like Go - but giving the programmer the ability to represent complex ideas elegantly and safely. Rust really shines in that regard. i'm fairly ignorant on the various differences but my general feeling was that Go is quite useful?

One of the philosophies behind Go is to keep the language extra simple. See "less is exponentially more". The same way some electric bikes are restricted to a given speed to keep their user safe. Some people call it "crippled", while some other call it "simple and safe to use".

Keeping a language simple just punts complexity from the language to the implementation that uses that language. This is all the same problems that C has and Go chose to for some reason copy this poor philosophy. It's like Go designers decided most programmers are too dumb to understand complex languages.

Re: My favorite Rust function

#195

Earlier quoted context omitted.

That was just an example. But maybe 'x' is a BigInt type that use a memory allocation to store its contents. The ownership would be transferred to the return value

But again, what would be the drawback(s) of using a pointer instead of transfering the ownership? Not rethorical, I'm genuinely curious as I used to struggle with the copy vs move decisions, and a bunch of issues with ownership which went all away when I started using pointer/borrowing everywhere.

The downside to using a mutable reference instead of passing around ownership is just that it would be awkward.

You'd have to write two extra lines of code to set up y and z separately from calling add(), and you'd have to make them mutable which is an extra mental burden.

And an immutable reference is bad because it would force extra objects to be allocated, wasting time and cache space.

Re: My favorite Rust function

#196

Earlier quoted context omitted.

> Enumerations type myEnum int const ( someValue myEnum = iota anotherValue moreValues ) > Sum types Consider thinking about the types in your sum type and what they have in common, and define an interface that they share. > Recursive types Not sure what you mean. This is valid Go: type tree struct { value int left *tree right *tree } > Parametric polymorphism Yes Go sucks in this area. `sort.Interface` is a good exa…

> Enumerations - those are integers not enumerations. In Golang they have a type Bool which is either true or false. Can I define my own type using the same convention in GoLang? No. I can't. Ideally I want the ability to do this: type Bool = Enum { True False } or type Tri = Enum { True False QuantumTrueFalseDuality } But in Golang I'm locked in with what the creators provided as primitive types. I can't go deeper.…

> Enumerations

I don't see the value in defining a custom underlying type for an enum. If it's for efficiency, sure. I've never had to use enums in a heavily performance-sensitive context so I don't personally relate to that.

> The assert also leaves an opening for a runtime error which is unacceptable.

You can handle errors gracefully.

    // default to 0
    maybeInt, _ := myValue.(int)

    maybeInt, ok := myValue.(int)
    if !ok {
      // do something else
    }
> imagine syntax like this:

In my opinion JSON with multiple types like that is poor design.

Regardless, even with sum types the programmer has to write code for most possible states each value could be in. You have the same capability in Go with type assertions.

    // Rust
    match myValue {
        int => ...,
        string => ...,
        // etc.
    }

    // Go
    switch myValue.(type) {
        case int:
            ...
        case string:
            ...
        // etc.
    }

Re: My favorite Rust function

#197

Earlier quoted context omitted.

> Enumerations - those are integers not enumerations. In Golang they have a type Bool which is either true or false. Can I define my own type using the same convention in GoLang? No. I can't. Ideally I want the ability to do this: type Bool = Enum { True False } or type Tri = Enum { True False QuantumTrueFalseDuality } But in Golang I'm locked in with what the creators provided as primitive types. I can't go deeper.…

> Enumerations I don't see the value in defining a custom underlying type for an enum. If it's for efficiency, sure. I've never had to use enums in a heavily performance-sensitive context so I don't personally relate to that. > The assert also leaves an opening for a runtime error which is unacceptable. You can handle errors gracefully. // default to 0 maybeInt, _ := myValue.(int) maybeInt, ok := myValue.(int) if !ok…

This isn’t about personal opinion. This is about understanding the fundamental mathematics behind types. In type theory there are two fundamental composite types. Product types and sum types. Sum types are types that can be A or B or C. Product types can be A and B and C.

An example of a product type is any type that can hold multiple typed entities, whether that’s a list, array, structure or map.

An example of a sum type is polymorphism defined using inheritance. The children of a parent type are encoded into the type itself, but the type instantiated can only take the form of one of the children.

Note that my example for the sum type is isomorphic to a typed enum. It’s literally the same concept. Sum types and product types are mathematical opposites. Every language that has algebraic data types has this concept encoded into it. Go is one of the few typed languages that doesn’t have it.

Let’s get away from the mathematics and talk about practicality. Your example of the switch and pattern matching. Let’s say myValue is an int, a string or a float.

Let’s also say that when you are coding you miss checking for the float case and you add an extra invalid case where the code checks for Double? What happens in rust or go? In go nothing happens because go doesn’t truly know the underlying type so by doing this the code compiles and you have encoded a runtime error into the code.

For rust exhaustive type checking will catch both the missing handler and the invalid case. That’s right rust will know you have missing logic based off of the type. This is a powerful feature that is encoded into most languages that have algebraic data types.

Now let’s take the conversation back to math. The fundamentals. Have you ever thought about what an Int actually is? Looks like an enum doesn’t it?

   type int = 0 | 1 | 2 | 3 ...
If you really want to get deep an int is actually a recursive enumeration similar to json.

   type int = 0 | (int, 1) | (int, 2) | (int, 3) | ... (int, 9); 
So for example ints are instantiated like this..

   0 = 0,
   1 = (0, 1)
   2 = (0, 2)
   .
   .
   .
   12 = ((0, 1) 2)
   .
   .
   .
   456 = (((0, 4), 5), 6)
Operations like addition and multiplication are defined in terms of inductive mappings between enumerations.

This fundamentally what a type is. Any language missing the ability to define this is missing a mathematical primitive. It is incomplete. Go is a language that simply has an arbitrary enumeration (int) defined and the rest of the code needs to build off of it as there is no mechanism to define your own. Ints should be encoded as enumerations not the other way around.

Post reply on HN