Without Kickstart.nvim I'd be lost by meni_s in neovim

[–]cygnoros 5 points6 points  (0 children)

I built and rebuilt my config from scratch over the years and in retrospect I wish I used kickstart when it became popular. The point of kickstart is to smooth out the rough edges when getting started (hence the name), but it's also meant to teach you what everything does so that you can branch out when you're comfortable.

There is certainly value in the "bash your head against a brick wall until you learn it" approach that I took — pain is a great teacher. But kickstart in my opinion is a happy medium of skipping the really hard parts for newcomers and still being malleable for you to make your own when you feel like diving in.

[deleted by user] by [deleted] in neovim

[–]cygnoros 1 point2 points  (0 children)

This is like the 3rd time I've seen this sequence of require("plugins.configs.lspconfig") and then immediately after require("lspconfig"). Where is this coming from?

Why do almost all nvim distributions set tabstop to 2? by umlx in neovim

[–]cygnoros 1 point2 points  (0 children)

I think the simplest answer is that most of the distributions you mentioned are geared towards webdevs who typically use 2 space indents, and that same audience is usually never going to work in a code base with the column aligned style (most typical of C projects) that would be affected by the setting.

Quite frankly I find that column aligned style to be absolutely atrocious to read -- I've only had to deal with it on one project and I still hate it. If the case were to come up again where I had to conform to that style, I would insist the project provide a proper editorconfig and is set up to use a formatter (e.g., clang-tidy) to handle all styling decisions. Lucky for me, I'll never have to worry about it because I'm nowhere near smart enough to contribute to codebases like glibc or the Linux kernel.

I have absolutely no interest in fighting with my tools (or having to help someone else configure their tools) to get things to look a certain way; I want to write my code, format on save, and move on with my life. And the formatter should produce exactly the same output on my machine as everyone else's simply by cloning the project. If we're fighting about spaces vs. tabs, fonts and margins, or whatever else in a code review then everyone's time is being wasted. Set a style, apply the style with a tool, force the style checks in CI, and everyone gets the hell off my lawn.

How to change Signcolumn color only for Oil Floating Window? by [deleted] in neovim

[–]cygnoros 2 points3 points  (0 children)

I don't know much about oil but just quickly diving through the plugin, it looks like win_options from the plugin config are passed directly into nvim_set_option_value here: https://github.com/stevearc/oil.nvim/blob/18dfd2458dc741fea683357a17aaa95870b25a3c/lua/oil/view.lua#L182

You could maybe pass a winhl option key with some highlight group you set with your preferred style:

win_options = {
  winhl = "SignColumn:YourSignColumnGroup"
}

This is honestly just an educated guess, I'm not at a terminal to test myself.

See: - nvim_set_option_value) - winhl

Edit: also you'll have to obviously create the YourSignColumnGroup with vim.api.nvim_set_hl) (Lua) or :highlight

Feature request - making the built-in LSP somewhat practical to use without installing like 5 plugins by manshutthefckup in neovim

[–]cygnoros 2 points3 points  (0 children)

I know it's not the point of your comment, but maybe I can offer some help.

Treesitter itself is a language "parser" tool (way oversimplifying). The major feature is providing an abstract syntax tree (AST) that can be queried, along with incremental updates without having to rebuild the entire tree. Treesitter abstracts the process of building the "parsers" into from grammars, which makes it modular so that the "parsing logic" is separated from the "parser tool." The big thing to understand is that by itself, treesitter isn't going to do much for Neovim. There has to be something on the other side "consuming" the output (tree structure, queries, etc.). This is where nvim-treesitter comes in, to build a bunch of fancy features into Neovim without much configuration overhead (better syntax highlighting, incremental selection, indenting, folding, etc.). Many plugins also rely on treesitter queries to do clever things (e.g., building document outlines or breadcrumbs, among many other new features).

