I have an object, that has one value, but that value can either be an integer, string, boolean or TDateTime. So, it is a Variant.
I use VarType() to check its type, but since VarType() has no 'varDate' or 'varDateTime', I am using 'varDouble', because as far as I can gather, a TDateTime is a double.
But that returns false. I also cannot use is to check if the Variant is TDateTime. Is there a way, or should I make some sort of type variable that determines which type the value is and use that to check it?
Your assumptions are incorrect; there is in fact a varDate.
Related
Is int type in Dart a value type or reference type?
What is "reference type","value type","canonicalized" in Dart? (concrete definition)
I was looking into the specific definitions of "reference type" and "value type", but in the end, I thought it would be good to understand the code that represents the difference and the behavior (result) of that code.
If possible, I would like Dart code, but if it has the same structure as Dart regarding the above issues, there is no problem in other languages, so I would appreciate it if you could give me sample code.
The meaning of "reference type" and "value type" used here is the distinction made by C#.
A reference type is a traditional object-oriented object. It has identity which it preserves over time. You can have two objects with the same state, but they are different objects.
You don't store reference type values directly into variables. Instead you store a reference to them. When you access members of the object, you do so through the reference (x.foo means "evaluate x to a reference, then access the foo member of the object referenced by that reference).
When you check for identity, identical(a, b), you check whether two different references refer to the same object.
A value type does not have identity. It's defined entirely in terms of its state, its contents. When you assign a value type to a variable, you make a copy of it. It's the "value" in call-by-value.
C# allows you to declare value types with that behavior.
(Reference types do not correspond to call-by-reference, rather to call-by-sharing.)
In Dart, all objects are reference objects. This differs from, say, Java, where an int is a value-type ("primitive type" in their parlance), and they have a separate Integer class which can wrap the int values and is a reference type. That's needed because Integer is a subtype of Object, but int isn't, so you can't store int values in a generic container which expects a subtype of Object.
In Dart, some reference types are still more value-like than others. In particular numbers.
A Dart number, like the integer 1, has precisely one object representing that value. If you write 1 in different places of the program, or even calculate 4 ~/ 4 or 3 - 2, you always get the same object representing the value 1. It's like it's not an object at all, and identical only compares values. And that's precisely what happens, because it allows the compiler to treat integers as primitive values internally, and not worry about sometimes having to give you the same 1 object back that you put in.
This is sometimes expressed as integers being "canonicalized": There is only one canonical instance representing each state.
Dart also canonicalizes other objects.
Constant expressions are canonicalized, so that two different constant expressions generating instances of the same type, with identical states, are made to return the same, canonical, instance representing that value.
Since the value is guaranteed to be immutable, there is no need to have equal objects with different identities. (If they were mutable, it matters very much which one you mutate and which one you don't).
I would like to get the initializer in the field corrected_time in code below. I found the field.initializer, but couldn't get much further. (the #Init annotation is temporary solution for now):
mixin PrerenderDoc on Doc implements AllowDelete {
#Init(init_int: 0)
int corrected_time = 0;
}
I'm guessing that field is an instance of FieldElement. Unfortunately, if that's the case, then the answer is that analyzer doesn't have a value for the initializer. The analyzer only computes values for (a subset of) expressions that are constant expressions. For field initializers, that means that the field needs to be declared to be const, and the one in the example isn't.
(Annotations are constants and hence have values, which is why your workaround works.)
If the field were declared const, then you could use VariableElement.constantValue to access a representation of the value (VariableElement is a superclass of FieldElement).
The other option available to you is to use the AST structure and examine the structure of the expression, but if you want / need to handle anything more than just simple literal values, that can be quite complex.
Is it legal for a record to have a nullable field such as:
type MyRec = { startDate : System.Nullable<DateTime>; }
This example does build in my project, but is this good practice if it is legal, and what problems if any does this introduce?
It is legal, but F# encourage using option types instead:
type MyRec = { startDate : option<DateTime>; }
By using option you can easily pattern match against options and other operations to transform option values as for example map values (by using Option.map), and abstractions such as the Maybe monad (by using Option.bind), whereas with nullable you can't since only value types can be made nullables.
You will notice most F# functions (such as List.choose) work with options instead of nullables. Some language features like optional parameters are interpreted as the F# option type.
However in some cases, when you need to interact with C# you may want to use Nullable.
When usign Linq to query a DB you may consider using the Linq.Nullable Module and the Nullable operators
F# does not allow types that are declared in F# to be null. However, if you're using types that are not defined in F#, you are still allowed to use null. This is why your code is still legal. This is needed for inter-operability, because you may need to pass null to a .NET library or accept it as a result.
But I would say it is not a good practice unless your need is specifically of inter-operability. As others pointed out, you can use the option feature. However, this doesn't create an optional record field whose value you don't need to specify when creating it. To create a value of the record type, you still need to provide the value of the optional field.
Also, you can mark a type with the AllowNullLiteral attribute, and F# compiler would allow null as a value for that specific type, even if it is a type declared in F#. But AllowNullLiteral can't be applied to record types.
Oh and I almost forgot to mention: option types are NOT compatible with nullable types. Something that I kind of naively expected to just work (stupid me!). See this nice SO discussion for details.
I am trying to compare JCR node's string properties with a double value in JCR-SQL2. But it is comparing the values as strings.
For example:
SELECT * FROM [nodex] as x where x.propertyY <= 20.50
Here propertyY is the string in the definition.
I tried this with CASE but it still does not work. Can I compare it as double without changing the property definition?
Standard JCR-SQL2 has a CAST(value AS DOUBLE) expression, but unfortunately it can only be used on the right-hand side of an expression. Yes, JCR-SQL2 is not nearly as flexible as normal SQL.
To my knowledge, there is not really a valid standard way to convert the property value to a double before running the comparison. If you cast the double value to a string, you'll get a lexicographical comparison -- which of course won't really be very useful.
I'm not sure about other implementations, but ModeShape would convert the property value to a double when the property is a residual property, since a residual property has no definition and therefore not type. It's quite likely that other implementations would not behave like this.
In F# mantra there seems to be a visceral avoidance of null, Nullable<T> and its ilk. In exchange, we are supposed to instead use option types. To be honest, I don't really see the difference.
My understanding of the F# option type is that it allows you to specify a type which can contain any of its normal values, or None. For example, an Option<int> allows all of the values that an int can have, in addition to None.
My understanding of the C# nullable types is that it allows you to specify a type which can contain any of its normal values, or null. For example, a Nullable<int> a.k.a int? allows all of the values that an int can have, in addition to null.
What's the difference? Do some vocabulary replacement with Nullable and Option, null and None, and you basically have the same thing. What's all the fuss over null about?
F# options are general, you can create Option<'T> for any type 'T.
Nullable<T> is a terrifically weird type; you can only apply it to structs, and though the Nullable type is itself a struct, it cannot be applied to itself. So you cannot create Nullable<Nullable<int>>, whereas you can create Option<Option<int>>. They had to do some framework magic to make that work for Nullable. In any case, this means that for Nullables, you have to know a priori if the type is a class or a struct, and if it's a class, you need to just use null rather than Nullable. It's an ugly leaky abstraction; it's main value seems to be with database interop, as I guess it's common to have `int, or no value' objects to deal with in database domains.
Im my opinion, the .Net framework is just an ugly mess when it comes to null and Nullable. You can argue either that F# 'adds to the mess' by having Option, or that it rescues you from the mess by suggesting that you avoid just null/Nullable (except when absolutely necessary for interop) and focus on clean solutions with Options. You can find people with both opinions.
You may also want to see
Best explanation for languages without null
Because every .NET reference type can have this extra, meaningless value—whether or not it ever is null, the possibility exists and you must check for it—and because Nullable uses null as its representation of "nothing," I think it makes a lot of sense to eliminate all that weirdness (which F# does) and require the possibility of "nothing" to be explicit. Option<_> does that.
What's the difference?
F# lets you choose whether or not you want your type to be an option type and, when you do, encourages you to check for None and makes the presence or absence of None explicit in the type.
C# forces every reference type to allow null and does not encourage you to check for null.
So it is merely a difference in defaults.
Do some vocabulary replacement with Nullable and Option, null and None, and you basically have the same thing. What's all the fuss over null about?
As languages like SML, OCaml and Haskell have shown, removing null removes a lot of run-time errors from real code. To the extent that the original creator of null even describes it as his "billion dollar mistake".
The advantage to using option is that it makes explicit that a variable can contain no value, whereas nullable types leave it implicit. Given a definition like:
string val = GetValue(object arg);
The type system does not document whether val can ever be null, or what will happen if arg is null. This means that repetitive checks need to be made at function boundaries to validate the assumptions of the caller and callee.
Along with pattern matching, code using option types can be statically checked to ensure both cases are handled, for example the following code results in a warning:
let f (io: int option) = function
| Some i -> i
As the OP mentions, there isn't much of a semantic difference between using the words optional or nullable when conveying optional types.
The problem with the built-in null system becomes apparent when you want to express non-optional types.
In C#, all reference types can be null. So, if we relied on the built-in null to express optional values, all reference types are forced to be optional ... whether the developer intended it or not. There is no way for a developer to specify a non-optional reference type (until C# 8).
So, the problem isn't with the semantic meaning of null. The problem is null is hijacked by reference types.
As a C# developer, i wish I could express optionality using the built-in null system. And that is exactly what C# 8 is doing with nullable reference types.
Well, one difference is that for a Nullable<T>, T can only be a struct which reduces the use cases dramatically.
Also make sure to read this answer: https://stackoverflow.com/a/947869/288703