Friday, 18 December 2015

Survey results: singular or plural for datetime component setters?

G'day:
Yesterday I asked you whether for methods for setting the discrete components of a datetime whether you prefer singular - eg: setMinute() - or plural - setMinutes(). The reason for this is that Adobe are adding those methods in ColdFusion 2016, and there seems to be some flip-flopping on whether each one should be singular or plural. Details here:  3374275: Add granularity to createDateTime().

I've had 50 responses now, and the trend is fairly clear, so I'll tabulate the results:

ComponentSingularPlural
Year96%4%
Month96%4%
Day96%4%
Hour80%20%
Minute76%24%
Second72%28%
Millisecond72%28%

So that's reasonably clear: most people prefer singular. That said, a decent percentage of people prefer singular for the date components and but plural for the time components.

Two people went plural for everything; 35 went singular for everything. One person went singular for everything except for the minute component (slightly odd choice, that one, I reckon).

There were a few comments too:

I would go for singular even though some sound better as plurals. Though in the end as long as it's consistently one or the other and not a horrible mix I would be OK with it.
This is my opinion too. It's not an exercise in grammatical accuracy or even to do with how human language would do it. They're methods of an object.

Arse Arse Arse
Yes. Yes you are. At least you spelt it right though.

you're setting an hour, not a range of hours
This came out a bit, and not something that occurred to me previously, but they're correct.

As far as getting or setting, I think the plural form is more conceptually consistent. Though both can be equally argued for. Second refers to the value place, but Seconds refers to values in that place. I believe both Java and Javascript use setSeconds(), which is probably more comparable to ColdFusion, but other languages use setSecond() and set('second'), and SQL uses dateAdd('seconds'...), so there doesn't seem to be a whole lot of consistency across languages. In the end, I hate date manipulation anyway, so whatever method they choose will work for me. Unless they go with something like changeTime('addSecond(s)'). :-)
I'd like it if you could tease out why plural is more conceptually consistent. I don't get that.

plural makes no sense to me here? You are setting the "hour of the day" not the "hours of the day"


I avoid plurals on my methods and DB field names. I have exactly 2 exceptions to this rule: Comments Details IMHO, these two by their nature are not singular. I also thing of these as being free-form text.


Consistency above all else. As indicated by my responses above, my preference is singular. This is in part because some just don't work (for me, mentally) as plurals. Consider: setYears()? Ew. Combine that logical preference for _some_ of them to be singular, with the desire for _all_ of them to be consistent, and you arrive at: All of them should be singular.


Either way, just please be consistent!
Good pragmatism.

use singular or plural to match JS implementation
Why JS? I don't think the JS implementation here is very sensible, and I was left wondering why they made the decision that they did.

I prefer all singular. Especially since year(), month(), day(), hour(), minute(), second() exist in the language. I think it'd be odd to keep those as-is and introduce .setHours(), .setMinutes(), setSeconds(). I'd rather introduce millisecond()/.setMillisecond(), even if I don't typically say "the millisecond", and retain consistency. On a different note, I am happy to see Adobe presented their proposal so that we can offer feedback. Very nice there. Thanks Adam for doing this survey!, -Aaron
Cheers dude.

Just follow what JavaScript has already done!


You are setting a single value of a property not several values although that value could be more than 1.


I would match the javascript date object setters: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date they use setDate() instead of setDay() for the date part of the month.
Again... I think JS ballsed this up, so not a good precedent to follow. There is also not intrinsic connection between CFML and JS to warrant following their precedent in the first place.

If you go look at the current date/time functions on cfdocs.org, you see MOST of the function names are singular (daysinMonth, daysinyear only plural), so it seems to me that Singular should be used to keep in sync with the rest of the date/time functions.
Good call. I did not check that. So internal consistency would be to be singular. The existing procedural "getters" are all singular, for example: year()... through to second().

You are setting a single value, therefore, it should be singular. setMillisecond() = set the millisecond value to
Correct.

Initially, I favored the plural for the Minutes, Seconds, and Milliseconds. But after thinking about it more, I think that the singular makes the most sense, and will help to keep the purpose clear. Otherwise, I could see someone saying those functions should take ranges.
Thanks for giving it some thought, and sufficiently so for you to actually change your position on the matter. Nice one.

Unsure as to why anyone would want some plural and some not. Let's pick a sensible rule and stick with it throughout. Signular all the way, as the method is referring to the property, not multiple things.


Date/Time is a singular entity If you were setting a range/duration, then this should plural


Adam loves the wallabies
Specifically their services to the All Blacks 2015 World Cup campaign. Cheers for that, Andy.


So there's a suggested case for following JavaScript's Date methods, which would be:

  • setFullYear() (setYear() is deprecated)
  • setMonth()
  • setDate()
  • setHours()
  • setMinutes()
  • setSeconds()
  • setMilliseconds()  

What a mess. There's four different approaches in the first four methods. Screw that. This is also ignoring the fact that those ones don't match the existing getter functions CFML already has. I think this is a pretty invalid position to take, to be honest.

The people advocating for this probably just meant in the context of plurals for hours, minutes, seconds, but I wanted to demonstrate that I think not a lot of thought went into how JavaScript did this, so I don't think there's a good reason to follow them.

Other people reckon using plurals for some but not others based on how one would use them in English: it's quite likely to refer to the year of the date, but the minutes of the hour. But the hour of the day. English is not a very sensible language, and not everyone speaks English so I think following English's weirdo rules (even though these words are in English) is about as helpful as following JavaScript.

So at the beginning of this I was fairly certain sticking with singular would be the better approach, and the more I think about it now and look at what other people say, I am even more adamant. I am going to advocate on 3374275 that they stick with singular. Which, indeed, is what they've already done and they were going to change it to plural for hours, minutes and seconds, so this saves them some work.

Cheers everyone.

And thanks, Andy, for reminding me how the All Blacks smashed the Wallabies in the Rugby World Cup final.

Righto.

--
Adam

Wednesday, 16 December 2015

Survey: singular or plural for datetime component setters?

G'day:
ColdFusion is adding date/time component setters methods to CFML, eg: myDate.setYear() etc. The ticket covering this is here: 3374275: Add granularity to createDateTime().

The methods could be implemented with a singular term for the date component, or plural. EG: setHour() or setHours(). There's currently some disagreement over the approach to take here.

I thought I'd put it to the CFML community, so have concocted a brief survey to ask the question: Date component setter methods for CFML. It basically asks what your preference is for each method, and there's a box for other observations.

Please go fill it out if you can be arsed.

Cheers.

--
Adam

Monday, 14 December 2015

ColdFusion: more on this encodeForHtml() crap

G'day:
This is a follow-up to last week's ColdFusion: please help me discourage Adobe from releasing bad code article; my inspiration drawing from Brad and Sean's comment on same. I found myself writing too much in reply, so have extracted it into an article instead.

First Brad:
[...] the word "encode" is noise in the method if the class is already called "Encode". I kind of like "Encode.forHTML()" to cut down on verboseness. I'm not too much of a fan of Ruby's uber-succinct shortcuts [methods like to_s() instead of toString() ] but I think there's something to be said for trimming down on unnecessary fluff typing.
I initially started with the same thought (see my comment on the ticket):
So they should be in something like:

String Encode.forHtml(String stringToEncode)
Sorry, was being hasty before. That class / method name example I gave was rubbish: Encode is a verb, so makes no sense as a class name; and the method suggestion had similar grammatical shortcomings. Something more like Encoder or StringEncoder or something for the class, and the methods themselves should be the same as their procedural counterparts, so:

static String StringEncoder.encodeForHtml(String stringToEncode)
The name of the method needs to stand on its own two feet (methods have two feet, just like you and I, apparently ;-). "forHtml()" does not adequately describe what the method does. This is a bit semantic given it'll generally be referenced in context with its class, but I still think a method name should describe what it does. "forHtml()" sounds like one is coming in half-way through the description.

Of course at that point, the only difference (to the average programmer) between

Encode.forHTML()

and

EncodeForHTML()

is one character and I think the latter is easier to remember and easier to type since it reads the same but isn't peppered with punctuation.
Well I'd be advocating StringEncode.encodeForHtml(), so that makes even more typing still. I think an appropriate level of brevity is a factor in language design, but not the chief one. And I programming is not an exercise in typing: it's an exercise in thinking. I am perpetually bemused by these people who think programming is some sort of typing race. In the bigger scheme of things, typing a few extra characters each time one wants to encode something? So what?

Also in equivocating over Encode.forHTML() and EncodeForHTML() you're arguing a case for something I'm not contesting. Or even talking about. This conversation is not about whether we should have a headless function or an OO method: that horse has already bolted.

I'm kind of torn here, because I like the highly-academic idea that a language does things "properly" and according to best practices (or at least the precedent set by other languages at the time) but I also like the idea that CF (and many other dynamic, loosely typed languages) bend rules here and there with an end result of making things as simple and easy for the developer as possible in order to get code out quickly and efficiently. (Push complexity on the compiler, not the programmer) At the end of the day, I'm not quite sure what real-world difference there is between a collection of related functions that differentiate themselves by starting with "Encode." and a collection of related functions that differentiate themselves by starting with "Encode".
This is - again - misdirected equivocation. This is not part of the discussion. The ticket is specifically about the member-function implementation of the encoding functions.

Wednesday, 9 December 2015

ColdFusion: so there won't be a ColdFusion 12?

G'day:
Yes, this is obviously a case of two things:

  1. Betteridge's law of headlines...
  2. ... being used for click baiting (or indeed in this case, click bating perhaps ;-).
There will definitely be a "next" version of ColdFusion, but it seems Adobe might  skipping forward 2005 major version numbers, and going with ColdFusion 2016 instead.

Well if this is anything to go by, anyhow:


This is on ticket 4097705, which is something about <cfpdfparam> or something. I did not read the detail as I don't care about PDFs. Or their params.

So... ColdFusion 2016? Yeah, why not.

Best I go re-tag all my "ColdFusion 12" articles as "ColdFusion 2016".

--
Adam

ColdFusion: please help me discourage Adobe from releasing bad code

G'day:
As you may or may not know, CFML has a bunch of headless functions for encoding strings according to OWASP security recommendations, eg:
These are - for all intents and purposes - wrappers for equivalent methods in OWASP's own Java library: org.owasp.esapi.reference.DefaultEncoder.

You should always use one of these functions when you are going to render untrusted content (user input, data from third-party APIs, databases, etc), eg don't do this:

Kia ora <cfoutput>#form.firstName# #form.firstName#</cfoutput>!

Do this:

Kia ora <cfoutput>#encodeForHtml("#form.firstName# #form.firstName#")#</cfoutput>!

Similarly if the value is going into JS, use encodeForJavaScript(), or a URL: encodeForUrl().

Also note these supercede older functions like htmlEditFormat() and urlEncodedFormat(), which do not do the job thoroughly, and should be actively removed from your codebase.

All good.

One thing that CFML has not had thusfar though are an OO approach to calling these functions, via a method rather than a headless function. It's really no great shakes that it doesn't, but it would be good if Adobe had done a thorough / complete job of implementing OO coverage of CFML's functionality. This is beginning to seem like their approach to CFScript coverage: it took about seven ColdFusion versions for them to complete the job, in the mean time CFML was marginalised as a language due to the play-school-looking code us CFMLers had to write our applications in.

There's a ticket in the bugbase to implement "member function" versions of these encoding functions: "Member functions for encoding". Cheers to Neil for raising that.

Unfortunately the Adobe ColdFusion Team have demonstrated their lack of OO nous in their implementation. Or lack of willingness to engage in language design. Or... really... preparedness to do good work.

The thought process seems to have been "well one passes a string to these functions, therefore they're clearly String member functions. We'll add them to the String class".

Well... no. A String class should have methods which describe the behaviour of a String object. Any String object so its methods should focus on ubiquious / generalised functionality relating to any string. Like finding & replacing sub-strings, comparing strings, etc. You know: the sort of general stuff that java.lang.String provides. Note how java.lang.String isn't a catch-all for every function which happens to take a string as an argument. That's not how OO works.

