HN user

parley

414 karma

Software Engineer.

Posts0
Comments113
View on HN
No posts found.

You're arguing for charitable interpretations of statements by people who claimed Go didn't need generics or even that Go was better without them, saying that one should be able to change ones opinion without being called dumb. I fully agree.

Similarly, a charitable interpretation of what kubb wrote would be that they are referring to those who might have been dishonest in their defense of Go's lack of generics, which one might say kubb does indicate by using words like apologetes and zealots. The Internet is full of people who pick a team and will say dishonest things in perceived defense of it. I agree with kubb in this regard. That is the charitable interpretation of what kubb wrote, but instead you assumed kubb referred to everyone who ever voiced that opinion and suggested kubb should refocus on what kind of person they want to be.

The Internet needs more of charitable interpretations, and HN in particular. Perhaps I failed to interpret you charitably now? Nuances get lost easily in online debates... :)

This was actually more challenging to respond to than I thought it would be.

In Go (as the blog post that I linked alludes to): "The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values."

However, it is not the expectation that libraries should recover from panics they didn't start themselves. If they did, it would be very hard to panic and actually have a natural expectation that your application would exit due to that panic, which is how most Go code behaves and expects to behave.

As I wrote in another reply, neither the main goroutine/function nor spawned goroutines automatically recover from panics. They DO shut down the entire server if any code in them panics (provided that no boiler plate recovery is performed at the root of the call stack, which in itself would make it very, very hard to reason about the consistency of the data that might have been touched before panicking at any one of countless of operations in the code in the call stack).

Therefore, one might also argue: Should the entire server shutdown if any worker thread causes a panic? I do agree that it is more plausible for an HTTP request thread to do so, but not enough to change such a basic behavior. Go doesn't allow to register a global panic handler to be able to perhaps recover but also log panics in a consistent way, such that it would be applied consistently across your entire process and customizable to the preferences of the developer as to their chosen trade off between "fail fast/never continuing processing in the face of unexpected programming errors" and "an unexpected programming error occurred but I still want to continue executing and hope that nothing broke in my application".

And I do acknowledge that different developers/organizations would want to make that trade off differently, but at present it is not very convenient to do consistently. The Go creators chose not to allow global panic handles (there are a bunch of discussions about it on Google Groups and similar, and I do agree with some of the arguments in them).

Some people (myself included) might prefer that the application fails and whatever orchestration manages this application triggers an alarm with operations staff, developers, etc, without instead risking that an application keeps running and perhaps due to some invariant now being violated and data inconsistent keeps making mistakes, perhaps serious mistakes.

This of course depends a lot on what kind of application you're building and how important this is, how much uptime for partial (but potentially buggy) functionality weighs against never risking serious mistakes. I tend to think that the correctness of most software in the world is actually important these days, but I fully admit there's a scale. Go however is being used to build all kinds of software these days.

If one doesn't like that strategy, and wants to build software that recovers in other fashions then perhaps one should have a look at Erlang and its process supervisor trees, or other systems with other trade offs.

It is a genuinely hard question, I admit that. I just don't think Go's stdlib in this case chooses a position on that trade off that I like, that's all. It's all opinion, and we're all entitled to them. Thanks for asking, and forcing me to put thoughts into words!

I'm not a native English speaker, so I had to look up a definition of disingenuous to make sure I didn't misunderstand you. I promise you I'm trying to be candid with my own opinion, and not trying to deceive in any way. What would my nefarious purpose be? I'm just stating my opinion. Whether something is brittle or not is an opinion within a range to me, not an absolute. Perhaps my English is just poor. I'm sorry if you genuinely feel I was being disingenuous.

It's comically easy to just wrap the root handler, catch panics yourself, and explode. And you need to provide your own handlers anyways, which seems reasonable to me, unless you're against writing code? Yes you need to read the docs to understand what a function does. This does not require being very careful where I'm from.

