Duck-Typing in ColdFusion - coldfusion

What is duck-typing and how is ColdFusion related?

ColdFusion allows function arguments to be specified as having type any. For this sort of argument, an arbitrary object can be passed in and method calls are bound dynamically at runtime. If an object does not implement a called method, a runtime exception is thrown which can be caught and handled gracefully. In ColdFusion 8, this can be picked up as a defined event onMissingMethod()rather than through an exception handler. An alternative argument type of WEB-INF.cftags.component restricts the passed argument to be a ColdFusion Component (CFC), which provides better error messages should a non-object be passed in.
http://en.wikipedia.org/wiki/Duck_typing#In_ColdFusion

Related

Can you tell if a parameter passed to a function is an anonymous temporary at the calling site?

I have a case where it would be useful to be able to tell if a function parameter is an anonymous temporary in the caller.
Is there a way to do this with C++ traits?
Assume any C++ standard is available to me.

std::logic_error classes are different kinds of std::invalid_argument, aren't they?

Let's have a look at classes that are derived from std::logic_error:
std::out_of_range is thrown when argument is out of range.
std::length_error is thrown when argument that specifies a length is out of supported values.
std::domain_error is supposed to be thrown when an argument is outside of expected domain.
std::future_error is thrown when std::future without a shared state is used (if we take the object as a hidden argument of a method, then std::future is an argument too).
It seems that all of the exceptions above are thrown when an invalid argument is passed (invalid position, invalid length, invalid future). If so, why are they not derived from std::invalid_argument? Should I derive my errors from std::invalid_argument
or from std::logic_error?
Are there a logic errors that are not related to an invalid argument usage?
Those first three exceptions may indicate that an argument is, for example, out of range.
They may also indicate that something else is out of range.
That could be the result of a calculation, or data provided from a service.
Not every piece of information is an argument.
As for future_error…
if we take the object as a hidden argument of a method, then std::future is an argument too
That interpretation is based on implementation details, which should not come into play when designing a class heirarchy or when describing semantically what a thing does. Logically, the std::future throws the exception, not some would-be free function that takes a std::future as an argument. As a result, again, the thing that's "wrong" is not an argument.

Best practices for abstract factory construction that fails

Background
Suppose we have an implementation of the abstract factory which is invoked as follows:
std::string ObjectName = "An Object Name";
std::string Args = "Argument passed directly to constructor by the factory";
std::unique_ptr<MyBaseClass> MyPtr(ObjectFactory::Instance().Construct(ObjectName,Args));
The factory uses a std::map to turn "An Object Name" into a constructor, which itself takes a std::string as an argument. The idea is that the user knows more about the constructed objects than I do, so I should get out of the way and let the user pass any information they want to the constructor.
Question
This works fine when Args is in exactly the form expected but I don't know the most idiomatic way of handling duff inputs. What should happen if a user supplies an invalid argument string?
I can think of the following:
have the object's constructor throw an exception
require the object provides a bool Validate(std::string x) method, which checks whether x is a valid argument string
Have the factory use the default constructor, and then call an initialisation method afterwards (begs the question: what if the init method fails?)
Set a bool member variable which, if true, means "this object is not in a sane state"
Some other option I've not thought of
Throw an exception. You're constructing an object (albeit in a different way than just new), failure is an exception that needs to be handled if it can happen.
"Solution 2" has nothing to do with handling this issue, it's more of a how to determine bad input. For such it can be an acceptable solution, but again it has nothing to do with the question at hand.
Solution 3 leaves the object in an indeterminate state in case of failure, which is unacceptable.
Solution 4 is another way to do it, and the only way if you don't have exception support in your language, but we do. Exceptions in this case are strictly better in my opinion because failing to construct an object is an action so destructive it should require alternative code or the program to die.
The first solution is the standard solution for constructor failure.
Solution #2 and #4 are pretty error prone (user might forget to check)
Solution #3 doesn't solve the problem
If you're making a library or just writing code that might be re-used in a "no exceptions allowed" environment, you could consider returning std::unique_ptr{nullptr}. Even if it is also error prone, that's the other standard way of handling construction failure.
Maybe the easiest way is to return a nullptr.
What ever you do, do not throw an exception from a constructor (as per Item #10 in More effective C++), as the destructor will not be called. It leads to newbie memory leaks and forces users to worry about exception handling.
I would just assert and return a Null Object, with dummy factory method implementations, or return nullptr.

Rationale behind the resumable functions restrictions

In the paper about resumable functions, in the section about restrictions three restrictions are listed:
Resumable functions cannot use a variable number of arguments. For situations where varargs are necessary,the argument unwrapping may be placed in a function that calls a resumable function after doing the unwrapping of arguments.
The return type of a resumable function must be future<T> or shared_future<T>. The restrictions on T are defined by std::future, not this proposal, but T must be a copyable or movable type, or ‘void’. It must also be possible to construct a variable of T without an argument; that is, it has to have an accessible (implicit or explicit) default constructor if it is of a class type.
Await expressions may not appear within the body of an exception handler and should not be executed while a lock on any kind is being held by the executing thread.
There must be a reason behind this restrictions and due to my lack of knowledge about concurrency I cannot deduce what reasons are. Could someone enlight me about this topic?
Variable number of arguments
This restriction is referring to the C-style variadic functions or the C++11 variadic template ones?
If is the C-style ones, the reason of the limitation is related to the magic trickery done by the va_* macros?
If is referring to the variadric template functions I assume that the limitation must be related with the unpacking of the parameter pack not with the fact that the function is a template one (there's no wording about template resumable functions, so I assume that they're legal).
In both cases, I thought that the compiler could be smart enough to deduce which function to use.
Default constructible and copyable/movable type
I understand the reason behind returning a std::future or std::shared_future, but I'm guessing that the reason of the limitation behind the usable types is related to the types that the futures could use.
So, the paper is proposing to extend the language with two new keywords (resumable and await) that provides the behaviour of resumable functions but in the end it trust on existent constructs to transfer the return values of resumable functions between the function and the caller.
Why not propose some kind of language extension for the return values too? that could (maybe) release the limitation to default constructible and copyable/movable types and fix the assimetry between the return type and the returned type:
It should thus be noted that there is an asymmetry between the function’s observed behavior from the outside (caller) and the inside: the outside perspective is that function returns a value of type future<T> at the first suspension point, while the inside perspective is that the function returns a value of type T via a return statement (...)
No awaitable exception handlers nor awaitable locked threads
I guess that awaiting something while catching an exception have no sense, but I haven't any clue about the limitation of the locked threads.
I'm pretty sure all of these restrictions are related to the fact that the context of a resumable function has to be "saved" and "resumed" - I expect the mechanism will create a temporary "copy of the stack" or something similar. So:
Variable number of arguments
This really means things using va_arg functionality - not because the macros involved, but because it's impossible for an outside agent to know the number of actual arguments - for printf, you'd have to read the format string, for some others the last one is marked with NULL. So how much context needs to be saved away?
Locked threads
So we have just said "we don't want this thread to be interrupted", and then we go and say "Now lets run something else". That's like saying "Please, under no circumstances shall I be interrupted while I take my bath" while stepping into the bath and at the same time say "Can you phone me in 2 minutes..." - assuming the bath takes more than 2 minutes, one of those will be untrue.
Default constructible
I'm pretty sure the logic here is that it would make the whole concept quite complex if the return value to be constructed has to have arguments passed to the constructor. How would you even describe such a thing? And you would also have to "hold on to" those arguments while in suspended state. Again, making the saving of the context more complex.

What happens when a method is called through IDispatch with the wrong number/types of arguments

If I call a method of a COM object through IDispatch (late-binding) with the wrong number/types of arguments, will some error code be returned, or will the program crash or have other malfunctions? I just want to know if late-binding with IDispatch is type-safe.
It depends from the actual implementation of the Invoke method of IDispatch; it may check if the parameters passed in pDispParams are correct or blindly use them, ignore the COM errors that arise from manipulating them in a wrong way or report these errors to the caller, ...
Still, if the interface you are calling uses the default DispInvoke function to implement IDispatch::Invoke you should be safe, since it implements reasonable sanity checks on the arguments.