People who design APIs. I am begging you. It doesn't matter how "simple" or "intuitive" or "elegant" your API is. You need to include sample code.
Another thing I am begging of people who make APIs: When you include sample code in the docs, include the "using"/"use"/"import"/"#include" statements. Please. Please. I just pasted this inline sample code https://mlem.ellpeck.de/articles/ui.html#setting-it-up into my hello world program, and it's failing because the symbol "UntexturedStyle" could not be found. "Are you missing a using directive or an assembly reference?", asks dotnet. Yeah, probably?? because you didn't tell me what using directives I needed?!?
MLEM.Ui | MLEM Documentation

"But it's obvious" I'M READING THE "GETTING STARTED" DOCUMENTATION. OBVIOUSLY I HAVE NO BASIS FOR COMPREHENDING WHAT IS OR ISN'T OBVIOUS
One other recurring thing that makes me tear my hair out in documentation: You document the type of the argument/variable/return value, but you don't document the *units*. Okay, so it's a rotation. But is it in degrees? Radians? [0.0, 1.0)? Is this time parameter in seconds, milliseconds, nanoseconds, CPU ticks? What direction is "Z"?! What is the handedness of your coordinate system?!!
Did you know it's common for VR gaming APIs to specify units in meters? Like actual, physical, literal meters? Like draw a cube of size 1.0 and you can get out a tape measure and peek out the little gap between the headset and your nose and the cube is one actual meter wide? Doesn't that make sense? Would you have *ever* guessed that if I hadn't just told you?
@mcc Answering your questions: no! (And I'm happy that it's metric and not in yards or inches or furlongs or something!)
@hisham_hm @mcc I forget what the deal is with Unreal Units, but IIRC they group in 16 or something which I found odd.
@onelson @hisham_hm @mcc 16 units per foot is pretty common for that lineage
@onelson @hisham_hm @mcc that sounds like fixed-point
@mcc that’s a pretty decent default unit of length, it would have been my guess. I’m pretty sure at least one 3D modeling program I’ve used defaulted to it (and the default cube was a cubic meter).
@mcc yes, I would assume that all graphics/simulation stuff used meters as their units unless explicitly specified otherwise
@porglezomp @mcc yeah, metric, right?
@ehproque @porglezomp @mcc even living in the US so not in my everyday life, all the 3d software I’ve used has had metric coordinate systems, like for their default physics engine settings.

@mcc Too bad all the other points of confusion you listed still exist in VR. 😮‍💨

"I want to make this object 3 meters tall!" Done! Easy! 👍

"Now I want to move it forward 2 meters!" Woah woah woah! Slow down! Are you using Unreal? Unity? DirectX? OpenGL? What even is "forward"?!?

@mcc Yeah, don’t even get me started on mapping that onto augmented reality using commodity hardware, where you also need to calibrate the camera to determine field of view and distortion characteristics. I used to know how to calculate the units coming out of that transform, but no longer.
@mcc I think that's the default for apple displaying usdz files, I would have guessed it was an industry standard
@mcc Yeah that's been a recurring annoyance for me. "Welp, I guess I gotta try all combinations."

@mcc Also, “a rotation”? You mean there are multiple rotations? Which one is it? Why isn't that part of the name, and since it's not, why isn't that part of the docs?

I loathe when people just take the name of a property, the name of the object it's on, slap an article in front and consider that documentation. There is *no useful information* in these docs, might as well be honest and delete them… (pet peeve when I do code reviews, sorry…)

@mcc This is exactly why I gave my sound library generic types Time<T>, Duration<T> and various T's such as AudioSample, Beat, and Second. Never had another unit-related bug. (Well, except in the actual unit conversion code 😅)

https://github.com/RobJellinghaus/NowSound/blob/master/NowSoundLibShared/NowSoundTime.h

NowSound/NowSoundLibShared/NowSoundTime.h at master · RobJellinghaus/NowSound

Low latency audio library for Windows 10, targeted at Unity UWP and desktop apps. - RobJellinghaus/NowSound