These encoding functions don't apply to most strings. They only apply to strings being used for a special purpose: a special sort of String, not the general String implementation. But these encoding functions are tricky ones. If there was a class "EncodableString" or something, then they'd be object methods of those. But what's the difference between a String and an EncodableString other than these functions? I don't think there's a decent case for that.

So what was OWASP's Java approach? Well one creates (or gets) an instance of an Encoder, and then passes the String to the encoder via the appropriate method. This makes sense in Java, and fits with the rest of the language. It looks a bit odd in CFML though:

<cfset myEncoder = new Encoder()>
Kia ora <cfoutput>#myEncoder.encodeForHtml("#form.firstName# #form.firstName#")#</cfoutput>!

Well it doesn't look odd, but it would be the first of a precedent of having built-in CFML classes which one creates instances of. Still: this sort of thing is where CFML should have gone with the release of CFMX 6.0: if they're in for a penny with OO, they should have been in for a pound.

So perhaps Adobe could have taken that approach.

However this still doesn't sit well with me. I rather more think that these methods are better suited to be static methods which one calls on the class. For CFML's needs there is no "object" needed here, as the Encoder doesn't have any stateful information. So I rather think the functions should be implemented as static methods:

Kia ora <cfoutput>#Encoder.encodeForHtml("#form.firstName# #form.firstName#")#</cfoutput>!

This follows on from the previous example: there's an Encoder class, and we just call the method on the class itself. I've suggested this in the ticket.

As is increasingly obvious, Adobe too often charges off and does work without public consultation, and then present some half-baked, half-working, design-absent solution. They have done this here too. There was never any community discussion, they simply did the work. And they plan to release it in ColdFusion 2016.

Adobe finally followed-up on the ticket (after a bit of should-be-unnecessary badgering), and seem to concede my suggested alternative makes sense. Cool. Except they also seem to be suggesting they're gonna release this current incorrect implementation in the mean time, and then - in a later ColdFusion release - look at fixing it. This is even more ill-conceived than their initial implementation! Once they release this stuff, it's out in the wild, and people will use it. Why would they release something that's been done wrong (you might think "wrong" is a heavy-handed description, but from a language design perspective, I don't see how it can be considered "right"?)? If they're short on time and/or resource, then they should simply park the work until they have time to do it properly. No-one's in a  rush for them to make CFML just that little bit more sh!t, are they? I can only surmise they're unprepared to concede "yeah that work didn't pass muster so should not be released", because that'd be an admission of error.

What I'd like people to do is to give this issue some thought, form yer own opinion, and express it on the ticket. From my perspective I'd like to vote for not releasing this solution until it's done right. I'd rather have no implementation than a bad one. We need to discourage Adobe form actually releasing sub-par work.

So have a vote and a comment if you feel like it (hey, vote and comment even if you don't agree with me; I'm not trying to ballot-stuff here. Well: maybe a bit ;-).

Righto.

--
Adam

Tuesday, 1 December 2015

Guest author: more on agile practices from Brian Sadler

G'day:
Once again I'm promoting a comment from another article (Guest author: a response to "Why good developers write bad code") to be an article in its own right, cos I reckon people ought to read it. Firstly I'll repost that to which Brian is replying (for context), then on with Brian's reply.

Estragon says:

@Brian - yes to smaller chunks of the elephant at a time, tasks that are too large are a major contributor to this behaviour ... but then what's too large for one dev is fine for another, and it can be hard to judge it right, especially when someone doesn't give early feedback on the requirements and then proves to be "quite reluctant to provide honest progress reports if things aren't going well". I guess getting the task size right for individual developers, and distinguishing legitimate concerns/cries for help from the usual background griping is one of the skills that makes a good team lead. Not easy though

I've actually never had the luxury of having a QA person on a dev team, so while what you say is no doubt true in those kinds of environments, my experience has been that there's no surer way to get a developer to lose sight of the big picture than presenting them with a bug list. At that stage it becomes all about fixing the bugs, not the code design

Brian says:

@Estragon Thanks for the comment! I'm nowhere near as engaged or as prolific as Adam, so apologies for the tardy response!

"what's too large for one dev is fine for another"

Agreed there's always going to be some variation in developer productivity, but I don't think that's hugely significant in most organisations. Rock star developers tend to clump together, as do mere mortals.

I'm going to assume that the developer(s) doing the work provides the estimates - and if that's not the case then run for the hills! :-) If we then impose time-boxing (estimate 1 day max per task) and mandatory progress reports (daily stand ups), then we have a mechanism for checking if the work is progressing as planned. The time-boxing addresses the potential issue of differences in individuals' capabilities. A slower developer might have to break down a large requirement into more one-day and sub-one-day tasks than a faster developer, but whatever speed developers work at, we have a daily report on progress.

"quite reluctant to provide honest progress reports if things aren't going well"

We then have to tackle the thorny question of getting honest progress reports. Again all sorts of things come into play, but in essence we have to:
1. encourage and reward honest reporting (especially when there's bad news to be delivered)
2. penalise dishonest reporting, and
3. enforce transparency.

The first two points are all about the culture you work in - and management must set the tone here. Raising your hand because you're falling behind schedule should result in assistance not admonition. If delays/problems are flagged up as soon as they are known by developers it gives management the largest possible amount of time to take corrective action. Hiding schedule problems and hoping to catch up time on other tasks is a recipe for disaster. The management's opportunity to take corrective action starts to recede and inevitably quality takes a nose dive on the other remaining tasks as we attempt to make up for last time.

Clearly we don't want a never ending stream of schedule problems, but that's where sprints / iterations and retrospectives come in. If we honestly, diligently and faithfully log the effort required to complete each task and, as part of our retrospective activities, compare expended effort against our initial original estimates we'll start to generate a feedback loop that should help us to get better at producing reliable estimates over time.

On the third point, Continuous Integration can play a major role here but we can also do things like define what "done" means to ensure that everyone has a common understanding of what it takes to complete a task. Many devs are quite happy to declare that they're finished when they press the save button on their IDE, more "enterprise" organisations might have a definition of done that includes all sorts of checks - unit testing, code review, functional testing, CI regression tests, performance tests etc. etc. The important point is that if a developer claims to have finished a task, then it must meet the organisation's definition of done, whatever that definition is (in agile circles that usually means, deployable to production).

On top of that, I'd mandate that any developer claiming to have finished a task should be able to demonstrate it. The conversation I've heard many times is,:

Dev: "Yeh I finished Feature A"
Colleague: "Great! Let's have a look!"
Dev: "Oh, actually you can't see it just yet, QA haven't signed it off"
Colleague: "OK... So, has your code been reviewed?"
Dev: "Err... no, not yet"
Colleague: "Have you even merged your code?"
Dev: "Erm... well, you see, I haven't committed my code yet"
Colleague: "So QA hasn't signed it off, the code hasn't been merged or reviewed, indeed you haven't even committed your code, but Feature A is done right?"
Dev: "Yeh!".

At this point I call BS :-) For a task to be finished it has to be in a state where it can at least be demo'ed. We're back to the agile principle of working software being the primary measure of progress. Add in the concept of binary milestones (there is no 90% done, it's either done or it's not done) and we start to concentrate minds.

"I've actually never had the luxury of having a QA person on a dev team"

It's not a luxury! ;-) I think the key here is shortening the feedback cycle. Some people use the analogy that unreleased code is akin to stock inventory in a traditional business, so unreleased code is just filling up space in the warehouse. Having code that is not only unreleased but untested is even worse. What it means is that we've got to manage code that we're not even sure is fit for purpose, and depending on your branching model it's either hanging around going stale on a feature branch or cluttering up your mainline.

Having testers and devs work together enables us to be much leaner, and get close to a kind-of JIT stock control system for coding. We write very small amounts of code which gets reviewed, tested and fixed very quickly, and as soon as possible we release it to production so that the business owners can make a return on their investment. If organisations deliberately choose to lengthen the feedback cycle they're just wasting time, money and effort. In my opinion that sort of waste is a luxury.