Yes, it's "comically" easy to do so if you know that you need to do it. I do it. I didn't say it was hard to do. But Go prides itself on being beginner friendly, having consistent behaviors and not having many ways of doing the same thing. The main function doesn't automatically recover from panics. Spawned goroutines don't automatically recover from panics. I feel like it wouldn't be outrageous to consider this an expected behavior for someone writing Go code, as very few libraries to my knowledge recover panics they didn't start themselves. The behavior of the stdlib HTTP utils diverge from that expected behavior. I think there are tons of developers in every language who don't necessarily scour the docs but assume consistency with some behaviors that seem basic and logical. Again, opinion, if that wasn't clear.

They make this pretty clear, that you shouldn't leak the panic, in which case it's just an implementation detail. If your library is brittle, that's on the implementer. You don't have to use panics for control flow. It's just something you can do. A tool. Sure, maybe it's sharp.

Yes, they make it clear how it should be used if it is used, and I didn't claim otherwise. I also didn't claim that leaking it was the problem, but instead that maintaining invariants in the data of the library using the mechanism can be a hard thing to do, and whenever something is hard to do right it can contribute to brittle software.

I've never seen anything remotely encouraging use of panic for control flow. The blog post even states it's uncommon and unusual. I don't know how you interpreted that blog post, which reads to me as "here's how defer works", to being "you should use panic for control flow whenever possible."

Yes, I will meet you half way here. :) This particular blog post doesn't encourage it, and at the moment I can't other any of the other places I've seen it. The blog post gives an example of Go stdlib using it, and then describes how to use it in a library if it is used. My personal preference would be to offer more caution or perhaps even discouraging in that blog post, but again that is personal opinion.

Summing up, I think Go is a language that both strives to be and is beginner friendly. Diverging from consistency in basic behaviors in the stdlib is not great, sharp tools not labeled as such is not great, etc, in my opinion. I know we don't agree and that's perfectly fine. I appreciate your reply. But I'm not trying to be disingenuous.

I would offer the same criticism of them, as it's the behavior in general that I don't prefer. But of course it's perfectly fine to disagree, this is all about preferences. I like fail fast, being required to handle errors and my tools (including programming languages) to very clearly help me identify where errors can occur.

I am not a Go expert so please correct me if I'm wrong, but... The fact that the stdlib HTTP utils in Go recover from panics in handlers and provide no way of changing this via easy setting is one of the things that really annoy me. Seemingly, they consider it a backwards compatibility break since it's a behavior change that would affect all existing middleware you try to use (see e.g. https://github.com/golang/go/issues/16542). You need to provide your own error handling middleware (of which several exist).

A beginner needs to be very careful and read the docs to catch e.g. this line:

"If ServeHTTP panics, the server (the caller of ServeHTTP) assumes that the effect of the panic was isolated to the active request. It recovers the panic, logs a stack trace to the server error log, and either closes the network connection or sends an HTTP/2 RST_STREAM, depending on the HTTP protocol. To abort a handler so the client sees an interrupted response but the server doesn't log an error, panic with the value ErrAbortHandler. "

I think that is an unintuitive assumption that makes for brittle software. Also, the fact that Go kind of blesses the use of panics internally in a library (e.g. "The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values.", https://blog.golang.org/defer-panic-and-recover) makes for even more brittle software, as predicting what state a control flow interruption like panic through a call stack leaves your data in can be challenging and require great care to avoid invariants being violated. Last I checked, e.g. Rust did not allow the reuse of data owned by a panicking call stack without explicitly asserting that it is still considered valid.

I guess I'm showing my bias for languages that make it harder to make mistakes, but I don't like brittle stuff like encouraging panic-like control flow for non-exceptional situations, implicit reuse of "panicked data", missing non-exhaustive match on enums, missing enums altogether, missing sum types and pattern matching making everything from detailed error management to proper state representation more brittle, etc etc. I'll stop there and not get into the rest of the stuff.

Go is one of the languages my employer pays me to write and I will say that I have a significantly higher appreciation for it now than when I started (it IS very beginner friendly and very ergonomic in general), but I wish it would help me more to write really robust and correct software.

This does seem very interesting, at first glance. One thought:

These “scoped life-time” reference counts are used by the C++ shared_ptr⟨T⟩(calling the destructor at the end of the scope), Rust’s Rc⟨T⟩(using the Drop trait), and Nim (using a finally block to call destroy)

So Rust's non-lexical lifetimes doesn't remedy this? Meaning the actual drop of xs needing to occur at the end of the example in the beginning of section 2.2, as opposed to right after the map. I would have thought that ys borrows nothing from xs, and the drop can be inserted right after map? Perhaps it's too early in the morning for thinking for me.

Edit: As varbhat has edited their post to clarify that they indeed did not mean to say backing in an adversarial way, my post can be ignored or just read as my understanding of the space.

Apologies if I misunderstand your post, in which case you can disregard my entire post, but -- I assume you mean as in adversarial backing?

These companies use practically all of these languages but to a different extent, for different uses, and for good reasons.

I currently get paid to write C and Go but I dabble in most things, and I'm certainly the happiest when I get to write Rust and ReasonML/ReScript. Having said that, I personally think it's fair to guess that Swift will continue to shine mainly as Apple ecosystem language, Go will continue to shine mainly as network server language and Rust (and whatever follows it) will continue to grow for network servers but will also slowly seep into our shared foundational layer of software. Slowly, slowly, libraries, kernel modules, runtimes, stdlibs for other languages, frameworks, etc. This a good thing, because it slowly rids us of old C and C++ code bases that may not have kept up with the times

Yes, all of these languages are being used to write excellent CLI tools, graphical applications, etc and that's wonderful (I use many of them), but none of these languages are realistically competing to kill any of the other in any definitive way.

Now if only Go would give me sum types (ADTs), my life would be even easier :)

On Browser Tabs 6 years ago

I recently "closed" 12000+ (not a typo) tabs in one of my Firefox profiles into OneTab. In another profile I have 30+ different windows open for different projects and contexts, and I have more profiles (typically one per WM workspace which are topical).

I've tried lots of browser addons/extensions and tools over the years, but none offered proper salvation. I have a design in my head of what kind of tool I'd like, but like everyone else I have no time between work and everything else to build it.

Long ago I used to blame the tools, but these days I realize it's me. I put minimum 32 GB RAM into my boxes, and it's because of VMs and browsers.

Yours is an excellent comment, factual and even handed. As someone who had to delve into these things and had to implement e.g. a variant of MultiPaxos for work (this was before Raft existed), I agree that there is a bit of unhealthy confusion going around.

We generalize every day because everyone can't be expected to learn everything, so we abstract away, define constraints and best practices and we select our library-fied tools and apply them. We do this with operating systems, file systems, encryption, and also with distributed systems. The basics of distributed systems and their invariants and trade offs are not that hard if you give yourself time to study them properly, but when you want high performance and scale it does get Challenging.

It is important that any abstractions we make, any generalizations, constraint definitions and best practices that we expect people to read, accept and adhere to are as correct as possible without breaking that abstraction. So thank you for your comment. Please note that mine is not a pro-Paxos comment either, just one appreciating good information being spread so that people can make good choices and trade offs.

Distributed systems are hard. To paraphrase: In the data flow, no one can hear your canary msg scream.

Yeah, I'm not really plugged into the community that well but I think reasonml.org is the long term plan and that some sort of transition might be going on? I've mostly used reasonml.github.io and Bucklescript docs, but lately I've started using the Discord channel and it's very welcoming, friendly and helpful!

React developers do not understand functional programming

As some sibling comments note, this is not a fair conclusion to draw. And not that it disproves your statement, but Reacts original creator Jordan Walke wrote the first React prototype in SML. Not understanding functional programming is not on the list of things I would ascribe to him. He's a smart guy.

On a slightly different note, I'd recommend anyone try out Reason. It's slowly maturing and can be a real joy, at least compared to JS/TS.

Oh, wow. I stumbled over the thread just the other day and mechanically just read the month and day... Since it was November I somehow assumed it was recent without reacting. Thanks for the correction! Well, belated props to you then. =o)

Yes, there are a lot of us out there who use Signal and have this single missing feature as our largest pain point. My previous phone (iOS) would have been donated or sold to someone who could make better use of it, had I been able to actually get years and years of Signal conversations (with media) and memories out of it. But I can't (without prohibitive amounts of manual work), so it lies unused in a drawer waiting for the day I might.