GitHub
@MCSpaceCadet That’s a good idea.
@shanecelis It's to the point that I cringe whenever I see "int" for anything other than a loop index. What KIND of "int" is it??? Or "float" and "double" for that matter.
@mcc Just like every timeout argument or configuration file entry randomly chooses seconds or milliseconds. Is it waiting for 3.6 seconds or an hour? shrug emoji
@mcc I don't remember where, but the most cursed thing I had to work with was half revolution unit, meaning a full rotation was 2.0, at least you just have to multiply by PI to get the radian but for a solid week I kept pulling my hair as to why my rotations where fucked up. Nowhere I looked mentioned it wasn't radians.
@mcc NGL I want this as a cross stitch.
@mcc This one gets me a lot, too.
@mcc This is something the UNIX man pages got right nearly 50 years ago. The synopsis included linker flags and #include files needed to call any routine.
@mcc God yes, especially c or c++ where there's almost never any relationship between the header file name and the type name and the compiler can rarely help you (recently I've run into this a lot with template specializations where the actual definition I need is in a different header than the declaration too).
@megmac C/C++ is a special hell because often you can import a symbol by *accident*. So code will work in one project and then you'll paste it into another and suddenly a critical symbol isn't found, because in the original project you included B.h which included A.h because nobody clearly told you in the first place you needed to include A.h.
@mcc @megmac clangd can help here: when you have LSP completion set up in your editor and you select (for example) a function 'foo' from the completion menu, if the header that declares 'foo' is not already included, clangd will auto-insert the appropriate `#include` directive at the same time that it inserts 'foo()'.

@mcc @megmac oh wait; you said "paste", in which case you don't get the popup menu...

However! In that case, clangd will offer auto-fixes (which insert the appropriate header) when you request a code-action[1][2] with the cursor at the point of the error.

[1] see textDocument/codeAction https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/

[2] usable e.g. in neovim with:
vim.keymap.set('n', '<A-f>', vim.lsp.buf.code_action, bufopts)

Specification

This document describes the 3.17.x version of the language server protocol. An implementation for node of the 3.17.x version of the protocol can be found here.

@mcc The Zulip API docs do such a good job of this! Every code example is a self-contained Python program, e.g., https://zulip.com/api/send-message . I love it. It's probably the only API documentation I've ever loved.
Send a message | Zulip API documentation

POST https://rust-cuda.zulipchat.com/api/v1/messages | Send a stream message or a direct message. | type string required | The type of message to be sent. | "direct" for a direct message and "stream" for a stream message. | Changes: In Zulip 7.0 (feature level 174), "direct" was added as the preferred way to request a direct message, deprecating the original "private". While "private" is still supported for requesting direct messages, clients are encouraged to use to the modern convention with servers that support it, because support for "private" will eventually be removed.

Zulip
@mcc Ooh! And also, I know your API "works best" with your custom build environment/IDE/editor/wrapper library/etc. But please, if it's possible to use without that, give me at least one example that's as close to a single file as you can make it, starts with the `main()` equivalent for the language in question, and does the bare bones init steps with a simple "did it work?" output.
@mcc so much this. Sample code should run and do something that makes sense.
@KevinMarks @mcc I have given up on so many source repos where the build command failed to compile or run the example, and it just isn't quite worth it to try to troubleshoot a problem *before* I try it out.
@travisfw @KevinMarks @mcc If it's not part of the solution, it's part of the precipitate.
@travisfw @KevinMarks @mcc the other day, I found a repo with a CI action to build the examples on all changes and at 3am every day. If the 3am build fail, the CI open a ticket.

@mcc OMG yes. "It's simple!" is always followed by the least-intuitive commands and return structures known to man.

MFs you gotta remember this is the first time we're interacting with your code, intuitive and easy for you is likely inscuitable and confusing for everyone else.

Drives me absolutely bonkers.

@wy477wh173 @mcc "Our API is so elegant that we still haven't figured how to write any sample code for it, but it's so simple that we expect that you can do it." ;)

