You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Christoph Reck <Ch...@dlr.de> on 2000/11/29 12:56:25 UTC

[PROPOSAL] syntax update in Velocimacros

Velocimacros are a great thing. Sadly enough it was quickly implemented 
without a second review.

This is a proposal to get the syntax updated to match common
practices (including ones used wihtin VTL). 
a) It does not affect the current functionality, but just the 
   way VMs are declared and invoked.
b) It helps VTL and VMs to be more intuitive and avoids
   having diferrent ways of invocations:
   #current(macro call syntax) vs. $object.method(call, syntax)
c) It avoids the current confusion of RHS directives (example below).
d) Maybe it is still time to update the VMs before they are
   widely spread. This proposal comes 9 days after the initial
   Velocimacro announcement.

Proposal:
1. parameters to VMs references should be comma separated.
2. The #macro directive is a real directive, whereas when 
   invoking it, it is a reference! Therefore it should be
   prefixed with a '$'and not a '#'.

Instead of:
> #macro( vmname arg1 arg2 )
>     <VM VTL code>
> #end
>[snip]
> #vmname( arg1 arg2 )

It should be:
  #macro(vmname: $arg1, $arg2)
      <VM VTL code fromatting the arguments>
  #end
* It could do without colon, commas to match the syntax in other 
  directives - but is strange within parameter lists, each
  directive could bring its own syntax: #foreach($a in $b)...#end,
  #macro(name: $a, ...)...#end, #include($a $b ...) [should
  use commas], #parse($a), and some new ones #eval($a), 
  #for(setAsignement; condition; postAssignement)...#end, etc.
* Note that the $arg1 declaration should contain the '$' to 
  match the #set directive.

And when invoking it:
  $vmname("string passed into arg1", $referencePassedIntoArg2)


Two ways exist to recognize a VM invocation:
A. During template parsing: a VM invocation contains a clear
   signature - no dot after the reference name and brakets.
   Every other context object contains either no parameters
   (implicit toString) or a dot and one or more identifiers
   following it. This can be used to place a macro reference
   node into the ASTree already during parsing.
B. During template merging: use "instanceof" to detect a VM 
   interface and invoke the VM method with the parameters in
   an array.


The problem with RHS directives can then be solved elegantly
by wrapping the directive in a macro and then using it
on the RHS:
   #macro(parse, $filename)#parse($filename)#end
   #set $data = $parse("filename")
No property options are required to disable scary constructs!


I hope this proposal receives many +1 votes and does not
start a flame war.

:) Christoph

Re: [PROPOSAL] syntax update in Velocimacros

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
I'll weigh in early to start the discussion  :) Note that no coffee has
yet been had, so consider that.  I am not voting here, just adding to
the discussion. (No voting before coffee...)

Christoph Reck wrote:
> 
> Velocimacros are a great thing. Sadly enough it was quickly implemented
> without a second review.

It wasn't _that_ quick.  I think I sent working VM code to the list
sometime in mid-late september, or very early october at the latest,
with my proposal.  I suspect that no one actually tried it, but the code
did work with the current CVS tree at that time.
 
> This is a proposal to get the syntax updated to match common
> practices (including ones used wihtin VTL).
> a) It does not affect the current functionality, but just the
>    way VMs are declared and invoked.
> b) It helps VTL and VMs to be more intuitive and avoids
>    having diferrent ways of invocations:
>    #current(macro call syntax) vs. $object.method(call, syntax)
> c) It avoids the current confusion of RHS directives (example below).
> d) Maybe it is still time to update the VMs before they are
>    widely spread. This proposal comes 9 days after the initial
>    Velocimacro announcement.

They must spread quickly!  VM := VirusMacro!
 
> Proposal:
> 1. parameters to VMs references should be comma separated.
> 2. The #macro directive is a real directive, whereas when
>    invoking it, it is a reference! Therefore it should be
>    prefixed with a '$'and not a '#'.

I disagree with both of these, because at least to my current thinking,
VMs are really a 'lightweight' directive of sorts, and not a reference. 
Here's why I disagree in more detail :

1) Currently, the VTL syntax for directives is a non-comma separated
list, #foo( $a $b )  Granted, this sort of looks to be in conflict with
reference methods, where we do require commas. $a.b($c,$d)  Maybe my
counterproposal would be to make the commas optional in method calls. 
Thats a bizarre idea for us programmers, but maybe not to a designer. 
Or both : if you want to sprinkle commas between directive args if that
makes you happy, great. But they shouldn't be required, I feel.

2) A VM is NOT a reference on invocation. No way.  It's not in the
context, which is pretty much the *defintion* of a reference.  Remeber
the 'rule' : it is the presence of a 'backing object' in the context
that determines if $foo is a context, not the fact that it has a $ in
the front of it.  Also, a template can create an instance of something
in the context via #set such that the java application using Vel can
access that reference.  You can't do that with a VM.  Further, I can't
think of a single example where
   $foo( $a, $b )
is actually possible.  In all cases, I think it would be 
   $foo.method1($a,$b)
so 
   $vmname($a, $b)
is not valid VTL at all.

> [SNIP]
>
> Two ways exist to recognize a VM invocation:
> A. During template parsing: a VM invocation contains a clear
>    signature - no dot after the reference name and brakets.
>    Every other context object contains either no parameters
>    (implicit toString) or a dot and one or more identifiers
>    following it. This can be used to place a macro reference
>    node into the ASTree already during parsing.
> B. During template merging: use "instanceof" to detect a VM
>    interface and invoke the VM method with the parameters in
>    an array.

