Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue 20099 - Memoize should handle lambdas #7507

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Biotronic
Copy link
Contributor

No description provided.

@Biotronic Biotronic requested a review from andralex as a code owner May 29, 2020 19:25
@dlang-bot
Copy link
Contributor

dlang-bot commented May 29, 2020

Thanks for your pull request and interest in making D better, @Biotronic! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Auto-close Bugzilla Severity Description
20099 enhancement Memoize should handle lambdas

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + phobos#7507"

std/functional.d Outdated Show resolved Hide resolved
std/functional.d Outdated Show resolved Hide resolved
@Biotronic Biotronic force-pushed the Issue20099 branch 2 times, most recently from 4fdf3a7 to 3536723 Compare May 31, 2020 00:38
@Biotronic
Copy link
Contributor Author

That should take care of the issues that have been pointed out, and also makes memoize handle overloads, which confused it before.

@kinke
Copy link
Contributor

kinke commented May 31, 2020

I don't think it does. Try

alias foo = memoize!(n => new Object());
assert(foo(0) is foo(0U));

@Biotronic
Copy link
Contributor Author

I don't see the problem there - you have a templated function and you expect it to be the same with different template arguments? First, that's a completely different issue from the above. Second, it's one that cannot possibly be handled sensibly in the language today. Third, it's code that didn't compile before, so it doesn't break any existing code.

@kinke
Copy link
Contributor

kinke commented May 31, 2020

You open the door for a single memoize!Func instantiation to (IMO quite probably unintentionally) break down into a multitude of actually memoized functions, depending on the used args, just for the sake of saving to type down the explicit parameter types for lambdas.

I think a memoize!F instance should stick binding to a single function. The user can always declare some alias memoizedFun(T) = memoize!((T p) => make(p)) in case a templated wrapper is actually desired.

@Biotronic
Copy link
Contributor Author

I do see that, but I think the issue is much smaller than you make it out to be. Note also that you have the same issue for explicit template functions:

int foo(T)(T t) {
    return T.stringof.length;
}
unittest {
    assert(memoize!foo(0) != memoize!foo(0U));
}

I hope the above both compiles and passes the assert.

We could in fact test for lamba-osity by static asserting on fun.stringof[0..8] == "__lambda", if we find that this is a big issue.

@n8sh
Copy link
Member

n8sh commented May 31, 2020

I hope the above both compiles and passes the assert.

It turns out that prior to this PR that code doesn't compile because Parameters!foo doesn't work for an uninstantiated template:

Error: template instance std.traits.Parameters!(foo) does not match template declaration
 Parameters(func...)
  with func = (foo(T)(T t))
  must satisfy the following constraint:
       isCallable!func

@kinke
Copy link
Contributor

kinke commented May 31, 2020

Yes, it currently (master) doesn't support any templates and always binds to one function (thus the 'confusion' for overloads), and the short-hand lambda syntax is one such case, but not so obvious by the produced error msges.

std/functional.d Show resolved Hide resolved
@kinke
Copy link
Contributor

kinke commented May 31, 2020

I do see that, but I think the issue is much smaller than you make it out to be.

You're probably right. I suppose the memoized wrapper now (this PR) cleanly wraps a symbol, incl. overloads and templates, and doesn't expand (just propagate) the domain of argument types.

@n8sh n8sh added the 72h no objection -> merge The PR will be merged if there are no objections raised. label Sep 12, 2020
@RazvanN7
Copy link
Collaborator

@Biotronic can you please rebase so we can get this in?

Comment on lines +1231 to +1252
static if (__traits(compiles, __traits(getOverloads, __traits(parent, fun), __traits(identifier, fun))))
alias getOverloads = __traits(getOverloads, __traits(parent, fun), __traits(identifier, fun));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to pass true as an additional argument to __traits(getOverloads) here in order to include template overloads. As-is, the check for anySatisfy!(isTemplate, overloads) below will always evaluate to false.

@RazvanN7
Copy link
Collaborator

ping @Biotronic

@n8sh
Copy link
Member

n8sh commented Jun 1, 2021

Rebased & expanded commit message.

@RazvanN7 RazvanN7 removed the 72h no objection -> merge The PR will be merged if there are no objections raised. label Sep 13, 2021
@LightBender LightBender added the Salvage This PR needs work, but we want to keep it and it can be salvaged. label Oct 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement Salvage This PR needs work, but we want to keep it and it can be salvaged. stalled
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants