Syntax of resource expressions (was: Decision: Near future of resource expressions)

38 views
Skip to first unread message

Andy Parker

unread,
Aug 5, 2014, 8:51:20 PM8/5/14
to puppe...@googlegroups.com
I'm pulling this discussion out into a new thread so that we can become more focussed. I'm also going to start a thread about one other topic that has been brought to my attention so that a decision can be reached.

In this thread I'd like to get to a decision about two aspects of resource expressions:

  1. Whether to allow expressions in the type position ($a { hi: })
  2. Whether to allow using hashes as resources parameters
  3. If we allow hashes as resource parameters, what token introduces it (no introducing token isn't an option because of implementation constraints).

The use case for number 1 is to provide determining the exact type of a resource at runtime. An example would be a module that had different implementations for debian vs redhat. It can then use parts of its self like so:

  apache::install::$osfamily { 'something': }

Note: I'm not promoting this or saying that this kind of construction should appear everywhere, but it is a feature that isn't available in the language at the moment.

The use case for number 2 is determining dynamically what parameters need to be included. In fact I saw a question just recently where someone tried to do (something like):

  service { 'apache':
    if $control_service {
      ensure => running
    }
    enabled => true
  }

That could be done instead as:

  $params = if $control_service { 
    { ensure => running }
   } else {
     { }
   }
   service { 'apache':
      * => $params;
    default: 
      enabled => true
    }

A second use case is to provide a way of allowing local defaults to be reused across multiple resources. And a third one was presented by Erik.

Are these use cases invalid or not needed? If not, how should they be solved? There is create_resources. Is that really a good solution? I ask that in all seriousness given that the only purpose of the puppet language is to construct catalogs of resources to manage configurations and the current syntax for those fundamental elements are so inflexible that we had to add a function to leave the language for slightly more advanced resource creation scenarios.

Puppet Labs has a UX department that is at the ready to perform any user testing or usability analysis that anyone thinks might be valuable to answer these questions. If we can work out what kinds of questions there are we can definitely get some study done.

On Tue, Aug 5, 2014 at 4:11 PM, Henrik Lindberg <henrik....@cloudsmith.com> wrote:
On 2014-05-08 18:24, Andy Parker wrote:
On Tue, Aug 5, 2014 at 8:18 AM, Erik Dalén <erik.gus...@gmail.com
<mailto:erik.gustav.dalen@gmail.com>> wrote:

    On 5 August 2014 16:25, Reid Vandewiele <re...@puppetlabs.com
    <mailto:re...@puppetlabs.com>> wrote:

        On Mon, Aug 4, 2014 at 3:18 PM, Henrik Lindberg
        <henrik.lindberg@cloudsmith.com
        <mailto:henrik.lindberg@cloudsmith.com>> wrote:


            So, to summarize: The use of * => as an operator is not
            liked but the concept of being able to set attributes from a
            hash is. Unfortunately, it is not possible to directly allow
            an expression at the position in question, there must be a
            syntactical marker.

            As pointed out earlier, the * => was thought to read as
            "any_attribute => from_these_values", but I totally grok if
            people have an allergic reaction.

            We can do this though:

            file { default: ($hash) }

            This works because it is impossible to have an attribute
            name in parentheses.

            In use:

            file (
               default   : ($my_file_defaults + { mode => '0666' });
               '/tmp/foo': ;
               '/tmp/bar': ;
            }

            Is that better? No new operator, but you have to use
            parentheses around the expression.

            We can naturally also revert the functionality, but it seems
            it is liked conceptually.


            - henrik



        I think the parenthesis are far preferable over *=>. That isn't
        to say I like them - I don't particularly. But the functionality
        is desirable, and if it's a matter of a technical limitation
        then parenthesis are a Good Enough (TM) compromise from the more
        ideal direct use of a hash.


    I really prefer the use of  * => over the parenthesis. Especially if
    you need to merge things into the hash. For example look at this
    example:

    # using parenthesis hash style
    class foo (

    $servername = $::fqdn,
    $port = 80,
    $ssl = false,
    $extra_opts={},

    ) {
    apache::vhost { $servername: ($extra_opts + {


    port => $port,
    ssl => $ssl,
    })

    }
    }
    # using * =>
    class foo (

    $servername = $::fqdn,
    $port = 80,
    $ssl = false,
    $extra_opts={},

    ) {
    apache::vhost { $servername:

    port => $port,
    ssl => $ssl,
    * => $extra_opts,


    }

    }


The behavior that we worked out doesn't allow having the splat along
with the other parameters, the reason being that it isn't clear what is
meant by that. You had in your head that port and ssl are overridden by
extra_opts (possibly because they come first?), but another, completely
reasonable interpretation is that it is the other way around (port and
ssl override extra_opts because they are explicitly given. In order to
remove any of that confusion the current specification and
implementation doesn't allow mixing. That can, I think, be changed.

In the current implementation this would need to be:

apache::vhost { $servername:
   * => $extra_opts + { port => $port, ssl => $ssl }
}

    IMO the *=> is way more readable (as gist here if formatting is
    screwed up for you:
    https://gist.github.com/dalen/57b37b80a9ba1879b78c). This is quite
    similar to what I linked earlier that I am doing in
    https://github.com/spotify/puppet-puppetexplorer/blob/master/manifests/init.pp#L89-L97
    So it is not just a contrived example.


My argument against using parenthesis is that parenthesis, are often
read as "seldom necessary grouping". I believe that most programmers
read them as usually only needed for fixing precedence problems, which
is really what is happening here but it doesn't look like it. Based on
that I can imagine that a common, and frustrating mistake would be:

   apache::vhost { $servername: $opts }

And then confusion and anger and bug reports.


Yeah, I think they are too subtle too (and hence the * =>).


One more proposal :-)

We could leave out the name part all together (i.e. drop the '*').

dalens' example would then look like this:


     apache::vhost { $servername:

     port => $port,
     ssl  => $ssl,
          => $extra_opts,

And if it is used for local defaults (or the only thing for a titled resource):

    file { default: => $hash }
    file { '/tmp/foo': => $hash }

This works best if it is restricted to being the only attribute operation for a title, but looks a bit odd when presented in a list where there are also named (i.e. name => expression) operations.

At least it is not a new operator.

Is this better than * => or requiring parentheses ?


- henrik

--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/lrrobu%245b1%241%40ger.gmane.org.

For more options, visit https://groups.google.com/d/optout.



--
Andrew Parker
Freenode: zaphod42
Twitter: @aparker42
Software Developer

Join us at PuppetConf 2014September 22-24 in San Francisco
Register by May 30th to take advantage of the Early Adopter discount save $349!

Trevor Vaughan

unread,
Aug 5, 2014, 11:39:53 PM8/5/14
to puppe...@googlegroups.com
1) I think that this is going to be used to develop highly complex and unmaintainable code but I see the use case. +1

2) Yes, I think this would be nice in some complex cases but I don't mind create_resources. Of course, I create resource on the fly in my Types so I may not be the best judge....

3) I think that, should you use a hash for parameters, it's something *really* clear like 'parameter_hash' or 'param_hash'. Fundamentally, every concrete chunk of code that I've seen with this in it has not thrilled me in terms of understandability by other users. I agree with a point made in the other thread that trying to search on *=> isn't going to get you very far. 

