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

WISH: apply design to cover function extension cases #171

Open
hiiamboris opened this issue Dec 1, 2024 · 3 comments
Open

WISH: apply design to cover function extension cases #171

hiiamboris opened this issue Dec 1, 2024 · 3 comments

Comments

@hiiamboris
Copy link

It was originally one of the use cases: here and here and here

Currently still, general extension of other functions with apply is quite convoluted. Example - extend any function with a single print statement:

traced: function [f [word! path!]] [
	args: parse spec: spec-of get f [collect any [
		/local to end
	|	set w [word! | lit-word! | refinement!] keep (to get-word! w)
	|	set w get-word! keep (to paren! w)
	|	skip
	]]
	func spec compose/deep/only [
		print (rejoin ["in " f])
		apply/all quote (f) compose/only (args)
	]
]

In the above I have to parse and arrange an argument list, fill it with get-words to avoid double evaluation, then on every invocation compose it to prepare values for possible get-args.

Test:

>> probe': traced 'probe
>> probe' "abc"
in probe
"abc"
== "abc"
>> quote': traced 'quote 
>> quote' probe
in quote
== probe

This wish is to have an easy extension without the need for composition on each call.

@GiuseppeChillemi
Copy link

GiuseppeChillemi commented Dec 1, 2024

Other than the need for a "passive mode" for the values block, the task of extending a function has another requirement:

The new function could have more arguments as it supports new refinement and args. So, if you call the old function, you need to match 1 -1 the existing arguments in both sides. This could be accomplished in an easy way if you support either:

  • a context whose words are matched by name with the called function specs (and non existing ignored)

In this way: a simple apply :f <object-here> would match the arguments too

  • a block of words which are matched by name with the called function specs and value taken (and non existing ignored)

With this technique: apply/match :f [word1 word2] would match the function arguments without convoluted solutions

@hiiamboris
Copy link
Author

The new function could have more arguments as it supports new refinement and args.

Actually this was pretty much covered by the apply 'my-func 'local idea. Without any new objects spawned.

@GiuseppeChillemi
Copy link

The new function could have more arguments as it supports new refinement and args.

Actually this was pretty much covered by the apply 'my-func 'local idea. Without any new objects spawned.

So you are proposing that if you pass a word, its context is used. If you support this, then supporting objects should be 1 line of code difference or less.
Instead, supporting block of words, whose names should match, and passive mode, opens the door to function arguments coming from getting values from map keys too.

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

No branches or pull requests

2 participants