Live data from Hacker News

Go is a good fit for agents

docs.hatchet.run

151–160 of 183 posts

Re: Go is a good fit for agents

#151
post #150

Earlier quoted context omitted.

Setting aside the full enum API, as well as certain optimizations, this is a rough equivalent of the enum I gave: public class Day extends Enum { private int _ordinal; private Day(int ordinal) { this._ordinal = ordinal; } public int ordinal() { return this._ordinal; } public static final Day SUNDAY = new Day(0); // ... public static final Day SATURDAY = new Day(6); } with the added constraint that the Day constructor…

> this is a rough equivalent of the enum I gave Yes, this echos what I stated earlier: "An enum is conceptually the same as you manually typing 1, 2, 3, ... as constants, except the compiler generates the numbers for you automatically" Nice to see that your understanding is growing. > Taking from your examples, the key point is that a Foo is not a Bar. I'm not sure that's a useful point. Nobody thinks class Foo {} cl…

I don't understand anything more now than I did at the start. It is clear we are talking past each other.

The values of Day are {SUNDAY, ..., SATURDAY} not {0, ..., 6}. We can, of course, establish a 1:1 mapping between those two sets, and the API provides a convenient forward mapping through the ordinal method and a somewhat less convenient reverse mapping through the values static method. However, at runtime, instances of Day are pointers not numbers, and ints outside the range [0, 6] will never be returned by the ordinal method and will cause IndexOutOfBoundsException if used like Day.values()[ordinal].

Tying back to purpose of this thread, Go cannot deliver the same guarantee. Even if we define

    type Day int
    const (
        Sunday Day = iota
        // ...
        Saturday
    )
then we can always construct Day(-1) or Day(7) and we must consider them in a switch statement. It is also trivial to cast to another "enum" type in Go, even if the variant doesn't exist on the other side. This sealed, nonconvertible nature of Java enums makes them "true" enums, which you can call tag-only discriminated unions or whatever if you want, but no such thing exists in Go. In fact, it is not even possible to directly adapt the Java approach, since sealed types of any kind, including structs, are impossible thanks to new(T) being allowed for all types T.

Re: Go is a good fit for agents

#152
post #150

Earlier quoted context omitted.

> this is a rough equivalent of the enum I gave Yes, this echos what I stated earlier: "An enum is conceptually the same as you manually typing 1, 2, 3, ... as constants, except the compiler generates the numbers for you automatically" Nice to see that your understanding is growing. > Taking from your examples, the key point is that a Foo is not a Bar. I'm not sure that's a useful point. Nobody thinks class Foo {} cl…

I don't understand anything more now than I did at the start. It is clear we are talking past each other. The values of Day are {SUNDAY, ..., SATURDAY} not {0, ..., 6}. We can, of course, establish a 1:1 mapping between those two sets, and the API provides a convenient forward mapping through the ordinal method and a somewhat less convenient reverse mapping through the values static method. However, at runtime, insta…

> This sealed, nonconvertible nature of Java enums makes them "true" enums, which you can call tag-only discriminated unions or whatever if you want, and no such thing exists in Go.

It is no secret that Go has a limited type system. In fact, upon release it was explicitly stated that their goal was for it to be a "dynamically-typed language with statically-typed performance", meaning that what limited type system it does have there only to support the performance goals. You'd have to be completely out to lunch while also living under a rock to think that Go has "advanced" types.

But, as before, enums are values. It is not clear why you want to keep going back to talking about type systems. That is an entirely different subject. It may be an interesting one, but off-topic as it pertains to this discussion specifically about enums, and especially not useful when talking in the context of Go which it isn't really intended to be a statically-typed language in the first place.

Re: Go is a good fit for agents

#154
post #107

Earlier quoted context omitted.

It's not so perplexing when you understand that Python has long had the best ecosystem of libraries for data science and ML, from which the current wave of AI stuff was born. There are plenty of reasons to dunk on Python, but the reality is lots of people were getting real work done with it in the run up to where we are today.

There are choices at multiple levels. Yes, today’s ML engineer has practically no choice but to use Python, in a variety of settings, if they want to be able to work with others, access the labor market without it being an uphill battle, and most especially if they want to study AI / ML at a university. But there were also the choices to initially build out that ecosystem in Python and to always teach AI / ML in Pyth…

When it comes to modern Python, the only thing that can make it not production-ready is it being slow. Given that people in machine learning are using Python as a glue language for AI/ML libraries, this negligibly impacts their workflow.

Re: Go is a good fit for agents

#155
post #142

Earlier quoted context omitted.

If you want to know only about the type system, nowadays it's mostly the lack of basic enums, a clear divide in basic features of the language and of the libraries (and modern generics support) leading to things like `len(..)` vs `.Len()`. Those actually end up playing a bigger role than it seems imho, but even just the rest is death by a thousand cuts. You can find many articles on the internet about it, but in my e…

> Lack of proper enums is hurting so much I can't describe it. Do you mean sum types? That is not a case of them not being "proper", though. They simply do not exist as a feature at all. Go's enums function pretty much like enums in every single other language under the sun. If anything, Go enums are more advanced than most languages, allowing things like bit shifts. But at the heart of it all, it's all just the same…

It's not about 'range', and like you said enum and sum types are tied concepts in other languages, and yes I was talking about sum types.

Even without sum types, there is a common pattern of defining a new type and const-defining the possible values that is a clear workaround on the lack of an 'enum' keyword.

Maybe because the compiler can't be sure that those const values are all the possible values of the type, we can't have things like enforcing exhaustive switches on this "enum", and that is left to the linter at best.

Default-zero initialization is always valid too, which can leave you with an "enum" value that is not present in the const definitions (not everything starts on iota, iota does not mean 0).

It's a hack, it became a pattern. It still is not a proper (or even basic) enum even without sum types.

Re: Go is a good fit for agents

#156
post #142

Earlier quoted context omitted.

If you want to know only about the type system, nowadays it's mostly the lack of basic enums, a clear divide in basic features of the language and of the libraries (and modern generics support) leading to things like `len(..)` vs `.Len()`. Those actually end up playing a bigger role than it seems imho, but even just the rest is death by a thousand cuts. You can find many articles on the internet about it, but in my e…

> Lack of proper enums is hurting so much I can't describe it. Do you mean sum types? That is not a case of them not being "proper", though. They simply do not exist as a feature at all. Go's enums function pretty much like enums in every single other language under the sun. If anything, Go enums are more advanced than most languages, allowing things like bit shifts. But at the heart of it all, it's all just the same…

Go doesn't even classic type-safe integer-value enums like in C++ or enums.

Yes, you can emulate this style of enums by using iota to start a self-incrementing list of integer constants. But that's not what any language (except for C) has ever meant by "enum".

Enums are generally assumed to be type-safe and namespaced. But in Go, they are neither:

  type Color int

  const (
      Red Color = iota
      Green
      Blue
   )

   func show(color Color) {
       fmt.Printf("State: %v", color)
   }

   fun main() {
       show(Red)
       show(6)
   }
There is no namespacing, no way to — well — enumerate all the members of the enum, no way to convert the enum value to or from a string (without code-genreation tools like stringer), and the worst "feature" of all is that enums are just integers that can freely receive incorrect values.

If you want to admire a cool hack that you can show off to your friends, then yeah, iota is a pretty neat trick. But as a language feature it's just a ugly and awkward footgun. Being able to auto-increment powers of two is a very small consolation prize for all of that (and something you can easily achieve in Rust anyway with any[1] number[2] of crates[3]).

[1] https://crates.io/crates/enumflags2

[2] https://crates.io/crates/bitmask-enum

[3] https://crates.io/crates/modular-bitfield

Re: Go is a good fit for agents

#157
post #142

Earlier quoted context omitted.

> Lack of proper enums is hurting so much I can't describe it. Do you mean sum types? That is not a case of them not being "proper", though. They simply do not exist as a feature at all. Go's enums function pretty much like enums in every single other language under the sun. If anything, Go enums are more advanced than most languages, allowing things like bit shifts. But at the heart of it all, it's all just the same…

It's not about 'range', and like you said enum and sum types are tied concepts in other languages, and yes I was talking about sum types. Even without sum types, there is a common pattern of defining a new type and const-defining the possible values that is a clear workaround on the lack of an 'enum' keyword. Maybe because the compiler can't be sure that those const values are all the possible values of the type, we…

> It's not about 'range'

It is to the extent that it helps explain what an enum is, and why we call the language feature what we do. Python makes this even more apparent as you explicitly have to call out that you want the enum instead of it always being there like in Go:

    for i, v in enumerate(array):
       # ...
In case I'm not being clear, an array enumerator like in the above code is not the same as a language enumerator, but an array enumerator (or something similar in concept) is how language enumerators are implemented. That is why language enumerators got the name they did.

> It still is not a proper (or even basic) enum even without sum types.

It most certainly is "proper". In fact, you could argue that most other languages are the ones that are lacking. Go's enums support things like bit shifts, which is unusual in other languages. Perhaps it is those other languages that aren't "proper"?

But, to be sure, it's not sum types. That is certain. If you want sum types you are going to have to look elsewhere. Go made it quite clear from the beginning that it wanted to be a "dynamically-typed language with statically-typed performance", accepting minimal static type capability in order to support the performance need.

There is definitely a place for languages with more advanced type systems, but there are already plenty of them! Many considerably older than Go. Haskell has decades on Go. Go was decidedly created to fill in the niche of "Python, but faster", which wasn't well served at the time. Creating another Haskell would have been silly and pointless; but another addition to the long list of obscure languages serving no purpose.

Re: Go is a good fit for agents

#158
post #125

Go has few advantages for this kind of workload - most of the time it'll just be waiting on io. And you suffer from the language itself; many type system features that you get for free in modern langauges require workarounds in Go. I've found that TypeScript is an excellent glue language for all kinds of AI. Python, followed by TS enjoy broad library support from vendors. I personally prefer it over Python because th…

Plus if one really needs more performance than V8 can delivery, I rather write a native module in C++/Rust than reach out to Go.

Re: Go is a good fit for agents

#159
post #113

Earlier quoted context omitted.

Can you elaborate a bit on how does "Go's quite horrendous and limited type system" get in the way of crafting agents? Honest question, I am genuinely interested in what cannot be done easily or at all due to limitations of the Go type system.

If you want to know only about the type system, nowadays it's mostly the lack of basic enums, a clear divide in basic features of the language and of the libraries (and modern generics support) leading to things like `len(..)` vs `.Len()`. Those actually end up playing a bigger role than it seems imho, but even just the rest is death by a thousand cuts. You can find many articles on the internet about it, but in my e…

> Companies started to use it as an alternative to C and C++, while in reality it's an alternative to python. Just like in python a lot of the work and warnings are tied into the linter as a clear workaround. Our linter config has something like 70+ linters classes enabled, and we are a very small team.

I thought the main "let's migrate our codebase to Go" crowd had always been from the Java folks, especially the enterprise ones. Any C/C++ code that is performant is about to get a hit, albeit small, from migrating to a GC-based runtime like Go, so I'd think that could be a put off for any critical realtime stuff - where Rust can be a much better target. And, true for both C++ and Java codebases, they also might have to undergo (sic) a major redux at the type/class level.

But yes, the Googlers behind Go were frustrated by C++ compile times, tooling warts, the 0x standard proposal and concurrency control issues - and that was primal for them, as they wanted to write network-server software that was tidy and fast [1]. Java was a secondary (but important) huge beast they wanted to tackle internally, IIRC. Java was then the primary language Googlers were using on the server... Today apparently most of their cloud stuff is written in Go.

[1] https://evrone.com/blog/rob-pike-interview

Re: Go is a good fit for agents

#160
post #142

Earlier quoted context omitted.

> Lack of proper enums is hurting so much I can't describe it. Do you mean sum types? That is not a case of them not being "proper", though. They simply do not exist as a feature at all. Go's enums function pretty much like enums in every single other language under the sun. If anything, Go enums are more advanced than most languages, allowing things like bit shifts. But at the heart of it all, it's all just the same…

Go doesn't even classic type-safe integer-value enums like in C++ or enums. Yes, you can emulate this style of enums by using iota to start a self-incrementing list of integer constants. But that's not what any language (except for C) has ever meant by "enum". Enums are generally assumed to be type-safe and namespaced. But in Go, they are neither: type Color int const ( Red Color = iota Green Blue ) func show(color C…

> Go doesn't even classic type-safe integer-value enums like in C++ or enums.

Sure, but now you're getting into the topic of types. Enums produce values. Besides, Go isn't really even intended to be a statically-typed language in the first place. It was explicitly told when it was released that they wanted it to be like a dynamically-typed language, but with statically-typed performance.

If you want to have an honest conversation, what other dynamically-typed languages support type-safe "enums"?

> But that's not what any language (except for C) has ever meant by "enum".

Except all the others. Why would a enum when used when looping over an array have a completely different definition? It wouldn't, of course. Enums are called what they are in a language because they actually use enums in the implementation, as highlighted in both the Go and Rust codebases above.

Many languages couple enums with sum types to greater effect, but certainly not all. C is one, but even Typescript, arguably the most type-intensive language in common use, also went with "raw" enums like Go.

Post reply on HN