On 2014-25-07 22:43, John Bollinger wrote:


On Thursday, July 24, 2014 7:32:13 PM UTC-5, Andy Parker wrote:

    Howdy,

    Henrik, David, Erik, John, and others have been having some pretty
    epic conversations around resource expressions, precedence, order of
    evaluation, and several other topics. What kicked all of that off
    was us looking for some feedback on decisions we were making for the
    Puppet 4 language about how resource overrides, defaults, and so on
    actually work (or don't in some cases). I think we've finally
    reached some decisions!

    Henrik took all of the ideas and started trying to work out what we
    could do and what we couldn't. Those are in a writeup at
    
https://docs.google.com/a/puppetlabs.com/document/d/1mlwyaEeZqCfbF2oI1F-95cochxfe9gubjfc_BXjkOjA/edit#
    
<https://docs.google.com/a/puppetlabs.com/document/d/1mlwyaEeZqCfbF2oI1F-95cochxfe9gubjfc_BXjkOjA/edit#>


    Lots of information in there, so here is the summary.

    The principles behind the decisions:
       1. Only make changes that have a high likelihood of *not* needing
    to be backed out later.
       2. Strict or explicit is better than lax or implicit. It uncovers
    issues and keeps you from lying to yourself.
       3. Puppet 3 has already stacked up a lot of changes. Do not break
    manifests unless we really have to.
       4. Let's not break manifests and then have to break them in
    almost the same way once we start working on a new catalog system.



Great principles.

    There are three kinds of resource expression that we have to deal with:

       1. Resource instantiation
       2. Resource defaults
       3. Resource overrides

    Looking forward, I think it is highly likely that the catalog system
    that we'll be working on during puppet 4 will be some sort of
    production (rules) system. In that kind of a world, resource
    instantiation likely remains as is, but defaults and overrides will
    end up having to change quite a bit, if not in syntax, at least in
    semantics.

    DECISION ONE

       Resource defaults and Resource overrides will be left untouched.

    Decision one follows from principles 3 and 4. In the discussions it
    became clear that changing when defaults or overrides are applied,
    the scope of defaults, or anything else about them was going to
    cause a lot of problems. Puppet's master branch changed resource
    defaults to follow the same scoping rules as variables. That change
    will be reverted.



I take it you mean that the current syntax for overrides and defaults
will continue to be supported and will continue to have the traditional
semantics.

yes, no new capabilities, and the same semantics - even keeping the dynamic scoping for resource defaults because the way we changed it on master makes it incompatible, and it is not replaced by something better.

Do you also mean that the new form of default declarations
will also have the same semantics (scope, laziness, ...) as the
traditional ones? (I suspect not.)

The new form of default is local to the resource instantiation expression. it is processed when the resource is instantiated as if
the attribute operations had been written out in long form - only
now they are in a common section, and can come from a hash.

(This only applies to resource instantiation, this is not available in the 3x style resource override and defaults expressions).



    DECISION TWO

       Resource instantiations are value producing expressions



Love it.

What about collection expressions?  Or does their late evaluation
present too much of a problem?

We are discussing this now. The result that is produced by a CollectionExpression is useless in the language - it has no information in it of value at that point, only after the catalog is completed.

Although it may be possible to assign the value, it is of a type that you cannot use for any practical purpose - a pice of dark matter.



    QUESTION: should the value always be an array of references? That
    would make it much more predictable.



How about making the value an array if and only if the title given in
the resource instantiation expression is an array?  In most cases either
you know the type of the title or you don't care; in the odd case that
you don't know the type of the title but you do care about the result
being an array then you can write

$array = flatten( [ notify {$maybe_array: message => 'hi' } ] )

(requires stdlib).


You can also use splat for this:

$array = * notify {$maybe_array: message => 'hi' }

since the splat operator turns something into an array if it appears in a place where individual elements are meaningless. (i.e. no standardlib required to array-ify).

If you want an array but you have only a single title then you can write
either

$array = notify { [ 'adieu' ]: message => 'bye' }

or

$array = [ notify { 'adieu': message => 'bye' } ]


or simply splat it.


    DECISION THREE

       Resource instantiation expressions will not be allowed in
    dangerous locations

    Once resource expressions can be placed anywhere there are a few
    places where they would actually just do more harm than good
    (principle 2). One example is as a parameter default (define a($b =
    notify {hi:}) {}).



Sounds wise, but even after reading the details in your googledoc I'm
not sure I follow the details.


Understood - it looked complicated at first but turned out to be quite simple and I did not clean that up. Basically there are a couple of places where assignment and resource creation is just weird, and we will just statically validate expressions in those positions to not contain any embedded assignments or resource expressions (instantiations, overrides or defaults).

The places I can think of right now are:

- parameter default value expressions
- case and selector options

Better to validate these than to cause possible mysterious errors caused by user mistakes. It is not taking away anything of value.


    DECISION FOUR

       The LHS of a resource *instantiation* expression can be an expression

    What?!? This means you can do:

       $a = notify
       $a { hi: }

    Once again, in clearing up odd cases in the grammar this is opened
    up to us. This is a very powerful feature to have available. Since
    this is very useful and fits well into the grammar I don't see this
    being a temporary thing that would then have to go away later
    (principle 1).



This one makes me a bit uncomfortable, but I could see it maybe being
useful.  Are there limitations on the value produced by an expression
used as the LHS of a resource instantiation expression?  For instance,
that it must evaluate to either a string or a (resource) type?


The LHS must evaluate to either a Resource[T] (e.g. Notify, File, etc) or a String that complies with the class name rule.

We reasoned that we already have create_resources in frequent use to solve real issues, so it is needed. I don't think create_resources is used simply because you can. Instead, it is because you do not statically know the type, or you want to decide which attributes to set based on calculations you made. Both of those require create_resources function. Now it moves into the language.

    DECISION FIVE (how many of these are there?)

       A resource with a title of default provides the default parameter
    values for other resources in the same instantiation expression.

    Thanks to David Schmitt for this idea!



Yes, this is cool.

    DECISION SIX

       There will be a splat operator for resource instantiation expressions

    To make the default resources (decision five) really useful there
    needs to be a way to reuse the same values across multiple defaults.
    The current, dangerous, semantics of resource default expressions
    skirt this issue by making defaults part of the (dynamic) evaluation
    scope. In order to make the default resources nearly as useful but
    much safer, we need to add a way to allow reuse of defaults across
    multiple resource instantiation expressions explicitly (principle 2).

       $owner_mode = { owner => andy, mode => '777' } # gotta make it secure
       file { default: *=> $owner_mode;
         '/home/andy/.bashrc': ;
         '/home/andy/.ssh/id_rsa': ;
       }

       file { '/etc/passwd': *=> $owner_mode }



"*=>" looks weird, even for Puppet.  What about contracting it to "*>",
parallel to the plussignment operator (+>) and to the ordinary value
binding operator (=>)?


The rationale is that you normally have:

   name => value

Now, you do not have names, and * is often used as a wildcard/splat/ "split it up", implied, the name is picked from the hash, and you may want to line them up:

file { default:
         *    => value ;

       foo:
         mode => '0777' ;
     }

Does that make it feel better?


The first proposal was:

    title: (expr)

Then, just use the splat operator:

   title: *expr

But then it became weird, because it is a special kind of splat that applies to the entire expression - that felt more confusing.


    DECISION EIGHT

       An array as a title expands to individual resource instantiation
    expressions with titles of the elements of the array.

    This isn't really too far off from the current semantics, no real
    change here.



Is there any change /at all/ there with respect to what current Puppet
already supports?  (I don't see any, but you've spooked me.)

Current implementation silently skips undef entries, balks at an undef title (not in an array), but allows other types than Strings as resulting individual titles (with the weird stringification taking place that we talked about above). Hence, "not too far off". Feel better now?

- 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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/lqukti%24ej5%241%40ger.gmane.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to