From 2021 and perhaps not relevant as mux is eol?
yeah, I’ve been wondering about that. gorilla was so popular for so long, and now it’s eol. I know I’ve used it in professional projects. I guess everyone saying to just use the standard library were proved right in this scenario. Not that it’s a huge deal though, the code still works.
Fair enough, but I posted this because another article about Go routing was on the front page—and it was from 2020.
An option since that article came out is Alex Edwards’s Flow router: https://pkg.go.dev/github.com/alexedwards/flow
My immediate thought was “Doesn’t Edwards also have an article about HTTP routing in Go?” He does, and you submitted it here about a year ago. I resubmitted it now so that people can compare.
I mostly agree, but I think in some cases, this advice oversimplifies. In particular, I think if one thing really just is another thing, it may be appropriate to emphasize that.
In source code and in our wiki, I have written “The Foo product just is a deployment of our monolith that doesn’t serve normal traffic, only…”
In that sentence, “just” adds emphasis, and could be omitted, but I think the sentence is better with that emphasis.
P.S. There’s probably a syntactic/semantic distinction you could draw between the different uses of “just”, but I don’t feel up to trying to draw it.
P.S. There’s probably a syntactic/semantic distinction you could draw between the different uses of “just”, but I don’t feel up to trying to draw it.
At a quick glance, I think there’s a relatively clear distinction between just meaning simply or only and just meaning exactly or precisely. (There are also other meanings altogether. E.g., He just made it. where just means barely.) That said, I can imagine cases where it’s hard to decide exactly which use an author intends.
On a charitable take, the author means for us to (just?) remove the uses that mean simply or only and not others. If I’m reading your example correctly, I think you are using just in the sense of exactly. You’re safe. :)
There is also a nuance where “just” means “this and no more” e.g. in the Django docs:
These profile models are not special in any way - they are just Django models that happen to have a one-to-one link with a user model.
In other words, there is nothing extra going on here. Or, you might have docs that say:
To enable this feature add just the following items to your config…
Meaning, “add the following and do not be tempted to do anything extra”.
This can sometimes contrast with:
To enable this feature just add the following items to your config…
Which implies “this isn’t going to be much work, it’s simple”. A native English speaker would understand the difference instinctively, although it’s a very small word order change.
“Just” basically means “literally only”, so it’s useful in the context of well-defined jargon and precise speaking, but is generally bad when you’re trying to convey a concept in few words, because the latter requires simplification and using “just” contradicts that.
In Zen and the Art of Motorcycle Maintenance, page 232, Pirsig described “just” as “a purely pejorative term, whose logical contribution to the sentence [is] nil,” when trying to analyze its usage and meaning. The history of “just” goes back to Latin, and its various meanings are concerned with justice and belief. In general, when somebody says “just”, they are saying “I believe that…”
In your example, I would interpret you to say something like “To this technical writer’s belief, the Foo product is a special deployment of our monolith which serves … instead of normal traffic.” And then, as Pirsig notes, the first clause is non-logical and only annotates the sentence as having some distinct epistemological foundation (based on the writer’s belief rather than e.g. evidence or cultural understanding); it can be dropped.
Personally, I try to avoid “just”. It has the nature of Iago to it, along with other words like “daresay”; it’s not just a weasel word, but a potent distorter of reality.
Personally, I try to avoid “just”. It has the nature of Iago to it, along with other words like “daresay”; it’s not just a weasel word, but a potent distorter of reality.
I’m not sure if you meant this to be a joke, but notice that in the second part of your sentence you’ve used just in a meaning that is distinct from the “I believe that…” meaning that you claim is dominant. In your sentence, just means only as it often does.
More importantly, I think that Pirsig, you, and teh_codez oversimplify. Words can mean lots of distinct things, and I think we do a disservice to writers and readers if we insist on trying to reduce complex words to (just—i.e. only?) one base meaning.
In this case I actually don’t think they mean distinct things at all. It’s more of a continuum. But, zooming out, focusing on the word “just”, or even a specific sense of the word “just”, is missing the point—belittling someone’s struggle is done using words, but it is not itself words. Blaming certain words for making the reader feel bad is like blaming certain chemical elements for making people get viruses.
In this case I actually don’t think they mean distinct things at all. It’s more of a continuum.
I’m not sure what you mean by this case, but (to be very blunt) the adverb just means several distinct things. I’m not sure why several people in this thread want to insist that they know better than dictionaries what just means. It’s an odd hill to die on.
I believe your ire may be misdirected. I apologise if I gave you the impression I was one of these people. Have a nice day.
It was a joke, yes. Remember that “but” means the same thing as “and”, logically; the logical content is the same as if I were to phrase everything with the subjunctive mood.
English is not a good language and we should not suffer its historical warts.
This entire post is very confusing to me.
What do people think happens when a package’s documentation appears on pkg.go.dev? Are people using that site for package discovery? I commit go packages to git(hub|lab) in various states of usability, and pkg.go.dev renders the documentation for it. I’ve never considered them scraping my packages and putting up a page with docs to be any kind of “publishing”. What about godocs.org? Do you “publish” there separately? Several other commenter have attempted to describe the difference between pkg.go.dev and pypi/npm/etc but those are almost entirely different things in my head. pkg.go.dev is like doxygen, but fully automatic for every go package, and hosted for you by Google. Another example that was pointed out to me is docs.rs, which seems to automatically document Rust crates.
This entire post is very confusing to me.
Sorry. That means I wasn’t clear enough. To be clearer, I mistakenly assumed that pkg.go.dev was like pypi, CPAN, RubyGems, or LuaRocks. I was definitely wrong, but that’s what I thought. I also didn’t realize that pkg.go.dev was merely “like doxygen, but fully automatic for every go package.” To be honest, I’m not sure that’s a universal view (though some people have said to me that they visit pkg.go.dev mostly for documentation.) For example, @peterbourgon, in another comment here, says, “[pkg.go.dev is] a catalog of all the code that exists and can be consumed. It’s a lazy read-thru cache.” That’s not quite the same thing as automatic doxygen for all Go packages. On pkg.go.dev’s about page, they say only, “Welcome to pkg.go.dev, your source for information about Go packages and modules.” That’s probably not meant as a definitive statement of what pkg.go.dev is for. Nevertheless, it doesn’t say or suggest exactly what you or Peter say. (My point being, I’m not sure that pkg.go.dev has a single clear purpose. That’s fine, but many people seem to think otherwise. Maybe some of them are right, but I’m not sure.)
I’m not sure how much all of this matters, but I wrote the post to describe my own misunderstanding and to help prevent others from having the same confusion. I also wanted to find out what other people thought about pkg.go.dev. Thanks for your response.
I think while Peter is technically correct there, since there is a search functionality so you can technically browse it. It shouldnt be considered a curated catalog. It’s just a catalog of all go software they can find anywhere on the internet. I searched for a project of mine that is primarily in Java but has a go client, and I found not only the go clients, but also internal CI components of the main project that happen to be written in go but would never be useful by anyone outside outside the main java project.
edit: also to be clear, I don’t think your post is confusing, I’m just confused how one could arrive at the idea that they should be treated like pypi/npm/etc, since it has fairly different functionality. I suppose if no one told you that go doesnt have one of those, you could reasonably assume it worked like every other language out there.
Here are two things that I learned after I listed a Go module on pkg.go.dev. Neither was obvious to me; hopefully, this will be useful to other people too.
The pkg.go.dev site isn’t a registry that you explicitly publish your module into, or anything like that. It’s a catalog of all the code that exists and can be consumed. It’s a lazy read-thru cache. The existence of a package in that site doesn’t imply anything about it’s production-readiness or etc.
All that said, it is easy to avoid this problem (once you know to avoid it). On projects that you may share publicly in a git repository but that you don’t consider serious enough for pkg.go.dev, don’t use a proper, full import path
It is not a problem that needs to be avoided. A project that is included in pkg.go.dev doesn’t imply anything beyond existence. There is no reason to make your code unusable (as is suggested here) in order to keep it out of that index.
To put this another way, I think that there is (and should be) a significant distinction between sharing something on GitHub (or the equivalent) and sharing something on RubyGems or pkg.go.dev.
RubyGems is a registry that code authors publish to explicitly. pkg.go.dev has totally different semantics.
The pkg.go.dev site isn’t a registry that you explicitly publish your module into, or anything like that. It’s a catalog of all the code that exists and can be consumed. It’s a lazy read-thru cache.
Right. I didn’t realize that. That’s my main point at the top of the post: I was very confused about what pkg.go.dev is and how it works. For what it’s worth, I tried hard not to blame anyone but me for that misunderstanding. I’m not upset with anyone. I don’t think pkg.go.dev is doing anything evil or wrong. But I was very confused about how it works and what it is.
The existence of a package in that site doesn’t imply anything about it’s production-readiness or etc.
I also didn’t realize that many people who write Go feel this way (though not all, based on my conversations with people about this on- and offline). Here’s a (random) quote from someone on the Gopher slack, “for me, seeing something on pkg.go.dev seems to suggest some level of support or guarantee for a module” (their emphasis). This other person may also be wrong, but people definitely don’t all have the same understanding of pkg.go.dev. I wrote the post partly to work out my own understanding of the site and partly to hear what others thought. Thanks for telling me what you think.
It is not a problem that needs to be avoided. A project that is included in pkg.go.dev doesn’t imply anything beyond existence. There is no reason to make your code unusable (as is suggested here) in order to keep it out of that index.
I can only say that I disagree. Here’s one example. When I read The Go Programming Language, I took notes in markdown and wrote code for lots of the exercises. I kept all that in a git repository, and I put the repository on GItHub so that I could easily work on it both at home and at work. I made the repository public because (a) why not and (b) others had done the same and their notes and code helped me. That repository ended up on pkg.go.dev, and I wish it hadn’t. In the future, I would use the trick I mention in the post to avoid this.
I understand everything you’re saying about no implication of production-readiness and so on, but I still think it’s ridiculous for my notes on GOPL to end up on pkg.go.dev. It’s doubly ridiculous since the repo didn’t have a license that pkg.go.dev recognizes. As a result, it’s listed there permanently and the code is not visible. (Which, I guess I’m grateful for since lots of it is embarrassing code.) I could file an issue to remove the listing, but that also feels silly. Why give busy work to someone else?
but people definitely don’t all have the same understanding of pkg.go.dev.
A real problem! Which I hope this post, and the comments to it, are able to correct, at least in some small way.
I still think it’s ridiculous for my notes on GOPL to end up on pkg.go.dev. It’s doubly ridiculous since the repo didn’t have a license that pkg.go.dev recognizes. As a result, it’s listed there permanently and the code is not visible. (Which, I guess I’m grateful for since lots of it is embarrassing code.) I could file an issue to remove the listing, but that also feels silly. Why give busy work to someone else?
Anything and everything on github.com, or any other source of truth for source code, can “end up” on pkg.go.dev. What goes there isn’t really a decision that anyone makes, and isn’t something you should feel like you need to manage. The site is more infrastructure than product. It’s a special-purpose archive.org.
For what it’s worth, I agree it’s weird, and surprising. The whole philosophy behind Go modules is surprising. But the ship has sailed.
This seems weird. I was planning on building a few packages and hosting them on github to get some feedback before I get it “officially” published but looks like I need to put some hack in so that it doesn’t reflect as a relase package.
Any way to see the slack discussion? Interested in what arguments did the maintainers have.
Is a hack necessary? Can`t you just version it something like v0.0.1-alpha or put a line in the README?
If people ignore that and import your toy code into their production system anyway, it really is their own fault. Whether they found your code on Github or on pkg.go.dev is irrelevant.
I’ve been releasing Go packages on Github for years, believe me, you don’t have to worry about getting too much unwanted uptake. :-)
Any way to see the slack discussion? Interested in what arguments did the maintainers have.
If you log into the main Gophers slack (https://join.slack.com/t/gophers/shared_invite/zt-1t9iutngg-Qxwm38dbU4v8UYsaeKrrTQ) and join the pkgsite
channel, you can view the whole conversation. (It’s not a very busy channel, and the conversation was just a few days ago. Just scroll up a bit.)
Thanks for writing and sharing these. Two further links for people interested in slog.
This sounds a bit inflammatory. For the benefits of us beginners, why do you consider that those tools are the right thing and golangci-lint should be avoided?
One example: golangci-lint
includes a linter called ireturn
which warns when you return interface
types from functions. It references Rob Pike’s opinion on the proverb “Accept Interfaces Return Struct/Concrete Types”.
To which he responded
I’m not a great fan of that one. It’s subtle and tricky to explain compactly. And although popular, it’s not often easy to apply well. Plus: Why structs? There are many other concrete types in Go […] It’s very hard to be clear about where it applies, and it often doesn’t.
It’s a bit comical that this manufactured lint rule appeals to authority by linking to a Rob Pike conversation … which ultimately disagrees with the proverb that influenced the lint rule.
Linter rules are a bunch of opinions that aren’t agreed upon, while native go tools are for better or worse the “law of the land”. Nobody will ask you to love the law, but you’ll abide by it as long as it remains unchanged.
That has nothing to do with avoiding golangci-lint though. That they have a lint available doesn’t mean you have to use that lint, as can be seen by TFA disabling a bunch of them.
And that something is a compiler error doesn’t mean everyone agrees with it, just that whoever wanted it got it through before the language was published.
Furthermore the existence of go vet
completely breaks your quip by both being “a buch of opinions that aren’t agreed upon” (because it’s a linter) and “the law of the land” (because it’s a native go tool).
I’ll gladly concede that go vet
is a linter and won’t bother arguing my ill defined concept of “land law” with respect to its checks :)
However every compiler error is indisputably the law of the land. Because you can disagree with compiler errors all day long, but without changing the compiler, any argument against them is moot. There is a high barrier to changing compiler errors; in that sense they are very much law.
As I said:
you’ll abide by it as long as it remains unchanged.
there are many issues with it, however the primary problem is that it bundles an old fork of staticcheck and disables many of their default lints. it also includes a bunch of linters that don’t really do anything.
here is one of several instances I know of from the staticcheck maintainer on twitter and I don’t even pay that much attention, I’m sure if you searched golangci-lint on the staticcheck issue tracker you’d find more
I’m not the maintainer, however, I feel sympathy for him. that being said, golangci-lint isn’t doing anything wrong or illegal, it’s open source software, you’re free to use it even in ways the original author doesn’t intend or approve of. that being said, you aren’t necessarily entitled to support
Sounds like a weak way to promote own tool. Just saying.
Not a very charitable take.
I don’t know anything about the specifics of that debate, and I haven’t (yet?) noticed problems using staticcheck with golangci-lint. But when I started using golangci-lint in December of last year, I immediately noticed that the results for revive were different if I used it under golangci-lint than if I used it alone. (Briefly, revive under golangci-lint was silent where there should have been warnings.) The problem persisted, and I ended up with this note in a git commit.
At the moment, the revive and golangci configurations are separate, and
they have some overlap. They don't seem to play nicely together, and
I don't want to spend too much time debugging that now. But I should
come back to this later.
As you can imagine, I never came back to it. The only way that I can get things to work correctly is (still) that I run revive alone and then I run golangci-lint for the rest of the linters I use. That’s not the end of the world, but it does suggest to me that the staticcheck maintainer is not making things up. golangci-lint seems to alter how (some?) tools operate under it. That may make sense—or even be necessary for some reason—but it can also be a pain. I like golangci-lint a lot, but it causes some problems too.
I’ve been using slog a bit, and I like it overall. That said, I hope that slog quickly adds a simple way to adjust the call depth level to make it easier to write helper functions. E.g., something like log.Output
. At the moment, you can adjust the call depth level, but it requires a fair amount of manual knob-turning.
slog is what I’d hoped the standard lib logger would have been when I started writing go. It has a few rough edges, but I’m hopeful that it’ll be added to the standard lib after some ironing.
I’m hopeful that it’ll be added to the standard lib after some ironing
The proposal has been accepted already, and slog seems likely to enter the standard library soon (1.21?) with very few changes. See this link and here’s the initial commit to the standard library.
I’m a teacher and my school’s spring break begins this afternoon. This weekend we’re going to clean the hell out of the apartment, and I’m going to finish Let’s Go and start The Karamazov Brothers. I’ve never read it, and I’ve been looking forward to it since reading Crime and Punishment for the first time at the end of last summer.
Can a designer explain what the word “stack” means in this context?
Is this a website that showcases my OS’s fonts?
The “stack” is the sequence of typefaces that the browser will try. You prefer the first, you’ll fall back in order to the last until you find one that is present on the users machine.
Is this a website that showcases my OS’s fonts?
The site tries shows font styles that are already available on people’s computers as part of their system fonts. If you pick one of these font listings for your CSS, then you don’t need to use web fonts. In that way, this site connects with the Stop Using Web Fonts article that’s also on the front page.
Yes, but formalizing what you used to do across platforms you hadn’t considered at that time. Basically it’s helping to answer the question “how am I most likely going to get a passably similar aesthetic across the permutation space of pre-installed font choices made by disparate vendors that don’t communicate with each other and can’t agree on a standard?”
I remember fiddling extensively to get fonts to appear similar in Windows/IE4 and Linux. Windows at the time had the meticulously hinted Verdana/Georgia/Tahoma TrueType fonts, whereas Linux (I think) only supported Type1 and bitmap fonts, and certainly couldn’t do hinting. Type1 fonts didn’t look good until you increased the point size to about 12-13, which was frankly too large for a resolution of 640x480.
I didn’t have access to a Macintosh at the time, and neither did anybody I knew, or I probably would’ve included them in my attempts.
I have to say, what the author did looks very good (and certainly better than my attempts at the time). I’m just amused by the word “modern”.
Pretty sure the “modern” is just to bring the stack collections up to date with current device trends; most of the other such stack recommendations out there are several years and numerous device generations out of date. The underlying problem predates the Windows/Mac/*nix trichotomy by at least the Gutenberg Press.
Yeah, but OSs ship with a lot more built-in fonts now, and nicer ones, so you don’t have to fall back on the same old Times/Arial/Verdana/Trebuchet/Georgia set. (Ugh. The only one of those I can still stand is Georgia.)
In this case, it’s just a list of operating system native fonts to use for similarish appearances. You can see more detail at the GitHub page: https://github.com/system-fonts/modern-font-stacks.
I’m not sure if anyone is following this thread anymore, but slog has officially been accepted into the standard library.
https://github.com/golang/go/issues/56345#issuecomment-1470506816
For people who want to use system fonts with different looks, here’s a useful site: https://github.com/system-fonts/modern-font-stacks.
I have very much the same point of view. After 10+ years of using only Apple’s ecosystem, their current CEO managed to “break” me and forced me to move to FreeBSD+Linux workstations. There’s just too many hostile UI/UX changes shipped with security patches and Apple for some years now doesn’t feel user-friendly (at least not power user-friendly), but only investor-friendly.
Their support’s responses to feedbacks and bug reports phrased like “the feature works as intended” shows lack of concern for users’ experience.
Sneaking changes in the user/vendor power relationship into security patches is the ultimate in cynical perversion.
As I get older, I do find that it’s more likely that any change to software is a change in a direction I don’t like, because by now I’ve set up a system that works for me.
I agree with this, and for me at least it goes even a bit further. I can often recognize the value in something new, but I still may not want to start using it. As an example, neovim has a ton of IDE-style abilities (powered by LSP) that part of me thinks are probably objectively good and helpful, but that I never use. Why not? Because it feels like I would have to effectively relearn how to use my editor, and I do not want that. I guess my real point is that “a direction I don’t like” can often involve something I don’t like (overall) even though I recognize its value and (sometimes) even regret that I’m not more flexible.
There’s just too much new stuff coming out, this industry moves too fast. At least when you’re a bit older you learn to pretty effectively dismiss silly stuff as such. And even then occasionally something cool comes out but you don’t have the time and energy to learn it. So you file it away, knowing it may one day be a useful tool (hopefully not forgetting that “there was this thing” when the time comes that you need it).
Of course, once in a while you still get blindsided, and the “silly thing” was actually useful and takes over the world (e.g. I dismissed React based on one failed experiment, and dismissed git for having a shitty UI). And other times you do invest a lot of time into something promising and clearly superior to other options, only to see it get ignored and dismissed by others and it fades into obscurity (like in my case Git’s contemporary DVCS competitors, NetBSD, Scheme).
But you have to manage your energy in some way by investing time strategically, or you’ll burn out. For me, I’m fortunate that I spent so much of my younger years “believing in” Open Source and Linux over proprietary software and Windows/.NET, and later PostgreSQL over MySQL. Those choices paid off dividends (although being too dogmatic probably also cost me a lot of opportunities at the start of my career - in some way it’s better to be a bit more pragmatic and invest time when something you already deem good appears to be growing more popular).
I’m in a bit of a middle ground at the moment, using macOS/iOS/iPadOS on my laptop and mobile devices, with a reasonably powerful PC running Gentoo (and some scripts to spin up short-lived spot instances on AWS) that I can remote into when I need Linux.
I like the hardware, and the level of integration when you have multiple Apple products (yes, yes, “you can already build such a system yourself quite trivially by getting an FTP account, mounting it locally with curlftpfs, and then using SVN or CVS on the mounted filesystem” /s). Fortunately, I’ve been lucky enough that recent UI changes haven’t impacted my workflow much.
From the top of my head:
/Applications
and considered them safe but Apple modified them during one of system updates.I switched from macOS some time after the 2017 MBP keyboard fiasco and don’t remember workflow-disrupting UI changes in macOS but as I still use an iPhone, I can mention “rich” text mode in Mail, Notes and several other apps which unnecessarily occupy screen space, “search” button on the screen while swipe down still has the same functionality, unnaturally over-tweaked pictures (3rd party app can be used to access “raw” versions), inability to switch off “volume to loud” in many world regions (Apple’s headphones have good upper volume level but for example JBL are more silent) and this is really the “top of my head” list of things.
M1 has great performance and battery though and I’m considering buying M1/M2/M3(?) when Asahi Linux will support all of its hardware well.
git jump is an optional tool that ships with Git in its contrib directory. git jump wraps other Git commands, like git grep and feeds their results into Vim’s quickfix list. This makes it possible to write something like git jump grep foo and have Vim be able to quickly navigate between all matches of “foo” in your project.
I’m an Emacs user, but can’t you use git grep directly in vim by setting grepprg? ie. :set greprg git\ grep
. It seems the jump merge and diff commands are the ones that are more valuable.
You would need to set grepprg
to (e.g.) grepprg=git\ grep\ -n\ --column
, but you probably wouldn’t want that all the time (only when working in git repositories and even then only in some circumstances). At other times, you’d probably want to set grepprg
to something else (e.g., I set mine to ripgrep). So even for grep, git jump
may be a helpful convenience.
While we are (sort of) on the subject, this gist has an excellent (and very small) set of tweaks to make grep
work better in {neo,}vim.
I’ve used Vim since I started programming in around 2005, but I switched to Neovim (for good) about three years ago. I don’t use LSP (I find it a bit hyper-active) or autocompletion plugins, but I much prefer Lua to Vimscript. The biggest adjustment was moving from Ultisnips to nvim-snippy. You can absolutely use Ultisnips with Neovim, but it depends on Python, and I didn’t want that dependency anymore. nvim-snippy is on the lighter side for a snippet plugin, but I’ve come to like that. It does 90% of what I want, and I can understand it. (By comparison, LuaSnip, which does a ton more than nvim-snippy, but I found it difficult to work with. In fairness, LuaSnip was changing very rapidly when I tried it, so I should probably try it again sometime.)
Obligatory dotfiles:
For learning how to do web servers with Golang, I found Let’s Go and Let’s Go Further by Alex Edwards both very good. The way he iteratively adds to programs, and inline-comments the changed parts with change reasoning and background is what I found more unique in these books.
I second this. I’m reading Let’s Go now, and so far it’s great.
Has anyone tried Writing an Interpreter in Go or Writing a Compiler in Go by Thorsten Bell? They look interesting, but I’d be curious to hear more about them.
There’s an additional issue that I only realized recently. You have to add t.Parallel()
twice if you use the (common) idiom of table-driven tests and sub-tests. E.g.
func TestReverseRight(t *testing.T) {
t.Parallel()
for msg, tc := range testCases {
tc := tc
t.Run(msg, func(t *testing.T) {
t.Parallel()
// Actual test code…
})
}
}
See also: https://go.googlesource.com/proposal/+/master/design/60078-loopvar.md