service { 'apache': param_hash => $param_hash } # Nice an descriptive, easy to search and probably what you're going to guess anyway

Q: "What's the parameter hash thing?"
A: "Oh, param_hash"

Trevor


To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/CANhgQXvw3AxSQgrUQQKpMyrCNPkdci9gytum-C832C7_q8v6xQ%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.



--
Trevor Vaughan
Vice President, Onyx Point, Inc
(410) 541-6699
tvau...@onyxpoint.com

-- This account not approved for unencrypted proprietary information --

David Schmitt

unread,
Aug 6, 2014, 2:25:12 AM8/6/14
to puppe...@googlegroups.com
Hi,

thanks for keeping the ball rolling!

On 2014-08-06 02:51, Andy Parker wrote:
> I'm pulling this discussion out into a new thread so that we can become
> more focussed. I'm also going to start a thread about one other topic
> that has been brought to my attention so that a decision can be reached.
>
> In this thread I'd like to get to a decision about two aspects of
> resource expressions:
>
> 1. Whether to allow expressions in the type position ($a { hi: })

> The use case for number 1 is to provide determining the exact type of a
> resource at runtime. An example would be a module that had different
> implementations for debian vs redhat. It can then use parts of its self
> like so:
>
> apache::install::$osfamily { 'something': }
>
> Note: I'm not promoting this or saying that this kind of construction
> should appear everywhere, but it is a feature that isn't available in
> the language at the moment.
>

What Trevor said: highly prone to misuse, but for the use case given, +1
as a shortcut to create_resources.

Note: we talked about $ a having various types, but I think this
question only is about values that are Strings or Types, which I think
is a very sensible restriction to avoid the complexities and abuses
beyond the specified use case.

> 2. Whether to allow using hashes as resources parameters
> 3. If we allow hashes as resource parameters, what token introduces
> it (no introducing token isn't an option because of implementation
> constraints).

I really like Reid's suggestion to use a proper attribute name instead
of an asterisk.

> The use case for number 2 is determining dynamically what parameters
> need to be included. In fact I saw a question just recently where
> someone tried to do (something like):
>
> service { 'apache':
> if $control_service {
> ensure => running
> }
> enabled => true
> }
>
> That could be done instead as:
>
> $params = if $control_service {
> { ensure => running }
> } else {
> { }
> }
> service { 'apache':
> * => $params;
> default:
> enabled => true
> }

This code gives me the hives. As I've replied in that thread, my usual
way to write this is

service { 'apache':
enabled => true
}

if $control_service {
Service['apache'] { ensure => running }
}

If I were forced to use hashes, I think I'd write something along these
lines:

$service_params = {
enabled => true
}
if $control_service {
$service_params['ensure'] = 'running'
}
create_resource('service', $service_params)

Re-reading that, it could be even argued, that it flows better because
the create_resource is at the end, and all relevant values are collected
before, while my way adds values after the resource definition. Also the
hash version doesn't duplicate the resource title. I'm beginning to like
it even better.

To show Reid's proposal:

$service_params = $control_service ? {
true => { $ensure => 'running' }
false => {}
}

service { 'apache':
enable => true,
defaults => $service_params;
}

also very concise and readable to me.


> A second use case is to provide a way of allowing local defaults to be
> reused across multiple resources. And a third one was presented by Erik.
>
> Are these use cases invalid or not needed? If not, how should they be
> solved? There is create_resources. Is that really a good solution? I ask
> that in all seriousness given that the only purpose of the puppet
> language is to construct catalogs of resources to manage configurations
> and the current syntax for those fundamental elements are so inflexible
> that we had to add a function to leave the language for slightly more
> advanced resource creation scenarios.
>
> Puppet Labs has a UX department that is at the ready to perform any user
> testing or usability analysis that anyone thinks might be valuable to
> answer these questions. If we can work out what kinds of questions there
> are we can definitely get some study done.

I do like both the defaults: title keyword and Reid's
'(attribute|param)_(override|defaults|hash)' metaparam instead of the
splat operator proposals. Both are shorthands for hash manipulation and
a create_resource call. In the most general sense, the whole Puppet DSL
is a shorthand for hash manipulation and create_resource calls. So for
me the questions is, are those shorthands understandable and valuable,
that is, more readable/modifyable/writeable than a hash+create_resource.
Like Trevor has suggested, we all might not be the best suited to reason
about this ;-)


Regards, David


> On Tue, Aug 5, 2014 at 4:11 PM, Henrik Lindberg
> <henrik....@cloudsmith.com <mailto:henrik....@cloudsmith.com>>
> wrote:
>
> On 2014-05-08 18:24, Andy Parker wrote:
>
> On Tue, Aug 5, 2014 at 8:18 AM, Erik Dalén
> <erik.gus...@gmail.com <mailto:erik.gus...@gmail.com>
> <mailto:erik.gustav.dalen@__gmail.com
> <mailto:erik.gus...@gmail.com>>> wrote:
>
> On 5 August 2014 16:25, Reid Vandewiele
> <re...@puppetlabs.com <mailto:re...@puppetlabs.com>
> <mailto:re...@puppetlabs.com <mailto:re...@puppetlabs.com>>>
> wrote:
>
> On Mon, Aug 4, 2014 at 3:18 PM, Henrik Lindberg
> <henrik.lindberg@cloudsmith.__com
> <mailto:henrik....@cloudsmith.com>
> <mailto:henrik.lindberg@__cloudsmith.com
> https://gist.github.com/dalen/__57b37b80a9ba1879b78c
> <https://gist.github.com/dalen/57b37b80a9ba1879b78c>). This is quite
> similar to what I linked earlier that I am doing in
> https://github.com/spotify/__puppet-puppetexplorer/blob/__master/manifests/init.pp#L89-__L97
> http://puppet-on-the-edge.__blogspot.se/
> <http://puppet-on-the-edge.blogspot.se/>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Puppet Developers" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to puppet-dev+unsubscribe@__googlegroups.com
> <mailto:puppet-dev%2Bunsu...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/__msgid/puppet-dev/lrrobu%245b1%__241%40ger.gmane.org
> <https://groups.google.com/d/msgid/puppet-dev/lrrobu%245b1%241%40ger.gmane.org>.
>
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
>
>
> --
> Andrew Parker
> an...@puppetlabs.com <mailto:an...@puppetlabs.com>
> Freenode: zaphod42
> Twitter: @aparker42
> Software Developer
>
> *Join us at PuppetConf 2014 <http://www.puppetconf.com/>, September
> 22-24 in San Francisco*
> /Register by May 30th to take advantage of the Early Adopter discount
> <http://links.puppetlabs.com/puppetconf-early-adopter> //—//save $349!/
>
> --
> You received this message because you are subscribed to the Google
> Groups "Puppet Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to puppet-dev+...@googlegroups.com
> <mailto:puppet-dev+...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/puppet-dev/CANhgQXvw3AxSQgrUQQKpMyrCNPkdci9gytum-C832C7_q8v6xQ%40mail.gmail.com
> <https://groups.google.com/d/msgid/puppet-dev/CANhgQXvw3AxSQgrUQQKpMyrCNPkdci9gytum-C832C7_q8v6xQ%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.


--
* Always looking for people I can help with awesome projects *
G+: https://plus.google.com/+DavidSchmitt
Blog: http://club.black.co.at/log/
LinkedIn: http://at.linkedin.com/in/davidschmitt

Henrik Lindberg

unread,
Aug 6, 2014, 10:22:23 AM8/6/14
to puppe...@googlegroups.com
On 2014-06-08 8:25, David Schmitt wrote:
> Hi,
>
> thanks for keeping the ball rolling!
>
> On 2014-08-06 02:51, Andy Parker wrote:
>> I'm pulling this discussion out into a new thread so that we can become
>> more focussed. I'm also going to start a thread about one other topic
>> that has been brought to my attention so that a decision can be reached.
>>
>> In this thread I'd like to get to a decision about two aspects of
>> resource expressions:
>>
>> 1. Whether to allow expressions in the type position ($a { hi: })
>
> > The use case for number 1 is to provide determining the exact type of a
> > resource at runtime. An example would be a module that had different
> > implementations for debian vs redhat. It can then use parts of its self
> > like so:
> >
> > apache::install::$osfamily { 'something': }
> >
> > Note: I'm not promoting this or saying that this kind of construction
> > should appear everywhere, but it is a feature that isn't available in
> > the language at the moment.
> >
>
> What Trevor said: highly prone to misuse, but for the use case given, +1
> as a shortcut to create_resources.
>
> Note: we talked about $ a having various types, but I think this
> question only is about values that are Strings or Types, which I think
> is a very sensible restriction to avoid the complexities and abuses
> beyond the specified use case.
>

We came to a conclusion that a String or ResourceType result were ok. We
could however restrict this further to only accept:

* static NAME (i.e. an unquoted lower case name, like today)
* ResourceType (i.e. the result of evaluating Resource['name'], File, etc).

This restriction would force the user that wants type indirection to
place any string expression inside a Resource[], either on the LHS, or
when assigning to a variable. Maybe this restriction more clearly
reflects the intent?

i.e. these would be allowed:

file { title: ...}
Resource[file] {title: ...}

$a = "file"
Resource[$a] {title: ...}

$b = "ile"
$a = Resource["fi${b}"]
$a {title: ...}

File { title: ... }
$a = File
$a { title: ... }

but not these:

'file' { title: ... }

$b = "ile"
"fi${b}" { title: ... }

$a = file
$a {title: }

Maybe this restriction helps people from inadvertent use of a string,
and makes it easier to understand the intent, as a user/reader would be
able to trace the value of an expression back to a Resource[] type
expression (or even to a specific type reference such as File.


>> 2. Whether to allow using hashes as resources parameters
>> 3. If we allow hashes as resource parameters, what token introduces
>> it (no introducing token isn't an option because of implementation
>> constraints).
>
> I really like Reid's suggestion to use a proper attribute name instead
> of an asterisk.
>

I am fine with that too. (It reserves an attribute name though, but that
is not the end of the world).

[...snip...]

> I do like both the defaults: title keyword and Reid's
> '(attribute|param)_(override|defaults|hash)' metaparam instead of the
> splat operator proposals. Both are shorthands for hash manipulation and
> a create_resource call. In the most general sense, the whole Puppet DSL
> is a shorthand for hash manipulation and create_resource calls. So for
> me the questions is, are those shorthands understandable and valuable,
> that is, more readable/modifyable/writeable than a hash+create_resource.
> Like Trevor has suggested, we all might not be the best suited to reason
> about this ;-)
>
I like that too.

I prefer 'attribute' prefix over 'param' (since parameters are declared
at the receiving side and the operation sets/passes attributes to the
params).

If we want both the "set" and "default" semantics, then I am slightly
concerned over the use of the "default" in yet one more place. Consider
something pathological like this:

type { default: attributes_defaults => $hash1,
attributes_hash => $hash2;

title1: attributes_defaults => $hash3,
attributes_hash => $hash4,
foo => 10;

title2: attribute_hash => $hash5;
}

Lots of defaults... If you really need defaults for a single resource,
it could be written in a separate body:

type { default: attributes_hash => $hash1 + $hash3;
title1 : attributes_hash => $hash4;
}
type { default: attributes_hash => $hash1;
title2 : attributes_hash => $hash5;
}

I think that is clearer. So, I think we do not need the
"attributes_defaults" special name.

- henrik

--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

Andy Parker

unread,
Aug 11, 2014, 8:41:09 PM8/11/14
to puppe...@googlegroups.com
I just did a quick search through the modules on the forge and the follow modules all use a parameter called 'attributes':

  * sensu-sensu-1.0.0
  * deric-mesos-0.2.0 through 0.4.1
  * CERNOps-activemq-0.0.1

This is the problem with trying to take a word (and the same problem that the meta parameters encounter), once that name is taken globally, then nobody else can use it, no matter how good their intentions :/

In different news, but related, Henrik has started working with the UX team to come up with something that we can put in front of people to get a more definitive answer. However, they are saying that they won't be able to get any results until the end of August. We need to come up with an interim solution and then probably make some changes in a "bugfix" release.
 

Regards, David


On Tue, Aug 5, 2014 at 4:11 PM, Henrik Lindberg

wrote:

    On 2014-05-08 18:24, Andy Parker wrote:

        On Tue, Aug 5, 2014 at 8:18 AM, Erik Dalén

        <mailto:erik.gustav.dalen@gmail.com>>> wrote:

             On 5 August 2014 16:25, Reid Vandewiele
        <re...@puppetlabs.com <mailto:re...@puppetlabs.com>
             <mailto:re...@puppetlabs.com <mailto:re...@puppetlabs.com>>>

        wrote:

                 On Mon, Aug 4, 2014 at 3:18 PM, Henrik Lindberg
                 <henrik.lindberg@cloudsmith.__com
        <mailto:henrik.lindberg@cloudsmith.com>
                 <mailto:henrik.lindberg@__cloudsmith.com


--
* Always looking for people I can help with awesome projects *
G+: https://plus.google.com/+DavidSchmitt
Blog: http://club.black.co.at/log/
LinkedIn: http://at.linkedin.com/in/davidschmitt
--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/53E1CA3D.4070509%40dasz.at.

For more options, visit https://groups.google.com/d/optout.



--
Andrew Parker
Freenode: zaphod42
Twitter: @aparker42
Software Developer

Join us at PuppetConf 2014September 22-24 in San Francisco
Register by May 30th to take advantage of the Early Adopter discount save $349!

Henrik Lindberg

unread,
Aug 11, 2014, 9:58:21 PM8/11/14
to puppe...@googlegroups.com
> '(attribute|param)_(override|__defaults|hash)' metaparam instead of
> the splat operator proposals. Both are shorthands for hash
> manipulation and a create_resource call. In the most general sense,
> the whole Puppet DSL is a shorthand for hash manipulation and
> create_resource calls. So for me the questions is, are those
> shorthands understandable and valuable, that is, more
> readable/modifyable/writeable than a hash+create_resource. Like
> Trevor has suggested, we all might not be the best suited to reason
> about this ;-)
>
>
> I just did a quick search through the modules on the forge and the
> follow modules all use a parameter called 'attributes':
>
> * sensu-sensu-1.0.0
> * deric-mesos-0.2.0 through 0.4.1
> * CERNOps-activemq-0.0.1
>
> This is the problem with trying to take a word (and the same problem
> that the meta parameters encounter), once that name is taken globally,
> then nobody else can use it, no matter how good their intentions :/
>
> In different news, but related, Henrik has started working with the UX
> team to come up with something that we can put in front of people to get
> a more definitive answer. However, they are saying that they won't be
> able to get any results until the end of August. We need to come up with
> an interim solution and then probably make some changes in a "bugfix"
> release.
>
>

And we added yet another option, a compromise of using an operator and a
name.

file { 'title': @attributes => $hash }

The @ only combines with the exact word attributes. This makes it
"googlable", descriptive, does not require name to be reserved, and it
meets the technical requirements (it can be parsed etc).

- henrik

--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

Spencer Krum

unread,
Aug 11, 2014, 11:54:22 PM8/11/14
to puppe...@googlegroups.com
1) I really don't want to see variable expansion in expressions that resolve to the names of types. This will be misused, it will make code unreadable. Please leave it out. Sets of parameters only make sense to distinct types anyways, if two types really do accept all the same parameters, then the RAL should be leveraged and different providers written.

2) I think allowing a params_hash metaparmeter to be expanded out into the parameters that the type takes is a great idea. The behavior I would expect is that any specifically called out parameter would override the value found in the hash. It was pointed out before that this presents a problem for undef, I don't have a solution for that. I would like to be able to specify undef and still have that override what is found in the params_hash.

3) I absolutely think a word/metaparameter must be used. I don't really care what it is but it should be unique and googleable. I don't like 'attributes' because its not unique enough to search on.


I think the addition of the params_hash metaparameter makes the 'default:' directive unnecessary.


$files = [

    '/root/file1' => {'owner' => 'root', 'mode' => '0700'},
    '/root/file1' => {'owner' => 'nibz'},
]

$defaults = {
     'mode' => '0644',
}

$files.each | $title, $attributes |
    $params = merge($files, $defaults)
    file { $title:
       params_hash => $params,
    }
}

I think this is better because now all the logic of create_resources is present here in the puppet code: the merging of defaults with specified parameters AND the iteration.


Thanks,
Spencer


--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Spencer Krum
(619)-980-7820

Henrik Lindberg

unread,
Aug 12, 2014, 11:55:35 AM8/12/14
to puppe...@googlegroups.com
On 2014-12-08 5:54, Spencer Krum wrote:
> 1) I really don't want to see variable expansion in expressions that
> resolve to the names of types. This will be misused, it will make code
> unreadable. Please leave it out. Sets of parameters only make sense to
> distinct types anyways, if two types really do accept all the same
> parameters, then the RAL should be leveraged and different providers
> written.
>
It is already used (via create_resources), and people want it to support
integration use cases between more tightly coupled modules.

> 2) I think allowing a params_hash metaparmeter to be expanded out into
> the parameters that the type takes is a great idea. The behavior I would
> expect is that any specifically called out parameter would override the
> value found in the hash. It was pointed out before that this presents a
> problem for undef, I don't have a solution for that. I would like to be
> able to specify undef and still have that override what is found in the
> params_hash.
>
> 3) I absolutely think a word/metaparameter must be used. I don't really
> care what it is but it should be unique and googleable. I don't like
> 'attributes' because its not unique enough to search on.
>
What do you think about the proposal to precede the "meta parameter"
name with @, since we have issues with reserving yet another name (all
good names seems to be in use somewhere already).

We proposed @attributes, so by analogy, it would be @params_hash, or
equivalent using the word you preferred.

>
> I think the addition of the params_hash metaparameter makes the
> 'default:' directive unnecessary.
>
>
> $files = [
>
> '/root/file1' => {'owner' => 'root', 'mode' => '0700'},
> '/root/file1' => {'owner' => 'nibz'},
> ]
>
> $defaults = {
> 'mode' => '0644',
> }
>
> $files.each | $title, $attributes |
> $params = merge($files, $defaults)
> file { $title:
> params_hash => $params,
> }
> }
>
I understand the idea (although the code seems a bit wrong as it will
end up attempting to create a file resource with the title mode, and a
$params with the value of '0644' (and then fail because it is not a hash).

(you probably wanted $params = $defaults + $attributes)

> I think this is better because now all the logic of create_resources is
> present here in the puppet code: the merging of defaults with specified
> parameters AND the iteration.
>
Yes, that is basicially rolling your own create_resources in a way that
it a bit more understandable. (I like that approach). And yes, when you
do it this way, you can control all aspects of what is default, and what
overrides by just changing the way hashes are merged.

Regards
- henrik

>
> Thanks,
> Spencer
>
>
> On Mon, Aug 11, 2014 at 6:58 PM, Henrik Lindberg
> <henrik....@cloudsmith.com <mailto:henrik....@cloudsmith.com>>
> wrote:
>
> On 2014-12-08 2:41, Andy Parker wrote:
>
> On Tue, Aug 5, 2014 at 11:25 PM, David Schmitt <da...@dasz.at
> <mailto:da...@dasz.at>
> '(attribute|param)_(override|____defaults|hash)' metaparam
> http://puppet-on-the-edge.__blogspot.se/
> <http://puppet-on-the-edge.blogspot.se/>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Puppet Developers" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to puppet-dev+unsubscribe@__googlegroups.com
> <mailto:puppet-dev%2Bunsu...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/__msgid/puppet-dev/lsbsbb%24ek1%__241%40ger.gmane.org
> <https://groups.google.com/d/msgid/puppet-dev/lsbsbb%24ek1%241%40ger.gmane.org>.
>
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
>
>
> --
> Spencer Krum
> (619)-980-7820
>
> --
> You received this message because you are subscribed to the Google
> Groups "Puppet Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to puppet-dev+...@googlegroups.com
> <mailto:puppet-dev+...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/puppet-dev/CADt6FWOZ6rPngVxbjD5NxxSLNR9Q2N2m6KEog_9TBcMfDQXFhQ%40mail.gmail.com
> <https://groups.google.com/d/msgid/puppet-dev/CADt6FWOZ6rPngVxbjD5NxxSLNR9Q2N2m6KEog_9TBcMfDQXFhQ%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.


--

Andy Parker

unread,
Aug 12, 2014, 1:03:52 PM8/12/14
to puppe...@googlegroups.com
On Mon, Aug 11, 2014 at 8:54 PM, Spencer Krum <krum.s...@gmail.com> wrote:
1) I really don't want to see variable expansion in expressions that resolve to the names of types. This will be misused, it will make code unreadable. Please leave it out. Sets of parameters only make sense to distinct types anyways, if two types really do accept all the same parameters, then the RAL should be leveraged and different providers written.


I hadn't looked for this information before because I just assumed that if it is possible it is being used :) However, I just did a quick trawl through the forge and the following modules use variables for the type in create_resources:

  * vstone-apache
  * puppetlabs-swift
  * jaydub-resource_factory
  * eNovance-cloud
 
There is also jakeb-system and erwbgy-system which seem to be copies of one another. They don't use create_resources, but seem to have forked it into a new function called system_create_resources which is then used with a variable type. It isn't clear to me what is different about the forked function.

Looking at the examples, usage of interpolating the type name is usually done in order to have different defined types for different situations, but shield the user of the module from needing to know about them. This seems like a very reasonable use.
 
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/CADt6FWOZ6rPngVxbjD5NxxSLNR9Q2N2m6KEog_9TBcMfDQXFhQ%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.



--

Luke Kanies

unread,
Aug 12, 2014, 2:48:51 PM8/12/14
to puppe...@googlegroups.com
On Aug 12, 2014, at 10:02 AM, Andy Parker <an...@puppetlabs.com> wrote:

On Mon, Aug 11, 2014 at 8:54 PM, Spencer Krum <krum.s...@gmail.com> wrote:
1) I really don't want to see variable expansion in expressions that resolve to the names of types. This will be misused, it will make code unreadable. Please leave it out. Sets of parameters only make sense to distinct types anyways, if two types really do accept all the same parameters, then the RAL should be leveraged and different providers written.


I hadn't looked for this information before because I just assumed that if it is possible it is being used :) However, I just did a quick trawl through the forge and the following modules use variables for the type in create_resources:

  * vstone-apache
  * puppetlabs-swift
  * jaydub-resource_factory
  * eNovance-cloud
 
There is also jakeb-system and erwbgy-system which seem to be copies of one another. They don't use create_resources, but seem to have forked it into a new function called system_create_resources which is then used with a variable type. It isn't clear to me what is different about the forked function.

Looking at the examples, usage of interpolating the type name is usually done in order to have different defined types for different situations, but shield the user of the module from needing to know about them. This seems like a very reasonable use.

The fact that only four modules use it is, to me, exactly validation that it’s a rare enough use case that it should be left to things like functions.

The language should be optimized for the most common use cases, not the complete list of them.

[…]

Spencer Krum

unread,
Aug 12, 2014, 4:02:42 PM8/12/14
to puppe...@googlegroups.com


    1) I really don't want to see variable expansion in expressions that
    resolve to the names of types. This will be misused, it will make code
    unreadable. Please leave it out. Sets of parameters only make sense to
    distinct types anyways, if two types really do accept all the same
    parameters, then the RAL should be leveraged and different providers
    written.

It is already used (via create_resources), and people want it to support
integration use cases between more tightly coupled modules.
The fact that only four modules use it is, to me, exactly validation that it’s a rare enough use case that it should be left to things like functions.

The language should be optimized for the most common use cases, not the complete list of them.

 
I think Luke has nailed it. Only in the rarest circumstances will this be used to make the code better, and thats not something that should be optimized for.





What do you think about the proposal to precede the "meta parameter" name with @, since we have issues with reserving yet another name (all good names seems to be in use somewhere already).

We proposed @attributes, so by analogy, it would be @params_hash, or equivalent using the word you preferred.


I think my disagreement on this is that I consider adding @something to the type syntax to be a bigger crime than reserving a word.  If it ends up googleale, I'm okay with it.




(you probably wanted $params = $defaults + $attributes)

Yes, I did. Thanks for taking the time to figure out what I meant, because what I said was garbage. Is $hash1 + $hash2 something that works? I would expect merge behavior there, is that what happens?

Thanks,
Spencer



--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Spencer Krum
(619)-980-7820

Henrik Lindberg

unread,
Aug 12, 2014, 6:07:46 PM8/12/14
to puppe...@googlegroups.com
On 2014-12-08 22:02, Spencer Krum wrote:
>
>
> 1) I really don't want to see variable expansion in
> expressions that
> resolve to the names of types. This will be misused, it
> will make code
> unreadable. Please leave it out. Sets of parameters only
> make sense to
> distinct types anyways, if two types really do accept all
> the same
> parameters, then the RAL should be leveraged and different
> providers
> written.
>
>
> It is already used (via create_resources), and people want it to support
> integration use cases between more tightly coupled modules.
>
>
> The fact that only four modules use it is, to me, exactly validation
> that it’s a rare enough use case that it should be left to things
> like functions.
>
> The language should be optimized for the most common use cases, not
> the complete list of them.
>
>
>
> I think Luke has nailed it. Only in the rarest circumstances will this
> be used to make the code better, and thats not something that should be
> optimized for.
>

It is not "optimized" for that in any way. We either validate it to be
an error, or we don't. It does not alter anything else.