@wy477wh173 @mcc It reminds me of a problem that comes up with game development - where because you're so close to the product and test it so often, puzzle difficulty can be hard to assess.

The "dead easy" puzzles are the ones you ran through a thousand times - that doesn't mean that they'll be easy to someone coming into the game the first time and who doesn't know what it does.

@AT1ST @mcc yep, no idea how many iterations out tutorial went through on Soul King, how many times i watched a player just faceplant on what i thought were simple barriers.

I assumed the visual language of a Bear trap paired with a huge "caught in a trap, mash f to escape", and the player staggering down would be enough. But nope, many times nope.

@wy477wh173 @mcc
The standard link for "intuitive" claims: https://www.asktog.com/papers/raskinintuit.html

»In short, "intuitive" in this context is an almost exact synonym of "familiar."«

Or, more meta: It’s said that "intuitive" is in a thing but it is in a person’s relation to that thing, so intuitive for one person is not intuitive for another. …it probably is very intuitive/familiar for the people who created it!

Jef Raskin on "Intuitive Interfaces"

@wy477wh173 @mcc Gotta love inverse Dunning-Krueger.

Someone who has become an expert in XYZ (far worse here, because XYZ was produced by the workings of their own brain) is very likely to think newcomers should find it just as "simple" as they now do.

@wy477wh173 @mcc

Yeah if the getting started docs contain “simply…” or “just…” I start to cringe just a little.

@mcc Or, you know, your API could tell you in its endpoints exactly how your API works.
@AeonCypher No!!! You need example code!! You make the endpoints clear and then 20 minutes later I'm scratching my head at why there's a thrown exception inside your code, or losing time because dotnet is insisting there's no package named "Mlem.Startup" because unbeknowst to me it's named "MLEM.Startup". There's always something!!!
@mcc I haven't made APIs in a long time. However, when I did I wrote them in such a way that the API would be self describing (hypermedia/HATEOS) and would be completely self documenting.
It was impossible for the API to incorrectly self-describe or have out of date specs, because the API was generated by introspection on the interface that handled the API.
Sample code: HTTP requests, would be identical to the description of the HTTP properties.
But, maybe I'm missing something.
@AeonCypher Here is an example of something that couldn't be self-documenting in the endpoints, because it concerns something that exists outside the endpoints. https://mastodon.social/@mcc/111882244957795896 If I don't know what package/namespace UntexturedStyle is in, I don't even know what set of self-documenting endpoints to get out.
@mcc Ah. You are referring to in usecases like packages and libraries.
I agree, you should have example code.
@AeonCypher An example of something for HTTP RPCs which exist "outside" of endpoint documentation however are things like how to obtain an API key, or what port you're running on.
@mcc Just to be clear, I'm not a fan of RCP.
There's no reason an HTTP endpoint can't also have text/html links to signup.
It's relatively common for hypermedia APIs to report back request information.
Everything you need to do from an endpoint should be available from that endpoint. You don't have to go look up instructions on how to use Amazon or Google. There are forms and links.

@AeonCypher "Endpoint" is a term from an entirely different realm of APIs. One that's so close to bordering absurdity that people who believe in them might as well talk about "Discord servers".

@mcc

@riley @mcc We figured out that I was talking about a very different kind of API than MCC.
@AeonCypher @riley An RPC API is certainly a type of API. However, I do not understand why so many people have responded to my initial post on the assumption that the word "API" refers to an RPC API and not anything else.
@mcc @riley I was assuming a web API, because 90% of the time when someone says API in an uncontextualized manner they mean an API over HTTP (TCP/IP).

@AeonCypher It's so insolent an answer that I must tirritate you by calling CONNECT an endpoint.

@mcc

@AeonCypher @riley i disagree with this statement completely

@mcc

And please if you have a WriteFN2(text,strlen) and a WriteFN3(text,strlen) be very very specific in your example as to why you need to use one vs the other…and if in the future you update the API code to discontinue WriteFN2 can you detail why in the update notes?!?

I am looking specifically at you, SolidWorksAPI team (or tribe/troop/barrel as you might truly be a bunch of monkeys…)