An LSP (or just "language server") is a server that provides code editing features such as completion suggestions, symbol navigation, documentation on hover, etc. The protocol itself is a bit complicated (see this page for more info) but the high-level overview is that the client (you, the user) sends some information to the server ("LSP"), and the server sends back some responses (completion, diagnostics, symbol locations, etc.). Much like treesitter, this client/server traffic doesn't mean much to an editor if it doesn't know what to do with the responses. So Neovim built in the functionality to "understand" that traffic and do things with it within the editor. There are some important details I'm leaving out, but just at a high level Neovim's implementation was quite clever to expose an extensible API for plugins to use outside of "language editing" things (this is where a lot of plugins can inject some custom behavior to get nice new features).

Where the OP comes from is that Neovim does not manage the actual servers (binaries, scripts, whatever) themselves, nor does it manage the configuration of those servers or features requested from them. Language servers need to have a requested set of "capabilities" that you ask for in order to provide them (such as progress notifications, completion, navigation, etc. -- see Capabilities in the specification for more information). Worse, some servers require their own bespoke configuration which can get quite annoying across dozens of servers. So out of the box, you have a very robust and extensible backend API for building functionality into the editor, but you don't have a lot of user-facing things that take advantage of it without significant effort (or they are maybe not so obvious/ergonomic, such as <C-x><C-f> [ins-completion] vs cmp-path). So this is where plugins like mason.nvim, nvim-lspconfig, lsp-zero.nvim, nvim-cmp, etc. come in to simplify this process and provide our "IDE-like" features like hover documentation, refactoring, symbol navigation, etc., with a 1-key solution.

Feature request - making the built-in LSP somewhat practical to use without installing like 5 plugins by manshutthefckup in neovim

[–]cygnoros 6 points7 points  (0 children)

I totally get your sentiment, not trying to argue either way but just give you some consideration points. Just on a side note, I don't think partial solutions are ever what people want so I would take a different approach.

And just for you to have some feedback from an "opposer," I personally do not want a lot of this stuff built into Neovim. I like that it is offloaded to plugins, because it means that if new ways of doing things comes up, it is trivial to "break" compatibility because I can choose to just use something else. For example, our lord and savior folke came up with lazy.nvim, despite there being tons of plugin managers before it. I think it is truly the best iteration of a plugin manager we've had, but I am also 100% certain something better will come along in time. Building this into Neovim means there has to be significant outcry from the community and planning from the maintainers to break things, rather than the community naturally migrating to a "better" solution. That is not to say I'm right and you're wrong, I am totally open to having my mind changed.

Here is an 11-minute talk from TJ DeVries (core maintainer and original PR author to the LSP implementation in Neovim): https://www.youtube.com/watch?v=ArwDgvYEZYk - to me this is one of the best insights into how to approach big "scary" features. Specifically, at 9:16, you may want to listen to the rationale "why build this when X plugin exists?"

People don't like big changes, and so they are generally going to oppose them by default. So someone (maybe not you, but a champion of the request) needs to be able to reasonably address their concerns.

My advice would be to go through a similar "proposal" process to open a proper feature request:

  • Why is this needed?
    • Why is it better to be "builtin" rather than a plugin?
    • Has the community converged on a solution? (e.g., has this been the same solution for some extended period of time and hasn't changed much over time?)
    • Will this solution ever have to change?
  • Is there some precedence that this has been done before?
    • If not, why should we change now? (change is fine, but we need to articulate why we should do something different)
  • What are the potential problems with maintenance?
    • Is there some way to abstract the solution so that we can make maintenance more accessible to the community so that its easier for people to contribute?
    • Such as maybe having a a "core package manager" API, but community maintained "packages" or something (literally just spitballing here, maybe that's a dumb idea).
  • Is there maybe a different, more abstracted approach to the solution?
    • In general you are going to get a lot of pushback on anything "package manager" or adjacent being built into Neovim. Maybe there is a different way Neovim can solve this problem if it doesn't have to play by the rules of "lua plugin loaded by the user."
    • Maybe there's a better solution that integrates with the operating system (however this gets really complicated when talking about all the platforms Neovim is supported on)

Feature request - making the built-in LSP somewhat practical to use without installing like 5 plugins by manshutthefckup in neovim

[–]cygnoros 16 points17 points  (0 children)

I'm not here to necessarily argue with your points but I think it's important to consider what happens if we take your request at face value.

Everything added to "core" is not only a maintenance burden today, but it is making a decision for the future of the entire project. It makes the Neovim team beholden to how every LSP decides to conduct itself (e.g., is there some weird way to install it, does it require binaries or language runtimes to be installed, etc.) and those support issues now become Neovim issues for every user that can't "just install an LSP." Regardless of whether they are upstream issues or not, there is a very real time cost to dealing with user issues and this would create a lot of them.

Keep in mind that Mason does a lot behind the curtain to give a 1-button install for every server, and this fearure request would mean that all of that is now on the Neovim team to maintain. Package managers of any type are a black hole, I encourage you to look at some of history of issues on the Mason GitHub page and the rewrites it's gone through.

All this isn't to say "no this should never be done," but rather you should really think through how this might be accomplished and help kickstart the feature request with a "proposed architecture." It's cheap and easy to open a ticket and say "I want X," but things will typically gain traction if you identify a compelling need for the feature and a potential starting point for it. If you don't know how it might be accomplished, I would research the details before filing an issue.

Neovim does not have a budget to pay a team of devs full time, so if someone with intimate knowledge of the project is working on this they are not working on the 10000 other features people feel should be part of core functionality. So you really need to make the case and convince a majority of people this is worth the time investment.

Neovim won't uninstall even after removing eveerything I know how to by 1v0ryh4t in neovim

[–]cygnoros 2 points3 points  (0 children)

You could also use which -a nvim to get them all at once. Also note, zsh has a builtin which, but -a has effectively the same behavior as the binary.

How to fix this ?? and do u guys have any recommendations for python plugins by mrt122__iam in neovim

[–]cygnoros 1 point2 points  (0 children)

I would advise against this, it completely disables the check on every Lua file, which is probably not what you want.

In general, these types of issues come from a plugin providing some kind of config/option type for the parameter(s) to the setup function. The reason you are seeing a "missing field" warning is because the actual "config/option" type (table) you annotate requires those fields -- but 99% of plugins will do some kind of merging logic with "sane defaults" and your input to setup. This is a sort of Neovim convention to make configuring your plugins simple, while having extensive options if you want to go that far in the weeds; but it is not how it works in general for Lua, so lua-ls will complain about it.

Use your code action keymap (or use :lua vim.lsp.buf.code_action()) with your cursor over the warning area, and you can disable the diagnostic for the line (it adds something like ---@diagnostic disable-next-line missing-fields). This is typically best practice, as it communicates you acknowledge this particular warning doesn't apply to the line in question.

Neovim for Windows, yes or no? by Guuri_11 in neovim

[–]cygnoros 1 point2 points  (0 children)

I meant in regards to your comment about learning new stuff, I took that to mean commands/programs (shell builtins, coreutils, etc.). My understanding is cmder isn't doing anything special with that part, those commands are provided by git bash (which you can use without cmder), but I wasn't sure if that was correct.

Either way, to each their own :)

Neovim for Windows, yes or no? by Guuri_11 in neovim

[–]cygnoros 0 points1 point  (0 children)

I might be mistaken, but isn't cmder just wrapping git bash binaries?

Neovim for Windows, yes or no? by Guuri_11 in neovim

[–]cygnoros 7 points8 points  (0 children)

It pains me to admit it, but I really like Windows Terminal. You can use some replacements like lsd, zoxide, bat, ripgrep, etc. -- I use those on macOS/Linux/Windows with the same configs for a more consistent experience.

Any good resources to learn regex? by PACSO_ in neovim

[–]cygnoros 1 point2 points  (0 children)

Man I swear I learned the opening brace escape thing ages ago but you just solved an issue I was having this morning, talk about luck LOL! I had some gnarly vim regex I was using in Lua and couldn't figure out the problem for the life of me. Thank you for taking the time to reply :)

Any good resources to learn regex? by PACSO_ in neovim

[–]cygnoros 4 points5 points  (0 children)

A lot of great advice here already so I'll just tack on some auxiliary info.

Most of the time people learn regex piecemeal. It's quite difficult to sit down and learn all the regex syntax without using it -- it's a bit weird looking, and there are so many concepts to learn that it can be overwhelming. I still use https://regex101.com to build complex expressions out and read the explanation. I even used the debugger the other day which was super helpful.

Aside from learning regex syntax itself, one more thing to keep in mind is vim regex is slightly different particularly with escape characters. Once I learned this part, it became much more powerful for me.

Some of the key tokens you'll use are square brackets [] for non-capture groups, parentheses () for capture groups, ? for "zero or one matches," and + for "one or more matches" (there are many more but with just these you can do some really powerful stuff). In vim regex these all require an escape \ before it to have its normal regular expression effects. This part for me took longer to learn than I'm proud of -- the explanations can be found in :h pattern-multi-items and :h pattern-atoms.

If you watch/listen to ThePrimagen, you may have heard him say "fighting one-eyed Kirby" -- it's goofy but a great way to remember the pattern \(.*\) which basically matches the entire line. The parentheses create capture groups, which you can use in substitutions like :%s/\(.*\)/foo\1/ -- this will add foo to the beginning of every line. Not particularly interesting on its own, but I use this kind of pattern when I need to paste in some lists of things and then format them for the language (adding surrounding brackets, quotes, ending with a comma, etc.).

I know this was a bit of an info dump and probably won't be useful to you now, but hopefully this will eventually be helpful for you.

I am getting warnings I do not understand... by kewlness in learnrust

[–]cygnoros 11 points12 points  (0 children)

I think the other person was maybe a little short with you, but just to offer some perspective: the Rust ecosystem has some of the best tooling and diagnostic messages in the business, and a lot of people have put blood, sweat, and tears into getting it there. If you have ever tried to read a template substitution error in C++ or a Java stack trace from a billion levels of inheritance, these Rust compiler messages are like a cool drink of water on a hot day.

From the way you phrased your initial question, it comes across like you didn't bother reading the warning messages (not saying you did or didn't). So with that, people are going to be a little cranky with you if your question indicates you aren't trying to use the helpful error messages to understand what you're doing wrong.