> What do you think about the proposal to precede the "meta parameter"
> name with @, since we have issues with reserving yet another name
> (all good names seems to be in use somewhere already).
>
> We proposed @attributes, so by analogy, it would be @params_hash, or
> equivalent using the word you preferred.
>
> I think my disagreement on this is that I consider adding @something to
> the type syntax to be a bigger crime than reserving a word. If it ends
> up googleale, I'm okay with it.
>

It ends up being googlable, we tried using similar searches for
constructs in other languages that use @keyword.

>
> (you probably wanted $params = $defaults + $attributes)
>
>
> Yes, I did. Thanks for taking the time to figure out what I meant,
> because what I said was garbage. Is $hash1 + $hash2 something that
> works? I would expect merge behavior there, is that what happens?
>

In future parser the + operator concatenates arrays (makes a new copy
with the concatenated result), and it merges hashes (also makes a new
copy). You can also use the - operator to remove one or more elements
from lists, or remove (one or more) keys from hashes (again a copy is
returned).

Luke Kanies

unread,
Aug 12, 2014, 10:30:48 PM8/12/14
to puppe...@googlegroups.com
> On Aug 12, 2014, at 3:07 PM, Henrik Lindberg <henrik....@cloudsmith.com> wrote:
>
>> On 2014-12-08 22:02, Spencer Krum wrote:
>>
>>
>> 1) I really don't want to see variable expansion in
>> expressions that
>> resolve to the names of types. This will be misused, it
>> will make code
>> unreadable. Please leave it out. Sets of parameters only
>> make sense to
>> distinct types anyways, if two types really do accept all
>> the same
>> parameters, then the RAL should be leveraged and different
>> providers
>> written.
>>
>>
>> It is already used (via create_resources), and people want it to support
>> integration use cases between more tightly coupled modules.
>>
>>
>> The fact that only four modules use it is, to me, exactly validation
>> that it’s a rare enough use case that it should be left to things
>> like functions.
>>
>> The language should be optimized for the most common use cases, not
>> the complete list of them.
>>
>>
>>
>> I think Luke has nailed it. Only in the rarest circumstances will this
>> be used to make the code better, and thats not something that should be
>> optimized for.
>>
>
> It is not "optimized" for that in any way. We either validate it to be an error, or we don't. It does not alter anything else.

He didn't mean in the technical sense, he meant in the sense of design
and user experience.

Design is about saying no to things, and this is something I think we
should say no to, because it optimizes the user experience of the
language around the wrong things.
[...]

John Bollinger

unread,
Aug 13, 2014, 11:37:08 AM8/13/14
to puppe...@googlegroups.com


On Tuesday, August 5, 2014 7:51:20 PM UTC-5, Andy Parker wrote:
I'm pulling this discussion out into a new thread so that we can become more focussed. I'm also going to start a thread about one other topic that has been brought to my attention so that a decision can be reached.

In this thread I'd like to get to a decision about two aspects of resource expressions:

  1. Whether to allow expressions in the type position ($a { hi: })


Although I agree that there are potential uses, I do not like it, and I would prefer for it to not enter the language.  My primary argument is basically Reid's: it makes the DSL more difficult to understand.  I would prefer to see defined types get a new automatic internal variable that provides a hash of all the declared parameters for that instance.  The relatively benign example presented could then be expressed as

apache::install { something: }

define apache::install(param1, ...) {
  case $osfamily {
    'RedHat': { apache::install::redhat { $title: attribute_hash => $declared_attributes } }
    'Debian': { apache::install::debian { $title: attribute_hash => $declared_attributes } }
    ...
  }
}

Yes, it's somewhat more verbose, but it's also more explicit, and the resource types involved are statically checkable.  It's also a natural progression from a hypothetical initial implementation of apache::install that initially supports only one OS, or that handles multiple OSes all internally.

Obviously, that also uses the proposed new feature of specifying attributes of an ordinary resource declaration via a hash, but it seems clear that that is going to be accepted in some form -- were just debating the details.

 
  2. Whether to allow using hashes as resources parameters


As I said, I think were debating the details here, not whether this feature will go in at all.  I am fine with a meta-attribute, as I use in the above example. 

I think it would also be fine if an expression -- which must evaluate to a hash -- were allowed in place of any explicit parameters.  An explicit parameter list is anyway a hash itself, though expressed in a slightly different (because undelimited) syntax than ordinary hash literals.  I like this better for its logical consistency, and as a bonus it does not require reserving any attribute name.  I don't at the moment see any grammatical issue with it.

 
  3. If we allow hashes as resource parameters, what token introduces it (no introducing token isn't an option because of implementation constraints).



I'm not currently seeing what those implementation constraints might be.  Nevertheless, if there must be an introductory token then I like a reserved meta-attribute such as the 'attribute_hash' I used in my example.  Though I did not use it, I think I rather like the idea of using an initial '@' in the name (@attribute_hash) to distinguish this name from ordinary attribute names.


John

Reply all
Reply to author
Forward
0 new messages