Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Currently not, as I only used it in smaller projects in the past.

In the future I’ll use it likely with QuasselDroid-NG, an app of mine that’s very early in development, and for which I developed it.

The use case there is that we have a list of IRC messages, constantly updating and adding messages at any point of the list, and we want to update the UI and animate.

The client can also cache, or preload, messages at any point, or throw them away.

Additionally, users can filter, search, or choose to disable some messages.

Other messages might get merged, or synthetic ones inserted.

So I have a backing store of messages that can constantly change, I have on top of that a stream of transformations taking part, and on top of that an interface presenting a single, consistent Java List, but also triggering the relevant updates on Android’s recyclerview.

Most importantly, you can just add a message to the lowest list, it will be properly filtered, transformed, animated, and displayed, and this properly threadsafe across UI thread, backend thread, and filtering threadpool, while being faster than the solutions Realms and co provide for such updated UI.



I'm not sure if I understand, are you actually using Go for your UI backing or using it as a backend for your application?


The application described above is Java. Runs on Android and desktop Java with JavaFX.

I tried to reimplement the desktop version with Go, due to native UI bindings. And failed.


Well, I don't see any problems with the logic part. Receiving, filtering, transforming, and notifying someone else about incoming messages (would probably do it in a few threads, sending messages between each other).

For the UI part: no wonder, Go, at least currently, is useless for UI's.


> (would probably do it in a few threads, sending messages between each other).

The problem is that I try to abstract these things away – in Java, I have a general framework, and just do

    var c = new ObservableCollection<Message>();
    var f = new AsyncObservableFilter<Message>();
    f.setSource(c);
    f.addFilter(new DayChangeMessageFilter());
    f.addFilter(new CollapseJoinLeaveMessageFilter());
    f.addFilter(new RemoveIgnoredMessagesFilter());
    var adapter = new ObservableAdapter<Message, MessageViewHolder>();
    adapter.setCollection(f.getResultCollection());
and then I can do

    c.add(new Message(new Date(), "cube2222", "Well, I don't see any problems with the logic part."));
And this works for any type – I can use the same code for observable collections of IRC networks, of channels, etc. And I do use them for that. And if I change the filters, it also does the minimum amount of work necessary to update the list, and not a single CPU cycle more.

I’m using it with over 11 different types in the Java version, and I’d have to maintain 11 identical, but with different types, versions in the Go version.

You can understand how much of a pain in the ass this is.

Oh, btw, this also abstracts away the entire thread handling, while still doing it in a reasonable way.

And the backing collection doesn’t have to be a normal ObservableCollection storing data in memory – I also have ones using SQLite as backend, or caches, and I have the ability to add listeners for scrolling up or down to load or unload data as well, if it’s not needed anymore.

In Go, I’d manually have to reify all these, and if I find a bug in one, I’d have to update all of the others, too.


Of course I can't say for 100% as I don't know your codebase. But I think you could easily do this with Message being an interface defining the common functionality of your messages (like, probably, render(), timestamp(), id()). Then you could just have you DayChangeFilter use the timestamp, joinleave do a type assertion, removeignored check for the id.

If the genericism for you is also abstracting away the source of the messages -> in Go you just usually abstract sources as io.Readers.

All filters can easily be an intermediate channel which only sends further proper messages. Or just write a filter(func (m Message) bool) function which abstracts that away.

Though I understand you may want to use your Reactive collections and streams, this isn't really a case for Go.

Have I understood your use-case correctly?


See, the problem is that "message" is only used in this one place.

In another place, I use there a type such as network, and the filters are entirely different ones.

In yet another place, I use even other types.

The types used there have nothing in common, nor do the filters.


Ok sorry, I thought the unit of generic'ness you mean is the message. You're basically just talking about generic custom collections. Yeah, it is a thing you won't get in Go. And you'll have to write it every time again.

I'm usually just writing custom ones for each case, takes just a little bit more work. If I need more genericness, as I said, I use Java/Scala/F#

EDIT: In theory you can hack this all together using interface{}, but I wouldn't do that, it's a hack and ignores the type safety of the language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: