Another idea

281 views
Skip to first unread message

Gert Franz

unread,
Feb 27, 2015, 12:10:06 PM2/27/15
to lu...@googlegroups.com

Hi all,

 

When thinking of posting this idea I already feel Adam’s or Sean’s breath in my neck and reminding me of what stupid idea I might come up with.

 

The following code snippet is something I do very often:

 

This is just sudo code.

string function something(required struct stConfig) {

            local.stTmp = arguments.stConfig.fileConfig.init;

            stTmp.initPath = "/";

            stTmp.initTimeStamp = true;

            stTmp.initUseCounter = request.fileConfig.counter + 1;

}

 

The code really doesn’t make sense and I know one can write it by setting an inline struct like this:

 

arguments.stConfig.fileConfig.init = {

                        initPath: "/",

                        initTimeStamp: true,

                        initUseCounter: request.fileConfig.counter + 1

            };

 

But that is not the idea here. What I do in order to speed up the runtime (and not having to resolve a multi-level struct is time consuming) and readability (you can’t tell me that this is easier to read:

 

arguments.stConfig.fileConfig.init.initPath = "/";

arguments.stConfig.fileConfig.init.initTimeStamp = true;

arguments.stConfig.fileConfig.init.initUseCounter = request.fileConfig.counter + 1;

 

)

I tend to assign a long hierarchy of subkeys to a temporary variable (stTmp) and then use only that one. But this seems kind of odd. So I remembered the good old Delphi and GFABasic days where one could write a statement like this:

 

with variable do {

            .key = something;

}

 

What would you think of the following code instead of the above:

 

string function something(required struct stConfig) {

            with(arguments.stConfig.fileConfig.init) {

                        .initPath = "/";

                        .initTimeStamp = true;

                        .initUseCounter = request.fileConfig.counter + 1;

}

}

 

Or somehow similar. That would immediately speed up the execution and the writing of the code.

Igal @ Lucee.org

unread,
Feb 27, 2015, 12:21:55 PM2/27/15
to lu...@googlegroups.com
I personally don't like Basic nor Delphi (though they bring up nice memories from my youth...), so I prefer to use inline structs for that and am unlikely to use such constructs.  but before I answer your question I must first ask another:

    arguments.stConfig.fileConfig.init = { ... }
would replace the object that init points to with a new one, thus discarding any other keys that are not set in the new assignment.

what would this construct do?

    with(arguments.stConfig.fileConfig.init) {
       .initPath = "/";
       .initTimeStamp = true;
       .initUseCounter = request.fileConfig.counter + 1;
}

in other words, let's say that before the assignment the init key points to a struct with the key "uniqueId".  the inline construct will lose it.  the original construct (the one you're trying to avoid) will keep it.  what would the new construct do?

Igal Sapir
Lucee Core Developer
Lucee.org

--
You received this message because you are subscribed to the Google Groups "Lucee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lucee+un...@googlegroups.com.
To post to this group, send email to lu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lucee/016001d052b0%24380ca960%24a825fc20%24%40lucee.org.
For more options, visit https://groups.google.com/d/optout.

Igal @ Lucee.org

unread,
Feb 27, 2015, 12:42:19 PM2/27/15
to lu...@googlegroups.com
also, would the proposed construct result in an atomic operation (like the inline struct) or not (like the original construct)?


Igal Sapir
Lucee Core Developer
Lucee.org

Sean Corfield

unread,
Feb 27, 2015, 1:18:42 PM2/27/15
to lu...@googlegroups.com
On Feb 27, 2015, at 9:21 AM, Igal @ Lucee.org <ig...@lucee.org> wrote:
in other words, let's say that before the assignment the init key points to a struct with the key "uniqueId".  the inline construct will lose it.  the original construct (the one you're trying to avoid) will keep it.  what would the new construct do?

I think Gert means it would be equivalent to the three assignments, in other words _not_ really the same as the inline struct. It would be _almost_ like the first example — with the local variable — but without explicitly creating the local variable in CFML.