"especially when someone doesn't give early feedback on the requirements"

QA can play a key role here as well. If a requirement isn't testable, then there are almost certainly problems with it, so get QA involved before we start to code, maybe even before the devs look at the requirement. If QA has no idea how to test a requirement, how can a developer hope to know when they have finished the task? The only answer is to down tools until the customer / business analyst / project manager can provide clarity.

"there's no surer way to get a developer to lose sight of the big picture than presenting them with a bug list"

To my mind that's a symptom of the tasks being too big. If you keep to one day max per task, how much damage can a half-decent developer do in one day's coding? Another question this raises is, if working at a micro level produces a mountain of bugs, how can our development at a macro level be expected to be any better?

"At that stage it becomes all about fixing the bugs, not the code design"

Whether we're fixing bugs or delivering new features we should always be fixing the design - evolutionary architecture mandates constant refactoring, even when we're fixing bugs.

"Not easy though"

Absolutely - but (to mix my metaphors) Rome wasn't built in a day and there is no Silver Bullet! :-) Sadly, I think many people choose to take a very short-term, static view of how agile methodologies might apply to them or their team. They look at a bunch of agile-like practices and think, meh, that won't make us better, faster, stronger etc. I have some sympathy for such viewpoints, because taken in isolation, and in the very short term, they won't produce dramatic results, but they're wrong!

The last principle listed on the agile manifesto states, "At regular
intervals, the team reflects on how to become more effective, then tunes
and adjusts its behaviour accordingly" and to my mind this is the key
to producing the dramatic improvements and eliminating the problems described in the OP.

If we take a look at how individuals and groups learn and grow over time, I think it's self-evident that regular, frequent opportunities to measure, reflect, take on board feedback and make changes are crucial for improvement to occur. The agile principle above demonstrates that such opportunities are hard-wired into agile, but without such opportunities I'd argue that improvement is virtually impossible.
Yeah, I've highlighted some bits as if I'm a student reading a text book. This is great stuff, and it's as if Mr Sadler should be writing more stuff more often. Anyway, I'm glad to have the content for this blog, so cheers fella.

Time to address my day job...

--
Adam

ColdFusion: I learn something about query of query

G'day:
Just a quick one (I'm supposed to be doing Clojure this morning, not CFML). Here's somethng I did not know about QoQ in CFML. Well: in ColdFusion's implementation of QoQ. It's LIKE statement supports (very limited) regex patterns in its value.

Here's an example:

colours = queryNew("id,en,mi", "integer,varchar,varchar", [
    [1,"red","whero"],
    [2,"orange","karaka"],
    [3,"yellow","kowhai"],
    [4,"green","kakariki"],
    [5,"blue","kikorangi"],
    [6,"indigo","poropango"],
    [10,"violet","papura"]
]);

coloursWithOorU = queryExecute(
    "SELECT * FROM colours WHERE mi LIKE :pattern",
    {pattern={value="%[ou]%"}},
    {dbtype="query"}
);

writeDump(var=coloursWithOorU, format="text", metainfo=false);

And the result:

query

 
[Record # 1] 
en: red 
id: 1 
mi: whero
 
[Record # 2] 
en: yellow 
id: 3 
mi: kowhai
 
[Record # 3] 
en: blue 
id: 5 
mi: kikorangi
 
[Record # 4] 
en: indigo 
id: 6 
mi: poropango
 
[Record # 5] 
en: violet 
id: 10 
mi: papura

Cool. Note this does not work on Lucee.

I dunno what the grammar of the patterns are, but it's not simply standard CFML regex patterning. For example Initially I tried to have a pattern which would match words of six letters or more (ie: .{6}), but that didn't work. I was gonna say "it'd be really grand if Adobe actually documented this stuff", but actually they have! It's right there on the "Query of Queries user guide" page. OK, so the grammar is very limited. Just to what I've shown, basically: single character classes. It doesn't even support repetition modifiers. So it's a bit disappointing that the grammar is so limited, but it's handy nevertheless.

Thanks to Tim Brenner on the CFML Slack Channel for bringing this to my attention!

--
Adam