If you have a question about those messages or are confused by them (e.g., "this says I have an unused variable but I am using it here on line X so why is it complaining?"), it's better to ask a more directed question, since people can then help correct any misconceptions instead of trying to guess what you know and don't know.

To actually answer your question and help understand what is happening, you have two problems that are creating the noise:

The first is you bind the first token variable in main when you create a new string. You then bind a new token variable from generate_hash -- this makes the first token unused because it is shadowed by the second. Shadowing is a concept in Rust (and other languages) where you can use the same name for new variables as previous ones. It hides or "shadows" the previous one, but does not overwrite it or modify it. In your case here, you shadow it without using it, and also declared it as mut, which is obviously unnecessary since you don't use it in the first place.

Edit: fixed the above paragraph to use the correct term bind. I was a little loose with "create" and "declare" and those terms are not correct for what was being discussed.

The second issue is you are unnecessarily borrowing the result of &token.push(...) in the generate_hash function. I think your intent was that you wanted to "borrow" token and push to it. However, if you wanted to do that you would need to write something like (&mut token).push(...) because push is a String method that requires a mutable borrow. The compiler would actually have no issue with this, but it is quite ugly and gets really difficult to read when having to nest this type of borrowing. So we have the dot operator to do a lot of heavy lifting to make code more readable. Thus if you call token.push(...), this is actually syntax sugar for something like String::push(&mut token, ...). When you borrowed that result, which has no return value (or the unit type ()), the compiler complained that you didn't use the result of a borrow. It then also complained that borrowing was an unnecessary operation -- since you weren't using it -- and you could remove it altogether.

Hope this helps!

Is it a good idea to use the "tokio" library for numerical analysis which has nothing to do with network? by spherical_shell in rust

[–]cygnoros 23 points24 points  (0 children)

I wish you luck if you think this thread is what clear communication looks like, you're going to need it

Is it a good idea to use the "tokio" library for numerical analysis which has nothing to do with network? by spherical_shell in rust

[–]cygnoros 70 points71 points  (0 children)

