Skip to content

all: support short lambda expressions like a.sorted(|x,y| x > y), in all callsites that accept a fn callback - #19390

Merged
spytheman merged 5 commits into
vlang:masterfrom
spytheman:feature/lambda_expressions_in_callsites
Sep 20, 2023
Merged

spytheman merged 5 commits into
vlang:masterfrom
spytheman:feature/lambda_expressions_in_callsites

Conversation

@spytheman

Copy link
Copy Markdown
Contributor
  • all: support short lambda expressions like a.sorted(|x,y| x > y), in all callsites that accept a fn callback
  • ci: fix v build-tools
  • fixes for vlib/v/parser/tests/anon_sum_type_multi_return_err.vv

@spytheman spytheman changed the title feature/lambda expressions in callsites all: support short lambda expressions like a.sorted(|x,y| x > y), in all callsites that accept a fn callback Sep 20, 2023
@spytheman
spytheman force-pushed the feature/lambda_expressions_in_callsites branch from 4cb0e4a to cbe975b Compare September 20, 2023 07:12
@JalonSolov

Copy link
Copy Markdown
Collaborator

Hmm... f(||42) looks like an error, to me. What's the use of the || if there are no variables listed between them?

@spytheman

spytheman commented Sep 20, 2023 •

Copy link
Copy Markdown
Contributor Author
import os

fn f( cb fn() string ) string { return cb() }

dump( f(fn() string { return os.args[0] }) )

// the same, just shorter:
dump( f(||os.args[0]) ) 

prints:

[a.v:5] f(anon_fn): /v/vnew/a
[a.v:6] f(|| os.args[0]): /v/vnew/a

i.e. using functions/expressions for callbacks, that get their values from external sources

@JalonSolov

Copy link
Copy Markdown
Collaborator

Must be too subtle for me... I don't get why the || is there, if there are no variables involved.

@spytheman

Copy link
Copy Markdown
Contributor Author

Must be too subtle for me... I don't get why the || is there, if there are no variables involved.

Because otherwise it would not be a lambda expression/function to call; it would get evaluated immediately.

It may be easier to see with:

import rand
fn f( cb fn() int ) string { return 'randoms: ${cb()}, ${cb()}, ${cb()}' }
dump( f(||rand.int()/1_000_000) )

which will produce something like:

[r.v:3] f(|| rand.int() / 1000000): randoms: 501, 657, 1345

i.e. the passed lambda expression will be executed 3 times, each with a different result.

Note, that the above is equivalent to this, just shorter:

import rand
fn f( cb fn() int ) string { return 'randoms: ${cb()}, ${cb()}, ${cb()}' }
dump( f( fn() int { return rand.int()/1_000_000 } ))

@JalonSolov

Copy link
Copy Markdown
Collaborator

So the || is a trigger to show that it is a lambda as opposed to a simple anonymous function.

Still looks strange...

@spytheman

Copy link
Copy Markdown
Contributor Author

Still looks strange...

I agree. It is just the logical reduction of the lambda syntax, for when the anon fn has 0 args.

@spytheman
spytheman merged commit f93d257 into vlang:master Sep 20, 2023
@spytheman
spytheman deleted the feature/lambda_expressions_in_callsites branch September 20, 2023 14:24
@daemonu

daemonu commented Oct 7, 2023

Copy link
Copy Markdown

awesome feature. could we maybe use _ if lambda doesn't need args instead of or ||?

@JalonSolov

Copy link
Copy Markdown
Collaborator

Probably the same idea... it would be identified as an anonymous function instead of a lambda, without the ||.

@dumblob

dumblob commented Oct 7, 2023

Copy link
Copy Markdown
Contributor

Looking at this I actually sort of like this tiny syntax sugar.

Shouldn't we also emphasize in the documentation that it is actually not a true lambda expression as known from other languages (which distinguish between a function and a lambda) but just syntax sugar for plain old V function definition?

Wertzui123 pushed a commit to Wertzui123/v that referenced this pull request Oct 8, 2023
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.

4 participants