Hacker Newsnew | past | comments | ask | show | jobs | submit | silverwind's commentslogin

It's quite a lot wider and thicker than a mini, and imho looks quite ugly when folded, I don't see the appeal as a single-handed device.

Yeah, the UI is the real and only reason to use Nitter. It's a very similar situation with old reddit.

Since a couple of weeks they force you to login to use old.reddit.

My visits have dropped by about 95%


You can use www.reddit.com (yes, this domain, not old.reddit.com) with the old UI if you set cookie "redesign_optout=true".

Thanks for that tip. Works like a charm.

Use Redlib [1] or one of the other alternative Reddit frontends.

[1] https://github.com/redlib-org/redlib


At that point though, it's like why. Reddit is, well, trash. It's barely worth visiting without an account, and if you're going to make me jump through hoops to visit, it's time to accept the message of "we don't want you here" and go somewhere else.

If you're browsing Reddit for its front page, yes, that's trash. But it can be a great source for getting information on narrow, specific topics on well-moderated subreddits filled with enthusiastic and obsessive people eager to share their knowledge. It's been very helpful for me when researching coffee grinders, refrigerators, solar battery backups, headphones, and other such things.

The reason to use it is that Reddit does provide the occasional answer to questions like "how to get a Samsung SCX 3400 to run on a Raspberry Pi" (etc.).

All those have been ingested by chatgpt, which ironically provides a better user experience.

Now all that's missing is Chatlib, a self-hosted proxy for ChatGPT which makes it possible to a) query the service without leaving a personally identifiable trace and b) separate out the facts from the dreamt-up fiction. Using Redlib I at least get to see the original posts which makes it easier to separate fact from fiction.

I've been making money from reddit, and for about a decade and a half and at this point, why bother? It's basically drained and what remains is of zero value.

Redreader still works on android.

Though, reddit's been infected by you tubers and clankers to the point that it's basically useless.


Reddit infected by Youtubers sounds like pest getting cholera, i.e. Reddit did not need an infection to be a bot-infested cesspit.

It sure didn't help any. People that get their info from YouTube tend to be morons with zero reading comprehension.

The same is and has been true for Reddit for a long time, the difference lies mostly in the ideological sauce flavouring these places, i.e. Little-endians vs. Big-endians. If you're a Reddit-endian you'll despise the Tube-endians and vice versa.

https://addons.mozilla.org/en-US/firefox/addon/old-reddit-re...

works for now. it's no longer just a redirect.

in the week or so it didn't function, I used https://photon-reddit.com/


Same, it’s been nice if I’m honest, them doing something to old.reddit.com was always going to be the final straw.

Outside this place it was the last of the “social” media’s I used.


Old reddit redirect extension

The only reason to use nitter is that for whatever reason twitter allows it access to its api. The UI is terrible and completely irrelevant.

I could use it without an account and know that any comment I clicked into would take me to the thread of posts under it without sponsored ads or posts.

The reason is that every copy of Nitter has a list of account tokens to log in with, and pretends to be a human using those accounts.

>the UI is the real and only reason to use Nitter.

Why is not wanting to share my reading habits with Elon not a real reason?


Isn't that basically AsyncGenerator?

Not really, that still yields on every invocation

It's possible to drive them hard enough to really read everything, but you have to go really hard on them with many many cycles.


Those benchmarks don't tell much, they only check if a problem was solved, not how. Also there's surely a lot of benchmaxxing going on in the model training.


There are no EU instances of GitHub, it's all in the US only.


More importantly: Once Anthropic is gone, all knowlege is lost.


It will probably be actioned off in the bankruptcy proceedings.


That’s an interesting angle. There’s probably some property value (though maybe not enough based on volume) to the books they purchased. I doubt there’s any value to the “backups” of those books. I’d imagine they’re normally transferable.


They cut the bindings off and feed loose leaf books through a document scanner. It would be difficult to store and probably unsellable, it's probably going in the trash.

To legally retain these scans, you must own the original book. You can sell or give away the original book (sans binding) but it's legally dubious as to whether the scan can be transferred along with it. So if Anthropic has no interest in storing thousands of loose leaf books, they are likely destroying both the original and scan as soon as possible.

At the end of the day, the only thing of value Anthropic has is the trained model which is definitely transferable.


It's already been distilled.


Most models are trained to be as "helpful" as possible which may work for a chatbot but not for code.


Changing output style shouldn't affect thinking at all.


Tell that to all the CLAUDE.md lines across dozens of repos I have to write to get them to understand that git commit standards and PR description standards are different.


