Live data from Hacker News

Go is a good fit for agents

docs.hatchet.run

141–150 of 183 posts

Re: Go is a good fit for agents

#141

Earlier quoted context omitted.

While I think there is some truth to that regarding the programming paradigm, I always felt the EVM have two big drawbacks, compared to something like Go: 1. Requiring a VM, making deployment more complex. 2. Not being natively compiled, or always having this performance roof for the inner loops. After considering both Erlang/Elixir and Go a lot for my scientific workflow manager, I finally went with Go for these exa…

releases give you a tar.gz with everything bundled.

The OG container.

Re: Go is a good fit for agents

#142
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…

> 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. Here are enum implementations in both Go and Rust:

[Go] https://github.com/golang/go/blob/f18d046568496dd331657df4ba...

[Rust] https://github.com/rust-lang/rust/blob/40daf23eeb711dadf140b...

While Go leans on the enum value produced by `range` to act as the language's enumerator, while Rust performs explicit incrementing to produce the enumerator, the outcome is no different — effectively nothing more than [n=0, n++]. Which stands to reason as that's literally, as echoed by the dictionary, what an enum is.

Re: Go is a good fit for agents

#143
post #121

Earlier quoted context omitted.

> enums are just sad. There isn't much more you can do with them. Literally all an enum can produce is a number. In increasingly common use in a number of languages, enums are being coupled with discriminated unions, using the enum value as the discriminant. This is probably what you're really thinking of, noticing Go's lack of unions. But where you might use a discriminated union if it were available, you would curr…

Java has true enums that are neither fancy integers nor discriminated unions. The following is not a list of integers: public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } To use this enum, you typically declare a variable of type Day, which is a subclass of Enum, itself a subclass of Object, which cannot be cast to or from int. If a variable is typed as Day, then it can only take one of…

> The following is not a list of integers

Then I am not sure how you think it is an enum? What defines an enum, literally by dictionary definition, is numbering.

It is hilarious to me that when enum is used in the context of looping over an array, everyone understands that it represents the index of the element. But when it comes to an enum in a language, all of a sudden some start to think it is magically something else? But the whole reason it is called an enum is because it is produced by the order index of an AST/other intermediate representation node. The very same thing!

While I haven't looked closely at how Java implements the feature of which you speak, I'd be surprised if it isn't more or less the same as how Rust does it under the hood. As in using a union with an enumerator producing the discriminant. In this case it would be a tag-only union, but that distinction is of little consequence for the purposes of this discussion. That there is an `ordinal` method pretty much confirms that suspicion (and defies your claim).

> you cannot represent Day(7) or Day(-1) in any way, shape, or form.

While that is true, that's a feature of the type system. This is a half-assed attempt at sum types. Enums, on the other hand, are values. An enum is conceptually the same as you manually typing 1, 2, 3, ... as constants, except the compiler generates the numbers for you automatically, which is what is happening in your example. The enum is returned by `ordinal`, like you said. Same as calling std::mem::discriminant in Rust like we already discussed in a sibling thread.

Re: Go is a good fit for agents

#144

Erlang is a way better fit for a distributed agent orchestration layer. You have a ton of dependencies, over network and maybe in userspace, you have a lot of inter-operability and reliability constraints, you want to hotswap code and capabilities at runtime, without degrading the overall system performance. And you get networking/distribution/async message passing for free https://github.com/arthurcolle/agents.erl I…

[deleted]

Re: Go is a good fit for agents

#145
post #126

Go's quite horrendous and limited type system makes it a poor fit for everything. The worst thing about Go is, in fact, the language. Everything except the language redeems it.

I wouldn't mind a well-maintained LISP/Scheme dialect that compiled to Go.

Definitely not well maintained, but it's interesting to see that something like that came out of SteelSeries:

https://techblog.steelseries.com/golisp/index.html

https://github.com/SteelSeries/golisp

I wonder if they still use it.

Re: Go is a good fit for agents

#146
post #143

Earlier quoted context omitted.

Java has true enums that are neither fancy integers nor discriminated unions. The following is not a list of integers: public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } To use this enum, you typically declare a variable of type Day, which is a subclass of Enum, itself a subclass of Object, which cannot be cast to or from int. If a variable is typed as Day, then it can only take one of…

> The following is not a list of integers Then I am not sure how you think it is an enum? What defines an enum, literally by dictionary definition, is numbering. It is hilarious to me that when enum is used in the context of looping over an array, everyone understands that it represents the index of the element. But when it comes to an enum in a language, all of a sudden some start to think it is magically something…

The existence of the ordinal method reveals nothing except that the ordinal exists. It can be (and is) simply a field on each Day object, not an index into anything (though the Day objects are probably stored in an array, this is not required by any property of the system). Day.SUNDAY is ultimately a pointer, not an int. It is also a symbolically resolved pointer, so it will never become Day.MONDAY even if I reorder the variants so that their ordinals are swapped. The ordinal is not a discriminant.

You seem to be trivializing the type system. This property is not imagined solely by the compiler, it is carried through the language and runtime and cannot be violated (outside of bugs or unsafe code). Go has nothing like this.

