How is VALUE? Does the function work?

I gave a small example of some code that I have that checks to see if a variable named class-name value assigned to it:

 ask-params: function [ config-file [file!] default-class-name default-fields ] [ probe value? 'class-name input either (value? 'class-name) [ probe class-name ] [ ;-- omit code in this branch for now ] ] ret-block: ask-params %simple-class.params.txt "Person" "First Name, Last Name" 

The expression value? 'class-name value? 'class-name here returns false. On the other hand, if I populate the missing branch with an assignment:

 ask-params: function [ config-file [file!] default-class-name default-fields ] [ probe value? 'class-name input either (value? 'class-name) [ probe class-name ] [ class-name: default-class-name ] ] ret-block: ask-params %simple-class.params.txt "Person" "First Name, Last Name" 

Will this return true for value? 'class-name value? 'class-name . But in this second case, class-name: default-class-name has not yet been executed.

I would have thought that the class name should not exist in memory, so value? 'class-name value? 'class-name should return false. Why value? returns true instead?

+4
source share
4 answers

You are using function . This scans the body of the function and pre-creates for you local variables initialized to NONE. This is why value? 'class-name value? 'class-name becomes true (because NONE is the legal value of a variable other than the "unset" situation).

If you used func instead, then both returned false.

+2
source

Here I will show you two examples that do not use FUNCTION, but are otherwise equivalent to your code:

 ask-params: func [config-file [file!] default-class-name default-fields] [ probe value? 'class-name input either (value? 'class-name) [ probe class-name ][ ] ] ask-params: func [ config-file [file!] default-class-name default-fields /local class-name ] [ probe value? 'class-name input either (value? 'class-name) [ probe class-name ][ ] ] 

value? is the value? function value? in the first example it gives #[false] , in the second example it gives #[true] . This is because the "refinement arguments" after the "unused refinement" (the refinement that is not used in the actual call) are initialized to #[none!] Along with the refinement variable. This also applies to /local variables, since the /local qualification is no different from other function qualifications (except that it is an agreement to use it to define local variables).

Because the function generator uses the /local method to implement local variables β€œunder the hood,” the above description applies to all the functions that it generates.

+1
source

There is another way that avoids the use of FUNC / LOCAL and still allows you to use the FUNCTION function.

That is, do not use SET-WORD! for the assignment. Instead, use the SET function on LIT-WORD!

 ask-params: function [config-file [file!] default-class-name default-fields] [ probe value? 'class-name input either (value? 'class-name) [ probe class-name ] [ set 'class-name default-class-name ] ] 

Will you get #[false] for the value? function value? . However, calling SET will set the class-name in the global environment ... not as local.

+1
source

I do not think function behaves differently than func /local . Take a look at these examples:

 >> f: func [/x] [value? 'x] >> f == true 

I did not give any value of x, but he says that he has a value. Same thing for / local

 >> f: func [/local x] [value? 'x] >> f == true 

Because when you create a local variable (or refinement), it means that you have already set a value for it (which is none), and this is what function does.

+1
source

Source: https://habr.com/ru/post/1314574/


All Articles