# findMethodByExample in Racket?

**URL:** <https://racket.discourse.group/t/findmethodbyexample-in-racket/1019>\
**Category:** Questions & Answers\
**Created:** [May 22, 2022, 11:16am UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019 "2022-05-22T11:16:33Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![rscho](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/rscho/32/726_2.png) [@rscho](https://racket.discourse.group/u/rscho)\
**Post date:** [May 22, 2022, 11:16am UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/1 "2022-05-22T11:16:33Z")

</div>

I've been looking at the `findMethodByExample` feature from Smalltalk, that does just what it says. I've also been wondering about a Racket implementation. Because I recently witnessed some criticism about Racket's discoverability, with people stating that finding stuff in the libraries/docs wasn't that easy. So, would you care to chime in about:

- Would a Racket `findMethodByExample` be a worthy feature?
- How would one go about it?

Looking at the Pharo stuff, the initial filtering of the methods is done by walking the class tree, then by metainfo on the procedures (number of args, etc.). I think in the end, there's also some whitelisting going on to avoid unwanted side-effect execution. In my understanding, the Racket equivalent couldn't really do it just by traversing the dependency tree, though? I think some "hardcoded" search paths would be needed for core language features, since we are not class/method based and modules do not rely on inheritance. However, maybe we could leverage the contract system in some way to approximate this functionality, especially since contracts don't have side-effects?

---

<div class="post-metadata">

**Author:** ![scolobb](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/scolobb/32/108_2.png) [@scolobb](https://racket.discourse.group/u/scolobb)\
**Post date:** [May 22, 2022, 3:49pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/2 "2022-05-22T15:49:13Z")

</div>

The Haskell community has Hoogle, which allows searching for a function by its type: [(a -\> a) -\> [a] -\> [a] - Hoogle](https://hoogle.haskell.org/?hoogle=(a%20-%3E%20a)%20-%3E%20%5Ba%5D%20-%3E%20%5Ba%5D). I've always found this search capability incredibly useful and have relied heavily on it.

Not all functions in Racket (can) have types, but this may be a reasonable first step.

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [May 22, 2022, 4:14pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/3 "2022-05-22T16:14:31Z")

</div>

How does this work in Smalltalk or Pharo; do you have a better link than [this](https://a2zfacts.net/articles/how-does-find-by-example-work-in-the-pharo-finder/)?

I think the situation in Racket is difficult because:

- Many useful functions do not have a Typed Racket type, or even a contract. Some have a "contract" that exists only in the form of a Scribble `defproc`. Some don't have documentation.

- Many useful things aren't even functions -- they're macros. Depending on how the macro was defined, the grammar might be clear, but it might be completely opaque. Again, there might exist a grammar via a Scribble `defform`, but maybe not.

I can imagine some tool that tries to scrape all these sources, within some user-defined scope that includes some combination of packages and/or personal projects, and refreshes that metadata in a database accessible by editor/IDE tools.

I can imagine that, but... imagining it also sort of gives me a headache. 😄 Seriously this feels like a project that would be challenging in a "never-ending" way --- a source of perpetual bug reports where users have quite reasonable expectations that can never quite be satisfied?

TL;DR I think it sounds like a wonderful thing to have, and if someone built it I might use it, but I probably wouldn't want to be the person attempting to build and maintain it?

---

<div class="post-metadata">

**Author:** ![rscho](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/rscho/32/726_2.png) [@rscho](https://racket.discourse.group/u/rscho)\
**Post date:** [May 22, 2022, 6:33pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/4 "2022-05-22T18:33:20Z")

</div>

Thanks for the input, @greghendershott. I got to conclusions that are similar to yours, although I think there are some points that save the idea somewhat:

1. We could limit the scope of the project to those functions that do have a type/contract.
2. That would enable a progressive (although neverending indeed) expansion of the project scope, as we could add the missing contracts along the way.
3. Macros can expand to contracted functions, I think. So, is that really such a problem?

So basically, I think we could start very small and expand. But is that worth the effort? It indeed seems like something that would be troublesome to maintain for a single contributor. On the other hand, contracts make Racket uniquely positioned for such a feature in the current language landscape, IMO.

@scolobb I agree that something similar to Hoogle is very enticing. Are you really specifically speaking about types, though? Or are you including contracts in that? I'm certainly no expert on either design-by-contract or type theory, but I think that somewhat changes things. Especially since the fraction of typed functions in the lib is minuscule compared to the untyped fraction (I think).

As for the implementation, I found the blog you linked and also related:

> <https://twitter.com/leastfixedpoint/status/1512391756318392324>

> **[GitHub - LinqLover/SimulationStudio: A developing suite of applications and...](https://github.com/LinqLover/SimulationStudio)**
>
> A developing suite of applications and tools for code simulation in Squeak/Smalltalk - GitHub - LinqLover/SimulationStudio: A developing suite of applications and tools for code simulation in Squea...

> **[Squeak - Dev - \[ANN\] SimulationStudio and sandboxed execution for Squeak](http://forum.world.st/ANN-SimulationStudio-and-sandboxed-execution-for-Squeak-td5127804.html)**
>
> \[ANN\] SimulationStudio and sandboxed execution for Squeak. Hi all! :-) I'm very excited to finally share my new project with you today, which I call SimulationStudio and have made available on...

---

<div class="post-metadata">

**Author:** ![EmEf](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@EmEf](https://racket.discourse.group/u/EmEf)\
**Post date:** [May 22, 2022, 6:46pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/5 "2022-05-22T18:46:23Z")

</div>

The information supplied in DrRacket's "blue boxes" (top right of the editor and REPL) could be a start.

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [May 22, 2022, 7:12pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/6 "2022-05-22T19:12:46Z")

</div>

For sure if there is some subset you think is satisfactory, I don't mean to discourage you. "The perfect is the enemy of the good".

Why I was primed to feel familiar with this space: Emacs has an "eldoc" feature. Given some function name, it tries to display its parameters (their order and names).

You could describe this as "function name -\> parameters" --- the "opposite" of "parameters -\> possible function names" (the latter being `findMethodByExample`).

Either way, there is the same set of challenges about discovering the number of parameters (much less the name and type/contract/syntax-class/kind of each).

And either way, if users are OK with some (pretty significant) limitations, there are useful things that could be done, for sure.

---

<div class="post-metadata">

**Author:** ![scolobb](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/scolobb/32/108_2.png) [@scolobb](https://racket.discourse.group/u/scolobb)\
**Post date:** [May 22, 2022, 9:06pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/7 "2022-05-22T21:06:21Z")

</div>

> [@rscho](#):
>
> @scolobb I agree that something similar to Hoogle is very enticing. Are you really specifically speaking about types, though? Or are you including contracts in that? I'm certainly no expert on either design-by-contract or type theory, but I think that somewhat changes things. Especially since the fraction of typed functions in the lib is minuscule compared to the untyped fraction (I think).

Indeed, I am not specifically speaking about types, and I agree with you that contracts or other tags may be used to do search. I do have the impression however that types would be easier to use than contracts, because the contract language is more expressive. For example, one would probably have to match `list?` with `(listof number?)` and with `(list (listof number?))`. On the other hand, there are indeed many more functions with contracts than functions with types, even though I'd qualify their proportion as "more than minuscule" 🙂

---

<div class="post-metadata">

**Author:** ![hendrikboom3](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hendrikboom3/32/2748_2.png) [@hendrikboom3](https://racket.discourse.group/u/hendrikboom3)\
**Post date:** [May 23, 2022, 6:42pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/8 "2022-05-23T18:42:40Z")

</div>

You could even restrict the search on types to typed racket.

---

<div class="post-metadata">

**Author:** ![countvajhula](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/countvajhula/32/65_2.png) [@countvajhula](https://racket.discourse.group/u/countvajhula)\
**Post date:** [May 23, 2022, 7:14pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/9 "2022-05-23T19:14:11Z")

</div>

I felt sure I'd seen something like this before, but I think I'm thinking of this package for Emacs Lisp that does it:

> **[GitHub - Wilfred/suggest.el: discover elisp functions that do what you want](https://github.com/Wilfred/suggest.el)**
>
> discover elisp functions that do what you want. Contribute to Wilfred/suggest.el development by creating an account on GitHub.

ELisp doesn't have contracts or types, so the way it works is by curating a relevant list of functions, and then trying all of them with the user's example interface, returning the ones that match and don't raise an error.

Doing it this way in Racket would take some design effort -- which functions are relevant? Can we dynamically obtain the list of relevant functions from installed libraries (maybe using something like [module-\>exports](https://docs.racket-lang.org/reference/Module_Names_and_Loading.html#%28def._%28%28quote._~23~25kernel%29._module-~3eexports%29%29))? Are there security concerns with invoking these functions -- do we trust the installed libraries? Are there performance concerns with invoking a potentially large number of functions? How do we parse the user's query reliably?

Of course, relying on types and contracts would be preferable where available, but this approach could be a reasonable fallback.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [May 23, 2022, 7:38pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/10 "2022-05-23T19:38:24Z")

</div>

> [@countvajhula](#):
>
> Are there security concerns with invoking these functions -- do we trust the installed libraries?

There even don't have to be security issues per se. For example, I wouldn't like it if a suggestion feature would "randomly" try [file system functions](https://docs.racket-lang.org/reference/Filesystem.html) that modify the file system. 😉

So I guess you'd need to be able to remove functions with (certain) side effects from the candidates to try before trying them.

...

I see `suggest.el` uses a [predefined candidate list](https://github.com/Wilfred/suggest.el#how-it-works):

> **How it works**
> 
> suggest.el uses enumerative program synthesis. It tries your inputs (in any order) against every function in `suggest-functions` .
> 
> `suggest-functions` is a carefully chosen function list: they're all pure functions with a small number of arguments using only simple data types. We only include functions that users could 'stumble upon' with the right set of inputs.

---

<div class="post-metadata">

**Author:** ![hendrikboom3](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hendrikboom3/32/2748_2.png) [@hendrikboom3](https://racket.discourse.group/u/hendrikboom3)\
**Post date:** [December 20, 2022, 4:11pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/11 "2022-12-20T16:11:17Z")

</div>

People have done this kind of thing when writing low-level code generators, exhaustively trying out different combinations of machine instructions and finding unexpectedly efficient ways of doing things.  
Of course the results are checked by people before any of them is used into a real compiler.

---

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [December 20, 2022, 5:47pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/12 "2022-12-20T17:47:32Z")

</div>

Could someone explain a scenario where findMethodByExample would be used? I'm not familiar with this feature so I'm not sure what it's good for.

---

<div class="post-metadata">

**Author:** ![jesse](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jesse/32/446_2.png) [@jesse](https://racket.discourse.group/u/jesse)\
**Post date:** [December 20, 2022, 7:25pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/13 "2022-12-20T19:25:05Z")

</div>

Concerning functions that have a documented contract but no actual contract: _should_ they have a contract? That is: are these things we could improve by adding actual contracts? (Maybe not everything.)

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [December 20, 2022, 8:58pm UTC](https://racket.discourse.group/t/findmethodbyexample-in-racket/1019/14 "2022-12-20T20:58:16Z")

</div>

I think the answer is probably, "No", for a few reasons:

- Quite a few things documented by Scribble `defproc`s aren't actually defined when/where `racket/contract` is available. For instance primitives defined in C or in Scheme.

- Quite a few things are macros documented by Scribble `defform`s.

- Even when things are defined in Racket, and where `racket/contract` is available, there might be an unacceptable performance penalty to wrapping them in an actual contract. (Although there seems to be a lot of great progress in making contracts faster, as well as ideas like option contracts.)

* * *

We already have the notion of run time, compile time, and even documentation production time.

You could propose a fourth time: Something like "tool time" or "humans writing code time". It can use some of the _results_ of the other times. For example "blue boxes" from doc production, as well as some sort of "crawling/scraping" of things like signatures/types/contracts resulting from compile time. (Insert prolonged, vigorous hand-waving here.)

Anyway, I think that is its own distinct "time", where (when?) things like `findMethodByExample` live.
