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

A basic non-closure form of lambda expressions. #91

Closed

Conversation

fusiongyro
Copy link

The attached fix sort of shows a direction for this. The problem is that these lambdas are not closures, so for instance: (lambda x: lambda y: x+y)(4)(5) does not work, because while the outer lambda correctly returns a Procedure, the binding of 4 to x is lost.

I'm not entirely sure the right way to solve this, but I figured if I showed you the code it may be obvious to you.

@codecov-commenter
Copy link

codecov-commenter commented May 10, 2021

Codecov Report

Merging #91 (68bdddf) into master (65886d0) will increase coverage by 0.06%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #91      +/-   ##
==========================================
+ Coverage   92.06%   92.13%   +0.06%     
==========================================
  Files           4        4              
  Lines         744      750       +6     
==========================================
+ Hits          685      691       +6     
  Misses         59       59              
Impacted Files Coverage Δ
asteval/asteval.py 93.07% <100.00%> (+0.07%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 65886d0...68bdddf. Read the comment docs.

@newville
Copy link
Member

@fusiongyro Hm, not sure I actually understand the implementation. Why is on_functiondef using on_lambda?
What is the collections.abc.Iterable thing doing?

@fusiongyro
Copy link
Author

My reasoning is that a defined function is just like an anonymous function, only with a name. This is slightly untrue in Python, since a named function can have a more complex body and arguments. The Iterable thing is a way of testing whether I have a list of items in the body or just a single item. I'm never quite sure what the right way to do that kind of type sniffing is.

@newville
Copy link
Member

@fusiongyro

I think a function can have additional nodes compared to a lambda, no?

re Iterables: shouldn't a list of items in the body return that list? Like, I think that probably should not be a special case -- just evaluate the nodes, no? But: I might be missing something too....

It may be that supporting lambda would require Procedure.__call__() to return the result of evaluating the body, instead of returning None. Maybe Procedure needs a flag to tell it to return the result of its body or something.

@fusiongyro
Copy link
Author

Yes, in fact the body of an ast.Lambda is a single ast.Expr, whereas for a function definition it is a list of ast.Exprs. Also, unless there is a ast.Return there is no return from a function, whereas there is from a Lambda. So there are some differences both in the AST structure and in the evaluation of the lambda and a function definition. The binding problem is the big one from an implementation point of view though.

I'm not entirely sure what a clean way to handle all of this is, but I'll see if I figure anything out tonight.

@newville
Copy link
Member

newville commented Mar 6, 2022

@fusiongyro we're at about 10 months since there was any activity here. Can we agree that it would be reasonable to close at the "inactive for one-year" mark?

@fusiongyro
Copy link
Author

Yes, sorry!

@fusiongyro fusiongyro closed this Mar 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants