How to simple make string uppercase in F#? - string

Try to make as described:
To convert a string to lowercase, you can call the String.ToLower()
method
let makeUpperCase s =
s.ToUpper()
Get as result
error FS0072: Lookup on object of indeterminate type based on
information prior to this program point. A type annotation may be
needed prior to this program point to constrain the type of the
object. This may allow the lookup to be resolved.

If you want to invoke members of a value that is passed as an argument to a function, you have to give F# some hint about what the type of the value is. The best way to do this is using a type annotation:
let makeUpperCase (s:string) =
s.ToUpper()
F# compiler needs this, because it cannot figure out what ToUpper method are you trying to invoke as there may be many .NET objects that have a method of this name.

Related

Is the `def` keyword optional? If so, why use it?

I am aware that a variable can be dynamically typed with the def keyword in Groovy. But I have also noticed that in some circumstances it can be left out, such as when defining method parameters, eg func(p1, p2) instead of func(def p1, def p2). The latter form is discouraged.
I have noticed that this is extendable to all code - anytime you want to define a variable and set its value, eg var = 2 the def keyword can be safely left out. It only appears to be required if not instantiating the variable on creation, ie. def var1 so that it can be instantiated as a NullObject.
Is this the only time def is useful? Can it be safely left out in all other declarations, for example, of classes and methods?
Short answer: you can't. There are some use cases where skipping the type declaration (or def keyword) works, but it is not a general rule. For instance, Groovy scripts allow you to use variables without specific type declaration, e.g.
x = 10
However, it works because groovy.lang.Script class implements getProperty and setProperty methods that get triggered when you access a missing property. In this case, such a variable is promoted to be a global binding, not a local variable. If you try to do the same on any other class that does not implement those methods, you will end up getting groovy.lang.MissingPropertyException.
Skipping types in a method declaration is supported, both in dynamically compiled and statically compiled Groovy. But is it useful? It depends. In most cases, it's much better to declare the type for a better readability and documentation purpose. I would not recommend doing it in the public API - the user of your API will see Object type, while you may expect some specific type. It shows that this may work if your intention is to receive any object, no matter what is its specific type. (E.g. a method like dump(obj) could work like that.)
And last but not least, there is a way to skip type declaration in any context. You can use a final keyword for that.
class Foo {
final id = 1
void bar(final name) {
final greet = "Hello, "
println greet + name + "!"
}
}
This way you can get a code that compiles with dynamic compilation, as well as with static compilation enabled. Of course, using final keyword prevents you from re-assigning the variable, but for the compiler, this is enough information to infer the proper type.
For more information, you can check a similar question that was asked on SO some time ago: Groovy: "def" keyword vs concrete type
in Groovy it plays an important role in Global and Local variable
if the variable name is same with and without def
def is considered local and without def its global
I have explained here in detail https://stackoverflow.com/a/45994227/2986279
So if someone use with and without it will make a difference and can change things.

Why doesn't calling repr on type objects work as expected?

First, let me say that I agree that eval(repr(some_string)) is potentially a bad idea. But it is a thing that exists, and I have a specific question about it.
Why doesn't this work?
my_type = int
my_type_str = repr(int)
my_type_from_str = eval(my_type_str)
To clarify, I know specifically why the eval call fails. The command repr(int) produces a string which cannot be automatically interpreted. I guess my issue is that this isn't behaving as I expect... so either my expectation is faulty or the implementation is faulty. Which is it?
Side Note
There are some tricks that can be used to get around this default behavior, some obvious, some not. For instance, this:
my_type = int
my_type_str = my_type.__name__
my_type_from_str = eval(my_type_str)
assert my_type is my_type_from_str
This sets off my "hack" alert hardcore, and I don't like it (or other similar hacks, for instance parsing the string "<class 'int'>" with some home made function).
The documentation explains:
Return a string containing a printable representation of an object. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a repr() method.
(emphasis mine)
So, it doesn't say that repr must always return valid Python code - sometimes it's not the case. Just another argument for not relying on it.

Does groovy ignore the type of null values in method signatures?

