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: in func any-word to preserve the found word type #160

Open
hiiamboris opened this issue Feb 19, 2024 · 9 comments
Open

WISH: in func any-word to preserve the found word type #160

hiiamboris opened this issue Feb 19, 2024 · 9 comments
Assignees
Labels

Comments

@hiiamboris
Copy link

Currently all slippers look the same:

>> in f: func [x][] 'x
== x
>> in f: func [/x][] 'x
== x
>> in f: func [/x][] /x
== x
>> in f: func [x][] /x
== x

So when I want to test if function f supports refinement /x, I don't have a fast and reliable way of doing that, because I may use a x: ... in the function which will be converted to a /local x, and in test will succeed.

What I'm proposing:

>> in f: func [x][] 'x
== x
>> in f: func [/x][] 'x
== /x
>> in f: func [/x][] /x
== /x
>> in f: func [x][] /x
== x
>> in f: func [:x][] 'x
== :x
>> in f: func ['x][] 'x
== 'x

So /x == in :f /x could then be used to be certain it's a refinement.

@greggirwin
Copy link
Contributor

My first instinct was YES, but then we have to consider that set/get don't work with refinements, so it changes some cases where you would normally only check for none? in .... Index? and context? as well.

@hiiamboris
Copy link
Author

You don't set/get a word in a spec of a function you haven't called yet, so should not be an issue ;)

it changes some cases where you would normally only check for none? in .... Index? and context? as well.

I didn't catch that (maybe because it's late ;), could you elaborate?

@greggirwin
Copy link
Contributor

Today it either returns the word or none, so you might do

>> obj: object [x: 1]
== make object! [
    x: 1
]
>> if w: in obj 'x [set w 2]
== 2

Which is still fine for objects. For functions, even if it returns the type given, that helps for refinements, but won't tell you if something is an arg or local. Thinking about it might be used, and where you aren't using a literal arg with in, so may not know if it's a word or refinement.

Once you're working inside the function, context? works, but where you would normally just use x in code, whether it's a refinement or not. Now context? would also need to support refinements.

@hiiamboris
Copy link
Author

OK. I do not propose context? to support refinements, or in obj to behave differently. Just in func.

@dockimbel dockimbel self-assigned this Feb 20, 2024
@dockimbel dockimbel added the Wish label Feb 20, 2024
@dockimbel
Copy link
Member

dockimbel commented Feb 20, 2024

The purpose of in is:

  • to check if a given word is part of a given context
  • return the argument word bound to the given context.

So what you are proposing would break the basic purpose of in, as refinements can't be bound to a context.

Eventually, your wish could be implemented as a new refinement to in, like /keep. Though, it would be hard to remember that in/keep is there to actually check if a refinement is defined or not...

If the goal is to check if a given function supports a given refinement, maybe we should rather consider extending reflect on function! for that need?

@hiiamboris
Copy link
Author

Though I don't see how this wish contradicts the stated goals, I don't mind in/keep or reflect solutions. This is a rare need, so particular interface is of tiny importance. I don't envision however how reflect can fit this need better. It's designed as reflect value field, where field is one of the predefined categories, not a specific word from the spec.

@greggirwin
Copy link
Contributor

Let's come back to the original use case: " I want to test if function f supports refinement /x"

What's wrong with mezz level?

refinement-in: func [
	fn [any-function!]
	ref [refinement!]
][
	find spec-of :fn ref
]

This should be reliable, and reasonably fast.

>> clock/times [refinement-in :find /match] 10'000
1.30 μs	[refinement-in :find /match]

@greggirwin
Copy link
Contributor

find-refinement would be a better name there.

@hiiamboris
Copy link
Author

That was my initial approach until @dockimbel was so kind to implement a more optimal option :)
But I have now to test each created style and want if it contains one of the supposed-to-be refinements as a local.
I don't want to go once again into the "it's fast enough in my console" argument with you ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants