Am 22.03.2023 um 02:49 schrieb Cottrell, Allin:
On Tue, Mar 21, 2023 at 6:43 PM Sven Schreiber
<sven.schreiber@fu-berlin.de> wrote:
Yes, that was a typo, sorry. In this example it is inconsequential, however, because the point is what happens when "null" is passed in.
Not totally inconsequential, in that passing "null" as an argument
keyword would automatically fail for level2() as written, since a
missing argument is not permitted by the function's signature.

I think we have been (just for a second) talking past each other, because of the double meaning or usage of "null": When I said "pass 'null' in", I meant to create a string and initialize it to null (string s1 = null), and then pass s1 to the function. That works. What you mean is to directly write "null" in the function call. This indeed fails when that arg does not have the '[null]' postfix.

It seems to me that this is a good example of why the double meaning of "null" is problematic. Maybe you're right and using "null" for initializing a new/empty string should be deprecated, instead using s1="". And the arg postfix for strings might then become '[""]'. (In the function call the keyword 'null' might still be used to indicate a missing argument.)

Well, I didn't take my example as a case of "null-setting" (as in with
your string, where you created a named, empty string variable). My
case just uses "null" as a keyword, meaning "don't pass any argument
corresponding to this parameter". If one wanted something less terse
than the ternary expression, the equivalent would be

if exists(s1)
   level2(s1)
else
   level2()
endif
Right - the whole point of this thread (apart from the double-meaning issue above) is that it feels clunky in hansl to need extra checking code involving exists() when all we want to do is to pass through the input. Whatever precise form this checking code takes.

Sorry, I don't really understand this example. If opts is not supplied
there's nothing to be checked, so one should simply do

if exists(opts)
   bcheck(&defaults, opts)
endif
Yes, again the point is: why do we need this if block with the exists() check in the first place when all we want to do is to channel opts to bcheck?
Moreover, the second argument to bcheck() is not optional, so passing
null as a substitute is not going to work. 

Again yes, but: As I showed in my post, we can do b=null and then pass b in. For you at the internal (C) level it makes a big difference whether nothing is passed in or whether it's an empty bundle. And I clearly understand the technical reason, given the status quo.

However, for a hansl programmer this looks slightly schizophrenic: in verbal pseudo-code the check reads "let's see if my input argument opts is 'null' / Oh, it is, so I need to to set it to 'null' before passing it on!". If that sounds absurd to you, then perhaps I'm getting my point across. 

About the use of 'null' for initializing a bundle, perhaps in analogy to your suggestion for strings, perhaps a solution would be to deprecate the syntax "b=null" as well, and the recommended thing would be "b=_()" (and "b=defbundle()", of course).

(And if so, then later one would probably have to talk about initializing other types such as arrays, too.)

However, thinking about the 3-argument usage of bcheck(), perhaps I'm
beginning to see what you mean. I need to think about it some more.

Yes, in that case the check at the hansl level would be even more involved, I guess.

thanks for sticking with me

Sven