Monday, January 9, 2017, 10:06:11 AM, Christoph Rüger wrote:
[snip]
>> > templateDialectMode=extend (FM-core + own functions using a prefix.)
>>
>> If you are using a prefix, then it's an auto-import (which you can do
>> already, though not with `:` and so you can call those functions with
>> `?`).
>>
>
> I guess you are referring to
> http://freemarker.org/docs/dgui_misc_namespace.html when you say
> "already". Yes we use auto-imports internally for some helper-macros
> in our templates. But they are not exposed for users. We could, but
> at the moment we use TemplateMethodModels for any additional
> user-facing functionality.
I meant that templateDialectMode=extend above is the same as
auto-imports (with `:` so that it can be used with `?`). Or is not?
>> > templateDialectMode=onlyOwnNamespaces (no FM-core, only own namespaces)
>> >
>> > The latter would be great if you want to provide an (sandboxed)
>> > environment with kind of a custom DSL (domain specific language) which
>> should be very limited.
>> >
>> > I think the general rule should be: FM-core functions are not
>> > customizable, but you should be able to add on top of it.
>>
>> That won't work, because then adding a new FM-core function will break
>> backward compatibility.
>>
> Hmm ok I see.
> I guess I am fine with ${x?my:bar} so we could provider all our own custom
> built-ins under this "my" prefix (or "sy" as we already do with our
> auto-import macros <@sy.foo "bar" />)
What could also work is that when you create a custom dialect, you
always has to specify which version of the standard dialect do you
base it on. Then you aren't allowed to define custom callables that
clash in name with a standard one that has already existed in that
version. But for callables added later than that version, yours wins.
So there can be unfortunate cases, where the user looks up something
in the Manual, and it's there yet it behaves differently, but
hopefully the chance of a such name clash is small enough to live with
it.
[snip]
>> > works (e.g. ${var1} foo ${var2} is easy to get and also
>> > ${mystring?lower_case} is easy to understand
>> [snip]
>>
>> Or is it? I was wondering for a while whether instead of
>> `exp?trim?upperCase` the more verbose `exp.#trim.#upperCase` would be
>> easier to grasp. Yes, it's uglier if your eyes are used to FTL. But if
>> not (and let's face it, that's the majority), as you probably already
>> know `.`, it's easy to understand that FTL adds some member its own,
>> and the names of those start with `#`. No additional operator, no
>> doubts about the precedence of it. (It's like extension methods in
>> some other languages, only it's clear at glance what's an extension
>> method.)
>>
>> Ah ok I see what you mean:
> The '.' tells you want to call something on the object,
> exp.#trim would call a FM built-in while
> exp.trim would call the trim() method on the underlying object in the data
> model.
The last has to be exp.trim() with our current ObjectWrapper-s, as
`exp.trim` returns the method itself (which you can pass around and
call later).
Not having the `()` there is yet another thing worths considering. If
someone once in a blue moon wants to get the method itself, they could
use some special syntax (like exp::trim as in Java 8, or some currying
syntax). But of course the problem here is that people are used to add
that `()` after method calls. We can tell that it's optional if you
have 0 arguments, but what will happen is that 90% of the users will
put the `()`, and the rest won't. So if you want to prevent chaos, the
only way is banning `exp.trim()`, which however some can see as
annoying. (We even have problems with getters there... many keep
writing `foo.getBar()` while they could just write `foo.bar`. With
that they damage both themselves an the raputation of FM. So in FM3 I
want to disallow calling `foo.getBar()` if you could do `foo.bar`
instead. Of course I would tell in error message what to do.)
As you see, there's a lot of things that perhaps could be changed to
make using FM more productive and satisfying for the users.
> Maybe I am the wrong person. I got used to the '?' operator.
> I was fine with the logic in my head:
>
> *Things calling stuff on the object directly:*
> '.' calls functions on the underlying object
> ? calls a FM built-in (which can be chained)
There's also lot of people who find the syntax of FTL sick. All the
`?` and `!`-s, especially they are next to each other. What I expect
to happen is that we stick to `?` and all, because of tradition. But
syntax is a not very thick layer on the top of the whole engine, so
ideally, if we ever get there, we could have another syntax, more like
in WebMacro/Velocity style, where the expression language is also more
aligned with the trends (such as the usage of `?` to marks something
that can be null, instead of `!` which almost nobody uses).
> *Method-like things*
> <#xxx> is a directive (if, else, list, all that stuff)
> <@foo> are macros (I always see them as functions...something which takes
> parameters and does something. )
${function(params)>> are function calls defined by <#function . They look
> the same as TemplateMethodModels
Macro VS function difference is something that confuses many. I used
to say that macros (and other directives) are called for their side
effects, which can include printing to the output stream (but that's
not always the case, think about #assign, #import, #if, etc.), while
functions are called to calculate/get a single value. Another
important difference is that the "result" of a macro is never subject
to auto-escaping, and it can't be a number, boolean, etc, only what's
called "output markup" in FM. Generally, thinks that are potentially
markup should be generated with macro, though that functions can now
return ?noEsc-ed values make this distinction somewhat blurry. I hope
that in FM3 these things will become less different *internally*, but
I guess the distinction will be enforced on the FTL level.
> My gut-feeling tells me that every extra thing / character which makes
> something look more verbose can be bad. But I also understand the technical
> side, that you need to distinguish between FM-core functions and the other
> functions.
A program can follow any kind of fallback rules to get rid of such
extra symbols, like in exp.trim I could first check if there's a
getTrim() or trim() Java method in that object, and if not, I check if
I have a trim function in the template language, etc. Surely it raise
some technical challenges (like speed issues), but the computer can
grinds through somehow. The problem is that it's also challenging for
the user. What's "trim", where to look it up? Why FreeMarker only
complains about not having a "tirm" (a deliberate typo) built-in on
runtime (because, it couldn't know if you have a getTirm() in your
object before that). And what if you add getTrim later? Suddenly the
behavior of your templates will change as now exp.trim doesn't fall
back to the built-in trim (i.e., you got a maintenance issue)? For
some applications, these aren't important enough problems to warrant
the extra symbols. But FreeMarker is the kind of template engine that
takes these seriously. I want to keep such "values" in FM3 too. I
believe it belongs to the identity of the project.
> There are some interesting articles on language verbosity:
> http://redmonk.com/dberkholz/2013/03/25/programming-languages-ranked-by-expressiveness/
> http://www.michael-snell.com/2015/03/on-verbosity-in-programming-languages.html
>
>
> Maybe it would be a good idea to write down the different notation-ideas on
> a single page somewhere and compare it side-by-side and ask more people
> about opinions.
> I think that syntax is an important topic, and the more "right" or
> "accepted" you can get it, the better. I am pretty satisfied with the
> current syntax, so you should carefully discuss the pros and cons of a new
> syntax.
Yeah, I will get into that in its own topic when the time comes. My
guess is that in FTL3 we won't change much on the look-and-feel,
because, it's still FTL. But we will see what others have to say.
> Thanks
> Christoph
>
>
>> --
>> Thanks,
>> Daniel Dekany
>>
>>
>
>
> --
> Christoph Rüger, Geschäftsführer
> Synesty <https://synesty.com/> - Automatisierung, Schnittstellen, Datenfeeds
> Tel.: +49 3641/559649 <+49%203641%20559649>
>
> Xing: https://www.xing.com/profile/Christoph_Rueger2
> LinkedIn: http://www.linkedin.com/pub/christoph-rueger/a/685/198
>
--
Thanks,
Daniel Dekany