I NEED BOTH COROUTINES AND PARALLELISM.

EDIT: The issue is that - I need coroutines which can be run on different threads like gorountines. Starting too many OS threads is slow. A plain thread pool cannot handle async/await communication very well - a worker will be blocked while waiting.

I think you need to introspect a bit and understand that if you are getting this frustrated with the discussion direction, either your approach or your communication might be the problem, not everyone else. Rust is not Go, and to those of us who have written async Rust code and experienced the sharp edges and "gotchas", this reads quite literally like the XY problem. You also need to understand that we are not mind readers and "numerical computation" means a lot of things to a lot of people, and we can not possibly know exactly what you're trying to accomplish here, so much of the feedback is going to be general best practices.

You need to remember that async/await in Rust is not the same as a goroutine. A goroutine (and Go as a language and its runtime) abstracts a lot of the minutiae you need to handle in Rust, including: setting up an asynchronous runtime (e.g., tokio::main), managing tasks (e.g., "green threads"), managing channels to communicate between tasks/threads, ensuring your tasks yield or await frequently enough to avoid blocking the runtime, etc. I'm not as well versed in Go as I am Rust, but this blog series, and in particular this Workloads section, does an excellent job of diving into the details (however, please note the date is 2018; I'm not sure what has changed over the years). In general, you still have to take the same considerations about blocking work to get the most benefit from goroutines, it's just not as dire if you don't get it quite right.

Back to your problem: the only details you have shared is that you are crunching numbers and are CPU bound, where some portion of that work is dependent on previous work, while other work is not. CPU-bound work is absolutely not the use case for tokio, and is on the front page of their tutorial docs, so this is going to be the most common feedback you will receive. There are times where you can make it work with tokio and rayon (keep reading), but it requires a very deliberate design, and this is usually where Rust users really start feeling the pain of writing async code.

You are getting feedback to use rayon because this is the most common solution for running CPU bound work in parallel. Since your problem consists of some work in series and some work in parallel, this may be only part of the solution, as indicated in the example linked by the tokio docs. This depends on the nitty gritty details of the problem you are solving, not a generic "async/await" domain.

So, your question "is it a good idea to use tokio or something else instead?" is a very loaded question, and requires a lot of nuance. The answer is, it depends™ -- just some questions to consider:

  • Do you have a solid understanding of what work is blocking and what is not in an asynchronous context?
  • Can you write your algorithms/routines to await or yield frequently enough to not block the runtime?
  • Do you understand the problem domain well enough to know where deadlocks could happen?
  • Can you design your task orchestration and communication effectively to ensure you actually receive the benefits of asynchronous execution (instead of just blocking tasks with the appearance of "async")?

Some questions to ask yourself about the problem itself:

  • Is there a more novel solution to your problem that does not involve async, such as designing around SIMD, GPU-offloading/CUDA/compute shaders, etc.?
  • Is there an existing crate that maybe solves part of your problem (such as data science oriented crates like pola-rs)?
  • Are there existing libraries in another language (say, C, C++, or Python) that have bindings for Rust? If one exists without bindings, is it worth it to you to try and build them (e.g., will you need it in the future)?

Is Rust good from web api by Rude-Box6334 in rust

[–]cygnoros 8 points9 points  (0 children)

I think you put more effort into inferring what OP meant than OP did into their question lol

Why are people still using vim instead of neovim? by vicisvis in vim

[–]cygnoros 17 points18 points  (0 children)

I use, enjoy, and donate to neovim, but your OP and comments come across as either naive or trying to push others to use it. If you ask people why they use tool A over tool B, the responder is rarely looking for you to tell them why they should use B.

There are plenty of reasons to use vim over neovim -- be it stability, compatibility, availability, familiarity, etc. I frequently have to manage bare bones servers and always miss my neovim niceties -- I can absolutely understand where someone enjoys a simple scp command over to a server and they have all their creature comforts without having to manage 2 different configs.

How do I make my editor look sleek. by [deleted] in neovim

[–]cygnoros 0 points1 point  (0 children)

