Page 1 of 1

Is it possible to "nest" functions

Posted: 03 Mar 2017 04:00
by BillH
Is it possible to "nest" one function inside of another? For example:

<bound for =TextPart({=GetLabelledText(%FACT.NOTE2%,"To: "}), 1, 0, TIDY)>

I can't get this to work and haven't been able to find anything on "nesting" in the help or KB.

Thanks,

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 06:35
by Gowermick
Bill,
I don't know the answer, as I'm not proficient in LUA, but don't see why not, most languages do. However, I do see your brackets are 'unbalanced', and have become mxed!
You have ( { ( on left but } ) ) on right!

Have a rethink, and re-position them.

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 07:30
by Jane
You need to wrap the complete function in the {} brackets not leave them in the middle.

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 07:53
by Gowermick
Jane,
To clarify, do you mean the order of the brackets should be { ( ( on left and ) ) } on right?

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 08:12
by Jane
Yes, as per the Advanced Help accessed from the Fact Type Fact Definition all functions and data references are wrapped in curly brackets, the function enclosed is exactly the same as what are valid in a query with the exception of the extended data references.

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 10:43
by Gowermick
Jane wrote:Yes, as per the Advanced Help accessed from the Fact Type Fact Definition.
Jane,
I'm a bit slow this morning, but how exactly do we access the above? I've searched help using keywords, but can't find what you are referring to!

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 11:02
by Jane
2017-03-03_110124.jpg
2017-03-03_110124.jpg (123.61 KiB) Viewed 8571 times

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 11:21
by SimonOrde
Hi Bill

the short answer is Yes - functions can be nested within one another. There is no limit to the number of levels that you can nest them either. When you call one function as a 'parameter' to another function, you must make sure that the type of value returned by the first function matches the parameter type required by the second.

In general, in a context in which you can use a function, the presence of a function is signalled by an equal sign (=) as in MS Excel. So, for example, in a Query, you put an = in front of a call to a function. Do not put an equal sign in front of any nested functions though.

Functions can be used in sentence templates for narrative reports (as in your example). But when you use a function in these contexts, you must wrap the whole expression in a pair of curly brackets (and then have an '=' sign immediately after the first curly bracket). For example:

Code: Select all

{=RecordId(GetRecord(%FACT%))}
In this example, the outer bit

Code: Select all

{=      ...        }


signals a function being used in a sentence template. Within that, the outermost function is RecordId(), which calls another function GetRecord(), which takes the data reference %FACT% as its sole parameter.

Remember you only need or use curly brackets round functions (or function expressions perhaps I should say), in sentence templates. You don't use the curly brackets elsewhere.

Here's another example of a nested call to a function without curly brackets (e.g. for use in a query):

Code: Select all

=Diff(Year(%INDI.BIRT.DATE%),Year(%INDI.~SPOU>BIRT.DATE%))
This expression will calculate the difference in age between a person and their spouse. The outermost function is 'Diff' which takes two parameters. There are two nested calls to the 'Year' function (each of which is passed a data reference referring to a date, as parameter).

Incidentally, as well as calling nested functions, you can also combine them using operators. These can be logical operators (such as 'and', 'or', 'not'), or they can be numeric operators (such as '+', '-', etc). Operators are explained in the Help in the Advanced Topics area. Here's an example of a function call that uses the minus sign (the subtraction operator):

Code: Select all

=Calc(Year(%INDI.BIRT.DATE%) - Year(%IND.~SPOU.BIRT.DATE%))
This is very similar to the previous example. The only difference between the two is that 'Diff' always returns a positive value, whereas 'Calc' will also return negative values.

You can only use operators in the context of a function expression. So if you have two functions and you simply want to put an operator between them, you may need a function like 'Calc' to provide a context for the operator to 'sit' in. The function 'IsTrue' provides a similar role for logical operators.

The only thing with using functions and operators is that it's very easy to make a mistake and fail to match up parameter types and return types etc. They're not very forgiving. If you are trying to put together a very complex expression, I recommend building it up in stages and testing each part if you can.

Hope that makes sense.

Simon

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 11:58
by Gowermick
Jane,
Many Thanks.
I was nearly there, I went to Fact Types, but then went to new..., rather than selecting a type then clicking Edit... :roll:

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 13:14
by tatewise
That is all covered with examples in how_to:understanding_expressions|> Understanding Expressions where it says:
Functions that begin with an = sign (except when used within another Function) and lots of nested examples.

Re: Is it possible to "nest" functions

Posted: 03 Mar 2017 17:45
by BillH
Mike, Jane, Simon, and Mike,

Thanks to all for your replies. They were all very helpful.

This was for use in a sentence template, so I did need the curly brackets, but I see as Mike pointed out that I do have mis-matched brackets. Last night I did try at least 20 other combinations and couldn't get it to work. I guess it was getting late last night and I was trying anything.

This morning after reading the messages, I matched up the brackets and put the curly brackets on the outside of the whole thing, but it still didn't work. Then I figured it out. I had too many = symbols.

<bound for {=TextPart(=GetLabelledText(%FACT.NOTE2%,"To: "), 1, 0, TIDY)}>

removing the = in front of GetLabelledText did the trick.

<bound for {=TextPart(GetLabelledText(%FACT.NOTE2%,"To: "), 1, 0, TIDY)}>

I figured the info was in the help or knowledge base somewhere, but I swear I looked for at least a 1/2 hour and couldn't find it by searching.

Thanks everyone for their help!

Re: Is it possible to "nest" functions

Posted: 19 Mar 2017 13:18
by pembfamily
To everyone who asked and answered above,

Thank you all. I now have a query that shows the individuals who appear in the 1881 census, and their ages at the time. Just what I wanted, and I was able to find the ages thanks to the advice given here.