classic example of how #golang does #composition better than any other language

took me all of about 30 minutes to completely refactor #realy to separate the "filter" out of the filter type, which i achived by extracting the fields (kinds/authors/tags/since/until) from the existing plain muddled "filter" structure

it is now called `simple.Filter` and the reason for doing this was to make a single structure that embeds elsewhere that is the primary parameters for an actual `/filter` request on the simplified nostr HTTP API

now i have a full interface composed of single APIs so i can treat them as a whole or separately... it was an important step on the path to implementing a full simplified API

i did add a `/subscribe-fulltext` endpoint to distinguish between the words-and-filter distinction instead of repeating the same mistake of making "optional" things when i want them to be extensions

continuing...

Reply to this note

Please Login to reply.

Discussion

yes, i'm not 100% certain this is all 100% to be honest but there is no errors and the relay seems to be behaving exactly as it was before, as it should be

so this is great, anyway, it means i can write code that handles this part of it, which i probably already wrote, and just move it into separate functions, and this becomes the simplified API and the legacy API just uses that code as part of its process

the same will happen to the event request as well

just to clarify

when you "embed" a struct in another struct in golang, pointer or directly, the methods associated with the type also become accessible from the type that has the new embedding

additionally, code that accessed those same fields that now are part of the embedded struct, have no change in syntax unless there is a conflict with another field name (which basically can't happen)

so the process of popping out a subset of a struct into a new struct is absurdly simple and smooth in #golang

no other language makes this as easy

go did this very well

i like clojure's protoypes better 🫣

go has closures as well, and prototypes smell objecty to me

what? how?

how do prototypes differ from interfaces and structures (named ordered lists of variables)

not that much in go a lot in other languages.

The biggest difference would be that they are explict (that's not something I'd assume you see as an advantage) and dynamic.

The biggest advatage (at least for me) is that you can implement protocols on types you don't own. Not by modifying or embedding them.

ok so they are just another silly name for interfaces, but trying to say they are not interfaces

you can do that now with interfaces with generic parameters in Go since 1.24, this "prototypes" thing

it's a relaxing of a rule that you can't define external (not in package) methods on a type, you can now define methods on a type alias

i barely even use generics in Go yet, mainly i just use it to make it so people can call my code with strings but my internal implementations remain in mutable bytes. they won't retract the mistake of making strings immutable

rust's immutable by default is exactly the opposite of how i think it should be done, and the immutables in Go are the biggest pressure on GC because you can't just make them into freelist buffers, they are immutable, they have to be disposed with the GC unless you want to dice with unsafe

also, in Go, effectively declaring a type is creating a prototype, because you can embed them in other types, you can alias them into new types, and now you can even declare new methods on the aliased type

Go lets you do all the things that you need, and rejects all the things you don't, in the overriding prime directive that no construct should be expensive to compile, or execute.

It's little bit apple and oranges because clojure is a dynamic and hosted language. Prototype do not compile. They don't actually need AOT neither. But protocols are way faster because they dispatches on a first argument not on arbitrary one as in case of multimethod.

so again, that's the point, they are just a double indirection like an interface, a static type abstraction, just as it is cheap to resolve a pointer it is cheap to resolve the "fat pointer" of type and variable in an interface

it's just an interface

they muddy the waters by inventing new names for well established concepts

type aliases were a huge step forward.

Go with aliases (2017?) and it's implicit interfaces allows you similar things like protocols. It's not very common in other languages.

Clojure was out there before go (2007) and they also need to distinguish between hosted (jvm) interfaces and clojure's solution to expression problem.

I'm more in FP and go was very hard to use that way. I'm simply like protocols more. And also use go for different applications.