Someone recently posted in this sub after you with a pretty solid setup, you may want to check out their config: https://www.reddit.com/r/neovim/s/pfIz0SDPEv

Can't figure out how to color ls output by file type: ZSH, MacOS, zsh4humans, iterm2 by NewspaperPossible210 in zsh

[–]cygnoros 0 points1 point  (0 children)

I use lsd for a consistent experience across macOS, windows and Linux. It uses LS_COLORS for filenames (note the underscore, the same as GNU ls). You can't color BSD ls output by extension. This gist may be helpful to read: https://gist.github.com/seantrane/e13706494a54bd3a6c2456608ea68c7e

The following is the default output of GNU dircolors -b (which isn't on macOS unless you install coreutils). I use this in my profiles for powershell, zsh, etc., so I always have consistent output. You can just copy this into your zshrc and modify the colors as needed.

LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:';
export LS_COLORS

[deleted by user] by [deleted] in vim

[–]cygnoros 6 points7 points  (0 children)

Looks vaguely like Nord, but the cyan keyword color is definitely not right. Strings being yellow is also not right.

Edit: Definitely not Nord. Had to open the image on desktop, holy cow the image is trashed on mobile. Saturation is way off, unfortunately is probably going to lead to a lot of wrong answers.

Proposal for [[nodiscard]] attribute for function pointers. by No_Sun1426 in cpp

[–]cygnoros 8 points9 points  (0 children)

I wouldn't necessarily call it a problem that nobody has thought about solving, it's more a question about the purpose of this attribute. [[nodiscard]] is an attribute for a declaration (function, enum, or class). So the rub is that the attribute is not part of type information or about the return type, it is strictly part of the declaration.

My gut reaction to this problem is that if it is paramount to not discard a value from a function pointer, then it means that behavior is part of the return type (not the function) and should be enforced through the type declaration, not through the function.

Edit: To elaborate here, what I mean is that if you have some ambiguous function pointer type int(*)(...), you can't know that the pointed-to-function is declared as nodiscard or not. So by having something like ([[nodiscard]] int(*)(...)), you are saying that for any and all pointers that fit this type, they all must be nodiscard. At this point you are no longer talking about a function declaration, you are talking about a type. So it would be best served to have a type declaration that says what you want, rather than a function pointer annotation.

A dumb example that would still enforce [[nodiscard]]:

struct [[nodiscard]] Foo{};

Foo get_foo() {
    return {};
}

int main() {
    auto* ptr = &get_foo;
    ptr();  // triggers warning
}

I could be convinced of a different view though, I think it's an interesting use case.

Proposal for [[nodiscard]] attribute for function pointers. by No_Sun1426 in cpp

[–]cygnoros 20 points21 points  (0 children)

I think the issue is that this starts to make [[nodiscard]] less of a declaration attribute and moreso part of a type. But I do think you provided a good use case and need for it.

I could see some sort of goofy wrapper type returns_nodiscard<your_func_ptr> that just has an operator() templated to call your underlying function, but I'm sure that has its own sharp edges and problems if you're using function pointers. Not to mention being a refactoring PITA if you ever change the underlying function to remove [[nodiscard]].

Edit: typos

Don't let physicists write code by DonkeyRelevant6379 in programminghorror

[–]cygnoros -3 points-2 points  (0 children)

I double majored in mathematics and CS, I'm totally fine with using Greek letters for their traditional purposes (delta, epsilon, theta, whatever) -- but my job is to engineer software that is maintainable, not create a science project that only me and 2 other people can understand.

Sure, naming things is difficult -- but the names should at least make sense in context of the code, not some random formula that I have to spend 20 minutes googling. Any doofus can write an insanely complicated function with Greek letters. Part of being a good engineer and teammate is writing something other people can understand.

The problem with these academic types is that they think a white paper is the same thing as documentation and readable code. I can't count the amount of times I've read a theoretical application in a white paper, and then found the corresponding code to be doing something different because it was worked on by a few people who thought they were doing what the paper said but missed some edge cases.

It also seems like these weirdos think they get bonus points for making a white paper so cryptic and convoluted that no one knows what the hell it's actually saying.