string function something(required struct stConfig) {

            with(arguments.stConfig.fileConfig.init) {

                        .initPath = "/";

                        .initTimeStamp = true;

                        .initUseCounter = request.fileConfig.counter + 1;

}

}


My first reaction is that the leading . looks very strange and I’m not entirely happy with the ( ) but the . at least disambiguates whether it’s a free variable or a struct / object reference.

If we had `with` we could also do:

with myObj {
.doSomething( args );
.doSomethingElse( moreArgs );
.andDoAnotherThing( stuff );
}

I don’t think it’s a necessary feature but it could make certain pieces of code cleaner. I’d want to research languages that have considered _and rejected_ `with` before having a strong opinion either way (in case there are really good reasons to _not_ add this).

Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)



Sean Corfield

unread,
Feb 27, 2015, 1:21:57 PM2/27/15
to lu...@googlegroups.com
On Feb 27, 2015, at 9:41 AM, Igal @ Lucee.org <ig...@lucee.org> wrote:
also, would the proposed construct result in an atomic operation (like the inline struct) or not (like the original construct)?

I can see arguments both for and against but given it’s really meant to be equivalent to the three long assignments, I don’t think there’s any need for it to be atomic.

Abram Adams

unread,
Feb 27, 2015, 1:24:01 PM2/27/15
to lu...@googlegroups.com
Interesting idea, if I follow what you are trying to demonstrate. Like Igal said, the behaviors are quite different and what it sounds like to me is you need something like an "extend" method.  In JS I often setup a struct to hold default values then use _extend() (in node, with client side I use jQuery's $.extend() method).  This merges the two without having to do "arguments.stConfig.fileConfig.init ="  repeatedly.

Also, Gert, are you saying that defining inline structs is slower at runtime than the dot method? 

Igal @ Lucee.org

unread,
Feb 27, 2015, 1:29:47 PM2/27/15
to lu...@googlegroups.com
In JS I often setup a struct to hold default values then use _extend() (in node, with client side I use jQuery's $.extend() method)
in Lucee you can do the "jQuery.extend()" with ".append( required struct, boolean overwrite=true)".


are you saying that defining inline structs is slower at runtime than the dot method? 
I don't believe that that's what he meant.  I believe that he meant that it would run faster than the original construct.


Igal Sapir
Lucee Core Developer
Lucee.org

Abram Adams

unread,
Feb 27, 2015, 1:31:38 PM2/27/15
to lu...@googlegroups.com
You're right, I've been in JS mode so wasn't thinking about structAppend/struct.append.

Gert Franz

unread,
Feb 27, 2015, 1:37:22 PM2/27/15
to lu...@googlegroups.com

Well it is just a shorthand notation to the following. And yes I agree that assigning a {} would replace the construct so it is unusable. But this code would be identical:

 

arguments.stConfig.fileConfig.init.initPath = "/";
arguments.stConfig.fileConfig.init.initTimeStamp = true;

arguments.stConfig.fileConfig.init.initUseCounter = request.fileConfig.counter + 1;

and

 

with(arguments.stConfig.fileConfig.init) {

       .initPath = "/";
       .initTimeStamp = true;
       .initUseCounter = request.fileConfig.counter + 1;
}


Sincerely
Gert Franz

 

RASIA GmbH

Spittelgasse 7

5103 Moeriken-Wildegg

Email: ge...@rasia.ch
Skype: gert.franz

Phone Switzerland: +41 76 5680 231

image001.png

Igal @ Lucee.org

unread,
Feb 27, 2015, 1:51:49 PM2/27/15
to lu...@googlegroups.com
then given the fact that it doesn't add anything I personally will not use this construct.  a simpler solution could be to assign the long-named variable to a short one (which I actually do in some places of my code), e.g.:

m = arguments.stConfig.fileConfig.init.initPath;  // cheap operation, just a pointer reference...

m.initPath = "/";
m.initTimeStamp = true;
m.initUseCounter = request.fileConfig.counter + 1;

(of course, if you don't like m [for Map] you can call it susi ;])

or use the Struct.append() method as Abram suggested.


Igal Sapir
Lucee Core Developer
Lucee.org

Gert Franz

unread,
Feb 27, 2015, 1:52:34 PM2/27/15
to lu...@googlegroups.com

No what I meant is that using this:

 

arguments.stConfig.fileConfig.init several times is slower than assigning it to a temporary variable stTmp and then use the short variable after that. Which is obvious because at runtime there have to be many evaluations taking place with the arguments notation instead of one with stTmp.

 

Sincerely
Gert Franz

 

RASIA GmbH

Spittelgasse 7

5103 Moeriken-Wildegg

Email: ge...@rasia.ch
Skype: gert.franz

Phone Switzerland: +41 76 5680 231

 

Von: lu...@googlegroups.com [mailto:lu...@googlegroups.com] Im Auftrag von Abram Adams
Gesendet: Freitag, 27. Februar 2015 19:24
An: lu...@googlegroups.com
Betreff: Re: [Lucee] Another idea

 

Interesting idea, if I follow what you are trying to demonstrate. Like Igal said, the behaviors are quite different and what it sounds like to me is you need something like an "extend" method.  In JS I often setup a struct to hold default values then use _extend() (in node, with client side I use jQuery's $.extend() method).  This merges the two without having to do "arguments.stConfig.fileConfig.init ="  repeatedly.

image001.png

Abram Adams

unread,
Feb 27, 2015, 1:55:02 PM2/27/15
to lu...@googlegroups.com
So it would be another way to represent:

arguments.strConfig.fileConfig.init.append({
        initPath: "/",
        initTimeStamp: true,
        initUseCounter: request.fileConfig.counter + 1 
},true);

Correct?  So this would be a kind of "map" function for objects/structs?

I agree with Sean that some research into other language's choice to include/exclude from the language.  

Interesting idea, just trying to wrap my head around use case.

Igal @ Lucee.org

unread,
Feb 27, 2015, 1:56:42 PM2/27/15
to lu...@googlegroups.com
correct.  true is the default for overwriteFlag so no need to specify it.


Igal Sapir
Lucee Core Developer
Lucee.org

Sean Corfield

unread,
Feb 27, 2015, 2:02:41 PM2/27/15
to lu...@googlegroups.com
On Feb 27, 2015, at 10:51 AM, Igal @ Lucee.org <ig...@lucee.org> wrote:
then given the fact that it doesn't add anything I personally will not use this construct.

As long as your personal opinion of the feature doesn’t affect whether or not it does into Lucee, if the community overwhelmingly want the feature (and research into other languages doesn’t determine a serious flaw with the concept).

Igal @ Lucee.org

unread,
Feb 27, 2015, 2:07:17 PM2/27/15
to lu...@googlegroups.com
as written very clearly in my statement, "I personally will not use". 

that does not mean that I have a problem with its addition to the language if it makes sense to others.


Igal Sapir
Lucee Core Developer
Lucee.org

--
You received this message because you are subscribed to the Google Groups "Lucee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lucee+un...@googlegroups.com.
To post to this group, send email to lu...@googlegroups.com.

Jochem van Dieten

unread,
Feb 27, 2015, 2:14:20 PM2/27/15
to lu...@googlegroups.com
On Fri, Feb 27, 2015 at 6:09 PM, Gert Franz wrote:

string function something(required struct stConfig) {

            with(arguments.stConfig.fileConfig.init) {

                        .initPath = "/";

                        .initTimeStamp = true;

                        .initUseCounter = request.fileConfig.counter + 1;

}

}


I would echo Sean and say that the starting . looks weird.

Would it be correct to use "with(argument) changes the scope of unscoped variables and methods in the block to that of the argument" as a generalized definition of what you are proposing? Or is it somewhat more limited and just refers to variable names?
 
Jochem

--

Gert Franz

unread,
Feb 27, 2015, 2:15:56 PM2/27/15
to lu...@googlegroups.com

Well for me (again personally) I don’t like to use additional variables. Hence. Every dump then could be full of temporary variables.

 

Sincerely
Gert Franz

 

RASIA GmbH

Spittelgasse 7

5103 Moeriken-Wildegg

Email: ge...@rasia.ch
Skype: gert.franz

Phone Switzerland: +41 76 5680 231

 

Von: lu...@googlegroups.com [mailto:lu...@googlegroups.com] Im Auftrag von Igal @ Lucee.org
Gesendet: Freitag, 27. Februar 2015 20:07
An: lu...@googlegroups.com
Betreff: Re: [Lucee] Another idea

 

as written very clearly in my statement, "I personally will not use". 

image001.png

Gert Franz

unread,
Feb 27, 2015, 3:10:55 PM2/27/15
to lu...@googlegroups.com

Actually what I just wanted is a shorter notation for long deep structures.

 

Sincerely
Gert Franz

 

RASIA GmbH

Spittelgasse 7

5103 Moeriken-Wildegg

Email: ge...@rasia.ch
Skype: gert.franz

Phone Switzerland: +41 76 5680 231

 

Von: lu...@googlegroups.com [mailto:lu...@googlegroups.com] Im Auftrag von Jochem van Dieten
Gesendet: Freitag, 27. Februar 2015 20:14
An: lu...@googlegroups.com
Betreff: Re: [Lucee] Another idea

 

On Fri, Feb 27, 2015 at 6:09 PM, Gert Franz wrote:

--

You received this message because you are subscribed to the Google Groups "Lucee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lucee+un...@googlegroups.com.
To post to this group, send email to lu...@googlegroups.com.

image001.png

Abram Adams

unread,
Feb 27, 2015, 3:20:14 PM2/27/15
to lu...@googlegroups.com
I would echo Sean and say that the starting . looks weird.
 
Had the same first impression here.  Though if thought of beyond struct key assignments it may help clarify intent.  Expanding on Sean's example:

with myObj { 
.doSomething( args );
                .key = someExternalFunc( .getSomething() ); // where .getSomething() returns a value from the current state of myObj after whatever .doSomething() did. 
.doSomethingElse( moreArgs );                   
.andDoAnotherThing( stuff );
}
prefixing with "." would indicate an action against "myObj".  

This object usage could be useful (more so than for struct key manipulation, imo), especially if you work with entity objects:

User = new model.User();
with User{
   
.firstName = rc.fname;
   
.lastName = rc.lname;
   
.closure = function(){
         
var fullName = .firstName & "  " & .lastName;
         
return .doSomething( fullName );
   
};
   
.addPet( new model.Pet( type = "dog", name = "Rover" ) );
   
.addPet( new model.Pet( type = "cat", name = "Tom" ) );
   
.save();
}


Contrived example, but just trying to feel out how it could be used.  I'm not sure it adds much to the language, but interested to see what others think.  

Unrelated (reminded of it when working the sample), but I think IIFEs would be a higher priority feature to enhance the language.

Adam Cameron

unread,
Feb 27, 2015, 3:43:29 PM2/27/15
to lu...@googlegroups.com


On Saturday, 28 February 2015 07:29:47 UTC+13, Igal wrote:
In JS I often setup a struct to hold default values then use _extend() (in node, with client side I use jQuery's $.extend() method)
in Lucee you can do the "jQuery.extend()" with ".append( required struct, boolean overwrite=true)".


Now... brace yourself Igal... I agree.

Gert's pseudocode:

arguments.stConfig.fileConfig.init = {
initPath: "/",
initTimeStamp: true,
initUseCounter: request.fileConfig.counter + 1
};

Code possible right now:

arguments.stConfig.fileConfig.init.append({
initPath: "/",
initTimeStamp: true,
initUseCounter: request.fileConfig.counter + 1
});

I don't see the need for another syntax construct if this is all the with construct would afford us.

However there might be other things one could do with a with sort of thing, so perhaps more / different use cases might help convince me. And also checking what more modern languages (pref ones similar to how CFScript generally works so we don't get more syntactical abominations added to the language ;-) do in this regard is probably a good suggestion from Sean too.

As an aside, I don't think adding syntax constructs to work around performance shortcomings of existing syntax is a good idea, in general. That sort of thing should not be dealt with at a language level. Language considerations should generally (I'm falling short of saying "only ever") concern themselves with making the coders using that language's life easier. It should not be leveraged to make the authors of the language's life easier. IE: performance considerations ought to be dealt with under the hood.

-- 
Adam

Adam Cameron

unread,
Feb 27, 2015, 3:45:19 PM2/27/15
to lu...@googlegroups.com


On Saturday, 28 February 2015 06:10:06 UTC+13, Gert Franz wrote:

Hi all,

When thinking of posting this idea I already feel Adam’s or Sean’s breath in my neck and reminding me of what stupid idea I might come up with.

 Personal attack, Gert!

;-)


-- 
Adam

Rory Laitila

unread,
Feb 28, 2015, 9:16:35 AM2/28/15
to lu...@googlegroups.com
Yes, this construct would be useful when building out large structures. For example, when serializing queries or objects for json output in a custom manner. If you have to do any complex logic during the serialization, then you can't use inline structs as you build out the hierarchy (because you can't have any logic). So that forces you to use temporary variables to hold the inner members that get appended to the outers, etc. The larger or more nested the output becomes the more cumbersome this is.

Essentially Gert's idea is the midway between inline structures and manual procedural structure creation. It allows nested blocks of execution that can contain statements. This would be useful to have when needed.

Luis Majano

unread,
Feb 28, 2015, 12:52:18 PM2/28/15
to lu...@googlegroups.com
Me personally, I think the idea is great.  Groovy already has the concept of a with closure that you can attach to ANY object to denote context.  It is mostly done for clear context and avoid repetitive assignments, retrievals and executions.  Me personally, I would love to have this same capability as well in CFML. (Reference: http://mrhaki.blogspot.com/2009/09/groovy-goodness-with-method.html)


Example of how it could be written in CFML:

component accessors="true"{
    property username;
    property email;
    property labels;
   
    function speakUp() { return "I am $username"; }
    function addLabel( required value ){
        labels.append( arguments.value );
    }
}

sample = new Sample()
sample.with {
    username = 'luis'
    email = 'lu...@majano.com'
    writeOutput( speakUp() )
    addLabel( 'CFML' )
    addLabel( 'Java' )
};

sb = new java:StringBuilder();
sb.with {
    append( 'Just another way to add ' )
    append( 'strings to the StringBuilder ' )
    append( 'object.' )

Peter Boughton

unread,
Feb 28, 2015, 2:02:40 PM2/28/15
to lu...@googlegroups.com
Definitely against the leading dots - it's unnecessarily restrictive to
make this only about setting/calling.

The command should simply set the default container for unscoped
variables (i.e. change it from local scope, or be the first checked if
cascading is enabled).

So then:

Some.Long.Dotted.Struct.Var1 = VarA;
Some.Long.Dotted.Struct.Other = Arguments.Whatever;

becomes:

with Some.Long.Dotted.Struct
{
Var1 = local.VarA;
Other = Arguments.Whatever;
}

(Where the scoping of VarA is required when cascading is turned off.)

And this allows adding logic (beyond simple ternary/null-coalescing):

with Some.Long.Dotted.Struct
{
Var1 = local.VarA;
Other = Arguments.Whatever?:0;

loop index=local.i item=local.item
{
Stuff[local.i] = doSomething(local.item);

if (Stuff[local.i])
++Other;
}
}

Of course, there's a good chance I'd just do that as a function with
Some.Long.Dotted.Struct passed by reference into it, but this seems to
be a potentially convenient bridge between that and the inability of an
inline struct to have a small bit of non-atomic logic.

Setting the default for unscoped variables seems to cater for what Gert
wants, whilst also being a simple concept to understand/explain, and
building upon what the language already has rather than a completely
new thing.
Message has been deleted

Kenneth Redler

unread,
Feb 28, 2015, 2:55:59 PM2/28/15
to lu...@googlegroups.com, lu...@sorcerersisle.com
I wonder if this has us edging closer to the concept of context managers (e.g., with-open or with-open-file macros in Clojure or Common Lisp, or the with keyword and related decorators in Python). I've often ended up creating my own setup and teardown methods within components, auto-running them, if present, through the use of some kind of factory pattern. A component or class is much heavier than simple lexical games with a deep struct, but perhaps it's worth kicking around some of these ideas. Maybe the lexical with as proposed could be implemented as a degenerate case of a context manager, allowing future expansion of the concept as the language evolves.

Jonas Hauß

unread,
Feb 28, 2015, 6:35:51 PM2/28/15
to lu...@googlegroups.com

I'm against it.

They already deprecated the with statement in JS strict mode for good reasons.

It can get really confusing for human readers especially when they dont know in which scope of the scope chain the key is.

Let's have a look at the following example:

function foobar(foo, bar) {
    with (bar) {
        dump(foo);
    }
}

If you forget to define foo in the passed object, you wont get an error but unexpected results.

According to my opinion we don't need a completely new statement to achieve this. How about self executing functions?
They can solve the problem as well:

(function (v) {
    dump(v.name.first & " " & v.name.last);
}(variables.foobar.users.user.susi));

You could use this approach multiple ways.

Adam Cameron

unread,
Feb 28, 2015, 8:28:18 PM2/28/15
to lu...@googlegroups.com


On Sunday, 1 March 2015 06:52:18 UTC+13, Luis Majano wrote:
Example of how it could be written in CFML:

All good, except you're using Groovy closure syntax, not CFML's.

Groovy:
{arg1, arg2, etc -> statements}

CFML:
function(arg1, arg2, etc){ statements}

I think the Groovy approach is OK, and there's definitely a precedent set (ie: Groovy does it), but it ought to use CFML syntax:

anyOldObject.with(function(arg1, arg2, etc){
    // statements where the anyOldObject is the scopeless context
});

Now if we were having a separate conversation about CFML's closure syntax being too wordy, then that's fine: let's have that conversation too. But that's not part of this conversation. Lets not conflate the two.


Or perhaps rather than having a special with() method which changes the way scopes are dealt with (which is a bit magical, so not that cool), instead we augment closure syntax to take an object which becomes the "this" context:

(function(arg1, arg2, etc) with (anyOldObject) {
    this.someProperty = newValue; // equiv to setting anyOldObject.someProperty
}))();

I've also added in IIFE syntax there, which CFML should have anyhow.

Or perhaps Lucee's implementation of IIFE syntax should be able to pass in what "this" should be?

Or, perhaps because "this" is misused in CFML, then referencing "this" like this is wrong, and the better fit is back to just the "anyOldObject" above is what's used for scopeless references. So a hybrid between the magic Groovy behaviour, but tuned to be more explicit and less magical and in-keeping with CFML's parlance:

(function(arg1, arg2, etc) with (anyOldObject) {
    someProperty = newValue; // equiv to setting anyOldObject.someProperty
})();

or

(function(arg1, arg2, etc) {
    someProperty = newValue; // equiv to setting anyOldObject.someProperty
}, anyOldObject)();

Of these two, I prefer the former as it couples the closure with the context, rather than the IIFE having the context coupled to it. I can see arguments both ways though.

-- 
Adam

Luis Majano

unread,
Feb 28, 2015, 9:07:35 PM2/28/15
to lu...@googlegroups.com, lu...@googlegroups.com
Personally I would not prefer a closure approach but a context approach much how transaction and lock work. They denote context and the syntax is not as verbose. 


--
You received this message because you are subscribed to a topic in the Google Groups "Lucee" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lucee/5QzTC7MXmX0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lucee+un...@googlegroups.com.

To post to this group, send email to lu...@googlegroups.com.

Adam Cameron

unread,
Feb 28, 2015, 9:52:17 PM2/28/15
to lu...@googlegroups.com


On Sunday, 1 March 2015 15:07:35 UTC+13, Luis Majano wrote:
Personally I would not prefer a closure approach 

Hang on!? You just suggested it in your previous post (ie: the one I replied to)? I'm well confused now.


but a context approach much how transaction and lock work. They denote context and the syntax is not as verbose. 

Well you know my opinion of that syntax ;-)

But you mean this sort of thing:

baseline for comparison:

lock name="myLock" timeout=5 {
   // stuff to lock
}

Therefore:

with object=anyOldObject {
    // statements where the anyOldObject is the scopeless context
}

I don't think there's enough similarity in what's going on when comparing those two to conflate the syntax. And the similar transaction syntax is no closer.

Perhaps thinking about how thread works:

thread name="myLock" action="run" {
   // stuff to run in thread
}

I guess our mileage will continue to vary here, but I'm simply never going to stop seeing that syntax as being the worst thing to happen to CFScript since CFScript was never treated like a first class citizen in CFML in the first place.

But thread does have the memory context isolation going on, so there is a precedent set already. And it does not require any "magical" behaviour like the suggested Groovy approach. So that's a win.

It just looks a very primitive and inelegant approach to me though. Basically cos it's solving script-centric issues with tag-based code. But that's all opinion, and we all know about those... ;-)


and the syntax is not as verbose. 

This:
with object=o {}

vs this:
o.with(function(){});

Hmmm. And what about when you start passing arguments into it:

with object=o x=1 y=2 {}

o.with(function(1,2){});

I don't really think there's enough in it to use verbosity as any sort of yardstick. Do you?

-- 
Adam


Dominic Watson

unread,
Mar 1, 2015, 3:59:31 AM3/1/15
to lu...@googlegroups.com
I was confused at first but Luis' example I think shows the benefit clearly.

I'm not a fan of the term "with"; I don't think it communicates what it does at all. That said, I understand there are precedences set in other languages and I don't have a better suggestion.

I prefer the code block style syntax over a generic closure syntax. Feels cleaner and the intent of context within the braces is more obvious I think.

Would love to see some more concrete examples (though I guess I could head over to Groovy docs for that eh ;)

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

To post to this group, send email to lu...@googlegroups.com.

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



--
Pixl8 Interactive, 3 Tun Yard, Peardon Street, London
SW8 3HT, United Kingdom

T: +44 [0] 845 260 0726 W: www.pixl8.co.uk E: in...@pixl8.co.uk

Follow us on: Facebook Twitter LinkedIn
CONFIDENTIAL AND PRIVILEGED - This e-mail and any attachment is intended solely for the addressee, is strictly confidential and may also be subject to legal, professional or other privilege or may be protected by work product immunity or other legal rules. If you are not the addressee please do not read, print, re-transmit, store or act in reliance on it or any attachments. Instead, please email it back to the sender and then immediately permanently delete it. Pixl8 Interactive Ltd Registered in England. Registered number: 04336501. Registered office: 8 Spur Road, Cosham, Portsmouth, Hampshire, PO6 3EB

Adam Cameron

unread,
Mar 1, 2015, 3:20:50 PM3/1/15
to lu...@googlegroups.com


On Sunday, 1 March 2015 21:59:31 UTC+13, Dominic Watson wrote:
I prefer the code block style syntax over a generic closure syntax. Feels cleaner and the intent of context within the braces is more obvious I think.

Except that almost all instances of braces usage in CFML does not behave anything like what this functionality does. Which makes it smell a bit. 

Off the top of my head, thread is the only one that behaves even kinda like the mooted functionality here, and even then it's not the same. The question is whether its similarity here is sufficient to claim "precedent", or whether it more points towards it being an earlier sloppy implementation (you can perhaps guess where I lean here).

As observed here http://blog.adamcameron.me/2015/01/cfml-evolution-of-functionality.html#block, it's fine to have a block of code as an argument to some functionality (like lock, thread, etc), but that's different from altering the behaviour of how the code actually works, which I think is the ground we're treading into here.

On the other hand the precedent is already (mostly) set with memory handling and scope-handling differences when it comes to functions in CFML. I say "mostly" because there is no precedent set in CFML for specifying what "scopeless" references refer to, hence needing a slight syntax augmentation to flag that. However this is still better than just have it working differently via magic. And there is a parallel precedent for this sort of thing in JS (for example): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/callhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply. Obviously those are quite different in syntax though, so I'm not sure if they can actually be used as a precedent for this.

TBH - and I seriously amn't saying this to be contrary - you've got me thinking about what is and is not obvious / predictable in these various syntax suggestions now, and I think the functional approach is more appropriate (even than I already thought it was, I mean) now that you have me thinking about that.

One question on how you think it's more obvious using block syntax over "closure" syntax: how comfortable are you with function expressions in general? People seem to shy away from the word "closure" slightly because it's "confusing". I don't happen to think it is really, but I've spent perhaps more time than most CFMLers looking at them. It's just obvious to me, but perhaps isn't to others? If it's an issue, this is a real consideration. But it's just a consideration, not a barrier.

-- 
Adam

Dominic Watson

unread,
Mar 2, 2015, 4:36:28 AM3/2/15
to lu...@googlegroups.com
> One question on how you think it's more obvious using block syntax over "closure" syntax: how comfortable are you with function expressions in general? People seem to shy away from the word "closure" slightly because it's "confusing". I don't happen to think it is really, but I've spent perhaps more time than most CFMLers looking at them. It's just obvious to me, but perhaps isn't to others? If it's an issue, this is a real consideration. But it's just a consideration, not a barrier.

I'm very comfortable. My gut reaction in this case is that function expressions are less terse. The variableName.with {} syntax is both terse and sits consistently with the language's existing constructs. I'm not wholly averse to something like variableName.with( function(){} ) (or some other variety), but to me it feels less of a language feature and more verbose to look at.

--
You received this message because you are subscribed to the Google Groups "Lucee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lucee+un...@googlegroups.com.
To post to this group, send email to lu...@googlegroups.com.

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

Gert Franz

unread,
Mar 2, 2015, 5:51:25 AM3/2/15
to lu...@googlegroups.com
My issue with the closure approach is, that it is slower in execution.

Gert

Sent from somewhere on the road

Adam Cameron

unread,
Mar 6, 2015, 3:36:41 AM3/6/15
to lu...@googlegroups.com


On Monday, 2 March 2015 10:51:25 UTC, Gert Franz wrote:
My issue with the closure approach is, that it is slower in execution.

I don't think language decisions ought to be made based on performance of the underlying implementation. 

Decide what the best syntax fit is for the language, then make sure its performance is acceptable. Not the other way around.

(NB: in this particular post I am not suggesting any of the syntax option are inherently better than others, I'm merely commenting on what factors should be considered when designing the language).

-- 
Adam

Andrew Penhorwood

unread,
Mar 6, 2015, 7:50:30 AM3/6/15
to lu...@googlegroups.com
While I basically agree with Adam I think it is good to know that one solution offers better performance over the other.

Andrew Penhorwood

Adam Cameron

unread,
Mar 6, 2015, 8:06:01 AM3/6/15
to lu...@googlegroups.com
On 6 March 2015 at 12:50, Andrew Penhorwood <penho...@gmail.com> wrote:
While I basically agree with Adam I think it is good to know that one solution offers better performance over the other.


True.

I think if it was a situation of "all other things being equal", then it could perhaps be the tie-breaker.

I dunno how often that situation would be the case though.

-- 
Adam
Reply all
Reply to author
Forward
0 new messages