It's sad that such basic stuff took this long. If we're lucky we might even see a `Map` function in our lifetimes.


The beauty of go is YAGNI. Language design makes it much harder for people so do stupid and cute things.

During my design process if I start realizing that I’m missing maps, More expressive Types, Or more complex polymorphism. I ask myself if I really need those things.

If I really do. I move off of go.

That’s the beauty of the language. Go does not need more complicated language features because it’s can handle the majority of trivial software work without unnecessary complexity.

The language does not need to solve complicated problems.


Ok, and what if you realize you want these things a million lines in? Do you still move off of Go?

Generic programming isn’t some fancy research language feature like dependent types. It’s just a bare minimum feature in any modern typed language.

It’s perplexing that after C# and Java both notably shipped without generics initially then added them later that they decided to ship Go without generics.. only to end up adding them later.


I guess it's possible that C# and Java taught the wrong lesson (you can add this later) and that actually reduced the impetus to ensure Go shipped generics in 1.0

It is also entirely fair to say there's a lot of complexity here and so there's a risk you exceed your complexity budget which for Go as I understand it was very slim. It is a possible a Go 1.0 with more generics doesn't take off because too many people bounce off the extra complexity and so a decade later it's an obscure thing Google made once that has a few fans but not much adoption.

Or that extra complexity means Go 1.0 ships five years later, after Rust 1.0 has given people an appetite for better performance and better safety and its sharpest corners have already been knocked off.


From what I've seen, I don't think the core Go team was ignoring the lessons of Java or C#.

Here's a sample quote from Russ Cox from 11 years ago on this site: [1]

We have spoken to a few true experts in Java generics and each of them has said roughly the same thing: be very careful, it's not as easy as it looks, and you're stuck with all the mistakes you make. As a demonstration, skim through most of http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.ht... and see how long before you start to think "was this really the best way to do this?"

And of course, they asked other experts for help, including Philip Wadler (of Featherweight Java and Haskell fame): [2] [3]

We’ve been thinking about generics since work on Go began, and we wrote and rejected our first concrete design in 2010. We wrote and rejected three more designs by the end of 2013. Four abandoned experiments, but not failed experiments, We learned from them, [...]

Last year [2018] we started exploring and experimenting again, and we presented a new design [...] and we’ve been working with programming language theory experts to understand the design better.

[1] https://news.ycombinator.com/item?id=9622417

[2] https://go.dev/blog/experiment

[3] https://go.dev/blog/generics-next-step#acknowledgements


FWIW, C# generics are way better (ergonomics) than the Java ones (due to type erasure), so Java waited too much. History is more complicated though for Java, since it was either having some generics vs having none. See [this](https://softwareengineering.stackexchange.com/questions/1766...) for a lengthier discussion.


Yes, .NET had the benefit of coming second and using F#, which was originally essentially OCaml 4 on .NET, as it's testing grounds. Same for Async

I am considering .NET for one of my compilers backends because of the reified generics. .NET can even pass around an object with generic methods that get specialized via JIT at runtime each time it sees a new data type (with reference types sharing implementations). Which also ties back to having true value types

It's a shame it took so long for .NET core to come around because even today the platform carries a reputation for being windows first which hasn't really been true for many years now


C# was meant to have generics in day one, but it didn’t make the cut and it was introduced on the next version (2.0)


People always forget this other post when arguing for the home team.

"They are likely the two most difficult parts of any design for parametric polymorphism. In retrospect, we were biased too much by experience with C++ without concepts and Java generics. We would have been well-served to spend more time with CLU and C++ concepts earlier."

https://go.googlesource.com/proposal/+/master/design/go2draf...


FWIW, I do remember that quote.

It doesn't seem particularly damning to me, though, especially written by Russ Cox in hindsight. It's almost a truism that if you had spent less time on approaches that didn't pan out and more time on approaches that did eventually pan out, you likely would have arrived at a workable solution sooner.

For example, if the core Go team had spent more time exploring C#-like approaches (as some suggest they should have), it's possible that would have delayed the whole thing.

(btw, consider me a "long time listener, first time caller" -- I pretty much always pause to read your comments while flicking through discussions here, including I appreciate you often bring in historical context, even if I might have a different take, or even if I might have expressed your take differently ;)


Maybe at some point it may even get the ternary conditional operator or a proper exception handling syntax.

Those things that Golang defenders say "dont make sense" until it's implemented, then 'it always made sense" and of course it's a good idea.


I'd welcome the ternary conditional operator but I hope exception handling never gets introduced (at least as I'm used to it from Java, C#, JS, etc.).

