News for hackers. Stuff that matters.
Re:Greppability is an underrated code metric by db48x on Monday September 02, 2024 @11:58PM (#41431114)
Rust and Javascript and Lisp all get extra points because they put a keyword in front of every function definition. Searching for “fn doTheThing” or “defun do-the-thing” ensures that you find the actual definition. Meanwhile C lacks any such keyword, so the best you can do is search for the name. That gets you a sea of callers with the declarations and definitions mixed in. Some C coding conventions have you split the definition into two lines, first the return type on a line followed by a second line that starts with the function name. It looks ugly, but at least you can search for “^doTheThing” to find just the definition(s).
Re:Greppability is an underrated code metric by CGamesPlay on Tuesday September 03, 2024 @12:19AM (#41431222)
Not JavaScript. Cool kids never write “function” any more, it’s all arrow functions. You can search for const, which will typically work, but not always (could be a let, var, or multi-const intializer).
Re:Greppability is an underrated code metric by pjerem on Tuesday September 03, 2024 @03:14AM (#41432163)
Yes but that’s an anti pattern. Arrow functions aren’t there to look cool, they’re how you define lambdas / anonymous functions.

Other than that, functions should be defined by the keyword.

Re:Greppability is an underrated code metric by wiseowise on Tuesday September 03, 2024 @03:26AM (#41432242)
How is that an anti-pattern?

> Other than that, functions should be defined by the keyword.

Says who?

Re:Greppability is an underrated code metric by tylerhou on Tuesday September 03, 2024 @03:55AM (#41432418)
As of a few years ago (not sure about now) the backtrace frame info for anonymous functions were far worse than ones defined via the function keyword with a name.
Re:Greppability is an underrated code metric by lukan on Tuesday September 03, 2024 @03:41AM (#41432326)
All the wise ones. Well, except for you maybe.

Serious arguments would be:

- readability - greppabiloty

Re:Greppability is an underrated code metric by lukan on Tuesday September 03, 2024 @01:09PM (#41436943)
(It wasn't an insult, but a joke on the username)
Re:Greppability is an underrated code metric by hansworst on Tuesday September 03, 2024 @04:28AM (#41432615)
Anonymous functions don't have names. This makes it much harder to do things like profiling (just try to find that one specific arrow function in your performance profile flame graph) and tracing. Tools like Sentry that automatically log stack traces when errors occur become much less useful if every function is anonymous.
Re:Greppability is an underrated code metric by medstrom on Tuesday September 03, 2024 @06:07AM (#41433235)

    const foo = () => {}
This function is not anonymous, it's called foo.
Re:Greppability is an underrated code metric by BlarfMcFlarf on Tuesday September 03, 2024 @07:09AM (#41433619)
Does the function know it’s called foo for tracing/error logging/etc?
Re:Greppability is an underrated code metric by croes on Tuesday September 03, 2024 @07:13AM (#41433655)
But to call foo in bar you must define foo before bar.

function foo(){} is also callable if bar is defined before foo.

Re:Greppability is an underrated code metric by sestep on Tuesday September 03, 2024 @08:31AM (#41434325)
Not true at the top-level.
Re:Greppability is an underrated code metric by wruza on Tuesday September 03, 2024 @10:25AM (#41435300)
Not sure what you find not true about it. All named “function”s get hoisted just like “var”s, I use post-definitions of utility functions all the time in file scopes, function scopes, after return statements, everywhere. You’re probably thinking about

  const foo = function (){}
without its own name before (). These behave like expressions and cannot be hoisted.
Re:Greppability is an underrated code metric by MetaWhirledPeas on Tuesday September 03, 2024 @10:55AM (#41435559)
> I use post-definitions of utility functions all the time in file scopes, function scopes, after return statements, everywhere

I haven't figured out if people consider this a best practice, but I love doing it. To me the list of called functions is a high-level explanation of the code, and listing all the definitions first just buries the high-level logic "below the fold". Immediately diving into function contents outside of their broader context is confusing to me.

Re:Greppability is an underrated code metric by wruza on Tuesday September 03, 2024 @11:29AM (#41435910)
I don’t monitor “best” practices, so beware. But in languages like C and Pascal I also had a habit of simply declaring all interfaces at the top and then grouping implementations reasonably. It also created a nice “index” of what’s in the file.

Hoisting also enables cross-imports without helper unit extraction headaches. Many hate js/ts at the “kids hate == and null” level but in reality these languages have a very practical design that wins so many rounds irl.

Re:Greppability is an underrated code metric by mrighele on Tuesday September 03, 2024 @08:31AM (#41434321)
Interesting, it seems that the javascript runtime is smart enough detect this pattern and actually create a named function (I tried Chrome and Node.js)

    const foo = () => {}
    console.log( foo.name );
actually outputs 'foo', and not the empty string that I was expecting.

   const test = () => ( () => {} );
   const foo = test();
   console.log( foo.name );
outputs the empty string.

Is this behavior required by the standard ?

Re:Greppability is an underrated code metric by svieira on Tuesday September 03, 2024 @09:00AM (#41434536)
Re:Greppability is an underrated code metric by Izkata on Tuesday September 03, 2024 @01:04PM (#41436891)
You're probably remembering how it used to work. This is the example I remember from way back that we shouldn't use because (aside from being unnecessary and weird) this function wouldn't have a name in stack traces:

  var foo = function() {};
Except nowadays it too does have the name "foo".
Re:Greppability is an underrated code metric by mapcars on Tuesday September 03, 2024 @09:31AM (#41434767)
Not really, its an anonymous function stored in a variable foo
Re:Greppability is an underrated code metric by mostlylikeable on Tuesday September 03, 2024 @08:27AM (#41434286)
To me, arrow functions behave more like I would expect functions to behave. They don’t include all the magic bindings that the function keyword imparts. Feels more “pure” to me. Anonymous functions can be either function () {} or () => {}
Re:Greppability is an underrated code metric by bobbylarrybobby on Tuesday September 03, 2024 @09:17PM (#41440947)
Functions and arrow functions have an important difference: arrow functions do not create their own `this`. If you're in a context where a nested function needs to maintain access to the outer function’s `this`, and you don't want to muck with `bind` or `call`, then you need an arrow function.
Re:Greppability is an underrated code metric by lispisok on Tuesday September 03, 2024 @12:21AM (#41431235)
Am I the only one who hates arrow functions?
Re:Greppability is an underrated code metric by crabmusket on Tuesday September 03, 2024 @02:47AM (#41432003)
I don't like using them everywhere, but they're very handy for inline anonymous functions.

But it really pains me when I see

export const foo = () => {}

instead of

export function foo() {}

Re:Greppability is an underrated code metric by creesch on Tuesday September 03, 2024 @02:52AM (#41432031)
Thank you, that's something I also never have understood myself. For inline anonymous functions like callbacks they make perfect sense. As long as you don't need `this`.

But everywhere else they reduce readability of the code with no tangible benefit I am aware of.

Re:Greppability is an underrated code metric by berkes on Tuesday September 03, 2024 @03:26AM (#41432234)
I wish javascript had a built-in or at least (defacto) default linter. Like go-fmt or rust fmt. Or clippy even.

One that could enforce these styles. Because not only is the export const foo = () {}

painful on itself, it will quite certainly get intermixed with the

function foo() {}

and then in the next library a

const foo = function() {}

and so on. I'd rather have a consistently irritating style, than this willy-nilly yolo style that the JS community seems to embrace.

Re:Greppability is an underrated code metric by throwitaway1123 on Tuesday September 03, 2024 @04:15AM (#41432537)
ESLint and Prettier are the de facto default linter/formatter combo in JS. There are rules you can enable to force your preferred style of function [1][2].

[1] https://eslint.org/docs/latest/rules/func-style

[2] https://eslint.org/docs/latest/rules/prefer-arrow-callback

Re:Greppability is an underrated code metric by berkes on Wednesday September 04, 2024 @05:05AM (#41443470)
They are miles away from `gofmt` or `rust fmt` or `cargo clippy` and so on.

It's not opinionated, but requiring you to form your own opinion or at least choose from a palette of opinions.

It requires effort to opt-in rather than effort to opt-out.

The community doesn't frown on code that's not adhering to the common standard or code that doesn't pass the "out of the box" linter.

So, if I have a typescript project with a tree of some 20 dependencies (which is, unfortunately, a tiny project), I'll have at least five styles of code when it browse through it. Some JS, some TS, some strictly linted with "no-bikeshedding", some linted with configs that are bigger than the codebase itself. Some linted with outdated. Many not linted at all. It's really a mess. Even if each of the 20 dependencies themselves are clean, beauties, the whole is an inconsistent mess.

Re:Greppability is an underrated code metric by throwitaway1123 on Wednesday September 04, 2024 @12:33PM (#41447630)
I personally believe that Prettier strikes a decent balance between being configurable vs being opinionated. I've used formatters that are much less opinionated than Prettier (e.g. the last time I used XCode it only handled indentation by default). ESLint also teeters on the edge between configuration vs convention quite well in my opinion, especially given the fact that browser JS and server side JS have vastly different linting requirements. I also love the extensibility of ESLint. Being able to write your own linting rules is a boon on productivity. Having access to custom framework specific linting rules is quite nice (I couldn't use React without the react-hooks/rules-of-hooks third party ESLint rules).

> Some JS, some TS

I think the JS community has done remarkably well amongst dynamically typed languages in settling on one form of gradual typing and adopting it fervently (Flow no longer has any market share at all). Whereas the last time I checked Python still had the Mypy/Pywright divide, and Ruby had the Sorbet/RBS dichotomy.

Ultimately though, most of your critique boils down to the fact that JS (unlike Rust and Go) isn't maintained by a single monolithic entity, and therefore there's no one to dictate the standards you're looking for. If Deno were the sole caretaker of JS for example, we'd have a standard linter and formatter devoid of complex configuration, but Deno doesn't control JS.

This is a consequence of JS being a collaborative product of the various browser vendors, TC39, and the server side JS runtimes that have adapted JS to run on servers. The advantage of this of course though is that JS can run natively in the browser. I think that's a decent tradeoff to make in exchange for having to wade through dependencies with different ideas about when it's appropriate to use arrow functions.

Re:Greppability is an underrated code metric by jappgar on Tuesday September 03, 2024 @07:12AM (#41433645)
These aren't equivalent as function foo will be hoisted but const foo will not be.
Re:Greppability is an underrated code metric by cxr on Tuesday September 03, 2024 @07:40AM (#41433873)
Sure the food that this restaurant serves is pricey, but you have to remember that it also tastes terrible.
Re:Greppability is an underrated code metric by crabmusket on Tuesday September 03, 2024 @10:16AM (#41435205)
Yep, and that usually doesn't matter at the top level.
Re:Greppability is an underrated code metric by NohatCoder on Tuesday September 03, 2024 @08:27AM (#41434288)
But do they make much of a difference? You have always been able to write:

    myArray.sort(function(a,b){return a-b})
People for some reason treat this syntactic sugar like it gives them some new fundamental ability.
Re:Greppability is an underrated code metric by marcosdumay on Tuesday September 03, 2024 @10:44AM (#41435460)
Oh Javascript would be much better if it could only be syntactic sugar...

`function(a,b){return a-b;}` is different from `(a,b) => a - b`

And `function diff(a,b) {return a-b;}` is different from `const diff(a,b) => a - b;`.

Re:Greppability is an underrated code metric by spartanatreyu on Tuesday September 03, 2024 @12:44AM (#41431342)
I did, until I used them enough where I saw where they were useful.

The bad examples of arrow functions I saw initially were of:

1. Devs trying to mix them in with OOP code as a bandaid over OOP headahes (e.g. bind/this) instead of just not using OOP in the first place.

2. Devs trying to stick functional programming everywhere because they had seen a trivial example where a `.map()` made more semantic sense than a for/for-in/for-of loop. Despite the fact that for/for-in/for-of loops were easier to read for anything non-trivial and also had better performance because you had access to the `break`, `continue` and `return` keywords.

Re:Greppability is an underrated code metric by mewpmewp2 on Tuesday September 03, 2024 @03:33AM (#41432286)
Another benefit of using for instead of array fns is that it is easy to add await keyword should the fn become async.

But many teams will have it as a rule to always use array fns.

Re:Greppability is an underrated code metric by jappgar on Tuesday September 03, 2024 @07:09AM (#41433629)
That gives you have the option of making it serially async but not parallel, which can be achieved easily using Promise.all in either scenario.
Re:Greppability is an underrated code metric by adregan on Tuesday September 03, 2024 @09:10AM (#41434616)
As an aside: It’s way less ergonomic, but you likely want `Promise.allSettled` rather than `Promise.all` as the first promise that throws aborts the rest.
Re:Greppability is an underrated code metric by wruza on Tuesday September 03, 2024 @10:35AM (#41435385)
It doesn’t really abort the rest, it just prioritizes the selection of a first catch-path as a current continuation. The rest is still thenable, and there’s no “abort promise” operation in general. There are abort signals, but it’s up to an async process to accept a signal and decide when/whether to check it.
Re:Greppability is an underrated code metric by adregan on Tuesday September 03, 2024 @01:19PM (#41437048)
Admittedly, I was being a bit hand-wavy and describing a bit more of how it feels rather than the way it is (I'm perpetually annoyed that promises can't be cancelled), but I was thinking of the code I've seen many times across many code bases:

    let results;
    try {
      results = await Promise.all(vals.map(someAsyncOp))
    } catch (err) {
      console.error(err)
    }
While you could pull that promises mapping into a variable and keep it thenable, 99% of the time I see the above instead. Promises have some rough edges because they are stateful, so I think it might be easier to recommend swapping that Promise.all for an Promise.allSettled, and using a shared utility for parsing the promise result.

I consider this issue akin to the relationship between `sort`, `reverse`, `splice`, the mutating operation APIs, and their non mutating counterparts `toSorted`, `toReversed`, `toSpliced`. Promise.all is kind of the mutating version of allSettled.

Re:Greppability is an underrated code metric by throwaway2037 on Tuesday September 03, 2024 @05:33AM (#41433038)

    > also had better performance because you had access to the `break`, `continue` and `return` keywords.
This is a great point.

One more: Debugging `.map()` is also much harder than a for loop.

Re:Greppability is an underrated code metric by medstrom on Tuesday September 03, 2024 @06:56AM (#41433524)
I feel there are a few ways to invoke .map() in a readable way and many ways that make the code flow needlessly indirect.

Should be a judgment call, and the author needs to be used to doing both looping and mapping constructs, so that they are unafraid of the bit of extra typing needed for the loop.

Re:Greppability is an underrated code metric by nosianu on Tuesday September 03, 2024 @02:32AM (#41431910)
A simple heuristic I use is to use arrow functions for inline function arguments, and named "function" functions for all others.

One reason is exactly what the subject of discussion is here, it's easier to string-search with that keyword in front of the name, but I don't need that for trivial inline functions (whenever I do I make it an actual function that I declare normally and not inline).

Then there's the different handling of "this", depending on how you write your code this may be an important reason to use an arrow function in some places.

Re:Greppability is an underrated code metric by turboponyy on Tuesday September 03, 2024 @02:37AM (#41431942)
I like them because it reinforces the idea that functions are just values like any other - having a separate keyword feels like it is inconsistent.
Re:Greppability is an underrated code metric by 0xfffafaCrash on Tuesday September 03, 2024 @03:09AM (#41432134)
Moreover the binding and lexical scope aspects supported by classic functions are amongst the worst aspects of the language.

Arrow functions are also far more concise and ergonomic when working with higher order functions or simple expressions

The main thing to be wary of with arrow functions is when they are used anonymously inline without it being clear what the function is doing at a glance. That and Error stack traces but the latter is exacerbated by there being no actual standard regarding Error.prototype.stack

Re:Greppability is an underrated code metric by mewpmewp2 on Tuesday September 03, 2024 @03:35AM (#41432294)
Why do you want to reinforce that idea?

To me arrow functions mostly just decrease readability and makes them blend in too much, when it should be important distinction what is a function and what is not.

Re:Greppability is an underrated code metric by turboponyy on Tuesday September 03, 2024 @04:57AM (#41432803)
Not to be dismissive, but because I like it - it just sits right with me.
Re:Greppability is an underrated code metric by benrutter on Tuesday September 03, 2024 @02:16PM (#41437534)
I'm not a javascript programmer, but I really like the arrow pattern from a distance exactly because it enforces that idea.

My experience is that newcomers are often thrown off and confused by higher order functions. I think partly because, well let's be honest they just are more confusing than normal functions, but I think it's also because languages often bind functions differently from everything else.

`const cool = () => 5`

Makes it obvious and transparent, that `cool' is just a variable where as:

`function cool() {return 5}`

looks very different from other variable bindings.

Re:Greppability is an underrated code metric by throwitaway1123 on Tuesday September 03, 2024 @03:38PM (#41438379)
Since we're on the topic of higher order functions, arrow functions allow you to express function currying very succinctly (which some people prefer). This is a contrived example to illustrate the syntactical differences:

  const arrow = (a) => (b) => `${a}-${b}`
  
  function verbose(a) {
    return function (b) {
      return `${a}-${b}`
    }
  }
  
  function uncurried(a, b) {
    return `${a}-${b}`
  }
  
  const values = ['foo', 'bar', 'baz']
  values.map(arrow('qux'))
  values.map(verbose('qux'))
  values.map(uncurried.bind(null, 'qux'))
  values.map((b) => uncurried('qux', b))
Re:Greppability is an underrated code metric by nsonha on Tuesday September 03, 2024 @10:42PM (#41441372)
> should be important distinction what is a function and what is not

code is to express logic clearly to the reader. We should assess it for that purpose, before assess for any derivative, secondary concern such as whether categories of things in code (function etc) visually pops out when you use some specific tool like vim, or grep. There are syntax highlighters for a reason. And maybe if grep sucks with code then build the proper tool for code searching, instead of writing code after the tool.

Re:Greppability is an underrated code metric by ndnxncjdj on Tuesday September 03, 2024 @01:19AM (#41431524)
I very much prefer the way scoping is handled in arrow functions.
Re:Greppability is an underrated code metric by nsonha on Tuesday September 03, 2024 @03:15AM (#41432176)
why the need to pronounce arbitrary preferences, who cares?
Re:Greppability is an underrated code metric by ajuc on Tuesday September 03, 2024 @07:17AM (#41433687)
I'm of the opinion that giving a global name to an anonymous function should result in a compilation error.
Re:Greppability is an underrated code metric by albedoa on Tuesday September 03, 2024 @03:42AM (#41432331)
I want to talk to the developer who considers greppability when deciding whether to use the "function" keyword but requires his definitions to be greppable by distancing them from their call locations. I just have a few questions for him.
Re:Greppability is an underrated code metric by supriyo-biswas on Tuesday September 03, 2024 @12:22AM (#41431240)
You can still search for `<keyword> = \(.*\) => `, albeit it's a bit cumbersome.
Re:Greppability is an underrated code metric by post-it on Tuesday September 03, 2024 @12:40AM (#41431324)
All you need is `<keyword> =`

Really, all you need is `<keyword>` and if the first result is a call to that function, just jump to its definition.

Re:Greppability is an underrated code metric by spartanatreyu on Tuesday September 03, 2024 @12:46AM (#41431352)
Exactly.

Just search the definition.

Any time that a function doesn't have a definition, it's never the target of a search anyway.

Re:Greppability is an underrated code metric by troupo on Tuesday September 03, 2024 @02:08AM (#41431782)
All you need is a tool that actually understands the language.

It's 2024 and HN still suggests using regular expressions to search through a code base.

Re:Greppability is an underrated code metric by lukan on Tuesday September 03, 2024 @03:45AM (#41432356)
Regex is a universal tool.

Your special tool might not work on plattform X, fails for edge case - and you generally don't know how it works. With regex or simple string search - I am in control. And can understand why results show up, or investigate when they don't, but should.

Re:Greppability is an underrated code metric by troupo on Tuesday September 03, 2024 @04:17AM (#41432545)
> Your special tool might not work on plattform X

As always, people come out with the weirdest of excuses to not use actual tools in the 99.9999% of the cases when they are available, and work.

When that tools doesn't work, or isn't sufficient, use another one like fuzzy text search or regexps.

> and you generally don't know how it works.

Do you know how your stove works? Or do you truly understand what the device you're typing this comment on truly works?

Only in programming I see people deliberately avoid useful tools because <some fringe edge case that comes up once in a millenium in their daily work>

Re:Greppability is an underrated code metric by kragen on Tuesday September 03, 2024 @07:04AM (#41433586)
if you think anything works in 99.9999% of cases, you’ve never programmed a computer
Re:Greppability is an underrated code metric by lukan on Tuesday September 03, 2024 @05:11AM (#41432885)
When you specialize in one thing only, do what you want.

But I prefer tools, that I can use wherever I go. To not be dependant and chained to that environment.

"Do you know how your stove works? Or do you truly understand what the device you're typing this comment on truly works?"

Also yes, I do.

" people deliberately avoid useful tools because <some fringe edge case that comes up once in a millenium in their daily work>"

Well, or I did already changed tools often enough, to be fed up with it and rather invest in tech that does not loose its value in the next iteration of the innovation cycle.

Re:Greppability is an underrated code metric by troupo on Tuesday September 03, 2024 @07:01AM (#41433558)
> When you specialize in one thing only, do what you want.

I specialize in one thing only: programming

> But I prefer tools, that I can use wherever I go.

Do you always walk everywhere, or do you use a tool available at the time, like cars, planes, bycicles, public transport?

> rather invest in tech that does not loose its value in the next iteration of the innovation cycle.

Things like "fund symbol", "find usages", "find implementation" have been available in actual tools for close to two decades now.

Re:Greppability is an underrated code metric by lukan on Tuesday September 03, 2024 @07:46AM (#41433923)
I did not say I do not use what is avaiable, but this debate is about in general having your code in a shape that simply searching for strings work.
Re:Greppability is an underrated code metric by troupo on Tuesday September 03, 2024 @11:24AM (#41435862)
Simply searching for strings rarely works well as the codebase grows larger. Because besides knowing where all things named X are, you want to actually see where X is used, or where it's called from, or where it is defined.

With search you end up grepping the code twice:

- first grepping for the name

We're literally in a thread where people invent regexes for how to search the same thing (a function) defined in two different ways (as a function or as a const)

- secondly, manually grepping through search results deducing if it's relevant to what you're looking for

It becomes significantly worse if you want to include third-party libs in your search.

There are countless times when I would just Cmd+B/Cmd+Click a symbol in IDEA and continue my exploration down to Java's own libraries. There are next to zero cases when IDEA would fail to recognise a function and find its usages if it was defined as a const, not as a function. Why would I willingly deny myself these tools as so many in this thread do?

Re:Greppability is an underrated code metric by wruza on Tuesday September 03, 2024 @11:16AM (#41435774)
It’s you who sees it as excuses. If I have a screwdriver multitool, I don’t need another one which is for d10 only. It simply creates unnecessary clutter in a toolbox. The difference between definition and mention search for a function is:

  gr<bs><bs>ion name<cr>
  vs
  grname<cr>
or for the current identifier, simply

  gr<m-w><cr>
I could even make my own useful tools like “\[fvm]gr” for function, variable or field search and brag about it watching miserable ide guys from the high balcony, but ain’t that unnecessary as well.
Re:Greppability is an underrated code metric by troupo on Tuesday September 03, 2024 @11:20AM (#41435818)
> It simply creates unnecessary clutter in a toolbox.

And then you proceed to... invent several pale imitations of a symbol/usages search.

More here: https://news.ycombinator.com/item?id=41435862 so as not to repeat myself

Re:Greppability is an underrated code metric by wruza on Tuesday September 03, 2024 @11:37AM (#41436006)
Doesn’t really apply, ignores things just said.
Re:Greppability is an underrated code metric by throwaway2037 on Tuesday September 03, 2024 @05:36AM (#41433059)
Not to move the goal posts too much, but when I am searching a huge Python or Java code base from IntelliJ, I use a mixture of symbol and text search. One good thing about text search, you get hits from comments.
Re:Greppability is an underrated code metric by troupo on Tuesday September 03, 2024 @07:02AM (#41433571)
Yup. I do, too.

I'm mostly ranting against this weird "we will never use great tools because full-text search" obsession

Re:Greppability is an underrated code metric by renox on Tuesday September 03, 2024 @06:45AM (#41433457)
The thing is: In large codebase the tool may become slow or crash, in a new language you may not have such tool.. Grep is far more robust!
Re:Greppability is an underrated code metric by troupo on Tuesday September 03, 2024 @11:26AM (#41435883)
When tools don't work or unsuitable, you use different tools.

And yet people are obsessed with never using useful tools in the first place because they can invent scenarios when this tool doesn't work. Even if these scenarios might never actually come up in their daily work.

Re:Greppability is an underrated code metric by wruza on Tuesday September 03, 2024 @10:58AM (#41435593)
Its current year and IDEs still can’t remember how I just transformed the snippet of code and suggest to transform the rest of the files in the same way. All they can do in “refactor” menu is only “rename” and then some extract/etc nonsense which no one uses irl.

By using regexps I have an experience that opens many doors, and the fact that they aren’t automatic could make me sad, if only these doors weren’t completely shut without that experience.

Re:Greppability is an underrated code metric by troupo on Tuesday September 03, 2024 @11:32AM (#41435951)
No one is stopping you from using regexps in IDEs.

And you somehow manage to undersell the rename functionality in an IDE. And I've used move/extract functionality multiple times.

I do however agree that applicable transformations (like upgrading to new syntaxes, or ways of doing stuff as languages evolve) could be applied wholesale to large chunks of code.

Re:Greppability is an underrated code metric by db48x on Wednesday September 11, 2024 @02:17AM (#41508521)
I both agree and disagree with this.

I was very careful about how I phrased my comment. Languages can gain points by being greppable, and they can gain points by having a well–implemented mode for my favorite editor, and they can also gain points by having a well–implemented language server. They can do all three to gain the most points (and of course there are many other ways to gain or lose points; this is just one tiny aspect of language design), but they don’t have to. And nobody should try to force every language designer to shave the yak of writing an Emacs mode or a Language Server.

And sometimes you just want to improve some random piece of software written in a language that you’ve never used before, without having to shave a bunch of yaks to get the language server installed. Sometimes all you have is grep and you’ll want to be able to use it on this weird new language.

Re:Greppability is an underrated code metric by spartanatreyu on Tuesday September 03, 2024 @12:29AM (#41431272)
Yes JavaScript.

You can search for both: "function" and "=>" to find all function expressions and arrow function expressions.

All named functions are easily searchable.

All anonymous functions are throw away functions that are only called in one place so you don't need to search for them in the first place.

As soon as an anonymous function becomes important enough to receive a label (i.e. assigning it to a variable, being assigned to a parameter, converting to function expression), it has also become searchable by that label too.

Re:Greppability is an underrated code metric by CGamesPlay on Tuesday September 03, 2024 @01:31AM (#41431579)
The => is after the param spec, so you’re searching for foo.*=> or something more complex, but then still missing multiline signatures. This is very easy to get caught by in TypeScript, and also happens when dealing with higher-order functions (quite common in React).
Re:Greppability is an underrated code metric by spartanatreyu on Tuesday September 03, 2024 @02:23AM (#41431859)
Why are you searching for foo.=>

Are you searching through every function, or functions that have a very specific parameter?

And whatever you picked, why?

---------------------------------------------------------------

- If you're searching for every function, then there's no need to search for foo.=>, you only need to search for function and =>.

- If you're searching for a specific parameter, then just search for the parameter. Searching for functions is redundant.

---------------------------------------------------------------

Arrow function expressions and function expressions can both be named or anonymous.

Introducing arrow functions didn't suddenly make JavaScript unsearchable.

JavaScript supported anonymous functions before arrow function expressions were introduced.

Anonymous functions can only ever be:

- run on the spot

- thrown away

- or passed around after they've been given a label

Which means, whenever you actually want to search for something, it's going to be labelled.

So search for the label.

Re:Greppability is an underrated code metric by Pxtl on Tuesday September 03, 2024 @11:34AM (#41435966)
You can still look for `(funcname)\s*=` can't you? I mean it's not like functions get re-declared a lot.
Re:Greppability is an underrated code metric by bionsystem on Tuesday September 03, 2024 @12:19AM (#41431223)
Doesn't cscope fit this usecase ?
Re:Greppability is an underrated code metric by eddieh on Tuesday September 03, 2024 @12:22AM (#41431241)
I used to define functions as `funcname (arglist)`

And always call the function as `funcname(args)`

So definitions have a space between the name and arg parentheses, while calls do not. Seemed to work well, even in languages with extraneous keywords before definitions since space + paren is shorter than most keywords.

Now days I don’t bother since it really isn’t that useful especially with tags or LSP.

I still put the return type on a line of its own, not for search/grep, but because it is cleaner and looks nice to me—overly long lines are the ugliest of coding IMO. Well that and excessive nesting.

Re:Greppability is an underrated code metric by semiinfinitely on Tuesday September 03, 2024 @12:38AM (#41431308)
python also!
Re:Greppability is an underrated code metric by jsjohnst on Tuesday September 03, 2024 @07:45AM (#41433915)
Python is the only one mentioned that “actually works” without endless exceptions to the rule in the normal case. The ones mentioned (Rust/Javascript/Lisp/Go) all have specific syntax that is commonly enough used which makes it harder to search. Possible, absolutely, but still harder.
Re:Greppability is an underrated code metric by zbentley on Tuesday September 03, 2024 @09:15AM (#41434651)
I'd say Python works well at greppability because community conventions generally discourage concealing certain kinds of definitions (e.g. function definitions are usually "def whatever").

However, that's just convention. Lots of modules do metaprogramming tricks that obscure greppability, which can be a pain. This is particularly acute when searching for code that is "import-time polymorphic"--that is, code which picks one of several implementations for a piece of functionality at import time at the module scope. That frequently ends up with some hanky-panky a la "exported_function_name = _implementation1 if platform_supported else _implementation2" at the module scope.

While sometimes annoying, that type of thing is usually done for understandable reasons (picking an optimized/platform-supported implementation of an interface--think select or selectors in the stdlib, or any pypi implementation of filesystem monitoring using fsnotify/fanotify/kqueue/fsevents/ReadDirectoryChangesW). Additionally, good type annotations help with greppability, though they can't fully mitigate this issue.

Much less defensible in Python is code that abuses locals/globals to indirect symbol access, or code that abuses star imports to provide interfaces/implementation switching.

Those, fortunately, are rare, but the elephant in the "no greppability ever" room is not: getattr bullshit in OO code is so often utterly obscure, unnecessary and terrible. And it's distressingly common on PyPi. At first I thought this was Ruby's encouragement of method_missing in the bad old days bleeding into the Python community, but the number of programmers for whom getattr magic is catnip seems to be disproportionate to the number of folks with Ruby experience, and, more concerningly, seems to me to be growing over time.

Re:Greppability is an underrated code metric by koito17 on Tuesday September 03, 2024 @12:57AM (#41431417)
Golang has a similar property as a side-effect of the following design decision.

  ... the language has been designed to be easy to analyze and can be parsed without a symbol table
Taken from https://go.dev/doc/faq

The "top-level declarations" in source files are exactly: package, import, const, var, type, func. Nothing else. If you're searching for a function, it's always going to start with "func", even if it's an anonymous function. Searching for methods implemented by a struct similarly only needs one to know the "func" keyword and the name of the struct.

Coming from a background of mostly Clojure, Common Lisp, and TypeScript, the "greppability" of Go code is by far the best I have seen.

Of course, in any language, Go included, it's always better to rely on static analysis tools (like the IDE or LSP server) to find references, definitions, etc. But when searching code of some open source library, I always resort to ripgrep rather than setting up a development environment, unless I found something that I want to patch (which in case I set up the devlopment environment and rely on LSP instead of grep to discover definitions and references).

Re:Greppability is an underrated code metric by eptcyka on Tuesday September 03, 2024 @03:23AM (#41432217)
Golang gets zero points from me because function receivers are declared between func and the name of the function. God ai hate this design choice and boy am I glad I can use golsp.
Re:Greppability is an underrated code metric by medstrom on Tuesday September 03, 2024 @06:04AM (#41433215)
Is it just hard to get used to, or does it fundamentally make something more difficult?
Re:Greppability is an underrated code metric by eptcyka on Tuesday September 03, 2024 @07:30AM (#41433796)
I have to always add wildcards between func and the function name, because I can never know how the other developer has decided to specify the name of the receiver. This will always be a problem as far as grepping with primitive tools that don't parse the language.
Re:Greppability is an underrated code metric by medstrom on Tuesday September 03, 2024 @08:18AM (#41434211)
FYI, many people use thin wrappers like this, it's still a primitive tool that doesn't parse the language, but it can handle that problem: https://jumpshare.com/s/zMENBSr2LwwauJVjo1wS (GIF)
Re:Greppability is an underrated code metric by eptcyka on Tuesday September 03, 2024 @08:33AM (#41434334)
On machines where I control the tooling, this is not an issue. But I can’t take my config to my colleagues machine.
Re:Greppability is an underrated code metric by lanstin on Tuesday September 03, 2024 @10:49AM (#41435507)
If only AFS had succeeded. What would a modern version of this look like?
Re:Greppability is an underrated code metric by ljm on Tuesday September 03, 2024 @06:28AM (#41433353)
Can’t say I’ve ever had an issue with it, but it does get a bit wild when you have a function signature that takes a function and returns one, unless you clear it up with some types.

  func (s *Recv) foo(fn func(x any) err) func bar(y any) (*Recv, err)
As an exaggerated example. Easy to parse but not always easy to read at a glance.
Re:Greppability is an underrated code metric by kragen on Tuesday September 03, 2024 @06:59AM (#41433544)
this thread is about using `grep` to find things, and this subthread is specifically about how the `func` keyword in golang makes it easy to distinguish the definition of a function from its uses, so yes, because `grep 'func lart('` will not find definitions of `lart` as a method. you might end up with something like `grep 'func .*) *lart('` which is both imprecise and enough noise that you will not want to type it; you'll have to can it in a script, with the associated losses of flexibility and transparency
Re:Greppability is an underrated code metric by medstrom on Tuesday September 03, 2024 @07:21AM (#41433722)
That's fair, I see many examples in this thread where people pass an exact string directly to grep, as you do. I'm an avid grepper, but my grep tool [1] translates spaces to ".*?", so I would just type "func lart(" in that example and it would work.

An incremental grep tool with just this one transformation rule gets you a lot more mileage out of grep.

[1] https://github.com/minad/consult/blob/screenshots/consult-li...

EDIT: Better demo https://jumpshare.com/s/zMENBSr2LwwauJVjo1wS

Re:Greppability is an underrated code metric by kragen on Tuesday September 03, 2024 @07:33AM (#41433818)
that's going to find all the functions that take an argument named lart or of a lart type too, but it also sounds like a thing i really want to try
Re:Greppability is an underrated code metric by vitus on Tuesday September 03, 2024 @07:50AM (#41433964)
Also, anything that contains "func" and "lart" as a substring, e.g. foobar(function), blart(baz).

It's not far off from my manually-constructed patterns when I want to make sure I find a function definition (and am willing to tolerate some false positives), but I personally prefer fine-grained control over when it's in use.

Re:Greppability is an underrated code metric by medstrom on Tuesday September 03, 2024 @08:04AM (#41434100)
Mmh, I type "func\ lart(" when I need the literal string. But it's less often, so it's fair that it's slightly more to type.
Re:Greppability is an underrated code metric by kragen on Tuesday September 03, 2024 @08:12AM (#41434156)
yeah!
Re:Greppability is an underrated code metric by alienchow on Tuesday September 03, 2024 @07:20PM (#41440290)
For functions: grep -P '^func funcName\('

For methods: grep -P '^func [^)]+\) methodName\('

Hope that helps.

Re:Greppability is an underrated code metric by kragen on Tuesday September 03, 2024 @08:23PM (#41440629)
thanks, that definitely looks better! pcre is kind of working against you here tho; i assume you're invoking it out of habit
Re:Greppability is an underrated code metric by alienchow on Tuesday September 03, 2024 @09:09PM (#41440899)
I am actually unaware of downsides of PCRE. Could you explain? I hardly ever use literal grep nowadays.
Re:Greppability is an underrated code metric by kragen on Wednesday September 04, 2024 @02:47AM (#41442588)
oh, i mean that instead of

    grep -P '^func [^)]+\) methodName\('
you could say

    grep 'func [^)]*) methodName('
which is a bit less typing

however, i have to admit that i sort of ensnared myself in my own noose here by being too clever! i forgot that grep's regexp dialect only supports + if you \ it, and it took me six tries to figure out why i wasn't getting any grep hits. there's a lot to be said for the predictability and consistency of pcre!

Re:Greppability is an underrated code metric by kiitos on Wednesday September 04, 2024 @04:08PM (#41450176)
No need for any func, you can just

    grep '\) methodName\('
Re:Greppability is an underrated code metric by kragen on Wednesday September 04, 2024 @05:17PM (#41450940)

    grep: Unmatched ) or \)
but your main point might be right; the few non-method matches to (pcre) '\)\s*\w+\s*\(' in /usr/share/go-1.19 seem to be uncommon things like this:

    static void __attribute__ ((constructor)) sigsetup(void) {
    void poison() __attribute__ ((weak));
    C3 = -(R + I) // ADD(5,6) NEG(-5,-6)
Re:Greppability is an underrated code metric by sethammons on Tuesday September 03, 2024 @07:48AM (#41433941)
I search ") myFunc" to find member functions. It would be nice to search "c myFunc", but a parentheses works
Re:Greppability is an underrated code metric by db48x on Wednesday September 11, 2024 @01:48AM (#41508362)
Yea, that was my workaround for Go as well. Go both gains and loses points here.
Re:Greppability is an underrated code metric by executesorder66 on Tuesday September 03, 2024 @10:16AM (#41435211)
How many God AI's have expressed their hate for this design? /s
Re:Greppability is an underrated code metric by kazinator on Tuesday September 03, 2024 @11:02AM (#41435636)
Receivers are utterly idiotic. Like how could anyone with two working brain cells sign off on something like that?

If you don't want OOP in the language, but want people to be able to write thing.function(arg), you just make function(thing, arg) and thing.function(arg) equivalent syntax.

Re:Greppability is an underrated code metric by Pxtl on Tuesday September 03, 2024 @11:31AM (#41435941)
C# did this for extension methods and it Just Works. You just add the "this" keyword to a function in a pure-static class and you get method-like calling on the first param of that function.
Re:Greppability is an underrated code metric by kazinator on Tuesday September 03, 2024 @11:37AM (#41436004)
If the function has to be modified in any way in order to grant permission to be used that way, then it is not quite "did this".

Equivalent means that there is no difference at the AST level between o.f(a) and f(o, a), like there is no difference in C among (a + i), a[i], i[a] and (i + a).

However, a this keyword is way better than making the programmers fraction off a parameter and move it to the other side of the function name.

Re:Greppability is an underrated code metric by tczMUFlmoNk on Tuesday September 03, 2024 @01:45PM (#41437256)
A search term here is "Uniform Function Call Syntax", as present in (e.g.) D:

https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax

Re:Greppability is an underrated code metric by db48x on Wednesday September 11, 2024 @01:57AM (#41508416)
I completely agree with that.
Re:Greppability is an underrated code metric by alienchow on Tuesday September 03, 2024 @07:17PM (#41440276)
I very rarely use literal grep at all. Perl grep is my standard goto.

For functions: grep -P '^func funcName\('

For methods: grep -P '^func [^)]+\) methodName\('

Re:Greppability is an underrated code metric by aadhavans on Wednesday September 04, 2024 @01:09PM (#41448097)
What about piped grep statements?

grep func | grep functionName

Re:Greppability is an underrated code metric by madeofpalk on Tuesday September 03, 2024 @04:41AM (#41432693)
The culture of single letter variables in golang, at least in the codebases I've seen, undoes this.
Re:Greppability is an underrated code metric by alienchow on Tuesday September 03, 2024 @06:44AM (#41433450)
Single letter variables in Golang are to be used in small, local contexts. Akin to the throwaway i var in for loops. You only grep the struct methods, the same way no one greps 'this' or 'self'.

The code bases you've been reading, and even some of the native libraries, don't do it properly. Probably due to legacy reasons that wouldn't pass readability approvals nowadays.

Re:Greppability is an underrated code metric by VonGallifrey on Tuesday September 03, 2024 @05:02AM (#41432831)
The way I have seen this is that single letter variables are mostly used when declaration and (all) usages are very close together.

If I see a loop with i or k, v then I can be fairly confident that those are an Index or a Key Value pair. Also I probably don't need to grep them since everything interacting with these variables is probably already on my screen.

Everything that has a wider scope or which would be unclear with a single letter is named with a more descriptive name.

Of course this is highly dependent on the people you work with, but this is the way it works on projects I have worked on.

Re:Greppability is an underrated code metric by lelanthran on Tuesday September 03, 2024 @05:27AM (#41432988)
> The culture of single letter variables in golang, at least in the codebases I've seen, undoes this.

The convention, not just in Go, is that the smaller the scope, the smaller the variable reference.

So, sure, you're going to see single-letter variables in short functions, inside short block scopes, etc, but that is true of almost any language.

I haven't seen single-letter variables in Go that are in a scope that isn't short.

Of course, this could just mean that I haven't seen enough of other peoples Go source.

Re:Greppability is an underrated code metric by iudqnolq on Tuesday September 03, 2024 @06:28AM (#41433358)
I like using l for logger and db for database client/pool/handle even if there's a wider scope. And if the bulk of a file is interacting with a single client I might call that c.
Re:Greppability is an underrated code metric by marcosdumay on Tuesday September 03, 2024 @10:37AM (#41435397)
> that is true of almost any language

You'd be surprised how often language-local cultures break that rule on either side. And a few times it's even an improvement.

Re:Greppability is an underrated code metric by lanstin on Tuesday September 03, 2024 @10:47AM (#41435484)
Zipf's law, right - these rules are a formalization of our brain's functionality with language.

Of course, with enough code, someone does everything.

Re:Greppability is an underrated code metric by kazinator on Tuesday September 03, 2024 @11:22AM (#41435843)
E.g. food and art are very important in Japan, so stomach is i and a drawing/painting is e.
Re:Greppability is an underrated code metric by BrandoElFollito on Tuesday September 03, 2024 @01:22PM (#41437083)
Food is very very important in France so we call it nourriture :)
Re:Greppability is an underrated code metric by vitus on Tuesday September 03, 2024 @07:41AM (#41433880)
I'm not so sure about greppability in the context of Go. At least at Google (where Go originates, and whose style guide presumably has strong influence on other organizations' use of the language), we discourage "stuttering":

> A piece of Go source code should avoid unnecessary repetition. One common source of this is repetitive names, which often include unnecessary words or repeat their context or type. Code itself can also be unnecessarily repetitive if the same or a similar code segment appears multiple times in close proximity.

https://google.github.io/styleguide/go/decisions#repetitive-...

(see also https://google.github.io/styleguide/go/best-practices#avoid-...)

This is the style rule that motivates the sibling comment about method names being split between method and receiver, for what it's worth.

I don't think this use case has received much attention internally, since it's fairly rare at Google to use grep directly to navigate code. As you suggest, it's much more common to either use your IDE with LSP integration, or Code Search (which you can get a sense of via Chromium's public repository, e.g. https://source.chromium.org/search?q=v8&sq=&ss=chromium%2Fch...).

Re:Greppability is an underrated code metric by klodolph on Tuesday September 03, 2024 @02:02PM (#41437417)
The thing about stuttering is that the first part of the name is fixed anyway, MOST of the time.

If you want to search for `url.Parse`, you can find most of the usages just by searching for `url.Parse`, because the package will generally be imported as `url` (and you won’t import Parse into your namespace).

It’s not as good as find references via LSP but it is like 99% accurate and works with just grep.

Re:Greppability is an underrated code metric by vitus on Tuesday September 03, 2024 @06:33PM (#41440002)
That works somewhat for finding uses of a native Go module, although I've seen lots of cases where the module name is autogenerated and so you need to import with an alias (protobufs, I'm looking at you). It also doesn't work quite so well in reverse -- you need to find files with `package url;`, then find instances of '\bfunc Parse\('.

Lastly, one of the bigger issues is (as aforementioned sibling commenter mentioned) the application of this principle to methods. This is especially bad with method names for established interfaces, like Write or String. Even with a LSP server, you then need to trace up the call stack to figure out what concrete types the function is being called with, then look at the definitions of those types. I can't imagine wanting to do that with only (rip)grep at my disposal.

Re:Greppability is an underrated code metric by alexvitkov on Wednesday September 04, 2024 @01:14PM (#41448145)
Wild that the people who made the language that forces me to type

  if err != nil {
      return nil, err
  }
after every second statement are advising against code repetition.
Re:Greppability is an underrated code metric by kiitos on Wednesday September 04, 2024 @04:05PM (#41450128)
Wild that you don't distinguish between error handling and name repetition.
Re:Greppability is an underrated code metric by alexvitkov on Wednesday September 04, 2024 @05:28PM (#41451052)
The issue is about "repetition" - a concept that exists on the syntactic level, and is unavoidable in Go.

To put it in a way you may understand, it's when you have to press keys in the same order a lot of times and you get sad.

Re:Greppability is an underrated code metric by kiitos on Thursday September 05, 2024 @04:29PM (#41460145)
Repetition at the syntactic level, as you describe here, is, statistically, zero percent of the time spent in any meaningful software project. It, quite literally, doesn't matter.

Time spent by authors typing source code characters into their editor is almost entirely irrelevant. The only thing that matters is the time spent by readers parsing and understanding the source code in the VCS.

Re:Greppability is an underrated code metric by remram on Tuesday September 03, 2024 @04:50PM (#41439067)
In golang you get `func (someName someType) funcname`, so it's much less greppable than languages using `func funcname`
Re:Greppability is an underrated code metric by tuetuopay on Wednesday September 04, 2024 @04:33AM (#41443247)
Go is horrible due to the absence of specific "interface implementation" markers. Gets pretty hard to find where or how a type implements an interface.
Re:Greppability is an underrated code metric by kiitos on Wednesday September 04, 2024 @04:07PM (#41450162)
Interfaces are consumer contracts, they say "I need this" not "I provide this".

Regardless, any reasonable LSP will let you "Find implementations" of any interface definition.

Re:Greppability is an underrated code metric by tuetuopay on Thursday September 05, 2024 @11:19AM (#41457456)
Yup, but we're talking about grep, not lsp. And that's precisely why I don't write go without an lsp (the rare times I do write go).
Re:Greppability is an underrated code metric by bryanrasmussen on Tuesday September 03, 2024 @01:22AM (#41431546)
JavaScript has multiple ways to define a function so you sort of lose that getting the actual definition benefit.

on edit: I see someone discussed that you can grep for both arrow functions and named function at the same time and I suppose you can also construct a query that handles a function constructor as well - but this does not really handle curried functions or similar patterns - I guess at that point one is letting the perfect become the enemy of the good.

Most people grepping know the code base and the patterns in use, so they probably only need to grep for one type of function declaration.

Re:Greppability is an underrated code metric by veltas on Tuesday September 03, 2024 @01:29AM (#41431574)
For most functions ^\S.*name( will find declarations and definitions.

Most of us use exuberant ctags to allow jumping to definitions.

Re:Greppability is an underrated code metric by skywal_l on Tuesday September 03, 2024 @01:40AM (#41431639)
Yet you reply to an article that defines functions as variables, which I've seen a lot of developers do usually for no good reason at all.

To me, that's a much common and worse practice with regards to greppability than splitting identifiers using string which I haven't seen much in the wild.

Re:Greppability is an underrated code metric by kazinator on Tuesday September 03, 2024 @02:18AM (#41431835)
C has "classical" tooling like Cscope and Exuberant Ctags. The stuff works very well, except on the odd weird code that does idiotic things that should not be done with preprocessing.

Even for Lisp, you don't want to be grepping, or at least not all the time for basic things.

For TXR Lisp, I provide a program that will scan code and build (or add to) your tags file (either a Vim or Emacs compatible one).

Given

  (defstruct point ()
    x
    y)
it will let your editor jump to the definition of point, x and y.
Re:Greppability is an underrated code metric by dan-robertson on Tuesday September 03, 2024 @02:24AM (#41431866)
Not sure this is very true for Common Lisp. Classic example are accessor functions where the generic function is created by whichever class is defined first and the method where the class is defined. Other macros will construct new symbols for function names (or take them from the macro arguments).
Re:Greppability is an underrated code metric by f1shy on Tuesday September 03, 2024 @02:30AM (#41431897)
Still you can extend the concept without a lot of work, couldn't you?
Re:Greppability is an underrated code metric by db48x on Tuesday September 03, 2024 @07:02AM (#41433573)
That’s true, but I regard it as fairly minor. Accessor functions don't have any logic in them, so in practice you don’t have to grep for them. But it can be confusing for new players, since they don't know ahead of time which ones are accessors and which are not.
Re:Greppability is an underrated code metric by hgomersall on Tuesday September 03, 2024 @02:48AM (#41432006)
Though glob imports in rust can hide a source, so those should be avoided.
Re:Greppability is an underrated code metric by mre on Tuesday September 03, 2024 @03:54AM (#41432405)
Exactly. I wrote an entire blog post about that: https://corrode.dev/blog/dont-use-preludes-and-globs/
Re:Greppability is an underrated code metric by zarzavat on Tuesday September 03, 2024 @02:53AM (#41432037)
C is so much worse than that. Many people declare symbols using macros for various reasons, so you end up with things like DEFINE_FUNCTION(foo) {. In order to get a complete list of symbols you need to preprocess it, this requires knowing what the compiler flags are. Nobody really knows what their compiler flags are because they are hidden between multiple levels of indirection and a variety of build systems.
Re:Greppability is an underrated code metric by skissane on Tuesday September 03, 2024 @06:24AM (#41433330)
> C is so much worse than that. Many people declare symbols using macros for various reasons, so you end up with things like DEFINE_FUNCTION(foo) {.

That’s not really C; that’s a C-based DSL. The same problem exists with Lisp, except even worse, since its preprocessor is much more powerful, and hence encourages DSL-creation much more than C does. But in fact, it can happen with any language - even if a language lacks any built-in processor or macro facility, you can always build a custom one, or use a general purpose macro processor such as M4.

If you are creating a DSL, you need to create custom tooling to go along with it - ideal scenario, your tools are so customisable that supporting a DSL is more about configuration than coding something from scratch.

Re:Greppability is an underrated code metric by kragen on Tuesday September 03, 2024 @07:01AM (#41433561)
the issue is that the c preprocessor is always available and usually used
Re:Greppability is an underrated code metric by skissane on Tuesday September 03, 2024 @07:38AM (#41433852)
Other languages have preprocessors or macro facilities too.

C's is very weak. Languages with more powerful preprocessors/macros than C's include many Lisp dialects, Rust, and PL/I. If you think everyone using a weak preprocessor is bad, wait until you see what people will do when you give them a powerful one.

Microfocus COBOL has an API for writing custom COBOL preprocessors in COBOL (the Integrated Preprocessor Interface). (Or some other language, if you insist.) I bet there are some bizarre abominations hidden in the bowels of various enterprises based on that ("our business doesn't just run on COBOL, it runs on our own custom dialect of COBOL!")

Re:Greppability is an underrated code metric by kragen on Tuesday September 03, 2024 @08:00AM (#41434069)
c's macro system is weak on purpose, based on, i suspect, bad experiences with m6 and m4. i think they thought it was easier to debug things like ratfor, tmg, lex, and (much later) protoc, which generate code in a more imperative paradigm for which their existing debugging approaches worked

i can't say i think they were wholly wrong; paging through compiler error messages is not my favorite part of c++ templates. but i have a certain amount of affection for what used to be called gasp, the gas macro system, which i've programmed for example to compute jump offsets for compiling a custom bytecode. and i think m4 is really a pathological case; most hairy macro systems aren't even 10% as bad as m4, due to a combination of several tempting but wrong design decisions. lots of trauma resulted

so when they got a do-over they eliminated the preprocessor entirely in golang, and compensated with reflection, which makes debugging easier rather than harder

probably old hat to you, but i just learned last month how to use x-macros in the c preprocessor to automatically generate serialization and deserialization code for record types (speaking of cobol): http://canonical.org/~kragen/sw/dev3/binmsg_cpp.c

Re:Greppability is an underrated code metric by skissane on Tuesday September 03, 2024 @08:05AM (#41434108)
C's is weak yet not weak – you can do various advanced things (like conditional expansion or iteration), but using esoteric voodoo with extreme performance cost. Whereas other preprocessors let you do that using builtins which are fast and easy to grok.

See for example https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,...

Poor C preprocessor performance has a negative real world impact, for example recently with the Linux kernel – https://lwn.net/Articles/983965/ – a more powerful preprocessor would enable people to do those things they are doing anyway much more cheaply

Re:Greppability is an underrated code metric by lanstin on Tuesday September 03, 2024 @12:43PM (#41436671)
I've always suspected the powerful macro facilities in Lisp are why it's never been very common - the ability to do proper macros means all the very smart programmers create code that has to be read like a maths paper. It's too bespoke to the problem domain and too tempting to make it short rather than understandable.

I like Rust (tho I have not yet programmed in it) but I think if people get too into macro generated code, there is a risk there to its uptake.

It's hard for smart programmers to really believe this, but the old "if you write your code as cleverly as possible, you will not be able to debug it" is a useful warning.

Re:Greppability is an underrated code metric by kazinator on Tuesday September 03, 2024 @11:31AM (#41435947)
If your Lisp macro starts with a symbol whose name begins with def, and the next symbol is a name, then good old Exuberant Ctags will index it, and you get jump to definition.

Not so with DEFINE_FUNCTION(foo) {, I think.

  $ cat > foo.lisp
  (define-musical-scale g)
  $ ctags foo.lisp
  $ grep scale tags
  g       foo.lisp        /^(define-musical-scale g)$/;"  f
Exuberant Ctags is not even a tool from the Lisp culture. I suspect it is mostly shunned by Lisp programmers. Except maybe for the Emacs one, which is different. (Same ctags command name, completely different software and tag file format.)
Re:Greppability is an underrated code metric by db48x on Tuesday September 03, 2024 @07:07AM (#41433604)
Yes, the usefulness of macros always has to be balanced against their cost. I know of only one codebase that does this particular thing though, Emacs. It is used to define Lisp functions that are implemented in C.
Re:Greppability is an underrated code metric by shadowgovt on Tuesday September 03, 2024 @10:37AM (#41435404)
It's a common pattern for just about any binding of C-implementation to a higher-level language. Python has a similar pattern, and I once had to re-invent it from scratch (not knowing any of this) for a game engine.
Re:Greppability is an underrated code metric by akritid on Tuesday September 03, 2024 @03:55AM (#41432425)
Looks fine (subjective) and there is also ctags
Re:Greppability is an underrated code metric by sva_ on Tuesday September 03, 2024 @04:56AM (#41432789)
People don't use LSP?
Re:Greppability is an underrated code metric by gregjor on Tuesday September 03, 2024 @05:12AM (#41432895)
That’s right, not everyone uses an LSP. Nothing wrong with LSPs, very useful tools. I use ripgrep, or plain grep if I have to, far more often than an LSP.

Working with legacy code — the scenario the author describes — I often can’t install anything on the server.

Re:Greppability is an underrated code metric by giancarlostoro on Tuesday September 03, 2024 @07:42AM (#41433890)
Fun fact: VS Code uses ripgrep by default.

https://github.com/microsoft/vscode-ripgrep

Re:Greppability is an underrated code metric by menaerus on Tuesday September 03, 2024 @10:44AM (#41435463)
LSP doesn't always work without issues with large C and C++ codebases which is why one needs to fallback to grep techniques.
Re:Greppability is an underrated code metric by gregjor on Tuesday September 03, 2024 @05:04AM (#41432839)
ctags.
Re:Greppability is an underrated code metric by mav3ri3k on Tuesday September 03, 2024 @05:27AM (#41432991)
Although in rust, function like macros make it super hard to trace code. I like them when I am writing the code and hate then when I have to read others macros.
Re:Greppability is an underrated code metric by throwawayffffas on Tuesday September 03, 2024 @05:51AM (#41433142)
> Meanwhile C lacks any such keyword

It's a hassle. But not the end of the world.

I usually search for "doTheThing\(.+?\) \{" first.

If I don't get a hit, or too many hits I move to "doTheThing\([^\)]*?\) \{" and so on.

Re:Greppability is an underrated code metric by jampekka on Tuesday September 03, 2024 @06:08AM (#41433245)
Rust though does lose some of those points by more or less forcing[1] snake_case. It's really annoying to navigate bindings which are converted from camelCase.

I don't care which case is used. It's a trivial superficial thing, and tribal zealotry about such doesn't reflect well on the language and community.

[1] The warnings can be turned off, but in some cases it requires ugly hacks, and the community seems to be actively hostile to making it easier)

Re:Greppability is an underrated code metric by kibwen on Tuesday September 03, 2024 @08:57AM (#41434511)
The Rust community is no more zealous about naming conventions than any other language which has naming conventions. Perhaps you're arguing against the concept of naming conventions in general, but that's not a Rust thing, every language of the past 20 years suggests naming conventions if for no other reason than every language provides a standard library which needs to follow some sort of naming conventions itself. Turning off the warnings emitted by the Rust compiler takes two lines of code, either at the root of the crate or in the crate manifest.
Re:Greppability is an underrated code metric by jampekka on Tuesday September 03, 2024 @09:20AM (#41434688)
I've yet to encounter another compiler that warns about naming conventions, by default at least. So at least it's most enforced zealotry I've encountered.

Yes, it can be turned off. But for e.g. bindgen generated code it was not trivial to find out.

Re:Greppability is an underrated code metric by kibwen on Tuesday September 03, 2024 @11:33AM (#41435961)
The Rust compiler doesn't produce warnings out of zealotry, but rather as a consequence of pre-1.0 historical decisions. Note that Rust doesn't use any syntax in pattern matching contexts to distinguish between bindings and enum variants. In pre-1.0 versions of Rust, this created footguns where an author might think they were matching on an enum, but the compiler was actually parsing it as a catch-all binding that would cause any following match arms to never be executed. This was exacerbated by the prevailing naming conventions of the time (which you can see in this 2012 blog post: https://pcwalton.github.io/_posts/2012-06-03-maximally-minim... (note the lower-cased enum variants)). So at some point the naming conventions were changed in an attempt to prevent this footgun, and the lint was implemented to nudge people over to the new conventions. However, as time went on the footgun was otherwise fixed by instead causing the compiler to prioritize parsing enum variants rather than bindings, in conjunction with other errors and warnings about non-exhaustive patterns and dead code (which are all desirable in their own right). At this point it's mostly just vestigial, and I highly doubt that anybody really cares about it beyond "our users are accustomed to this warning-by-default, so they might be surprised if we stopped doing this".
Re:Greppability is an underrated code metric by jampekka on Tuesday September 03, 2024 @01:26PM (#41437124)
Ah, thanks for the info! I do think this default does have some ramifications, especially in that binding casings are typically changed due to it even for "non-native" wrappers which I find materially makes things more difficult.
Re:Greppability is an underrated code metric by wruza on Tuesday September 03, 2024 @07:02AM (#41433564)
Meanwhile C lacks any such keyword, so the best you can do is search for the name. That gets you a sea of callers with the declarations and definitions mixed in

That’s why in my personal projects I follow classic “type\nname” and grep with “^name\>”.

looks ugly

Single line definitions with long, irregular type names and unaligned function names look ugly. Col 1 names are not only greppable but skimmable. I can speedscroll through code and still see where I am.

Re:Greppability is an underrated code metric by akira2501 on Tuesday September 03, 2024 @07:03AM (#41433578)
> so the best you can do is search for the name

This is why in C projects libs go in "lib/" and sources go in "src/". If your header files have the same directory structure as libs, then "include/" is a also a decent way to find definitions.

Re:Greppability is an underrated code metric by suprjami on Tuesday September 03, 2024 @08:25AM (#41434269)
> Meanwhile C lacks any such keyword, so the best you can do is...

...use source code tagging or LSP.

Re:Greppability is an underrated code metric by marcosdumay on Tuesday September 03, 2024 @10:33AM (#41435374)
Those also make your language easier to parse, and to read.

Many people insist that IDEs make the entire point moot, but that's the kind of thing that make IDEs easier to write and debug, so I disagree.

Re:Greppability is an underrated code metric by johannes1234321 on Tuesday September 03, 2024 @10:35AM (#41435389)
One thing which works for C is to search something like `[a-z] foo\(.+\) \{` assuming that spacing matches the coding style, often the shorter form `[a-z] foo\(` works well, which tries to ensure there is a type definition and bin assignment or something before name. Then there is only a handful false positives.
Re:Greppability is an underrated code metric by andersa on Tuesday September 03, 2024 @10:38AM (#41435410)
Do people really use text search for this rather than an IDE that parses all of the code and knows exactly where each declaration is, able to instantly jump to them from a key press on any usage...? Wild.
Re:Greppability is an underrated code metric by iamwil on Tuesday September 03, 2024 @10:39AM (#41435414)
Yes. Not everyone uses or likes an IDE. Also, when you lean on an IDE for navigation, there is a tendency to write more complicated code, since it feels easy to navigate, you don't feel the pain.
Re:Greppability is an underrated code metric by fsckboy on Tuesday September 03, 2024 @10:51AM (#41435527)
C, starting with K&R, has all declarations and definitions on lines at the left margin, and little else. this is easy to grep for.
Re:Greppability is an underrated code metric by wpollock on Tuesday September 03, 2024 @12:07PM (#41436326)
In the bygone days of ctags, C function definitions included a space before opening parenthesis, while function calls never had that space. I have a hard time remembering that modern coding styles never have that space and my IDE complains about it. (AFAIK, the modern gtags doesn't rely on that space to determine definitions.) Even without *tags, the convention made it easy to grep for definitions.
Re:Greppability is an underrated code metric by mzs on Tuesday September 03, 2024 @12:55PM (#41436780)
space after builtin was recommended instead:

  if (x == 0) { ...
  sizeof (buf);
  return (-1);
  exit(0);
Re:Greppability is an underrated code metric by drewg123 on Tuesday September 03, 2024 @12:58PM (#41436821)
In terms of C, that's one reason I prefer the BSD coding style:

int

foo(void) { }

vs the Linux coding style:

int foo(void) { }

The BSD style allows me to find function definitions using git grep ^foo.

Re:Greppability is an underrated code metric by leogout on Tuesday September 03, 2024 @01:43PM (#41437241)
Javascript is a bit trickier i think nowadays with the fat arrow notation : const myFunc = () => console. log("can't find me :p");
Re:Greppability is an underrated code metric by darepublic on Tuesday September 03, 2024 @01:59PM (#41437397)
There is arrow syntax with js