If you choose to call this "not an enum", that is certainly your idiosyncratic prerogative, but that doesn't make for very interesting discussion. Even though I agree that discriminated unions aren't enums and am somewhat annoyed by Rust's overloading of the term, this is not that.

Re: Go is a good fit for agents

#147
post #90

Earlier quoted context omitted.

Yep exactly, might as well use a language that works with JSON natively like TypeScript; which has arguably far more powerful type system than Go.

> like TypeScript; which has arguably far more powerful type system than Go. "arguably". Typescript is just a thin wrapper over javascript who doesnt have these types at all.

Wait, you can't be saying that TypeScript doesn't have a much more powerful type system than Go.

AGDTs, mapped types, conditional types, template literal types, partial higher-kinded types, and real inference on top of all that.

It had one of the most fully loaded type systems out there while the Go team was asking for community examples of where generics might be useful because they're not sure it might be worth it.

Re: Go is a good fit for agents

#148
post #143

Earlier quoted context omitted.

> The following is not a list of integers Then I am not sure how you think it is an enum? What defines an enum, literally by dictionary definition, is numbering. It is hilarious to me that when enum is used in the context of looping over an array, everyone understands that it represents the index of the element. But when it comes to an enum in a language, all of a sudden some start to think it is magically something…

The existence of the ordinal method reveals nothing except that the ordinal exists. It can be (and is) simply a field on each Day object, not an index into anything (though the Day objects are probably stored in an array, this is not required by any property of the system). Day.SUNDAY is ultimately a pointer, not an int. It is also a symbolically resolved pointer, so it will never become Day.MONDAY even if I reorder…

> The existence of the ordinal method reveals nothing except that the ordinal exists.

It strongly suggests that implementation is a discriminated union, just like Rust. Again, it is tag-only in this case, where Rust allows also attaching payload, but that's still a type of discriminated union. That it is a set of integers – contrary to the claim made earlier – combined with you explaining how the compiler treats it like a discriminated union — as in that there are type checks against the union state, that does reveal that it couldn't be anything other than a discriminated union that is effectively identical to what we find in Rust, along with many other languages these days.

> It can be (and is) simply a field on each Day object, not an index into anything

So...? Enum is not staunch in exactly where the number comes from; it simply needs to number something. Indices are convenient, though, and I am not sure why you would use anything else? That doesn't necessarily mean the index will start where you think it should, of course.

For example,

    enum Foo { A, B, C }
    enum Bar { X, Y, Z } 
In some languages, the indices might "reset" for each enum [A=0, B=1, C=2, X=0, Y=1, Z=2], while in other languages it might "count from the top" [A=0, B=1, C=2, X=3, Y=4, Z=5]. But, meaningless differences aside, where else is the number going to come from? Using a random number generator would be silly.

But, humour us, how does Java produce its enums and why doesn't it use indices for that? Moreover, why did they choose to use the word `ordinal` for the method name when that literally expresses that it is the positional index?

Re: Go is a good fit for agents

#149
post #148

Earlier quoted context omitted.

The existence of the ordinal method reveals nothing except that the ordinal exists. It can be (and is) simply a field on each Day object, not an index into anything (though the Day objects are probably stored in an array, this is not required by any property of the system). Day.SUNDAY is ultimately a pointer, not an int. It is also a symbolically resolved pointer, so it will never become Day.MONDAY even if I reorder…

> The existence of the ordinal method reveals nothing except that the ordinal exists. It strongly suggests that implementation is a discriminated union, just like Rust. Again, it is tag-only in this case, where Rust allows also attaching payload, but that's still a type of discriminated union. That it is a set of integers – contrary to the claim made earlier – combined with you explaining how the compiler treats it l…

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 cannot be invoked by reflection, and the static instances shown herein can be used in a switch statement (which may reduce them to their ordinals to simplify the jump table). Each instance is ultimately a pointer, so yes it could be pulled from a sort of RNG (the allocator). As I said they are probably in an array, so it's likely that the addresses of each variant start from some semi-random base but then increase by a fixed amount (the size of a Day object). A variable of type Day stores the pointer, not the ordinal.

Now, it really seems to be in the weeds of pedantry when you start talking about discriminated unions that have only discriminants and no payload. Taking from your examples, the key point is that a Foo is not a Bar and is also not an int. Regardless of whether the variants are distinct or overlapping in their ordinals, they are not interchangeable with each other or with machine-sized integers.

Re: Go is a good fit for agents

#150
post #148

Earlier quoted context omitted.

> The existence of the ordinal method reveals nothing except that the ordinal exists. It strongly suggests that implementation is a discriminated union, just like Rust. Again, it is tag-only in this case, where Rust allows also attaching payload, but that's still a type of discriminated union. That it is a set of integers – contrary to the claim made earlier – combined with you explaining how the compiler treats it l…

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 {}
   class Bar {}
...are treated as being the same in Java, or, well any language that allows defining types of that nature. That is even the case in Go!

    type Foo int
    type Bar int

    const f Foo = iota
    const b Bar = f // compiler error on mismatched types
But what is significant to the discussion about enums is the value that drives the inner union of the class. As in, the numbers that rest beneath SUNDAY, MONDAY, TUESDAY, etc. That's the enum portion.
Post reply on HN