[Petal] New syntaxes

Fergal Daly fergal at esatclear.ie
Wed Jul 9 15:12:47 BST 2003


On Wednesday 09 July 2003 12:36, Jean-Michel Hiver wrote:
> Just throwing ideas in the wild...
> 
> How about we could prefix variable names with their types to hint the
> compiler?
> 
> Example:
> 
> %foo/bar # foo is a hash ref
> @foo/0   # foo is an array ref 
> ~foo/bar # foo is an object
> foo/bar  # unknown

one weird thing then is that

$hash->{thing}->{key1}->{key2}

would be

%thing/%key1/key2

The thing I like about thing{key}[0] is that it's basically Perl which should 
be natural for anyone using Petal.

> It would ve quite easy for me to get Petal to just ignore those
> syntaxical changes in its expression parser. We could maintain
> compatibility with both systems (with added tests to the test suite)
> until everybody feels that CodePerl is good enough to be merged back
> into Petal.

Is there a need for the current Petal to understand these extension? As long 
as Petal::CodePerl (PCP) remains backwards compatible and passes Petal's test 
suite then we can play with ideas there, rather than fiddling with Petal.

If I make the PCP's grammar configurable, brave people can define their own 
grammars or tweak the existing one.

 > As for passing arguments to functions, I would much rather see it
> functionning with the following syntax, which is a natural extension of
> the way things work at the moment:
> 
> --foo           equates to      "foo"
> 'foo'           equates to      'foo'
> foo             equates to      $hash->{foo} or something
> $foo            equates to      $hash->{foo} or something
> ${foo}          equates to      $hash->{foo} or something
> ${foo/bar baz}  equates to      $hash->{foo}->bar ('baz')
> etc.

I think PCP implements this except I'm not sure about that last one, should 
you have written $hash->{foo}->bar ($hash->{baz}) ? That's what PCP gives at 
the moment.

I'd like there to be a way to signal the end of the argument list, so that you 
can call methods on the return value of a method. Wrapping the args in () 
seems to be a nice and familiar way of doing that.

Or do you mean that ${} would work outisde strings? So I could do

${foo/bar baz}/frob

> Of course as you mentionned there is a problem with modifiers modifier,
> but unfortunately that is unavoidable given the very flexible nature of
> modifiers.

This reminds me of something else I meant to mention - modifiers. They are 
basically uncompilable as things stand because of this very flexible nature. 
However there is a way to keep this flexibilty and solve the compilation 
problem.

Firstly I should say that I don't consider string:, path:, not: and exists: to 
really be modifiers, they are parts of the basic grammar. At least string: 
and path: defintely are because they fundamentally effect the parsing of what 
comes after.

Current modifiers look like this

modifier_name ":" modifier_body

and they run by passing the modifier_body string into the modifier without any 
alterations.

so

true:thing/key

beomes

$MODIFIERS->{true}->("thing/key")

and this routine has to parse "thing/key" at run time. This is slow and also 
means that any modifier that wants to work on a path has to know how to parse 
paths at run time which makes them more complicated and means the full 
grammar parser has to be loaded for that template.

To make modifiers more compilable, I'd like to see them changed to

modifier_name ":" expression

that is the modifier no longer gets passed the string that follows the colon, 
insead, that string is compiled as a Petales expression

so

true:thing/key

could compile to

$MODIFIERS->{true}->($hash->{thing}->{key})

and 

reverse:uppercase:thing/key

could compile to

$MODIFIERS->{reverse}->($MODIFIERS->{uppercase}->($hash->{thing}->{key}))

No run-time compilation going on any more.

All of the modifiers included with Petal and given in the examples parse their 
argument as an expression anyway, so most templates would stay the same, just 
the backend implementation would change. So in Petal::Hash::UpperCase, you 
would change process from

sub process {
  my $class = shift;
  my $hash  = shift;
  my $args  = shift;

  my $result = $hash->fetch ($args);
  return uc ($result);
}

to

sub process
{
	my $self = shift;
	my $string = shift;
	return uc($string);
}

Which is simpler and faster.

Any modifier that really needs an actual string rather than an expression 
could be used like this

"custom:string:something to be interpreted by the custom modifier"

or if you can use "" and '' as in my earlier mail

"custom:'something to be interpreted by the custom modifier'"

and would look like

$MODIFIERS->{custom}->('something to be interpreted by the custom modifier')

In fact I think this is the real reason why I came up with allowing "" or '' 
as an alternative to string:

Finally if someone is feeling brave then could add a perl() method to 
Petal::Hash::UpperCase

sub perl
{
	my $self = shift;
	my $expr = shift;

	return "uc($expr)";
}

When compiling

uppercase:thing/key

the compiler spots that Petal::Hash::UpperCase has a perl() method and so 
passes in the expression to that method to get

uc($hash->{thing}->{key});

So the modifier is fully compiled.

Without making this change it will be impossible to compile modifiers without 
modifiying the grammar every time you add a modifier,

F



More information about the Petal mailing list