To illustrate the following example I created a litte spock test (but it's about groovy itself, not spock):
void "some spock test"() {
given: String value = null
expect: someMethod(value) == 3
}
int someMethod(String s) {
return 3
}
int someMethod(Map s) {
return 5
}
There are two methods who's signatures only differ by the type of the given parameter. I thought that when I give it a null value that is explicitly typed as a string, the string-method will be called.
But that doesn't happen; the test fails, because the map-method is called! Why?
I guess groovy ignores the type and treats all nulls the same. There seems to be some kind of priority of types: When I use Object instead of Map as the parameter type of the wrong-method, its all the same, but when I for instance use Integer, the test succeeds.
But than again: If groovy really ignores the type of nulls, why can the following fix the original test:
expect: someMethod((String) value) == 3
If you read my answer to the question Tim already mentioned you will see that I talk there about runtime types. The static type plays normally no role in this. I also described there how the distance calculation is used and that for null the distance to Object is used to determine the best fitting method. What I did not mention is that you can force method selection by using a cast. Internally Groovy will use a wrapper for the object, that also transports the type. Then the transported type is used instead. But you surely understand, that this means a one additional object creation per method class, which is very inefficient. Thus it is not the standard. In the future Groovy maybe change to include that static type information, but this requires a change to the MOP as well. And that is difficult

what does getType do in antlr4?

This question is with reference to the Cymbol code from the book (~ page 143) :
int t = ctx.type().start.getType(); // in DefPhase.enterFunctionDecl()
Symbol.Type type = CheckSymbols.getType(t);
What does each component return: "ctx.type()", "start", "getType()" ? The book does not contain any explanation about these names.
I can "kind of" understand that "ctx.type()" refers to the "type" rule, and "getType()" returns the number associated with it. But what exactly does the "start" do?
Also, to generalize this question: what is the mechanism to get the value/structure returned by a rule - especially in the context of usage in a listener?
I can see that for an ID, it is:
String name = ctx.ID().getText();
And as in above, for an enumeration of keywords it is via "start.getType()". Any other special kinds of access that I should be aware of?
Lets disassemble problem step by step. Obviously, ctx is instance of CymbolParser.FunctionDeclContext. On page 98-99 you can see how grammar and ParseTree are implemented (at least the feeling - for real implementation please see th .g4 file).
Take a look at the figure of AST on page 99 - you can see that node FunctionDeclContext has a several children, one labeled type. Intuitively you see that it somehow correspond with function return-type. This is the node you retrieve when calling CymbolParser.FunctionDeclContext::type. The return type is probably sth like TypeContext.
Note that methods without 'get' at the beginning are usually children-getters - e.g. you can access the block by calling CymbolParser.FunctionDeclContext::block.
So you got the type context of the method you got passed. You can call either begin or end on any context to get first of last Token defining the context. Simply start gets you "the first word". In this case, the first Token is of course the function return-type itsef, e.g. int.
And the last call - Token::getType returns integral representation of Token.
You can find more information at API reference webpages - Context, Token. But the best way of understanding the behavior is reading through the generated ANTLR classes such as <GrammarName>Parser etc. And to be complete, I attach a link to the book.

Pass a dynamic variable in a static parameter of a method in C# 4

This is what I am trying to do:
public void method(int myVal, string myOtherVal)
{
// doing something
}
dynamic myVar = new SomeDynamicObjectImplementer();
method(myVar.IntProperty, myVar.StringProperty);
Note that my properties are also DynamicObjects. My problem is that the TryConvert method is never called and that I get a runtime error saying the method signature is invalid.
The following is working great:
string strVar = myVar.StringProperty;
int intVar = myVar.IntProperty;
And I would like to avoid
method((int)myVar.IntProperty, (string)myVar.StringProperty);
Is it possible to override something in DynamicObject to allow this? (or something else)
Thank you
The problem is your assumption that it will try a dynamic implicit convert on arguments of an dynamic invocation to make a method call work, this is not true.
When your arguments aren't statically typed, it will use the runtime type to find the best matching method (if the runtime type matches the static rules for implicit conversion to the argument type this will work too), since your your IntProperty,StringProperty seem to be returning a DynamicObject rather than an Int and a String or something that could statically be converter implicitly, this lookup will fail.
If SomeDynamicObjectImplementer could actually return an Int for IntProperty and a String for StringProperty your method call for without casting would actually work. It's also probably a better dynamic typing practice if you data type is based on the actually type of data rather than usage using try convert. You could add actually implicit convert methods for every possible type that you could return to that returned DynamicObject type, but that could cause strange resolution issues to depending on how much you are overloading.
However, another option to keep your dynamic implementation the same is to mix a little controlled static typing in, you can use ImpromputInterface (in nuget) to put an interface on top of a dynamic object, if you do that then the TryConvert method would be called on your returned DynamicObjects.
public interface ISomeStaticInterface{
int IntProperty {get;}
string StringProperty {get;}
}
...
var myVar = new SomeDynamicObjectImplementer().ActLike<ISomeStaticInterface>();
method(myVar.IntProperty, myVar.StringProperty);
Instead of using myVar.IntProperty can't you just put them in variables first, like you already did, and then use then for your method?
so method(intVar , strVar); seems fine. At least more elegant than casting.
Of course, if you're already certain your object will have IntProperty and StringProperty, why not just make an actual object with those properties instead?
Why are you doing the cast?
method(myVar.IntProperty, myVar.StringProperty);
should compile.
If the two properties must be the types suggested by the names then they shouldn't be dynamic.

Resources