News for hackers. Stuff that matters.
Re:Diving into Go by building a CLI application by pansa2 on Wednesday May 27, 2020 @03:07AM (#23320218)
> [Go] is forgiving enough that you can do exploratory programming in it.

I agree with most of your post, but I’m not sure I would describe Go as “forgiving”. In fact, it’s well known for being strict. For example, exploratory programming would be significantly easier if the Go compiler could (optionally) ignore unused variables and unreachable code.

I’ve also found exploratory programming in Go is hindered by needing to frequently cast between different integer types. Maybe I’m doing something wrong, but my Go code is often littered with casts between different integer sizes and signedness. It’s much easier with Python’s arbitrary-precision integers.

Re:Diving into Go by building a CLI application by kstenerud on Wednesday May 27, 2020 @04:24AM (#23320727)
I maintain a modified compiler (https://github.com/kstenerud/go/blob/master/README.md#the-go...) that can issue warnings instead for unused things.

I use it as my daily driver for go development.

main.go:

    package main

    import "fmt"

    func main() {
        var start int = 1

        breakOuter:
        // for x := start; x < 10; x++ {
        for x := 3; x < 10; x++ {
            for y := 0; y < 10; y++ {
                result := y * 10 + x
                // fmt.Printf("Result: %d\n", result)
                // if result == 42 {
                //  fmt.Printf("Breaking")
                //  break breakOuter
                // }
            }
        }
    }
Building:

    $ go build
     # example
     ./main.go:3:8: imported and not used: "fmt"
     ./main.go:8:5: label breakOuter defined and not used
    (compilation fails)

    $ go build -gcflags=-warnunused
     # example
     ./main.go:8:5: Warning: label breakOuter defined and not used
     ./main.go:3:8: Warning: imported and not used: "fmt"
     ./main.go:6:9: Warning: start declared and not used
     ./main.go:12:13: Warning: result declared and not used
    (compilation succeeds)
Re:Diving into Go by building a CLI application by rat9988 on Wednesday May 27, 2020 @07:41AM (#23321835)
That's cool! It is so annoying to just try to try something fast, and then the compiler stops you...
Re:Diving into Go by building a CLI application by LanceH on Wednesday May 27, 2020 @10:47AM (#23324152)
I had the same opinion you did until I went to a Go meetup and everyone else was a C programmer. Coming from Ruby, Go wasn't expressive or forgiving. But everyone coming from C thought it was wonderful.

Personally, I feel you with respect to casting integer types. I'll code away with int's until something suddenly needs an int64 to use a package and I have to cast everything or refactor everything to int64. I once commented in a thread where people were asked, "In hindsight what feature would you like in Go?" I said that int should just be an alias for int64 (and float == float64), since these were the defaults in the stdlib. I was downvoted into oblivion in a thread on hypotheticals. I understand the historical machine dependent 32/64 difference, but since the stdlib made a choice, the default should line up nicely. That said, I mostly run into this in Project Euler problems, so not in my day to day work.

Re:Diving into Go by building a CLI application by gerbilly on Wednesday May 27, 2020 @07:48AM (#23321874)
When programming in Java, I routinely run code that has compile errors in it.

As long as my execution path doesn't hit any code containing errors, I can run debug and even modify code in the debugger.

That's exploratory programming.

Re:Diving into Go by building a CLI application by swsieber on Wednesday May 27, 2020 @07:53AM (#23321912)
That's not a general java attribute though, is it? I suspect that's because of the eclipse compiler.
Re:Diving into Go by building a CLI application by gerbilly on Thursday May 28, 2020 @01:44PM (#23340156)
Yeah you're right it's eclipse.

I haven't been able to get IntilliJ to run broken code, which is one of the main reasons I stay with eclipse at least part of the time.

Re:Diving into Go by building a CLI application by sacado2 on Wednesday May 27, 2020 @05:18AM (#23321053)
> Maybe I’m doing something wrong, but my Go code is often littered with casts between different integer sizes and signedness.

It can actually be a feature, and one of the things that brought me to go, as you can define your own integer (or float, or string, etc.) types, thus making them incompatible with each other:

    type distance int
    type speed int
    func distFor(d distance, t time.Time) speed { ... }
    ...
    x = distFor(x, t) // Oops, that's probably a bug!
Not many languages let you do this, especially back then. But yeah, not great for exploratory programming.
Re:Diving into Go by building a CLI application by mikekchar on Wednesday May 27, 2020 @06:15AM (#23321319)
This is probably the biggest thing I wish was easier to do in Rust. You can make "newtypes" by wrapping the value in a tuple (that gets compiled away), but it's a fair amount of boilerplate or macros to make the newtype useful. Once you have what you need, it's fine, but it's even less convenient for exploratory programming ;-)
Re:Diving into Go by building a CLI application by zozbot234 on Wednesday May 27, 2020 @06:50AM (#23321526)
> but it's a fair amount of boilerplate or macros to make the newtype useful.

As mentioned in the docs, you can use the Deref facility to have the newtype implement everything that the original type does. Rust just gives you the choice of doing this vs. wrapping with a custom set of impls.

Re:Diving into Go by building a CLI application by mikekchar on Wednesday May 27, 2020 @07:27AM (#23321755)
I'm not sure why I didn't recall that :-P Of course you are correct!
Re:Diving into Go by building a CLI application by hoseja on Wednesday May 27, 2020 @06:20AM (#23321341)
Oh, Rust does not have elegant strong typedefs? Bummer. Are they at least planned? It's such a boon for type correctness/safety.
Re:Diving into Go by building a CLI application by abjKT26nO8 on Wednesday May 27, 2020 @06:42AM (#23321482)
Re:Diving into Go by building a CLI application by hoseja on Friday May 29, 2020 @03:06AM (#23347059)
I'm sorry but that does not look like an elegant first-class language construct, more like a pattern workaround.
Re:Diving into Go by building a CLI application by mikekchar on Saturday May 30, 2020 @09:48AM (#23361170)
I have to admit that I felt that way about it too. In fact, I think everybody felt that way about it at first. It was a work-around. The reason it was never changed, though, was that people didn't find anything significantly better. Rust is already a big language. It doesn't necessarily need new constructs.

However, as the OP of this thread, I have to admit that I often feel conflicted about it. Using the Deref trait certainly feels like another hack (and some people really dislike it). Basically Deref is what's used to dereference a reference. It's invoked automatically when you are calling a trait function on a variable. So if you have a variable that's a struct that implements a trait, it will bind to the function on that trait. If your variable contains a reference to the struct, then the compiler is smart enough to see if the struct implements the trait and then automatically uses the Deref train to derefernce the reference and bind to the function.

So if you want to delegate from one type to exactly one other type, you can do it simply by implementing the Deref trait on the first type and having it convert to the second type. It's kind of elegant, but also kind of hacky :-) There are people who feel that Deref should only be used for objects that are actually memory references. Other people feel that it's OK to use it when one type is masquerading as another type (as we are doing when we put a data structure inside a tuple to make it a "new type").

On the plus side, it gives you really fine grained control without adding new constructs to the language. You can make a "new type" that incurs no runtime overhead (in speed or space) and you can choose whether to delegate all of the function calls to the contained type, or to control them explicitly. The former is really, really easy (essentially 5 lines of boilerplate) and the latter is extremely easy to read and reason about. I have to admit that it's hard to justify adding a new construct for something that is not actually broken (except when you first look at it ;-) ).

And, really, to me this is Rust in a nutshell. It's got a lot of really elegant and intelligent decisions going into its implementation, but all of them look incredibly unlikely when you first look at them. The result is that the learning curve is quite high and the road to fluency long. Often newbies (which I probably still qualify for) ask, "Why the heck is it done this way". When you get the answer, it make sense, but it's often not as satisfying as you had initially hoped :-) Still, like others who push past that point, I've got to say that I really enjoy writing Rust code. It's strange.

Re:Diving into Go by building a CLI application by abjKT26nO8 on Friday May 29, 2020 @07:39AM (#23348767)
What specific problems do you see with it?
Re:Diving into Go by building a CLI application by rob74 on Wednesday May 27, 2020 @03:57AM (#23320556)
Ok, let's say that it's more suitable to exploratory programming than other compiled languages? On one hand, yes it's strict about unused variables, but other features (e.g. fast compile times) more than make up for the disadvantages.
Re:Diving into Go by building a CLI application by boyter on Wednesday May 27, 2020 @03:18AM (#23320307)
What I mean is that while the compiler is strict its fairly easy to throw something together that mostly works. The large standard library really helps there. It's certainly not as easy as in Python though.