The Signal devs don't discuss their roadmap, as is their prerogative. The result is of course that no one knows if such features are even planned, let alone worked on. Half a decade (?) of sad and frustrated forum posts and GitHub issues attest to that. I scan through them from time to time to see if there's any word.

But! There was actually a tweet from Moxie just a few weeks ago in a thread started by Matthew Green, I think, hinting that they might be working on it. It did make me a little happier. But yes, five years is a long time to wait for this feature, and we don't know for sure if or when it's coming. Me, amidst all the frustration I am very happy for the software they are giving me almost for free (I've donated a little bit).

By the way, Josh, props to you for your patience and professionalism in the debian-devel thread about librsvg the other day.

Do you mean to say that you think that the OpenSSL project feeling obliged to implement the heartbeat extension created by a standards body is significantly more to blame for causing Heartbleed than the (understandable) causes for the general quality of the OpenSSL project code base (like lack of funding, etc)?

EDIT: Clarification.

I really think that's an oversimplification.

There are always the pro and con arguments about software mono culture and there are good points on both sides, and in this case there is indeed a gigantic cost to maintaining more than one implementation -- no one is debating that. Also, an across-the-board evaluation would probably find Firefox technically inferior at the moment, although I think that's more of an interesting debate and also a measurement where I feel the gap has lessened these last few years. My disclaimer would be that I'm a long-time user of both browsers, but ethically on Mozilla's side.

However, I think the following

and to an implementation which satisfy every interests (the ones of Googles and the one of Microsoft/mozilla)

doesn't put nearly enough emphasis on exactly how different those interests are. Google's main source of income depends on user surveillance and privacy intrusions (to use some loaded wording), and while Mozilla's indirectly does too through their sources of funding the two entities have very different goals and core beliefs.

That in itself doesn't preclude sharing an implementation, but thinking that those differences won't (and don't) cause conflicts of interest that affect both the evolving of the standards and how the actual implementations work would be, I believe, a big mistake.

Just saying "ensure the respect of privacy in the chromium source code" and that they should maintain a set of patches or a "micro fork" I think ignores the level of control they will be (or rather won't be) able to exert over the Chromium code base. I don't think Opera, Brave, Microsoft, Mozilla or anyone else that decides to either be a downstream user of or active participant in Chromium will be able to keep Google from doing whatever is in their best interest with the code base. Additionally, I think keeping patch sets (that won't end up being very complicated and will slow down or put to a grinding halt independent development) won't be able to make up for the implementation differences caused by the differences in goals. Keeping patch sets can be extremely painful.

Chromium is open source and has those two main actors: opera and Microsoft.

I really apologize for my tone, but... Please. In what regard are they main actors? Certainly not to the extent that they have any significant control over the main direction of the Chromium code base or any power to stop Google from completely controlling it.

The core beliefs and goals of the entity exerting the main control over the code base matters a lot more than your post makes it sound like. And if Chromium really were the only code base able to browse the modern web, then that would also put the standardization of the World Wide Web more or less in Googles hands.

Also, for someone asking for better "intellectual riguour", you do a pretty so-so job at showing your understanding of the arguments of the people you don't agree with.

I am a paying Spotify customer since 2010 or so and have also spent countless hours developing software for personal use integrating with Spotify. I've used e.g. their old (now deprecated) C-library and now rely on the web API. Therefore I have no qualms on calling them out on some of their hypocrisy.

Many music streaming services have no API:s, and those that do have (to the best of my knowledge) worse API:s than Spotify. I'm very grateful that they provide any means of integration. However, that doesn't get them a free pass to get on as high a horse as they try.

Now for the part where I gripe. They recently created a dedicated site shaming Apple for, in part, not exposing the same internal API:s/abilities/possibilities to Spotify as they did to their own and perhaps some other third party apps. That's pretty rich.

Where is the protocol specification or available-for-everyone library for creating a Spotify Connect endpoint? Locked behind Hardware Partner Applications, NDA:s, Evaluation Agreements, New Product Applications, Device Certifications and Distribution Agreements (yes, all of those, according to their own site). Talk about subjectiveness and forcing people to jump through a thousand hoops -- like they accuse Apple of. "and final approvals for commercial usage will always be left up to the discretion of Spotify and its partners". Three cheers for transparency and a level playing field.

Where is the web API support for folders, a feature that you clearly use yourself in the desktop application? The web API has been launched for years without folder support. This feature is completely private and unavailable to others. In the GitHub issue about it that they closed with WONTFIX the motivation was in part that folder support didn't fit well into their REST API, which is some of the weakest sauce I've had in quite some time. I used your C library and I know that you implemented folders as "begin" and "end" markers in the huge, flat playlist list. Perhaps you regret that design decision, but if that makes it an expensive API call then rate limit it accordingly. Make it subject to change as you evolve. Just don't close it off and keep it private for your own apps.

Yes, I'm annoyed. I've been a loyal customer, user, developer and fan for almost a decade. They get to expose or not expose any API they like, that's their prerogative. But what they don't get to do is gripe about the subjectivity and closed off-ness of others if they don't practise what they preach. I hate hypocrisy.

If you've read this far, I apologize for spouting bile. Time to sleep, probably.

I’ll add to all the examples in this thread that the Rust (also partly of ML descent) compiler was written in OCaml until it became self hosting.

I’ll also +1 the comments about ReasonML which is very promising.

Though I suppose these are both ”language” related — just not strictly the OCaml language.

Rust 1.32 released 8 years ago

Ha, that was a superb answer, thanks! :D I'll be checking that site!

I know you may not have your fingers in this particular flower pot, so the "you" was directed at the entire Rust community. However, while we're here you still get a big personal thanks -- your Rust for Rubyists got me hooked those years back and the docs/book (1st ed and then 2nd ed with Carol) work you've done since is nothing short of amazing -- and with these latest developments I hope you find a great place to continue your work <3

Rust 1.32 released 8 years ago

I'm waiting eagerly too, thanks for all the hard work you do!

I read somewhere in all the discussions that Carl was hesitant to go all-in on futures 0.3 (those are definitely landing in std, right?) in tokio before some additional ergonomics had landed, possibly some language feature among them but I may misremember...

Do you know the list of things and possibly their tracking issues? Futures in std, async/await, etc, something something more? Would love to be able to keep track and follow along :)

You remember correctly. This is present in "A fire upon the deep" by Vinge, which is one of the best sci-fi books I have read (although I am not particularly well read). Really, that book contained several concepts (the drifting tech zones, the hive mind mechanisms, etc) that made it an amazing read. I would recommend it to anyone who appreciates sci-fi.

EDIT: I forgot to add that the book was also a Hugo Award (Best Novel) winner, which I just noticed/remembered as I took it down from my bookshelf to re-read it... =o)

I like that line of thinking.

When discussing the suitability of different programming languages I always point to the problem at hand and identifying the abstraction level the problem is at. What your problem requires you to care about and pay attention to gives this.

Ideally, solving your problem would be a one-liner in an already existing DSL created for your specific problem (domain). In reality, this rarely happens and you must have your pick beteeen everything from niche DSL:s to assembly, but the key really is identifying that problem abstraction level.

I work in a mainly C/JS shop whereas I privately prefer Rust/ReasonML. Rust would be a great fit at work, but Go would also work nicely for tons of things we do. Alas, the inertia of organizations.

Yeah, the difference in pressure required is a huge part of it! I feel that a lot with gel pens. I also really love the clear, legible lines.

Interesting about your moving on to a fountain pen. Now I feel inspired to look up that local pen expert and go do some more experimenting!

I went through so many years without bothering to find out why I hated some pens and loved some pens, until I decided to dive into the subject a bit. The type of ink and pen affects writing joy so much. I discovered that I was a gel pen kind of person and tried a bunch of different makes, so now and then I buy a big pack of Pilot Super Gel 07, and now I always have pens around that I love writing with. I'm probably going to get one or two quality gel pens too, like Parkers or similar, because now I know what I like.

I highly recommend finding out which kind of ink and pen give you the most writing joy! A simple comparison to get you started can be found on the gel pen Wikipedia page: https://en.wikipedia.org/wiki/Gel_pen

Absolutely. I've been a Rust lurker (and later user/advocate) since ~2012/2013, I think, and the visible WASM support strides being taken right now coupled with my trust in the Rust community gives me great hope for Rust on the front end.

It remains to be seen to what extent and which problems it will be suitable for, but just as Rust despite the fears of some is (again, IMHO) turning out to be ergonomic enough to write all kinds of end user apps in (although some areas are still lacking, but give it time), so too I think it might surprise people with how widely applicable it may turn out to be on the front end.

And I'm hopeful and optimistic. I feel like we're seeing some tides turn with respect to how important software correctness/robustness really is perceived to be and -- importantly -- what we're prepared to pay for it. We're still a "young" industry compared to a lot of engineering disciplines, so it's not surprising that we're still maturing with periodic waves of change. Of course, many will disagree with the direction, but for me it can't come fast enough.

Sorry, I hadn't ranted in a while, and it is Friday afternoon. =o)

Sure. I would say that Rust and ReasonML are very alike and very different at the same time, and I'll explain why I feel that. ReasonML's own docs give Rust a notable mention: "Close cousin of ours! Not garbage collected, focused on speed & safety."

They both

- have powerful static type systems with good inference.

- default to immutability, with optional mutability.

- encourage functional constructs over procedural/imperative ones.

- ADTs and exhaustive pattern matching with great ergonomics which can be used for everything from rigorous error management to unambiguous program state representation.

- have escape hatches to write "I know what I'm doing and need more wiggle room"-code, but those are clearly visible for linting/auditing/testing, as opposed to languages that allow foot guns to invisibly permeate entire code bases because the language has no clearly discernible rigorous subset that one easily and naturally can keep to.

The list of features that make them alike can be made as long as your arm, and it's basically a laundry list of features that (once internalized in the developers mind) helps one build robust, correct, maintainable software. Sure, they're not carbon copies of each other but what it comes down to is enabling and encouraging the same semantic constructs.

So where are they not alike? I would say that the one constraint that the main differences result from is the fact that ReasonML's automatic memory management is a run-time solution (garbage collection) whereas Rusts is a compile-time solution (using static analysis), coupled with Rusts focus on raw performance. Everything else about the Rust language has (IMHO) been designed with the same sound underlying values as many other languages which encourage correctness. The differences that one notes when learning Rust are really mainly just the concessions that were necessary to make to achieve compile-time automatic memory management and raw performance.

Did that help? And as always, if I'm mistaken about anything, please correct me. I'm not a PLT person.

I have, and really enjoy it. My previous go-to for frontend was TypeScript, but it wore me down. I am ridiculously productive in ReasonML with proper ADTs, (exhaustive!) pattern matching, immutability and other niceties. The superb type inference is also great for prototyping, and I could go on and on. Rust for backend and ReasonML for frontend is making me very happy these days. I think the community will only keep growing. I feel like I’m an extra in the filming of Revenge Of The MLs, and it feels great.

I use TS myself. It helped make front end development OK for me again. But man, one really misses some things.

I recently picked it up again and struggled to remember how to properly do pattern matching and exhaustive checks, until I realized that there were more hoops to jump through than at a circus convention. A friend ultimately pointed me to https://pattern-matching-with-typescript.alabor.me/ but that made me weep.

Then I remembered how I hadn't been able to figure out how to use object spread to perform variable assignments of all members from an object returned from a function, with compiler verification that no object members had been forgotten. That may be possible now, I'm not sure. I don't think it was possible last I battled with it.

Don't get me started on the ergonomics of immutables. Again, this may have improved, and no one would be happier about that than I.

But all in all I feel that TS is not what I'd like to use for front end development. However, it's where the community and development effort is at, and I feel like I could never convince my colleagues to go with BS/PS/Reason/anything else. I haven't even been able to push them from JS to TS yet.

If someone wants to show me the error of my ways, I'd love it, since I'll probably be using TS for some time to come.

That sounds interesting! Have you considered open sourcing your work?

I've been working on similar things on and off for a long time (specifically a sort of meld between Workflowy and spreadsheets, but supporting DAGs), but it takes significant effort to reach a stage where tools are useful and reliable...