Exceptions should not be conflated with regular error handling, especially when they're allowed to bubble up from anywhere. I very much appreciate that functions that can return errors force the caller to deal with them, for the most part. True exceptions can already be thrown with panic, although I actually find it incredibly rare that I need to reach for that tool. I'd argue that when people talk about exceptions they almost always actually want "unhappy path" error handling.

Now, if Go wanted to add a sleeker way to handle those errors, similar to Rust's approach, I'd be very interested. Minimum three lines for every call to a function that returns an error does get a bit verbose, arguably hurting readability. A little sugar could improve readability without making error handling implicit.


Usually, if you're in microservices land, it's often possible to spin off a separate service and move the part that has different requirements over. Obviously that isn't always trivial, but service boundaries at least give you that option.

I had a team convinced that a particular subsystem was a mess and that they needed a stronger type system to build it properly because Go would just lead to hacks. They built a better one in Rust, deployed it, and moved traffic over.

Ditto, to some extent, if you're building desktop applications. Many large desktop applications already have multiple components or processes under the hood, and if you're at millions of lines, introducing that complexity may be worth it.

However, not all programs fit the above category. Sometimes you really do need a single lightweight binary and it needs to do a lot of stuff. But I think it's relatively uncommon to need one single binary that is simultaneously very large, architecturally diverse, and unable to delegate substantial complexity to other processes or services.

I see this most in the Kubernetes world, where something that starts as a simple binary gradually increases in scope and complexity. I've seen vendors struggle to keep up and start playing whack-a-mole with that complexity, but generally Go still scales surprisingly well here. Outside of K8s, there are also domains where you may strongly prefer a single-process or single-binary application, such as edge computing or developer tools.

Luckily, products where Go excels in these spaces also tend to have a natural upper bound on their domain complexity, because the operating model is generally about doing one or a few things well.

If Go's type system actually starts fighting you rather than merely being an inconvenience, then yeah, I would seriously look into moving off Go.

If you're working in a space that doesn't fit any of the above, I'd genuinely be interested in hearing about what you're building.


So your argument is that they should have gotten it exactly right first time and stuck to their guns?

I mean come on. The Golang team created a useful language people use for building real things — it’s easy to work with especially on large teams, and when the lack of generics turned out to be a pain point in the end (after years of production reality) they understood what the community wanted and actually… added them..

Now what, it’s not good enough?

No one forced you to use go.

No programming language is perfect. I personally find the language has served me well.

And after being so very pro generics myself, i actually find myself not even really using them that much apart from calling the slices module etc which has them under the hood anyway…


Nope, I’m saying that the language that was seemingly designed with either an ignorance of or disdain for the hard-won lessons from decades of prior programming languages.

There was even this condescending attitude that Google engineers couldn’t understand fancy languages anyway, so they had to dumb Go down.

My criticism really isn’t even about Go itself. Yeah it’s improving, which is great.

My criticism is about this anti-intellectual attitude that has permeated the entire Go community since its inception. It’s like hearing that college is a waste of time from people who never graduated high school.


my criticism is that if we make every language identical, we might as well only have one language. (C++, obviously)

There is room for a language without generics. There was a language without generics. Now there is not.


Well here’s the thing on generics. Go always had generics since the very beginning. It’s just that only certain built-in types had them.

Slices, maps, and channels all were generic from day one. Same with functions like append, copy, etc.

Your criticism makes no sense unless you think Go shouldn’t have had generics from the start, which it did.


I think when people mention generics, they don’t mean builtins from the language but a language construct for generics.


By that logic C has generics because pointers are a generic type - you can have a pointer to any type you want.


Sure, lots of languages have some level of parametric type support.

This is just basic programming stuff and not limited to esoteric research languages.

Yet so many in the Go community treated it as some kind of language-ruining complexity.


Go only took off thanks to Docker pivot from Python into Go, and Kubernetes from Java into Go, after the respective teams got some Go folks into the project.

The usual RIX approach, followed the whole devops hype cycle that created all those CNCF projects half of which no one in devops space actually knows they exist.


And the kubernetes code and APIs still read like corporate Java for years after, too


Which kind of shows the outcome of devs being pushed to use the wrong tool for the job.

Alone the code generation machinery that Kubernetes used to have for working around lack of generics.


This. One should never pick a language that regresses in terms of features from the get go.


Map function leads to poor code in Go. Function literals are verbose and inlining is far less agressive. It simply isn't the way of the language. Even python shuns map and filter in favor of comprehensions. A for loop is more readable than the lambda soup.