I'm not quite sure what you are getting at.  I am working on something I
call 'late binding' to allow you to invoke a VM in a template *before*
it's actually defined via #macro().  This makes a pair of recursive VMs
possible

#macro( foo )
  #bar()
#end
#macro( bar )
  #foo()
#end

and allows lazy people like Jon Stevens to not have to bother to cut and
paste his #macro() calls to the top of his templates :)


> The problem with RHS directives can then be solved elegantly
> by wrapping the directive in a macro and then using it
> on the RHS:
>    #macro(parse, $filename)#parse($filename)#end
>    #set $data = $parse("filename")
> No property options are required to disable scary constructs!

I think that the RHS idea was met with resistance, which was ignored via
interpolation :)  So you have this functionality right now, w/o having
to go the extra step of defining the VM.

> I hope this proposal receives many +1 votes and does not
> start a flame war.
> 
> :) Christoph

Like I said, I am not voting immediately. I wanted to get my 0.02 in.

geir

-- 
Geir Magnusson Jr.                               geirm@optonline.com
Dakota tribal wisdom: "when you discover you are riding a dead horse,
the best strategy is to dismount."

Re: [PROPOSAL] syntax update in Velocimacros

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
I'll weigh in early to start the discussion  :) Note that no coffee has
yet been had, so consider that.  I am not voting here, just adding to
the discussion. (No voting before coffee...)

Christoph Reck wrote:
> 
> Velocimacros are a great thing. Sadly enough it was quickly implemented
> without a second review.

It wasn't _that_ quick.  I think I sent working VM code to the list
sometime in mid-late september, or very early october at the latest,
with my proposal.  I suspect that no one actually tried it, but the code
did work with the current CVS tree at that time.
 
> This is a proposal to get the syntax updated to match common
> practices (including ones used wihtin VTL).
> a) It does not affect the current functionality, but just the
>    way VMs are declared and invoked.
> b) It helps VTL and VMs to be more intuitive and avoids
>    having diferrent ways of invocations:
>    #current(macro call syntax) vs. $object.method(call, syntax)
> c) It avoids the current confusion of RHS directives (example below).
> d) Maybe it is still time to update the VMs before they are
>    widely spread. This proposal comes 9 days after the initial
>    Velocimacro announcement.

They must spread quickly!  VM := VirusMacro!
 
> Proposal:
> 1. parameters to VMs references should be comma separated.
> 2. The #macro directive is a real directive, whereas when
>    invoking it, it is a reference! Therefore it should be
>    prefixed with a '$'and not a '#'.

I disagree with both of these, because at least to my current thinking,
VMs are really a 'lightweight' directive of sorts, and not a reference. 
Here's why I disagree in more detail :

1) Currently, the VTL syntax for directives is a non-comma separated
list, #foo( $a $b )  Granted, this sort of looks to be in conflict with
reference methods, where we do require commas. $a.b($c,$d)  Maybe my
counterproposal would be to make the commas optional in method calls. 
Thats a bizarre idea for us programmers, but maybe not to a designer. 
Or both : if you want to sprinkle commas between directive args if that
makes you happy, great. But they shouldn't be required, I feel.

2) A VM is NOT a reference on invocation. No way.  It's not in the
context, which is pretty much the *defintion* of a reference.  Remeber
the 'rule' : it is the presence of a 'backing object' in the context
that determines if $foo is a context, not the fact that it has a $ in
the front of it.  Also, a template can create an instance of something
in the context via #set such that the java application using Vel can
access that reference.  You can't do that with a VM.  Further, I can't
think of a single example where
   $foo( $a, $b )
is actually possible.  In all cases, I think it would be 
   $foo.method1($a,$b)
so 
   $vmname($a, $b)
is not valid VTL at all.

> [SNIP]
>
> Two ways exist to recognize a VM invocation:
> A. During template parsing: a VM invocation contains a clear
>    signature - no dot after the reference name and brakets.
>    Every other context object contains either no parameters
>    (implicit toString) or a dot and one or more identifiers
>    following it. This can be used to place a macro reference
>    node into the ASTree already during parsing.
> B. During template merging: use "instanceof" to detect a VM
>    interface and invoke the VM method with the parameters in
>    an array.

I'm not quite sure what you are getting at.  I am working on something I
call 'late binding' to allow you to invoke a VM in a template *before*
it's actually defined via #macro().  This makes a pair of recursive VMs
possible

#macro( foo )
  #bar()
#end
#macro( bar )
  #foo()
#end

and allows lazy people like Jon Stevens to not have to bother to cut and
paste his #macro() calls to the top of his templates :)


> The problem with RHS directives can then be solved elegantly
> by wrapping the directive in a macro and then using it
> on the RHS:
>    #macro(parse, $filename)#parse($filename)#end
>    #set $data = $parse("filename")
> No property options are required to disable scary constructs!

I think that the RHS idea was met with resistance, which was ignored via
interpolation :)  So you have this functionality right now, w/o having
to go the extra step of defining the VM.

> I hope this proposal receives many +1 votes and does not
> start a flame war.
> 
> :) Christoph

Like I said, I am not voting immediately. I wanted to get my 0.02 in.

geir

-- 
Geir Magnusson Jr.                               geirm@optonline.com
Dakota tribal wisdom: "when you discover you are riding a dead horse,
the best strategy is to dismount."