Tuesday, March 6, 2018, 3:59:22 AM, Woonsan Ko wrote: > On Sat, Mar 3, 2018 at 11:22 AM, Daniel Dekany <ddek...@apache.org> wrote: >> Below I propose a solution for the basic treatment of null VS >> "missing" in FM3. Please tell me what you think! >> >> The way FM2 deals with null-s has quite severe limitations (and >> glitches). The root of the problems is that null and missing is the >> same for the template language. It's not aware of the concept of null; >> for example a variable has either non-null value, or the variable is >> considered to be nonexistent. So <#assign x = obj.m()> fails when >> obj.m() returns null, for the same reason <#assign x = noSuchVariable> >> does. (Note that even if we store null into x on the implementation >> level, reading x will fall back to higher scopes to find an x there, >> instead of returning null.) Another problem is with >> macro/function/method arguments; f(noSuchVariable) will not fail if f >> provides a default for the parameter (as in <#function f(x=0)>), on >> the basis that noSuchVariable is missing, so the parameter was >> practically omitted. Not good, as thus we have suppressed an error >> that tells us that there's no noSuchVariable. Also, if in f you want >> to call a obj.javaMethod(x), where x is the parameter of f, and you >> want to allow x to be null, because obj.javaMethod(x) allows that, you >> can't. Because, if you don't provide a default, f(m.willReturnNull()) >> will be an error for using a null/missing value for a required >> parameter, and if you do provide a default, then since null is not a >> thing in the template language, you can't specify null as the default >> value of the parameter. >> >> So, here's my plan for FM3. >> >> The template language will know null, and it's different that from >> "missing". I think so far everyone who has used FM2 heavily will >> agree. >> >> On the API and implementation level we will have a singleton, >> TemplateNullModel.INSTANCE, that stands for things that do exist but >> has null value, while a plain null value indicates that the thing is >> missing. For example, Environment.getVariable(name), >> TempateHashModel.get(key), and TemplateSequenceModel.get(index) >> returns null if the subvariable is missing, and >> TemplateNullModel.INSTANCE if it's present but stores a null value. >> Also in TemplateDirectiveModel and TemplateFunctionModel the >> `TemplateModel args` argument of execute(...) will contain null if >> the argument was omitted on the caller side (like in f() the 1st >> parameter is omitted), but TemplateNullModel.INSTANCE if it the >> argument was present, but has null value on the template language >> level (like in f(null) or f(obj.willReturnNull())). >> >> The above can be confusing, as null on the template language level is >> TemplateNullModel.INSTANCE on the API level, and null on the API level >> is "missing" on the template language level... So when I write null, >> pay attention to if it's null on the template language level, or null >> on the API/implementation level. > > Could it be an option to use either TemplateModel.NULL_VALUE or > TemplateModel.MISSING_VALUE, whether in Environment.getVariable(name) > or in TemplateCallableModel#...)? > It might be more readable if doable. > I guess there should be quite a change even with > TemplateNullModel.INSTANCE or null in CallableUtils.java (e.g, > #getOptionalStringArgument(...)) as it should be determined how to > handle null or missing value there.