> A for loop is more readable than the lambda soup.

Let's assume you have a slice of strings you want to uppercase. Which of the following is more readable?

    uppercased := slices.Map(inputSlice, strings.ToUpper)
    // or
    uppercased := make([]string, 0, len(inputSlice))
    for _, s := range inputSlice {
      uppercased = append(uppercased, strings.ToUpper(s))
    }
Let's say you want to parse a bunch of user-given inputs into durations, surely the following is more readable?

    parsed, err := slices.MapErr(inputstrings, time.ParseDuration)
I think map functions lead to cleaner code when used like the above, and a lot of for loops end up falling into those patterns.


I think in a language designed around FP ergonomics and expectations there's a lot to like about it.

In your second example, as a retrofit, I find myself asking "when does MapErr stop consuming the input list?", "which error gets returned if multiple errors could be returned?", "is it a errors.Joim situation", "if there are multiple errors how do I map them to the failed elements in parsed", "if I did want each parse to have either success or fail (think Result type) how would I represent this generically in a language that favours multiple return types"

There's a lot going on with that example that a for loop makes explicit and flexible for other choices.


IMO it depends on the language… to me, map/collect/etc are useful in languages that have the concept of immutable data, because you can initialize an array with a single call chain, and be sure that nothing after that can modify it.

What I’ve seen in the “for loop” approach that I can’t stand, are things like (pseudo code)

  var a = []
  for x in coll1 {
    a.push(foo(x))
  }

  do_stuff_with(a)

  // … further down the function

  for y in coll2 {
    a.push(bar(y))
  }

  do_other_stuff_with(a)
Reading code like that, is the first call to do_stuff_with(a) a bug, because it’s not fully built from both coll1 and coll2 yet? Or is the second call to do_other_stuff_with(a) a bug because a now contains more stuff than the developer probably thought? Can I safely move both loops next to each other, or does that break something subtle? If I need to pass a to a new function, where can I safely do this? Before or after I add from coll2? (In my actual times seeing this, a is really a map of cached key/values or something, and it’s kinda ok that the contents were different each time it was used, but subtle bugs emerged…)

IMO the sane way to do it is to just not incrementally mutate things like that, and stick with giving things a single place where they’re defined and initialized. Go doesn’t really help you here because there’s no such thing as immutable data. So just adding Map/collect or whatever doesn’t really buy you much.


Often the mutation might have performance benefits.

Of course if you're Rust the stdlib and compiler might conspire to optimise an operation you wrote which reads as non-mutating into an actual mutation which was faster.

This is another benefit of the "destructive move". If I consume X and spit out Y, the X is gone, so it's OK if secretly I just mutate X and tell you that's Y now.


map functions are very useful for iterating over collections. Most functions iterating over collections are useful, because a lot of the data you're commonly dealing with is collections. And most collections are generic.

> Function literals are verbose and inlining is far less agressive.

> Even python shuns map and filter in favor of comprehensions.

That's the problem of the language design. And Python isn't the best language to turn to for language design

> A for loop is more readable than the lambda soup.

A for loop shoving modified items into a temp variable with append() that is then returned is less readable than a map function transforming data. Too bad Go decided to turn lambdas into unreadable soup.


Python uses comprehensions because whitespace sensitivity was a horrendous language decision, then couldn’t find a way to support multiline lambdas.

Comprehensions are not a well-designed feature but a consequence of poor design.


Nope, as someone there at the time, they are an influence how language like Haskell do them.

Which by the way has no issues being whitespace sensitive and having multiline lambdas.

The only reason Python doesn't support them is Guido not wanting to have them.


Comprehensions are way cleaner and more optimizable for the common case.


This is also why people eventually leave languages. Satisfy everyone’s wishes for long enough and you get lots of different styles of doing things and … «wow look at that much simpler language over there; let’s try that instead»


Go's whole philosophy was to keep the language simple. It's a shame they're abandoning that now and becoming the next C++/Zig/Rust/Java


Those who held that philosophy (Thompson, Pike) are now retired. Those who still have careers ahead of them want to have something to do.

The natural consequence of a "bullshit job" economy.


They threw many babies out with the bathwater chasing yhe rather unspecified "simplicity" and making parts of the lsngusge more complex to use as a result.


Turns out programming languages are complex for a reason.


But diversity is good. If I want C++, I already know where to find it.


The fallacy of "simple" languages is not understanding the history of programming languages, why and how they grow with the community, assuming they get any adoption at all.

No one among the folks that created Scheme or C, would assert R7RS or C23 are that simple.


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

Search: