How do you determine if a variable is "callable" in dart? - dart

I am doing a small experiment in dart and I couldn't find a way to determine if a variable is "callable" without explicitly checking for each type (String, int, bool, ect) and guessing that it was callable if it was none of those. I also experimented with a try/catch which to me just seems wrong.
Whats the right way or at least the best way to make that determination?
Here is an example I did to show what I am trying to accomplish:
https://gist.github.com/digitalfiz/3f431dc07ca761389062

Use this function:
bool isCallable(v) => v is Function;
Usage Examples:
class Callable {
call() => 42;
}
void main() {
var foo = () => 42;
var bar = new Callable();
var baz = 42;
print(isCallable(foo)); //true
print(isCallable(bar)); //true
print(isCallable(baz)); //false
}

Related

How can I check if argument is null, and if not use it in a function?

Is there a shorter, more elegant way to do that?
var? x = null == y ? null : foo(y!);
Something like this, maybe?
int? y = null;
double? x = y?.toDouble() ?? null;
(it should be null safe as well)
No.
There is currently no operation in Dart which takes a value, checks if it is non-null, and if so, does something to it other than calling a method on the object.
What you can do, if you want to, is to introduce an extension like
extension CallWith<T> on T {
R pipeTo<R>(R Function(T) f) => f(this);
}
Then you can write:
y?.pipeTo(foo);

Is there a generic Type in Dart like Class<T> in Java/Kotlin?

In Kotlin I can do something like:
var myType : KClass<String>? = null
and can assign to it like:
myType = String::class
but NOT like:
myType = Int::class // Type mismatch: inferred type in KClass<Int> but KClass<String>? was expected
Is there something similar in Dart? I know of the Type type but it is not generic and while it can represent String or List<int> I seem not to be able to write similar code as my Kotlin example:
Type? t = null;
I can assign to it:
t = String;
AND also:
t = int;
but I want the second example to fail compilation. I would need some kind of Type<String>. Is this possible in Dart?
The Type class is not generic, and doesn't support subtype checks (or any other reasonable type-related operation). There is no way to use it for what you are trying to do.
So, don't. It's useless anyway. However, in Dart you can create your own type representation that is actually useful, because Dart doesn't erase type arguments, and you can then ask people using your code to ass that instead.
Say:
class MyType<T> implements Comparable<MyType>{ // Or a better name.
const MyType();
Type get type => T;
bool operator >=(MyType other) => other is MyType<T>;
bool operator <=(MyType other) => other >= this;
bool isInstance(Object? object) => object is T;
R runWith<R>(R Function<T>() action) => action<T>();
#override
int get hashCode => T.hashCode;
#override
bool operator==(Object other) => other is MyType && T == other.type;
}
With that you can write:
MyType<String?> type;
type = MyType<Null>(); // valid
type = MyType<String>(); // valid
type = MyType<Never>(); // valid
type = MyType<int>; // EEEK! compile-time error
You can use it where you need to store a type as a value.
The thing is, most of the time you can just use a type variable instead ,and creating an actual value to represent a type is overkill.
So, first try to just use a type parameter, instead of passing around Type or MyType objects. Only if that fails should you consider using MyType. Using Type is probably a mistake since it's not good for anything except doing == checks, which is antithetical to object orientation's idea of subtype subsumption.
I think this is the best you can get :
void main() {
aFunction<String>(String, '');
aFunction<String>(String, 1);
}
void aFunction<V>(Type type, V value) {
print(value.toString());
}
if you run this in a dartpad, you will see that
aFunction<String>(type, 1);
Doesn't compile.
But that's not really efficient because the type isn't guessed by Dart, you have to specify the generic type by hand.
I'm using Dart 2.17

Has the Dart lambda syntax for method an effect at runtime?

In JavaScript there is a difference between m1 and m2:
class A {
m1() { return 123; }
m2 = () => 123;
}
Here, m1 is stored in the prototype (it exists in the object that represents the class) while a copy of m2 is stored in each instance as a property. So the first syntax is better where it is adapted.
I would like to know if there is a similar difference in Dart for this kind of code:
class A {
int m1() { return 123; }
int m2() => 123;
}
At runtime, are m1 and m2 completely equivalent?
In Dart, there's no difference.
The docs explain it:
The => expr syntax is a shorthand for { return expr; }. The => notation is sometimes referred to as arrow syntax.
The JavaScript difference is due to historical reasons and no sane language would have the same distinction between the two notations.

Instantiating a struct with stdin data in Rust

I am very, very new to Rust and trying to implement some simple things to get the feel for the language. Right now, I'm stumbling over the best way to implement a class-like struct that involves casting a string to an int. I'm using a global-namespaced function and it feels wrong to my Ruby-addled brain.
What's the Rustic way of doing this?
use std::io;
struct Person {
name: ~str,
age: int
}
impl Person {
fn new(input_name: ~str) -> Person {
Person {
name: input_name,
age: get_int_from_input(~"Please enter a number for age.")
}
}
fn print_info(&self) {
println(fmt!("%s is %i years old.", self.name, self.age));
}
}
fn get_int_from_input(prompt_message: ~str) -> int {
println(prompt_message);
let my_input = io::stdin().read_line();
let my_val =
match from_str::<int>(my_input) {
Some(number_string) => number_string,
_ => fail!("got to put in a number.")
};
return my_val;
}
fn main() {
let first_person = Person::new(~"Ohai");
first_person.print_info();
}
This compiles and has the desired behaviour, but I am at a loss for what to do here--it's obvious I don't understand the best practices or how to implement them.
Edit: this is 0.8
Here is my version of the code, which I have made more idiomatic:
use std::io;
struct Person {
name: ~str,
age: int
}
impl Person {
fn print_info(&self) {
println!("{} is {} years old.", self.name, self.age);
}
}
fn get_int_from_input(prompt_message: &str) -> int {
println(prompt_message);
let my_input = io::stdin().read_line();
from_str::<int>(my_input).expect("got to put in a number.")
}
fn main() {
let first_person = Person {
name: ~"Ohai",
age: get_int_from_input("Please enter a number for age.")
};
first_person.print_info();
}
fmt!/format!
First, Rust is deprecating the fmt! macro, with printf-based syntax, in favor of format!, which uses syntax similar to Python format strings. The new version, Rust 0.9, will complain about the use of fmt!. Therefore, you should replace fmt!("%s is %i years old.", self.name, self.age) with format!("{} is {} years old.", self.name, self.age). However, we have a convenience macro println!(...) that means exactly the same thing as println(format!(...)), so the most idiomatic way to write your code in Rust would be
println!("{} is {} years old.", self.name, self.age);
Initializing structs
For a simple type like Person, it is idiomatic in Rust to create instances of the type by using the struct literal syntax:
let first_person = Person {
name: ~"Ohai",
age: get_int_from_input("Please enter a number for age.")
};
In cases where you do want a constructor, Person::new is the idiomatic name for a 'default' constructor (by which I mean the most commonly used constructor) for a type Person. However, it would seem strange for the default constructor to require initialization from user input. Usually, I think you would have a person module, for example (with person::Person exported by the module). In this case, I think it would be most idiomatic to use a module-level function fn person::prompt_for_age(name: ~str) -> person::Person. Alternatively, you could use a static method on Person -- Person::prompt_for_age(name: ~str).
&str vs. ~str in function parameters
I've changed the signature of get_int_from_input to take a &str instead of ~str. ~str denotes a string allocated on the exchange heap -- in other words, the heap that malloc/free in C, or new/delete in C++ operate on. Unlike in C/C++, however, Rust enforces the requirement that values on the exchange heap can only be owned by one variable at a time. Therefore, taking a ~str as a function parameter means that the caller of the function can't reuse the ~str argument that it passed in -- it would have to make a copy of the ~str using the .clone method.
On the other hand, &str is a slice into the string, which is just a reference to a range of characters in the string, so it doesn't require a new copy of the string to be allocated when a function with a &str parameter is called.
The reason to use &str rather than ~str for prompt_message in get_int_from_input is that the function doesn't need to hold onto the message past the end of the function. It only uses the prompt message in order to print it (and println takes a &str, not a ~str). Once you change the function to take &str, you can call it like get_int_from_input("Prompt") instead of get_int_from_input(~"Prompt"), which avoids the unnecessary allocation of "Prompt" on the heap (and similarly, you can avoid having to clone s in the code below):
let s: ~str = ~"Prompt";
let i = get_int_from_input(s.clone());
println(s); // Would complain that `s` is no longer valid without cloning it above
// if `get_int_from_input` takes `~str`, but not if it takes `&str`.
Option<T>::expect
The Option<T>::expect method is the idiomatic shortcut for the match statement you have, where you want to either return x if you get Some(x) or fail with a message if you get None.
Returning without return
In Rust, it is idiomatic (following the example of functional languages like Haskell and OCaml) to return a value without explicitly writing a return statement. In fact, the return value of a function is the result of the last expression in the function, unless the expression is followed by a semicolon (in which case it returns (), a.k.a. unit, which is essentially an empty placeholder value -- () is also what is returned by functions without an explicit return type, such as main or print_info).
Conclusion
I'm not a great expert on Rust by any means. If you want help on anything related to Rust, you can try, in addition to Stack Overflow, the #rust IRC channel on irc.mozilla.org or the Rust subreddit.
This isn't really rust-specifc, but try to split functionality into discrete units. Don't mix the low-level tasks of putting strings on the terminal and getting strings from the terminal with the more directly relevant (and largely implementation dependent) tasks of requesting a value, and verify it. When you do that, the design decisions you should make start to arise on their own.
For instance, you could write something like this (I haven't compiled it, and I'm new to rust myself, so they're probably at LEAST one thing wrong with this :) ).
fn validated_input_prompt<T>(prompt: ~str) {
println(prompt);
let res = io::stdin().read_line();
loop {
match res.len() {
s if s == 0 => { continue; }
s if s > 0 {
match T::from_str(res) {
Some(t) -> {
return t
},
None -> {
println("ERROR. Please try again.");
println(prompt);
}
}
}
}
}
}
And then use it as:
validated_input_prompt<int>("Enter a number:")
or:
validated_input_prompt<char>("Enter a Character:")
BUT, to make the latter work, you'd need to implement FromStr for chars, because (sadly) rust doesn't seem to do it by default. Something LIKE this, but again, I'm not really sure of the rust syntax for this.
use std::from_str::*;
impl FromStr for char {
fn from_str(s: &str) -> Option<Self> {
match len(s) {
x if x >= 1 => {
Option<char>.None
},
x if x == 0 => {
None,
},
}
return s[0];
}
}
A variation of telotortium's input reading function that doesn't fail on bad input. The loop { ... } keyword is preferred over writing while true { ... }. In this case using return is fine since the function is returning early.
fn int_from_input(prompt: &str) -> int {
println(prompt);
loop {
match from_str::<int>(io::stdin().read_line()) {
Some(x) => return x,
None => println("Oops, that was invalid input. Try again.")
};
}
}

Avoid using "mutable" variable to call a method with a byref (out in C#) parameter?

So I have this class in C#:
public class Foo : IFoo {
public bool TryConnect(out Status status) {
...
}
}
And I want to consume it with F#.
Unfortunately I had to use some hackery such as:
type FooService (foo : IFoo) =
member x.Execute() =
let mutable status = Unchecked.defaultof< ^Status>
foo.TryConnect(&status) |> ignore
(...do something with status...)
Is there a way to not use "mutable" here? In the end, I'm not actually using the first initialization value at all.
(I'm using F# 2.0, but if you have hints that only apply to F# 3.0, I'll be happy to hear them.)
Thanks
out params are automatically tuplized. So, you can do:
let res, status = foo.TryConnect()
For more info, see Passing by Reference on MSDN.

Resources