It sits, like a hat, on top of the variables that it protects. So, without needing to write the comment, the above is implicitly understood to be equivalent to:
Ideally, the language would protect you by putting the protected things inside the Mutex, so that it’s not possible to accidentally use them without going through the Mutex:
But yeah, if that’s going to be enforced by developers being careful instead, make it as clear as possible with explicit comments. As casperin said, better to also write doc comments on the protected fields so that they show up in autocomplete!
yeah, this is one of those awful consequences of go not having generics for so long. at my work (a go shop) we have many packages that just wrap a bunch of old standard library stuff with safer generics based equivalents.
hopefully eventually the standard library will all be updated and the old versions will be deprecated.
I was completely surprised that the comment included the second field. It doesn’t even share the name. I would put a doc comment (does Go have those?) on both the protected fields so they at least show up in the editor when you auto complete.
I disagree with this, only because it’s imperialism. I’m British, in British English I write marshalling (with two of the letter l), sanitising (-sing instead of -zing except for words ending in a z), and -ise instead of -ize, among other things. You wouldn’t demand an Arabic developer to write all his comments in English for your sake for the sake of being idiomatic, would you?
I’ve worked for a few companies in Germany now, about half of them with their operating language being in German. All of them had comments being written exclusively in English. I don’t know how that is in other countries, but I get the impression from Europeans that this is pretty standard.
That said, my own preference is for American English for code (i.e. variable names, class names, etc), but British English for comments, commit messages, pull requests, etc. That’s because the names are part of the shared codebase and therefore standardised, but the comments and commit messages are specifically from me. As long as everyone can understand my British English, then I don’t think there’s much of a problem.
EDIT: That said, most of these suggestions feel more on the pedantic end of the spectrum as far as advice goes, and I would take some of this with a pinch of salt. In particular, when style suggestions like “I tend to write xyz” become “do this”, then I start to raise eyebrows at the usefulness of a particular style guide.
All of them had comments being written exclusively in English. I don’t know how that is in other countries, but I get the impression from Europeans that this is pretty standard.
Developers in China seem to prefer Chinese to English. When ECharts was first open-sourced by Baidu most of the inline comments (and the entire README) were in Chinese:
In Japan I feel like the tech industry is associated with English, and corporate codebases seem to use mostly English in documentation. However, many people’s personal projects have all the comments/docs in Japanese.
If someone wants to force everyone to spell something the same within a language they should make sure it’s spelled wrong in all varieties, like with HTTP’s ‘referer’.
The Go core developers feel so strongly about their speling that they’re wiling to change the names of constants from other APIs.
The gRPC protocol contains a status code enum (https://grpc.io/docs/guides/status-codes/), one of which is CANCELLED. Every gRPC library uses that spelling except for go-grpc, which spells it Canceled.
Idiosyncratic positions and an absolute refusal to concede to common practice is part and parcel of working with certain kinds of people.
We’re drifting off-topic, but I have to ask: gRPC is a Google product; Go is a Google product; and Google is a US company. How did gRPC end up with CANCELLED in the first place?!
You wouldn’t demand an Arabic developer to write all his comments in English for your sake for the sake of being idiomatic, would you?
If this is something other than a private pet project of a person who has no ambition of ever working with people outside of his country? Yes, yes I would.
I believe the advice is still applicable to non-native speakers. In all companies I worked for in France, developers write code in English, including comments, sometimes even internal docs. There are a lot of inconsistencies (typically mixing US English and GB English, sometimes in the same sentence.)
In my experience (LatAm) the problem with that is people tend to have pretty poor English writing skills. You end up with badly written comments and commit messages, full of grammatical errors. People were aware of this so they avoided writing long texts in order to limit their mistakes, so we had one-line PR descriptions, very sparse commenting, no docs to speak of, etc.
Once I had the policy changed for the native language (Portuguese) in PRs and docs they were more comfortable with it and documentation quality improved.
In Europe people are much more likely to have a strong English proficiency even as a second or third language. You have to know your audience, basically.
While I like to write paragraphs of explanation in-between code, my actual comments are rather ungrammatical, with a bit of git style verb-first, removing all articles and other things. Proper English feels wrong in these contexts. Some examples from my currently opened file:
; Hide map’s slider when page opens first time
;; Giv textbox data now
;;Norm longitude within -180-180
; No add marker when click controls
;; Try redundant desperate ideas to not bleed new markers through button
;; Scroll across date line #ToDo Make no tear in marker view (scroll West from Hawaii)
Those comments would most likely look weird to a person unfamiliar with your particular dialect.
In a small comment it’s fine to cut some corners, similar to titles in newspapers, but we can’t go overboard: the point of these things is to communicate, we don’t want to make it even more difficult for whoever is reading them. Proper grammar helps.
For clarification, this is not my dialect/way of speaking. But I see so many short interline comments like this, that I started thinking they feel more appropriate and make them too, now. Strange!
Is “hat” a standard term regularly used in the golang ecosystem for a specific thing and on the list given in the article? If not, it is not relevant to the point in the article.
(And even generalized: if it happens to be an important term for your code base or ecosystem, it probably makes sense to standardize on how to spell it. in whatever language and spelling you prefer. I’ve worked on mixed-language codebases, and it’d been helpful if people consistently used the German domain-specific terms instead of mixing them with various translation attempts. Especially if some participants don’t speak the language (well) and have to treat terms as partially opaque)
I had to solve this once. I maintain a library that converts between HTML/CSS color formats, and one of the formats is a name (and optional spec to say which set of names to draw from). HTML4, CSS2, and CSS2 only had “gray”, but CSS3 added “grey” as another spelling for the same color value, and also added a bunch of other new color names which each have a “gray” and a “grey” variant.
Which raises the question: if I give the library a hex code for one of these and ask it to convert to name, which name should it convert to?
The solution I went with was to always return the “gray” variant since that was the “original” spelling in earlier HTML and CSS specs:
I don’t think it’s really “imperialism”—firstly, “marshaling” isn’t even the preferred spelling in the US. Secondly in countries all over the world job listings stipulate English language skills all the time (even Arabic candidates) and the practice is widely accepted because facilitating communication is generally considered to be important. Lastly, while empires certainly have pushed language standardization as a means to stamp out identities, I don’t think it follows that all language standards exist to stamp out identities (particularly when they are optional, as in the case of this post).
“marshaling” isn’t even the preferred spelling in the US
What makes you say that? (Cards on the table, my immediate thought was “Yes, it is.” I had no data for that, but the ngram below suggests that the single l spelling is the (currently) preferred US spelling.)
A question about commit messages: what do people here feel about repos that enforce a rule of (almost always and only) single-line commit messages?
I ask because I’ve run into this rule more than once when contributing to open source projects. I’m used to it by now, but I was frankly confused the first time someone said “Why did you include a whole paragraph after the commit message?” (To be fair, they also seemed confused that I had included what seemed like a novel to them in my commit message.)
I’m tempted to file it under the “how to not use Git” category. Somewhere close to the projects that demand contributors to push subsequent revisions and feedback actions in follow-up commits of the PR (aka git commit -m "Fix stuff" and git commit -m "Fix stuff again"), never rebase, never squash, and end up with a polluted, non-bisectable, non-making-sense history that serves no higher purpose other than “this git thing gets in the way of writing code”.
nononono. A one-line commit message might be appropriate if it’s “import the vendor list for 2025-03” or “add a missing comma”, but if the actual change required any significant amount of thought then the commit message should be equally thoughtful. Anywhere between two sentences and most of a page is appropriate. Any longer, and you should probably writing a document somewhere else, and including a link and a summary in the commit (and possibly in the code).
Here’s a fairly typical message of mine (reflowed for your reading pleasure):
supervisor: remove empty slices from the qState.tokens map
When returning tokens, if there are no more tokens, remove the slice from the tokens map instead of leaving an empty slice in place. Otherwise, qStates will accumulate map entries for all of the queues they have ever had tokens for, which may be substantial. Profiles show a lot of time spent in mapiter2 called from qState.mdvalue, so this should help with that.
Sounds really weird. At first I thought “Single line commit rule? He must mean repositories forbid single line commits?”
As a junior developer I also wrote commits with only the single line often. And I still do in hobby projects where I might commit once per week. But the commit text is so helpful when the repository grows older. Want to find out why somebody changed that line of code 3 years ago? The reason is not in the code (it might in a comment), but if you’re lucky and the guy wrote a good commit message, then it’s in the commit message.
The more difficult a bug / problem is to solve, the longer my commit messages get to explain what the problem was and why it’s fixed in the way I did it.
In a remote-only role my commit messages usually also are a good wrap-up of all the considerations that went into making this commit as is (and thus might answer some questions the reviewer has already).
I do not remember a project that forbid longer commit messages. Sometimes the requirement is that the first line should be meaningful and concise (then you can add an empty line and more text). Often the rule is that the commit message must start with a ticket number (a change request or a bug report).
That sounds like a bad idea, as you can’t explain every kind of commit in a single line.
You’ve encountered this more than once?
I feel like the problem maintainers have is that contributors typically write terrible, meaningless commit messages, so the maintainers are usually trying to get people to elaborate more in their commit messages.
Yes. I’ve also seen plenty of repos where single-line commits are the norm—and where the exception is maybe a sentence or two. Maybe I’m hanging out in the wrong software circles.
Nice! Was able to clean up lots of files that can live under ~/.config.
However, the very first thing this prints is
The $XDG_RUNTIME_DIR environment variable is not set, make sure to add it to your shell's configuration before setting any of the other environment variables!
⤷ The recommended value is: /run/user/$UID
Is this applicable to macOS? Some quick searching didn’t really give a definitive answer…
“Applicable” is very debatable. The XDG Base Directory Specification is in theory applicable to any POSIX-like system. But it is most “at home” on Linux and other systems that follow a more traditional Unix filesystem layout than MacOS offers.
If you mean, “can I use it on MacOS?” the answer is yes, with some caveats:
If you install an application (say, from brew) that uses the XDG Base Directory Specification for its file locations, then you may not have a choice but to create/manage XDG directories on MacOS.
Some XDG variables default to values that MacOS either doesn’t use or doesn’t have. For example, XDG_CONFIG_DIRS defaults to /etc/xdg which is not present on MacOS.
MacOS has its own application file organization system, mostly under ~/Library. If you want to use XDG-compatible apps, the “philosophically correct” thing to do is set the XDG base directories to their respective locations under ~/Library via shell environment variables yourself, as Apple does not do this for you. (Although I don’t know how you’d set environment variables for a GUI app in MacOS.) This gist may provide some guidance, although I am not convinced about all of their choices.
I version control my dotfiles, and I have a pet peeve of some cross-platform(!) *nixy terminal software that decides to use folders in ~/Library for macOS, in a misguided attempt to be more ‘native’ to the platform or something.
macOS is a certified UNIX, and a comfortable UNIX environment at that, there’s no need for a *nixy terminal program that uses all of macOS’ *nixy affordances and almost entirely works on its UNIX compatibility to try to be more native on macOS by putting its configuration somewhere I have to symlink them.
It’d be more native to just stick with the *nix conventions entirely instead of half-*nix–half-Aqua conventions. The UNIX side is just as much (modern) macOS as the Aqua side, even if it’s not the (especially) unique part about macOS. In fact, the Maccy parts are built on the UNIX foundation, the UNIXy stuff isn’t some separate compatibility layer on top of a Maccy foundation.
As for configuring XDG directories to be under ~/Library as a user, I’ve considered it before, but I think it’s better to maintain a separation between *nixy configuration which tends to have edited by hand, version controlled, and have their own config DSLs or use some simple config language, and configuration of macOS Aqua apps, which are machine-generated and -edited plist (i.e. XML) files that aren’t version controlled.
I just checked and I have an mpv.plist and io.mpv.plist in ~/Library/Preferences (I’m guessing one for mpv run from a terminal and the other for the mpv macOS application bundle). I was curious if the GUI mpv bundle had created an mpv directory in ~/Library/Application Support, like a lot of apps do for themselves, and it hadn’t, but if it had, and I’d set XDG_CONFIG_DIR="$HOME/Library/Application Support", the $XDG_CONFIG_DIR/mpv directory would have been an interesting conflict between the GUI bundle.
Even on Linux I don’t bother setting most of these if I’m happy with the defaults. Why clutter my profile script with setting XDG_CONFIG_HOME="$HOME/.config" when the spec says tools should use that value anyway when that variable is unset? Though maybe I really should set them all, since “explicit is better than implicit” as Pythonistas like to say.
The one thing I can think of is that completion is just transparent. If the target command already has completion, you don’t have to wire up completion for the alias like you would have to for a function.
Zsh also has global aliases that can appear in any position, not just as the command word. For example, I alias \u.. to @{u}.. (a git range) as I use it frequently and the former is easier to type.
I’m not a Gopher myself, but this article seems interesting from an algorithms and data structures point of view. Would it be worthwhile to add the compsci tag to this link as well?
To clarify for anyone who is on this comments page and does not see a “suggest” button, you can only see that button from the homepage where posts are listed. (That is, I read fanf’s comment from this comments page and thought, “What ‘suggest’ button?”)
Edit: actually, this is weird. I only see the “suggest” button for some of the posts in the homepage’s listing. Does anyone know whether that is deliberate? (Image here: https://imgur.com/LQHuJJM. Some posts have the “suggest” link and some don’t. I am confused.)
Second edit: see sknebel’s comment below. I misunderstood. You can see the “suggest” button on the comments page if there is a “suggest” button to be seen.
Nil channels are useful because essentially any practical use of channels should have a select with multiple branches and nil lets you turn off one branch of the select while keeping the others working. Even the most basic thing you can do, send work to some worker goroutines and receive answered data back, will have two branches for send data and receive data and at a certain point you will have sent everything and want to turn the sending branch off while still receiving.
You don’t really need nil for that, even if it’s the easiest ATM.
The same thing can be done with an empty channel for select arms that receive, and a channel with a full buffer for send arms. The zero value for a channel could’ve instead been a valid channel with no buffer, which would satisfy both of the above.
I’m personally not a fan of having nil be a valid value for some blessed types, it’s pretty error prone IMO (as nil is in general).
Some of these things are historical patterns that have trickled down. Go really should be approached in the context of C and non-object oriented approaches to compound types. They were not trying to make an entirely new language with no baggage: they were comfortable with C and they just wanted something a bit better. If that’s a good thing or not is a different matter. I’d say for some things the defaults are not clear; some these things could be compile or runtime errors.
But much like in C a variable declaration does not initialize it (disregard zero values here); it’s also not a compile error to use an unitialized variable. Just like in C to both create and initialize things you resort to function patterns like makeX – make(X) in Go – or newX – NewX in Go. Just like in C passing an unitialized pointer to a struct as an argument to a function is allowed and the function decides what to do with it (e.g. passing a nil slice to append).
In the Plan9 source code you find these exact same patterns in C which makes the decisions in Go much clearer. For example the function that appends to a string automatically initializes it if the string pointer given to it is NULL. In the absense of a constructor-like approach this kind of late-initialization helps with the ergonomics when writing C. That’s why you also see the pattern if x == nil { x.init() } in some Go methods where x is a pointer receiver.
Having that frame of reference also help make some “weird” things clearer, like why you can append to a nil slice but not assign to a nil map – append() is a function and initializes the nil slice on the spot; somemap["key"] = "value" is a dereferencing operation and dereferencing a NULL pointer (the nil map) makes no sense. A whole bunch of other things also start to make more sense in that headspace.
I know why Go is how it is, and understand their decisions. Doesn’t mean I can’t disagree with some of them! “It is what it is” is not a good reason for status quo when designing, what at the time was, a new thing; especially when trying to make it fool/Googler proof ;)
Here specifically, the chan struct could’ve been designed so the zero value is an unbuffered empty channel, which makes sense for a zero value and avoids needing to add nil to the mix.
Yeah I wasn’t necessarily writing to you in particular but more in general for people that might pass this by and maybe get a better way to look at these issues. There’s plenty to disagree!
Digressing into the second topic, I think they were well justified in not straying from the status quo when creating Go. I believe many of the decisions they made were actually very good and showed foresight, even if the language does not cover all the bases. But that’s a longer conversation.
Rob Pike has been beating this drum for a long, long time. In 1983, he gave a paper complaining about the addition of arguments to cat. In 1984, he and Brian Kernighan turned that into a paper, “Program Design in the UNIX Environment” (PDF link).
Consistency doesn’t make him right (or wrong), but he is consistent.
That said, I agree with several of the commenters here that this talk strikes me as too general and vague to be helpful to most people. (It reminds me—in a bad way—of Strunk and White on writing. In that case, the authors don’t help most students by telling them to “omit unnecessary words” or to replace multiple “loose sentences” with “[whatever sequence of clauses] best represent the real relations of the thought.” In Pike’s case, he hasn’t said nearly enough to help anyone decide which dependencies are worth it and how to manage them.)
It’s fine to repost a submission after 6 months. I don’t find that kind of duplication a huge issue.
I’m however not familiar with the rationale for disabling commenting on submissions after a certain amount of time. Performance issue? Spam mitigation?
It might be spam mitigation. There’s a blog I read that’s been active for 25+ years, and still allows comments on old posts. Occasionally an old post will get spammed with links in, I think, an attempt to boost (for lack of a better term) page rank for the links, and by targeting old posts, the spammers hope the links go unnoticed by anyone but the webbots.
When I tried to post it again, I saw this note demanding I justify my resubmission. (After I saw the note, I gave up on the resubmission.)
What has changed or warrants new discussion?
(Not just that you think it’s still interesting or read it for the first time.)
From one point of view, nothing has changed and nothing necessarily warrants new discussion. (Command line flag handling hasn’t changed recently in some novel way..) Also, it is true that I recently read the article for the first time. From another point of view, when it was first submitted, the post received essentially no discussion. Also, I’m interested in the topic. Am I supposed to write that? What do other people do in such a case?
Every morning, I run sudo portup and neoup --clean. The first updates MacPorts and keeps it reasonably lean, and the second updates neovim and my plugins.
Neither are fancy, and as you say I don’t really need to do them every day. But I like keeping things tidy, so to speak.
I find midlang to perfectly describe the ethos of Go. Everything in it is perfectly so-so, with the language trying really hard to prevent anyone from coming up with anything “too smart” in an name of avoiding all the possible bad uses.
Costed me some dowvotes, but it’s true. :D . And I will be surprised if a community will be happy about a weird, unconventional error handling operator. Though … it is kid of mid too… so maybe?
I think about this sort of thing whenever I’m working with LaTeX. Pretty much everyone I know starts with some other LaTeX base and then builds and tweaks from that. In the case of LaTeX, the problem for me is the enormous gap between the small, easily learned core of things and the immense, almost impossible to learn amount you need to know if you want to customize documents beyond very simple changes. When I read Lamport’s LaTeX book, everything seemed elegant and straightforward, but as soon as I tried to customize things, I was quickly way over my head. After nearly an entire summer of work years ago, I have a LaTeX structure that looks great and that I can use for my very specific need (student commentaries on Greek and Latin texts), but I barely understand 50% of the code, and I have to be careful when I update anything.
ConTeXt, being monolithic, allows completely separating presentation logic from document content. For my Markdown editor, KeenWrite, Markdown is first converted to XHTML (i.e., XML). A second pass converts XML into ConTeX macros using the base KeenWrite theme. In the third step, a specific theme modifies the base ConTeXt macros to produce its output document.
I rarely have to modify the base theme any more and since all different aspects of a document are in separate files (breaks, pagination, hyphenation, rules, paragraphs, margins, tables, figures, etc.), breaking unrelated functionality rarely happens. Modifying a specific theme cannot ever break an unrelated theme.
I agree completely and had a similar experience, minus the template (other people at my work definitely share a base template full of stuff though).
This phenomenon led me to ConTeXt, which is hugely more learnable and consistent than LaTeX, where the solution often seems to be “find someone’s special package that fixes it.” Learning ConTeXt then helped me learn TeX better, which soured me completely on LaTeX. I used ConTeXt to typeset a few small books and the process was way easier to customize and way more rewarding than trying to use LaTeX would have been.
Lately I have been using Typst, and while I don’t do a huge amount of typesetting these days, it’s very much a breath of fresh air. I have had a mind to revisit the books I typeset before with it and see if it pays off there; I suspect it will.
Also, don’t forget that all your knowledge may break depending on which TeX engine you use. I’ve switched back and forth several times because some things worked better on e.g. LuaLatex, but a certain layout I needed broke when not used with pdfLatex.
I am one of the people who began to wonder “Is my phone listening to me?” because of Instagram ads. I never really believed that they were, but it felt like they could be given how targeted the ads were. Here’s a dilemma.
Instagram/Meta/Whoever was listening and sending me microphone-based targeted ads. That’s definitely bad.
Instagram/Meta/Whoever was not listening but they still had a method to send me (and people I talked with) ads (well) targeted enough that they felt as if they could have been based on microphone data. (E.g., I talk to my wife about needing sweaters. Within minutes, both wife and me have buckets of ads for men’s sweaters on Instagram.) That’s also definitely bad.
Either way, I’m glad I quit Instagram (and all social media) as a 2022 New Year’s resolution.
There are plenty ways to track users nowadays: cookies, pixels, tcp hello handshake,… Each comes with a different “resolution” allowing advertisers to send you more relevant ads. Chance is that Meta, Google, Adobe, Alibaba, Bytedance are just really good at building these data pipelines and segment them with different clustering algorithms, ML powered recommendations. It’s next to impossible to disable these completely given that many of these services also design and sell the underlying compute platform that you are using: android, chrome, search, email, isp, etc…
I think all these fear mongers created a really good selling pitch for Apple’s private compute pitch. However, i doubt that it gona last long bc Apple could start selling ads themselves
“Ads that are delivered by Apple’s advertising platform may appear on the App Store, Apple News, Stocks, and Apple TV app. Apple’s advertising platform does not track you, meaning that it does not link user or device data collected from our apps with user or device data collected from third parties for targeted advertising or advertising measurement purposes, and does not share user or device data with data brokers.”
Yes. Why does nobody believe anything a company says any more?
When companies are caught lying even a tiny bit it’s headline news. And yet a lot of people seem convinced you can’t believe anything any company says about anything.
I guess the big problem here is probably around telling the difference between marketing and material statements. If a company says “our product is the best solution on the market” that’s a different category of statement from “our products do not listen to your microphone to target ads” or “we don’t train our LLMs on your inputs”.
Why does nobody believe anything a company says any more?
Because they’re incentivized to lie by the only factor that they care about, money. If they can make more money by lying, they will, then pay a fine or a PR agency or fire some token employee if it comes out. Doing otherwise would be failing the great god of “maximizing shareholder value”. I mean, look who the richest man in the world is right now; what’s his history with materially false statements?
I also believe that “they are listening”. I’m a software engineer who’s worked in ad-tech and has developed mobile apps in the past.
I’m aware that, for example, the Facebook app may not be able to literally use my microphone to listen at that exact second. But I am also aware at a high level that lots of data is collected and exchanged between companies for advertising.
So whether or not Google’s app is listening to me, or my “smart TV” is listening and sending that info with identifying IP or other identity resolution methods, or someone else’s phone is listening and sharing text plus ip and geo, the result is the same. I have many times said incredibly specific things and immediately gone from seeing zero ads about that product to seeing an ad for that product.
It’s kind of like solving a crime or debugging a production issue. The advertisers possess the motive. I believe that they do possess the means (other devices or maybe other more unscrupulous apps on your phone).
More often than not the xkcd observation is true “Correlation doesn’t imply causation, but it does waggle its eyebrows suggestively and gesture furtively while mouthing ‘look over there’”.
You make a good point. While I am comfortable with Apple, and their promise of protecting users, my home network has several IoT devices of questionable origin (like the 4K projector that allows me to login to Netflix and plays sound), and I cannot be sure that they aren’t listening in.
As an example, Chinese random projector brands offer their $300+ projectors for peanuts (like under $50) with coupon codes. I won’t be surprised if these are actually CCP survellience devices. I cannot prove it either way, but I am inclined to believe the no-name cheap Chinese projector is doing something nasty.
I’m not a fan of languages that can’t detect misspelled variables at parse time. Perl was my first dynamic language, and I was dismayed that other dynamic languages are worse at detecting typos.
Lua’s 1-based indexing hasn’t bothered me, and I’m saying this as a long time C programmer (35 years, and before that, assembly programmer), but that could be just me. In fact, I recall having a harder time going from assembly to C as there were things I could do easily in assembly that were hard (at the time) in C (my biggest complaint at the time—the inability to return multiple values easily).
I wouldn’t really say that they disagree, so much as that they both can work in ways that are surprising to people coming from other languages or with specific expectations. But maybe I’m misunderstanding what you mean. Can you give an example of the disagreement you have in mind?
for index,value in ipairs(table_variable) do
...
end
It works by starting at 1, and continuing until an index returns nil. # is the length operator, and for tables, it does a binary search to find the ending index (seriously). So as an example, if you had the array { true , true , nil , true , true , true , true , true } (element at index [3] is nil) then it could return 8, or maybe 2, depending on how the binary search jumps around.
Arrays in Lua have always worked this way (as far as I can tell). The terminology around this is a bit strange, but Lua calls what we would call an “array” a “sequence”—a table has elements at array indexes starting at 1 and each subsequent index increases by a whole number and ends with an index returns nil (marking no entry; as an optimization, it will keep such a sequence in an actual array, but it has to be constructed pretty much in order for that to happen). The length of such a sequence is, as stated, found by a binary search.
One consequence of this is the inability to determine the difference between “undefined” and “no value”. In other words, every table has a “value” for every key you could imagine; it’s just that most of the values are nil. A nil in a sequence: { 'a' , 'b' , nil , 'd' , 'e' } is undefined by the Lua language semantics. Enough people complained about this that the team added false to address this issue (and added true to have an actual Boolean value). The only two values in Lua that are treated as false in a Boolean sense are nil and false (such that if 0 is considered true because the value exists). If you want a nil (logically, not physically) in a sequence, you are supposed to use false instead, as that will keep the sequence legal in the language sense. { 'a' , 'b' , false , 'd' , 'e'} is a valid sequence of length 5. Before using such a value, you use if value.
As the documentation that I linked to says, #t finds an arbitrary border in the array part of the table, and as the article says, ipairs(t) finds the first.
As the documentation that I linked to says, #t finds an arbitrary border in the array part of the table, and as the article says, ipairs(t) finds the first.
Got it. I understand what you and spc are saying, but I don’t see this as a disagreement. As I understand the documentation, neither ipairs nor # offers an answer to the question “What is the length of a table with nils in it?” That doesn’t seem unreasonable to me since the question does not have a single, unambiguous answer. In any case, thanks for clarifying.
As I understand the documentation, neither ipairs nor # offers an answer to the question “What is the length of a table with nils in it?” That doesn’t seem unreasonable to me since the question does not have a single, unambiguous answer.
It’s not that it’s an ambiguous question; it’s more like an impossible question. Asking for the length of a table with nils in it is like asking how many nothings you can fit in a bag before it gets full; the question itself is kind of nonsensical given Lua’s definition of nil and table.
I’m not a fan of languages that can’t detect misspelled variables at parse time. Perl was my first dynamic language, and I was dismayed that other dynamic languages are worse at detecting typos.
Honestly this used to be a much bigger problem before LSP became a thing; nowadays it’s very easy to detect mistyped identifiers as you type. (Even without LSP it’s easy to catch with luacheck but before LSP that required a separate manual step.)
Re indexing for arrays, the author says “In Lua, indexing generally starts at index 1, but is only a convention. Arrays can be indexed by 0, negative numbers, or any other value (anything but nil).” I agree and disagree with “only a convention.”
Yes, it’s only a convention in the sense that a Lua interpreter will not throw an error if you create an array-like table starting from 0 (or some other number). But, no, it’s not only a convention in the sense that the standard library for tables and built-ins like ipairs assume array-like tables with indexes starting at 1. So, for nearly all practical purposes, you probably want to index your array-like tables starting at 1. (As Programming in Lua says, “The Lua libraries adhere to th[e] convention [that array-like tables start at 1]; so, if your arrays also start with 1, you will be able to use their functions directly.”)
foo = { [0] = "fizz", [1] = "buzz" }
for _, word in ipairs(foo) do
print(word)
end
-- Prints only "buzz"
A similar point applies to what the author says about nil-terminated arrays. If you know (or suspect or worry) that you may have a sparse array, you must not use ipairs to loop over that table. Instead, you can use pairs (or next) to get at the whole set of items without stopping at the first nil. (If the order matters, however, you’d have to save the items in a new table and sort that table before use.)
Maybe the bigger point is that Lua does not really have arrays in the sense of sequences. There’s just tables, and the tables are always key-value hashes. Sometimes the keys are integers, but—by a (strong!) convention—the indexing of array-like tables should start at 1 and usually the sequence shouldn’t have any gaps.
Maybe the bigger point is that Lua does not really have arrays in the sense of sequences. There’s just tables, and the tables are always key-value hashes. Sometimes the keys are integers […]
I think this is a pretty good way to put it. Another way to say it is that an array is not a data type; it’s a way of treating a table.
You can take any table whether it’s an array or not, and do array things to it. This will lead to surprising results IF you assume that nil in Lua behaves like nil in other languages; it takes some time to internalize Lua’s meaning of nil as the genuine absence of value. But once you do, it’s a good deal more consistent than how many other languages treat nil.
This is true of almost every feature of Lua that people complain about; it’s not that it’s bad, but it’s frustrating if you come to it assuming it works like other languages.
I find this attitude bizarre, but not because you owe anyone anything. (I don’t have strong opinions about that.) I find it bizarre because the only open source projects I have are things I use. If someone reports a bug, they are helping me—even if they do nothing but report the bug. I can’t see why I would ever knowingly leave something broken when I use it.
That said, and in fairness to more popular open source contributors, nothing I write is used by very many people.
I depended heavily on my largest OSS project … eight years ago, when I began authoring it. About six years ago I no longer had that need, but in the meantime it grew some users, and as an “expert” (cough cough) in the field, I kept on maintaining it and improving it from time to time.
Since then it’s grown much, much bigger. I’ve deliberately cultivated relationships and brought contributors on board and helped them feel empowered and confident to merge without my explicit approval, but still at the end of the day it’s on kivikakk/blah. There’s plenty of open issues and bugs, but wow am I tired. I encourage end-users to open a PR if they’re able, and advise I’ll be happy to guide them in the right direction. It doesn’t always work out, but that’s OK; someone else might come along. Occasionally I get a burst of energy and come back and tend to the garden, so to speak, but otherwise, it’s still going fine, even with some messy corners.
Sure, but that’s a whole big thing involving many decisions: I’d have to name and create that organisation (the project name itself is taken by a user already), actually choose a governance model, likely get a bit more buy-in from my current ‘core’ contributors (which might have ramifications — some have $dayjobs at companies that might enjoy more control over the project, so I’d really have to take care with how I structured things), …
As with many things, the literal execution is easy, but the human factors involved are much more involved. Right now, that would take much more energy than my tending to the garden, and represents a lot more risk for me, the tens of thousands of dependent projects, and the millions of people impacted it as a result.
I may not be an active user myself any more, but I see my role as a shepherd now — I think I do that pretty well, and my collaborators and users are increasingly vocal in appreciating the work I do in this regard. (A really nice change from a few years ago!) There’s a tension between piling in new features, shedding baggage/dependencies, and maintaining compatibility, and my experience has been that having someone who isn’t Highly Motivated to push in one of these directions at the expense of the others has been good for quality overall.
I do try to find opportunities to involve it in my own activities and work when I can, but it’s rare since I don’t participate in the language ecosystem (Rust) much these days.
So, in short, I’m pretty happy with the status quo, and in answering the original comment:
I find it bizarre because the only open source projects I have are things I use […] That said, and in fairness to more popular open source contributors, nothing I write is used by very many people.
Maybe that is indeed the difference. If I’d dropped it as soon as I stopped using it, I think the world would be worse off for it, but I decided to keep on maintaining it anyway. It grew into its own little thing, and I’ve been (overall) pretty happy to continue to tend to it, despite my software journey having gone in a different direction long since. :)
If you didn’t already know about the bug, chances are that it’s not affecting you. Eg, think of any open source project that you use daily (maybe TypeScript), and go check their bug tracker. Were you already aware of most of the bugs there? Because I’d say chances are really good those bugs have never impacted you.
If you didn’t already know about the bug, chances are that it’s not affecting you.
Maybe. Or maybe it has been affecting me, and I was less observant than the person who filed the bug. Either way, if the bug is real, I’d rather solve it—whether it has been affecting me without my realizing it or it may affect me later.
There is a potentially unbounded number of bugs potentially affecting through the dependency cone of all the open source projects you are using. Absolutist thinking like ‘I must fix all bugs’ would mean you would never get anything done, for example at your job, while all those bugs are open.
Yes, in theory all sorts of work (and not just work) has the possibility to fill all available time. In practice, I’ve never found this to be a problem. As I said, I am happy to get bug reports and to fix problems. Your mileage may vary.
What about bugs that only apply to an operating system or hardware that you don’t use? Bugs that involve using the project in a way it was not intended (or at least not how you would ever use it)? Bugs when trying to use it at a scale you will never reach?
Not to say I disagree that you should try to fix them, but there is plenty of bug potential that really wouldn’t affect you directly.
What about bugs that only apply to an operating system or hardware that you don’t use?
I would need help to fix that most likely.
Bugs that involve using the project in a way it was not intended (or at least not how you would ever use it)?
The first is not a bug (in my view). The second is a judgment call; I’d make it on a case by case basis.
Bugs when trying to use it at a scale you will never reach?
Again, a judgment call.
[T]here is plenty of bug potential that really wouldn’t affect you directly.
I don’t deny that. What I would or could fix in those cases would depend on a lot of factors. I’d still probably try up to a point, and then I’d stop or leave it for others to help out. I don’t have fixed answers to all these hypotheticals other than to repeat that I find the OP’s view (“Don’t fix anything. Don’t try to confirm or test anything.”) bizarre.
Two notes about his book recommendations and three recommendations of my own.
I’m surprised that Might concludes that Strunk and White’s Elements of Style “is still a good, if not perfect, reference on style” since he cites Geoffrey Pullum who tears Elements of Style apart. People should take a look at Pullum here (PDF link) and here if they want to judge for themselves, but I think that Strunk and White is simply not a good book despite being very popular.
A tip about Joseph Williams’s Style book: buy the first edition, which you can find used very cheaply. Prentice and Hall keeps coming out with new editions, mostly I think to prevent undergrads from buying used copies and cutting into new book sales. (They now charge $55 for a paperback that is substantially the same as the book I taught in the 90s when it was about $12.)
Anne Greene’s Writing Science in Plain English is also terrific, and it’s very affordable. (Greene has a more narrow focus and is more basic than Kane, but don’t let the title put you off. Even if you are not writing about science, the core advice is excellent.)
If you care a lot about writing and you are interested in a less directly practical book, I highly recommend Clear and Simple as the Truth by Francis-Noël Thomas and Mark Turner. They take a philosophical approach to writing and treat “clear writing” as one style among others.
A port that reads from or writes to a terminal has a terminal mode; this is either cooked or raw. …
A terminal port in cooked mode provides some standard processing to make the terminal easy to communicate with. For example, under unix, cooked mode on input reads from the terminal a line at a time and provides editing within the line, while cooked mode on output might translate linefeeds to carriage-return/linefeed pairs. In general, the precise meaning of cooked mode is operating-system dependent, and furthermore might be customizable by means of operating-system utilities. The basic idea is that cooked mode does whatever is necessary to make the terminal handle all of the usual user-interface conventions for the operating system, while keeping the program’s interaction with the port as normal as possible.
A terminal port in raw mode disables all of that processing. In raw mode, characters are directly read from and written to the device without any translation or interpretation by the operating system. On input, characters are available as soon as they are typed, and are not echoed on the terminal by the operating system. In general, programs that put ports in raw mode have to know the details of interacting with the terminal. In particular, raw mode is used for writing programs such as text editors.
You should write the comment anyway.
Ideally, the language would protect you by putting the protected things inside the Mutex, so that it’s not possible to accidentally use them without going through the Mutex:
But yeah, if that’s going to be enforced by developers being careful instead, make it as clear as possible with explicit comments. As casperin said, better to also write doc comments on the protected fields so that they show up in autocomplete!
yeah, this is one of those awful consequences of go not having generics for so long. at my work (a go shop) we have many packages that just wrap a bunch of old standard library stuff with safer generics based equivalents.
hopefully eventually the standard library will all be updated and the old versions will be deprecated.
I was completely surprised that the comment included the second field. It doesn’t even share the name. I would put a doc comment (does Go have those?) on both the protected fields so they at least show up in the editor when you auto complete.
In addition, lots of Go developers use tools like betteralign that makes the whole argument moot because they rearrange stuct fields for performance.
I disagree with this, only because it’s imperialism. I’m British, in British English I write marshalling (with two of the letter l), sanitising (-sing instead of -zing except for words ending in a z), and -ise instead of -ize, among other things. You wouldn’t demand an Arabic developer to write all his comments in English for your sake for the sake of being idiomatic, would you?
I’ve worked for a few companies in Germany now, about half of them with their operating language being in German. All of them had comments being written exclusively in English. I don’t know how that is in other countries, but I get the impression from Europeans that this is pretty standard.
That said, my own preference is for American English for code (i.e. variable names, class names, etc), but British English for comments, commit messages, pull requests, etc. That’s because the names are part of the shared codebase and therefore standardised, but the comments and commit messages are specifically from me. As long as everyone can understand my British English, then I don’t think there’s much of a problem.
EDIT: That said, most of these suggestions feel more on the pedantic end of the spectrum as far as advice goes, and I would take some of this with a pinch of salt. In particular, when style suggestions like “I tend to write xyz” become “do this”, then I start to raise eyebrows at the usefulness of a particular style guide.
Developers in China seem to prefer Chinese to English. When ECharts was first open-sourced by Baidu most of the inline comments (and the entire README) were in Chinese:
In Japan I feel like the tech industry is associated with English, and corporate codebases seem to use mostly English in documentation. However, many people’s personal projects have all the comments/docs in Japanese.
If someone wants to force everyone to spell something the same within a language they should make sure it’s spelled wrong in all varieties, like with HTTP’s ‘referer’.
The Go core developers feel so strongly about their speling that they’re wiling to change the names of constants from other APIs.
The gRPC protocol contains a status code enum (https://grpc.io/docs/guides/status-codes/), one of which is
CANCELLED. Every gRPC library uses that spelling except for go-grpc, which spells itCanceled.Idiosyncratic positions and an absolute refusal to concede to common practice is part and parcel of working with certain kinds of people.
We’re drifting off-topic, but I have to ask: gRPC is a Google product; Go is a Google product; and Google is a US company. How did gRPC end up with
CANCELLEDin the first place?!When you use a lot of staff on H-1B and E-3 visas, you get a lot of people who write in English rather than American!
Wait until you hear about the HTTP ‘Referer’ header. The HTTP folks have been refusing to conform to common practice for more than 30 years!
If this is something other than a private pet project of a person who has no ambition of ever working with people outside of his country? Yes, yes I would.
I believe the advice is still applicable to non-native speakers. In all companies I worked for in France, developers write code in English, including comments, sometimes even internal docs. There are a lot of inconsistencies (typically mixing US English and GB English, sometimes in the same sentence.)
In my experience (LatAm) the problem with that is people tend to have pretty poor English writing skills. You end up with badly written comments and commit messages, full of grammatical errors. People were aware of this so they avoided writing long texts in order to limit their mistakes, so we had one-line PR descriptions, very sparse commenting, no docs to speak of, etc.
Once I had the policy changed for the native language (Portuguese) in PRs and docs they were more comfortable with it and documentation quality improved.
In Europe people are much more likely to have a strong English proficiency even as a second or third language. You have to know your audience, basically.
While I like to write paragraphs of explanation in-between code, my actual comments are rather ungrammatical, with a bit of git style verb-first, removing all articles and other things. Proper English feels wrong in these contexts. Some examples from my currently opened file:
Those comments would most likely look weird to a person unfamiliar with your particular dialect.
In a small comment it’s fine to cut some corners, similar to titles in newspapers, but we can’t go overboard: the point of these things is to communicate, we don’t want to make it even more difficult for whoever is reading them. Proper grammar helps.
For clarification, this is not my dialect/way of speaking. But I see so many short interline comments like this, that I started thinking they feel more appropriate and make them too, now. Strange!
“If you use standard terms, spell them in a standard way” is not the same as “use only one language ever”.
Is “chapéu” or “hat” the standard way of spelling hat in Golang? If it’s “hat”, your standard is “only use American English ever”.
Is “hat” a standard term regularly used in the golang ecosystem for a specific thing and on the list given in the article? If not, it is not relevant to the point in the article.
(And even generalized: if it happens to be an important term for your code base or ecosystem, it probably makes sense to standardize on how to spell it. in whatever language and spelling you prefer. I’ve worked on mixed-language codebases, and it’d been helpful if people consistently used the German domain-specific terms instead of mixing them with various translation attempts. Especially if some participants don’t speak the language (well) and have to treat terms as partially opaque)
What? England had the word “hat” long before the USA existed.
I had to solve this once. I maintain a library that converts between HTML/CSS color formats, and one of the formats is a name (and optional spec to say which set of names to draw from). HTML4, CSS2, and CSS2 only had “gray”, but CSS3 added “grey” as another spelling for the same color value, and also added a bunch of other new color names which each have a “gray” and a “grey” variant.
Which raises the question: if I give the library a hex code for one of these and ask it to convert to name, which name should it convert to?
The solution I went with was to always return the “gray” variant since that was the “original” spelling in earlier HTML and CSS specs:
https://webcolors.readthedocs.io/en/latest/faq.html#why-does-webcolors-prefer-american-spellings
I thought you guys loved imperialism?
Imperialism is like kids, you like your own brand.
I don’t think it’s really “imperialism”—firstly, “marshaling” isn’t even the preferred spelling in the US. Secondly in countries all over the world job listings stipulate English language skills all the time (even Arabic candidates) and the practice is widely accepted because facilitating communication is generally considered to be important. Lastly, while empires certainly have pushed language standardization as a means to stamp out identities, I don’t think it follows that all language standards exist to stamp out identities (particularly when they are optional, as in the case of this post).
What makes you say that? (Cards on the table, my immediate thought was “Yes, it is.” I had no data for that, but the ngram below suggests that the single l spelling is the (currently) preferred US spelling.)
https://books.google.com/ngrams/graph?content=marshaling%2Cmarshalling&year_start=1800&year_end=2022&corpus=en-US&smoothing=3&case_insensitive=true
It’s imperialist to use social and technical pressure to “encourage” people to use American English so their own codebases are “idiomatic”.
I disagree. I don’t see how it is imperialism in any meaningful sense. Also “pressure” is fairly absurd here.
A question about commit messages: what do people here feel about repos that enforce a rule of (almost always and only) single-line commit messages?
I ask because I’ve run into this rule more than once when contributing to open source projects. I’m used to it by now, but I was frankly confused the first time someone said “Why did you include a whole paragraph after the commit message?” (To be fair, they also seemed confused that I had included what seemed like a novel to them in my commit message.)
Sounds counterproductive.
I’m tempted to file it under the “how to not use Git” category. Somewhere close to the projects that demand contributors to push subsequent revisions and feedback actions in follow-up commits of the PR (aka
git commit -m "Fix stuff"andgit commit -m "Fix stuff again"), never rebase, never squash, and end up with a polluted, non-bisectable, non-making-sense history that serves no higher purpose other than “this git thing gets in the way of writing code”.nononono. A one-line commit message might be appropriate if it’s “import the vendor list for 2025-03” or “add a missing comma”, but if the actual change required any significant amount of thought then the commit message should be equally thoughtful. Anywhere between two sentences and most of a page is appropriate. Any longer, and you should probably writing a document somewhere else, and including a link and a summary in the commit (and possibly in the code).
Here’s a fairly typical message of mine (reflowed for your reading pleasure):
Sounds really weird. At first I thought “Single line commit rule? He must mean repositories forbid single line commits?”
As a junior developer I also wrote commits with only the single line often. And I still do in hobby projects where I might commit once per week. But the commit text is so helpful when the repository grows older. Want to find out why somebody changed that line of code 3 years ago? The reason is not in the code (it might in a comment), but if you’re lucky and the guy wrote a good commit message, then it’s in the commit message.
The more difficult a bug / problem is to solve, the longer my commit messages get to explain what the problem was and why it’s fixed in the way I did it.
In a remote-only role my commit messages usually also are a good wrap-up of all the considerations that went into making this commit as is (and thus might answer some questions the reviewer has already).
I do not remember a project that forbid longer commit messages. Sometimes the requirement is that the first line should be meaningful and concise (then you can add an empty line and more text). Often the rule is that the commit message must start with a ticket number (a change request or a bug report).
That sounds like a bad idea, as you can’t explain every kind of commit in a single line.
You’ve encountered this more than once?
I feel like the problem maintainers have is that contributors typically write terrible, meaningless commit messages, so the maintainers are usually trying to get people to elaborate more in their commit messages.
Yes. I’ve also seen plenty of repos where single-line commits are the norm—and where the exception is maybe a sentence or two. Maybe I’m hanging out in the wrong software circles.
Nice! Was able to clean up lots of files that can live under ~/.config.
However, the very first thing this prints is
Is this applicable to macOS? Some quick searching didn’t really give a definitive answer…
“Applicable” is very debatable. The XDG Base Directory Specification is in theory applicable to any POSIX-like system. But it is most “at home” on Linux and other systems that follow a more traditional Unix filesystem layout than MacOS offers.
If you mean, “can I use it on MacOS?” the answer is yes, with some caveats:
XDG_CONFIG_DIRSdefaults to/etc/xdgwhich is not present on MacOS.MacOS has its own application file organization system, mostly under
~/Library. If you want to use XDG-compatible apps, the “philosophically correct” thing to do is set the XDG base directories to their respective locations under~/Libraryvia shell environment variables yourself, as Apple does not do this for you. (Although I don’t know how you’d set environment variables for a GUI app in MacOS.) This gist may provide some guidance, although I am not convinced about all of their choices.I version control my dotfiles, and I have a pet peeve of some cross-platform(!) *nixy terminal software that decides to use folders in
~/Libraryfor macOS, in a misguided attempt to be more ‘native’ to the platform or something.macOS is a certified UNIX, and a comfortable UNIX environment at that, there’s no need for a *nixy terminal program that uses all of macOS’ *nixy affordances and almost entirely works on its UNIX compatibility to try to be more native on macOS by putting its configuration somewhere I have to symlink them.
It’d be more native to just stick with the *nix conventions entirely instead of half-*nix–half-Aqua conventions. The UNIX side is just as much (modern) macOS as the Aqua side, even if it’s not the (especially) unique part about macOS. In fact, the Maccy parts are built on the UNIX foundation, the UNIXy stuff isn’t some separate compatibility layer on top of a Maccy foundation.
As for configuring XDG directories to be under
~/Libraryas a user, I’ve considered it before, but I think it’s better to maintain a separation between *nixy configuration which tends to have edited by hand, version controlled, and have their own config DSLs or use some simple config language, and configuration of macOS Aqua apps, which are machine-generated and -edited plist (i.e. XML) files that aren’t version controlled.I just checked and I have an
mpv.plistandio.mpv.plistin~/Library/Preferences(I’m guessing one formpvrun from a terminal and the other for the mpv macOS application bundle). I was curious if the GUI mpv bundle had created anmpvdirectory in~/Library/Application Support, like a lot of apps do for themselves, and it hadn’t, but if it had, and I’d setXDG_CONFIG_DIR="$HOME/Library/Application Support", the$XDG_CONFIG_DIR/mpvdirectory would have been an interesting conflict between the GUI bundle.Even on Linux I don’t bother setting most of these if I’m happy with the defaults. Why clutter my profile script with setting
XDG_CONFIG_HOME="$HOME/.config"when the spec says tools should use that value anyway when that variable is unset? Though maybe I really should set them all, since “explicit is better than implicit” as Pythonistas like to say.This suggests a few possible ways to handle this though nothing I would call “definitive.”
https://stackoverflow.com/q/14237142/26702
It’s a minor thing, but re “No reloading; changes are picked up immediately,” I like the following aliases.
Overall, I agree with many of the commenters that aliases, functions, and scripts all have their uses.
what is the use for an alias? (what can an alias do that a function can’t)
The one thing I can think of is that completion is just transparent. If the target command already has completion, you don’t have to wire up completion for the alias like you would have to for a function.
Zsh also has global aliases that can appear in any position, not just as the command word. For example, I alias
\u..to@{u}..(a git range) as I use it frequently and the former is easier to type.…
I can’t comprehend why I haven’t thought of this yet.
I’m not a Gopher myself, but this article seems interesting from an algorithms and data structures point of view. Would it be worthwhile to add the
compscitag to this link as well?Use the “suggest” button instead of posting a meta-comment
TIL: thanks.
To clarify for anyone who is on this comments page and does not see a “suggest” button, you can only see that button from the homepage where posts are listed. (That is, I read fanf’s comment from this comments page and thought, “What ‘suggest’ button?”)
Edit: actually, this is weird. I only see the “suggest” button for some of the posts in the homepage’s listing. Does anyone know whether that is deliberate? (Image here: https://imgur.com/LQHuJJM. Some posts have the “suggest” link and some don’t. I am confused.)
Second edit: see sknebel’s comment below. I misunderstood. You can see the “suggest” button on the comments page if there is a “suggest” button to be seen.
it disappears once an edit through suggestions has been applied, to prevent “edit wars” I guess.
Thanks for clarifying. I see what you mean about edit wars, but isn’t it possible that a post deserves multiple (non-competing) suggestions?
Nil channels are useful because essentially any practical use of channels should have a select with multiple branches and nil lets you turn off one branch of the select while keeping the others working. Even the most basic thing you can do, send work to some worker goroutines and receive answered data back, will have two branches for send data and receive data and at a certain point you will have sent everything and want to turn the sending branch off while still receiving.
You don’t really need
nilfor that, even if it’s the easiest ATM. The same thing can be done with an empty channel for select arms that receive, and a channel with a full buffer for send arms. The zero value for a channel could’ve instead been a valid channel with no buffer, which would satisfy both of the above.I’m personally not a fan of having
nilbe a valid value for some blessed types, it’s pretty error prone IMO (asnilis in general).Some of these things are historical patterns that have trickled down. Go really should be approached in the context of C and non-object oriented approaches to compound types. They were not trying to make an entirely new language with no baggage: they were comfortable with C and they just wanted something a bit better. If that’s a good thing or not is a different matter. I’d say for some things the defaults are not clear; some these things could be compile or runtime errors.
But much like in C a variable declaration does not initialize it (disregard zero values here); it’s also not a compile error to use an unitialized variable. Just like in C to both create and initialize things you resort to function patterns like
makeX–make(X)in Go – ornewX–NewXin Go. Just like in C passing an unitialized pointer to a struct as an argument to a function is allowed and the function decides what to do with it (e.g. passing anilslice toappend).In the Plan9 source code you find these exact same patterns in C which makes the decisions in Go much clearer. For example the function that appends to a string automatically initializes it if the string pointer given to it is
NULL. In the absense of a constructor-like approach this kind of late-initialization helps with the ergonomics when writing C. That’s why you also see the patternif x == nil { x.init() }in some Go methods wherexis a pointer receiver.Having that frame of reference also help make some “weird” things clearer, like why you can append to a nil slice but not assign to a nil map –
append()is a function and initializes thenilslice on the spot;somemap["key"] = "value"is a dereferencing operation and dereferencing a NULL pointer (thenilmap) makes no sense. A whole bunch of other things also start to make more sense in that headspace.I know why Go is how it is, and understand their decisions. Doesn’t mean I can’t disagree with some of them! “It is what it is” is not a good reason for status quo when designing, what at the time was, a new thing; especially when trying to make it fool/Googler proof ;)
Here specifically, the
chanstruct could’ve been designed so the zero value is an unbuffered empty channel, which makes sense for a zero value and avoids needing to addnilto the mix.Yeah I wasn’t necessarily writing to you in particular but more in general for people that might pass this by and maybe get a better way to look at these issues. There’s plenty to disagree!
Digressing into the second topic, I think they were well justified in not straying from the status quo when creating Go. I believe many of the decisions they made were actually very good and showed foresight, even if the language does not cover all the bases. But that’s a longer conversation.
I never thought about this. Thanks!
make(chan T, 0)indeed seems to work asnilwith my (simple) tests.https://go.dev/play/p/bnVOQnQMW-c
Rob Pike has been beating this drum for a long, long time. In 1983, he gave a paper complaining about the addition of arguments to
cat. In 1984, he and Brian Kernighan turned that into a paper, “Program Design in the UNIX Environment” (PDF link).Consistency doesn’t make him right (or wrong), but he is consistent.
That said, I agree with several of the commenters here that this talk strikes me as too general and vague to be helpful to most people. (It reminds me—in a bad way—of Strunk and White on writing. In that case, the authors don’t help most students by telling them to “omit unnecessary words” or to replace multiple “loose sentences” with “[whatever sequence of clauses] best represent the real relations of the thought.” In Pike’s case, he hasn’t said nearly enough to help anyone decide which dependencies are worth it and how to manage them.)
It’s fine to repost a submission after 6 months. I don’t find that kind of duplication a huge issue.
I’m however not familiar with the rationale for disabling commenting on submissions after a certain amount of time. Performance issue? Spam mitigation?
It might be spam mitigation. There’s a blog I read that’s been active for 25+ years, and still allows comments on old posts. Occasionally an old post will get spammed with links in, I think, an attempt to boost (for lack of a better term) page rank for the links, and by targeting old posts, the spammers hope the links go unnoticed by anyone but the webbots.
In practice, however, I find that the site discourages reposts. For example, I recently wanted to submit Conventions for Command Line Options. It was posted here four years ago and received only one comment.
When I tried to post it again, I saw this note demanding I justify my resubmission. (After I saw the note, I gave up on the resubmission.)
From one point of view, nothing has changed and nothing necessarily warrants new discussion. (Command line flag handling hasn’t changed recently in some novel way..) Also, it is true that I recently read the article for the first time. From another point of view, when it was first submitted, the post received essentially no discussion. Also, I’m interested in the topic. Am I supposed to write that? What do other people do in such a case?
Every morning, I run
sudo portupandneoup --clean. The first updates MacPorts and keeps it reasonably lean, and the second updates neovim and my plugins.Neither are fancy, and as you say I don’t really need to do them every day. But I like keeping things tidy, so to speak.
Funny timing: I came across this older link about using ndjson in Go just last week.
Something tells me midlang devs are not going to be very enthusiastic about this syntax and how “complex” it is.
What’s a midlang dev?
My guess: mid is a slang for average and often used pejoratively. so it means average language.
My guess: 4chan slang for golang.
Thank you. Exactly.
I find midlang to perfectly describe the ethos of Go. Everything in it is perfectly so-so, with the language trying really hard to prevent anyone from coming up with anything “too smart” in an name of avoiding all the possible bad uses.
Costed me some dowvotes, but it’s true. :D . And I will be surprised if a community will be happy about a weird, unconventional error handling operator. Though … it is kid of mid too… so maybe?
Am I the only one who tires of language holy war stuff?
My guess: typo for middling.
I think about this sort of thing whenever I’m working with LaTeX. Pretty much everyone I know starts with some other LaTeX base and then builds and tweaks from that. In the case of LaTeX, the problem for me is the enormous gap between the small, easily learned core of things and the immense, almost impossible to learn amount you need to know if you want to customize documents beyond very simple changes. When I read Lamport’s LaTeX book, everything seemed elegant and straightforward, but as soon as I tried to customize things, I was quickly way over my head. After nearly an entire summer of work years ago, I have a LaTeX structure that looks great and that I can use for my very specific need (student commentaries on Greek and Latin texts), but I barely understand 50% of the code, and I have to be careful when I update anything.
tl;dr - there’s a lot of “then draw the rest of the owl” in tech. My favorite example is LaTeX.
Have you used ConTeXt?
ConTeXt, being monolithic, allows completely separating presentation logic from document content. For my Markdown editor, KeenWrite, Markdown is first converted to XHTML (i.e., XML). A second pass converts XML into ConTeX macros using the base KeenWrite theme. In the third step, a specific theme modifies the base ConTeXt macros to produce its output document.
I rarely have to modify the base theme any more and since all different aspects of a document are in separate files (breaks, pagination, hyphenation, rules, paragraphs, margins, tables, figures, etc.), breaking unrelated functionality rarely happens. Modifying a specific theme cannot ever break an unrelated theme.
I agree completely and had a similar experience, minus the template (other people at my work definitely share a base template full of stuff though).
This phenomenon led me to ConTeXt, which is hugely more learnable and consistent than LaTeX, where the solution often seems to be “find someone’s special package that fixes it.” Learning ConTeXt then helped me learn TeX better, which soured me completely on LaTeX. I used ConTeXt to typeset a few small books and the process was way easier to customize and way more rewarding than trying to use LaTeX would have been.
Lately I have been using Typst, and while I don’t do a huge amount of typesetting these days, it’s very much a breath of fresh air. I have had a mind to revisit the books I typeset before with it and see if it pays off there; I suspect it will.
I love how the recommended debugging technique for LaTeX is to backtrack to the last working version and replay your changes until the error appears.
Also, don’t forget that all your knowledge may break depending on which TeX engine you use. I’ve switched back and forth several times because some things worked better on e.g. LuaLatex, but a certain layout I needed broke when not used with pdfLatex.
I am one of the people who began to wonder “Is my phone listening to me?” because of Instagram ads. I never really believed that they were, but it felt like they could be given how targeted the ads were. Here’s a dilemma.
Either way, I’m glad I quit Instagram (and all social media) as a 2022 New Year’s resolution.
There are plenty ways to track users nowadays: cookies, pixels, tcp hello handshake,… Each comes with a different “resolution” allowing advertisers to send you more relevant ads. Chance is that Meta, Google, Adobe, Alibaba, Bytedance are just really good at building these data pipelines and segment them with different clustering algorithms, ML powered recommendations. It’s next to impossible to disable these completely given that many of these services also design and sell the underlying compute platform that you are using: android, chrome, search, email, isp, etc…
I think all these fear mongers created a really good selling pitch for Apple’s private compute pitch. However, i doubt that it gona last long bc Apple could start selling ads themselves
https://www.apple.com/legal/privacy/data/en/apple-advertising/
Apple already sells ads.
“Ads that are delivered by Apple’s advertising platform may appear on the App Store, Apple News, Stocks, and Apple TV app. Apple’s advertising platform does not track you, meaning that it does not link user or device data collected from our apps with user or device data collected from third parties for targeted advertising or advertising measurement purposes, and does not share user or device data with data brokers.”
And you’re just going to take their word for it?
Yes. Why does nobody believe anything a company says any more?
When companies are caught lying even a tiny bit it’s headline news. And yet a lot of people seem convinced you can’t believe anything any company says about anything.
I guess the big problem here is probably around telling the difference between marketing and material statements. If a company says “our product is the best solution on the market” that’s a different category of statement from “our products do not listen to your microphone to target ads” or “we don’t train our LLMs on your inputs”.
Because they’re incentivized to lie by the only factor that they care about, money. If they can make more money by lying, they will, then pay a fine or a PR agency or fire some token employee if it comes out. Doing otherwise would be failing the great god of “maximizing shareholder value”. I mean, look who the richest man in the world is right now; what’s his history with materially false statements?
None of the companies I have ever worked for have seemed like that as an insider.
So what? That still allows selling targeted ads.
If there’s no user or device data shared with data brokers, how are those brokers targeting ads?
People buying ads from apple can target them at “segments” based on personal info, so long as each segment contains at least 5000 people. It’s in the link above. https://www.apple.com/legal/privacy/data/en/apple-advertising/
I also believe that “they are listening”. I’m a software engineer who’s worked in ad-tech and has developed mobile apps in the past.
I’m aware that, for example, the Facebook app may not be able to literally use my microphone to listen at that exact second. But I am also aware at a high level that lots of data is collected and exchanged between companies for advertising.
So whether or not Google’s app is listening to me, or my “smart TV” is listening and sending that info with identifying IP or other identity resolution methods, or someone else’s phone is listening and sharing text plus ip and geo, the result is the same. I have many times said incredibly specific things and immediately gone from seeing zero ads about that product to seeing an ad for that product.
It’s kind of like solving a crime or debugging a production issue. The advertisers possess the motive. I believe that they do possess the means (other devices or maybe other more unscrupulous apps on your phone).
More often than not the xkcd observation is true “Correlation doesn’t imply causation, but it does waggle its eyebrows suggestively and gesture furtively while mouthing ‘look over there’”.
You make a good point. While I am comfortable with Apple, and their promise of protecting users, my home network has several IoT devices of questionable origin (like the 4K projector that allows me to login to Netflix and plays sound), and I cannot be sure that they aren’t listening in.
As an example, Chinese random projector brands offer their $300+ projectors for peanuts (like under $50) with coupon codes. I won’t be surprised if these are actually CCP survellience devices. I cannot prove it either way, but I am inclined to believe the no-name cheap Chinese projector is doing something nasty.
Lua has 1-based indexing for strings as well as arrays. In my experience it’s a pain in the arse.
The length of arrays is tricky. It’s possible for
ipairs(t)and#tto disagree.I’m not a fan of languages that can’t detect misspelled variables at parse time. Perl was my first dynamic language, and I was dismayed that other dynamic languages are worse at detecting typos.
Lua’s 1-based indexing hasn’t bothered me, and I’m saying this as a long time C programmer (35 years, and before that, assembly programmer), but that could be just me. In fact, I recall having a harder time going from assembly to C as there were things I could do easily in assembly that were hard (at the time) in C (my biggest complaint at the time—the inability to return multiple values easily).
I wouldn’t really say that they disagree, so much as that they both can work in ways that are surprising to people coming from other languages or with specific expectations. But maybe I’m misunderstanding what you mean. Can you give an example of the disagreement you have in mind?
ipairs()is an iterator, so it’s use it like:It works by starting at 1, and continuing until an index returns
nil.#is the length operator, and for tables, it does a binary search to find the ending index (seriously). So as an example, if you had the array{ true , true , nil , true , true , true , true , true }(element at index[3]isnil) then it could return 8, or maybe 2, depending on how the binary search jumps around.Arrays in Lua have always worked this way (as far as I can tell). The terminology around this is a bit strange, but Lua calls what we would call an “array” a “sequence”—a table has elements at array indexes starting at 1 and each subsequent index increases by a whole number and ends with an index returns
nil(marking no entry; as an optimization, it will keep such a sequence in an actual array, but it has to be constructed pretty much in order for that to happen). The length of such a sequence is, as stated, found by a binary search.One consequence of this is the inability to determine the difference between “undefined” and “no value”. In other words, every table has a “value” for every key you could imagine; it’s just that most of the values are
nil. Anilin a sequence:{ 'a' , 'b' , nil , 'd' , 'e' }is undefined by the Lua language semantics. Enough people complained about this that the team addedfalseto address this issue (and addedtrueto have an actual Boolean value). The only two values in Lua that are treated as false in a Boolean sense arenilandfalse(such thatif 0is considered true because the value exists). If you want anil(logically, not physically) in a sequence, you are supposed to usefalseinstead, as that will keep the sequence legal in the language sense.{ 'a' , 'b' , false , 'd' , 'e'}is a valid sequence of length 5. Before using such a value, you useif value.Edited to add: the description of how it works in the Lua manual.
As the documentation that I linked to says,
#tfinds an arbitrary border in the array part of the table, and as the article says,ipairs(t)finds the first.Got it. I understand what you and spc are saying, but I don’t see this as a disagreement. As I understand the documentation, neither
ipairsnor#offers an answer to the question “What is the length of a table withnils in it?” That doesn’t seem unreasonable to me since the question does not have a single, unambiguous answer. In any case, thanks for clarifying.It’s not that it’s an ambiguous question; it’s more like an impossible question. Asking for the length of a table with nils in it is like asking how many nothings you can fit in a bag before it gets full; the question itself is kind of nonsensical given Lua’s definition of nil and table.
Honestly this used to be a much bigger problem before LSP became a thing; nowadays it’s very easy to detect mistyped identifiers as you type. (Even without LSP it’s easy to catch with
luacheckbut before LSP that required a separate manual step.)Re indexing for arrays, the author says “In Lua, indexing generally starts at index 1, but is only a convention. Arrays can be indexed by 0, negative numbers, or any other value (anything but nil).” I agree and disagree with “only a convention.”
Yes, it’s only a convention in the sense that a Lua interpreter will not throw an error if you create an array-like table starting from 0 (or some other number). But, no, it’s not only a convention in the sense that the standard library for tables and built-ins like
ipairsassume array-like tables with indexes starting at 1. So, for nearly all practical purposes, you probably want to index your array-like tables starting at 1. (As Programming in Lua says, “The Lua libraries adhere to th[e] convention [that array-like tables start at 1]; so, if your arrays also start with 1, you will be able to use their functions directly.”)A similar point applies to what the author says about nil-terminated arrays. If you know (or suspect or worry) that you may have a sparse array, you must not use
ipairsto loop over that table. Instead, you can usepairs(ornext) to get at the whole set of items without stopping at the firstnil. (If the order matters, however, you’d have to save the items in a new table and sort that table before use.)Maybe the bigger point is that Lua does not really have arrays in the sense of sequences. There’s just tables, and the tables are always key-value hashes. Sometimes the keys are integers, but—by a (strong!) convention—the indexing of array-like tables should start at 1 and usually the sequence shouldn’t have any gaps.
I think this is a pretty good way to put it. Another way to say it is that an array is not a data type; it’s a way of treating a table.
You can take any table whether it’s an array or not, and do array things to it. This will lead to surprising results IF you assume that
nilin Lua behaves likenilin other languages; it takes some time to internalize Lua’s meaning ofnilas the genuine absence of value. But once you do, it’s a good deal more consistent than how many other languages treat nil.This is true of almost every feature of Lua that people complain about; it’s not that it’s bad, but it’s frustrating if you come to it assuming it works like other languages.
I find this attitude bizarre, but not because you owe anyone anything. (I don’t have strong opinions about that.) I find it bizarre because the only open source projects I have are things I use. If someone reports a bug, they are helping me—even if they do nothing but report the bug. I can’t see why I would ever knowingly leave something broken when I use it.
That said, and in fairness to more popular open source contributors, nothing I write is used by very many people.
I depended heavily on my largest OSS project … eight years ago, when I began authoring it. About six years ago I no longer had that need, but in the meantime it grew some users, and as an “expert” (cough cough) in the field, I kept on maintaining it and improving it from time to time.
Since then it’s grown much, much bigger. I’ve deliberately cultivated relationships and brought contributors on board and helped them feel empowered and confident to merge without my explicit approval, but still at the end of the day it’s on
kivikakk/blah. There’s plenty of open issues and bugs, but wow am I tired. I encourage end-users to open a PR if they’re able, and advise I’ll be happy to guide them in the right direction. It doesn’t always work out, but that’s OK; someone else might come along. Occasionally I get a burst of energy and come back and tend to the garden, so to speak, but otherwise, it’s still going fine, even with some messy corners.Can’t one change that rather easily? (By transferring it to an organization, assuming this is GitHub or GitLab)
Sure, but that’s a whole big thing involving many decisions: I’d have to name and create that organisation (the project name itself is taken by a user already), actually choose a governance model, likely get a bit more buy-in from my current ‘core’ contributors (which might have ramifications — some have $dayjobs at companies that might enjoy more control over the project, so I’d really have to take care with how I structured things), …
As with many things, the literal execution is easy, but the human factors involved are much more involved. Right now, that would take much more energy than my tending to the garden, and represents a lot more risk for me, the tens of thousands of dependent projects, and the millions of people impacted it as a result.
I may not be an active user myself any more, but I see my role as a shepherd now — I think I do that pretty well, and my collaborators and users are increasingly vocal in appreciating the work I do in this regard. (A really nice change from a few years ago!) There’s a tension between piling in new features, shedding baggage/dependencies, and maintaining compatibility, and my experience has been that having someone who isn’t Highly Motivated to push in one of these directions at the expense of the others has been good for quality overall.
I do try to find opportunities to involve it in my own activities and work when I can, but it’s rare since I don’t participate in the language ecosystem (Rust) much these days.
So, in short, I’m pretty happy with the status quo, and in answering the original comment:
Maybe that is indeed the difference. If I’d dropped it as soon as I stopped using it, I think the world would be worse off for it, but I decided to keep on maintaining it anyway. It grew into its own little thing, and I’ve been (overall) pretty happy to continue to tend to it, despite my software journey having gone in a different direction long since. :)
If you didn’t already know about the bug, chances are that it’s not affecting you. Eg, think of any open source project that you use daily (maybe TypeScript), and go check their bug tracker. Were you already aware of most of the bugs there? Because I’d say chances are really good those bugs have never impacted you.
Maybe. Or maybe it has been affecting me, and I was less observant than the person who filed the bug. Either way, if the bug is real, I’d rather solve it—whether it has been affecting me without my realizing it or it may affect me later.
There is a potentially unbounded number of bugs potentially affecting through the dependency cone of all the open source projects you are using. Absolutist thinking like ‘I must fix all bugs’ would mean you would never get anything done, for example at your job, while all those bugs are open.
Yes, in theory all sorts of work (and not just work) has the possibility to fill all available time. In practice, I’ve never found this to be a problem. As I said, I am happy to get bug reports and to fix problems. Your mileage may vary.
What about bugs that only apply to an operating system or hardware that you don’t use? Bugs that involve using the project in a way it was not intended (or at least not how you would ever use it)? Bugs when trying to use it at a scale you will never reach?
Not to say I disagree that you should try to fix them, but there is plenty of bug potential that really wouldn’t affect you directly.
I would need help to fix that most likely.
The first is not a bug (in my view). The second is a judgment call; I’d make it on a case by case basis.
Again, a judgment call.
I don’t deny that. What I would or could fix in those cases would depend on a lot of factors. I’d still probably try up to a point, and then I’d stop or leave it for others to help out. I don’t have fixed answers to all these hypotheticals other than to repeat that I find the OP’s view (“Don’t fix anything. Don’t try to confirm or test anything.”) bizarre.
Yeah, I also find it weird. Just wondered if you really fix every bug :)
Two notes about his book recommendations and three recommendations of my own.
I’m surprised that Might concludes that Strunk and White’s Elements of Style “is still a good, if not perfect, reference on style” since he cites Geoffrey Pullum who tears Elements of Style apart. People should take a look at Pullum here (PDF link) and here if they want to judge for themselves, but I think that Strunk and White is simply not a good book despite being very popular.
A tip about Joseph Williams’s Style book: buy the first edition, which you can find used very cheaply. Prentice and Hall keeps coming out with new editions, mostly I think to prevent undergrads from buying used copies and cutting into new book sales. (They now charge $55 for a paperback that is substantially the same as the book I taught in the 90s when it was about $12.)
Thomas Kane’s New Oxford Guide to Writing offers a ton of helpful practical advice.
Anne Greene’s Writing Science in Plain English is also terrific, and it’s very affordable. (Greene has a more narrow focus and is more basic than Kane, but don’t let the title put you off. Even if you are not writing about science, the core advice is excellent.)
If you care a lot about writing and you are interested in a less directly practical book, I highly recommend Clear and Simple as the Truth by Francis-Noël Thomas and Mark Turner. They take a philosophical approach to writing and treat “clear writing” as one style among others.
S&W has the advantage of being really short. S&W’s competition isn’t all these great works, it’s authors never reflecting their style at all.
Short is only beneficial if the advice in the short book is accurate and helpful. I’d argue that S&W is neither.
That said, Anne Greene’s Writing Science in Plain English is also short (128 pages), though not as short as S&W.
Not reflecting on one’s style at all would be far preferable to reading S&W. It is better to receive no advice than bad advice.
What is meant by ‘cooked mode’ in this article?
It’s the informal name for canonical mode input processing, the opposite of raw mode.
From the MIT/GNU Scheme 12.1 documentation:
This answer on Stackexchange may also help: https://unix.stackexchange.com/a/21760.
I’m not sure how non-standard it is, but I like git-delta a lot for viewing diffs.