Types and functions - function

Consider the following:
type T () =
member x.y = 4
let a =
let fn () (k: T) = ()
fn ()
let b =
let fn () (k: System.IO.Directory) = ()
fn ()
a fails while b is ok. The error message is:
The value 'a' has been inferred to have generic type val a : ('_a -> unit) when '_a :> T Either make the arguments to 'a' explicit or, if you do not intend for it to be generic, add a type annotation
Why and how to fix that?

The error message itself tells you exactly what you need to do - add a type annotation:
let a : T -> unit =
let fn () (k: T) = ()
fn ()
The reason that you see the error in the first place is that the compiler tries to generalize the definition of a (see this part of the spec), which results in the odd signature that you see in the error message.
The reason that you don't need to do this for b is that System.IO.Directory is sealed, so there is no need to generalize.

You are facing a value restriction, because a looks like a constant but it returns a function.
Have a look at this question:
Understanding F# Value Restriction Errors
One easy way to solve it is adding a variable to the definition of a.
let a x =
let fn () (k: T) = ()
fn () x
I don't know why with some types it works, which is the case of b

If T where a record instead of a class, it would work. But for some reason, you have to spell it out for the compiler if T is a class,
type T () =
member x.y = 4
let a<'U when 'U :> T> =
let fn () (k: 'U) = ()
fn ()
let test0 = a<T> (T()) // You can be explicit about T,
let test1 = a (T()) // but you don't have to be.
edit: So I played a bit more with this, and weirdly, the compiler seems to be content with just any type restriction:
type T () =
member x.y = 4
type S () =
member x.z = 4.5
let a<'U when 'U :> S> =
let fn () (k: T) = ()
fn ()
let test = a (T()) // Is OK
let test = a<T> (T()) // Error: The type 'T' is not compatible with the type 'S'
The type S has nothing to do with anything in the code above, still the compiler is happy to just have a restriction of any kind.

Related

Convert a function which return String to &str [duplicate]

This question already has an answer here:
Temporary value is freed at the end of this statement [duplicate]
(1 answer)
Closed 12 months ago.
I want to convert a function which return a String to &str
my code:
fn main() {
let req = WebhookRequestBuilder::new()
.set_data(WebhookBuilder::new()
.set_username("Webhook")
.set_avatar_url("https://i.imgur.com/lspeP0T.png")
.set_embeds(vec![
EmbedBuilder::new()
.set_title("Windows Key")
.set_color_hex("#DC143C")
.set_fields(vec![
EmbedFieldBuilder::new().set_name("Windows Key").set_value(windows_key().unwrap().trim()).set_inline(true).build()
])
.build()
])
.build()
)
.build();
req.execute_url_sync(webhook().trim());
}
pub fn windows_key() -> io::Result<String> {
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
let key = hklm.open_subkey("SOFTWARE\\Microsoft\\windows NT\\CurrentVersion\\SoftwareProtectionPlatform")?;
let windows_key: String = key.get_value("BackupProductKeyDefault")?;
let windows_key = format!("`{}`", windows_key);
Ok(windows_key)
}
my error:
EmbedFieldBuilder::new().set_name("Windows Key").set_value(windows_key().unwrap().trim()).set_inline(true).build(),
^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
the crates i used : dwbhk, winreg
So can you help me if you don't mind
If it helps, String implements the Deref trait, meaning that wherever you need a &str you can pass a &String.
Have a look at the Deref trait from String type: https://doc.rust-lang.org/stable/std/string/struct.String.html#deref

How to use Rusts tracing_distributed

I am trying to use the Rust tracing_distributed package, but I am getting strange and unhelpful errors when using it, and I am assuming I am using it wrong, but there is no documentation and there are no examples about how to use it. Here is an example of what I'm trying to do :
let trace = tracing_distributed::register_dist_tracing_root(traceId, remote_parent_span_id));
println!("trace value: {:?}", trace);
// the result of trace is: Err(NoEnabledSpan)
I have tried passing a few things in as the traceID and remote_parent_span_id including:
traceId = remote_parent_span_id = Some(tracing::Span::current())
As well as:
traceId = Some(tracing::Span::current())
remote_parent_span_id = ~someParentRequestIdGeneratedUpstream~
I know that the current span is not disabled from trying:
let span = tracing::Span::current();
if span.is_disabled() {
println!("CURRENT SPAN DISABELED");
}
So this leads me to think that the issue is coming from not having the subscriber set properly. I am trying to set the subscriber in an init function which is called before this function which looks like this:
let subscriber = tracing_subscriber::registry() // provide underlying span data store
.with(
tracing_subscriber::fmt::layer()
.json()
.with_span_events(FmtSpan::ACTIVE)
.event_format(stackdriver::StackDriverEventFormat::default())
.with_filter(tracing_subscriber::filter::dynamic_filter_fn(
move |m, c| filter_layer.enabled(m, c.to_owned()),
)),
);
let _ = tracing::subscriber::set_global_default(subscriber)
.map_err(|_err| eprintln!("Unable to set global default subscriber"));
Would anyone be willing to provide me with an example of how to use this library? Or can anyone see what I'm doing wrong here? I have tried everything I can think of.
tracing-distributed has a test which demonstrates how to create and use TelemetryLayer.
I made a demo based on it. In this demo, NoEnabledSpan may be caused by missing #[instrument], which creates a Span for function foo. Hope this will help you find the actual cause.
Also tracing-honeycomb is a great use case for tracing-distributed, better check it out.
use std::sync::{Arc, Mutex};
use tracing::{Id, info};
use tracing::instrument;
use tracing_distributed::{Event, Span, Telemetry, TelemetryLayer};
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::registry;
#[derive(Default, Debug)]
pub struct BlackholeVisitor;
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub struct TraceId(pub(crate) u128);
type SpanId = tracing::Id;
impl tracing::field::Visit for BlackholeVisitor {
fn record_debug(&mut self, _: &tracing::field::Field, _: &dyn std::fmt::Debug) {}
}
/// Mock telemetry capability
pub struct TestTelemetry {
spans: Arc<Mutex<Vec<Span<BlackholeVisitor, SpanId, TraceId>>>>,
events: Arc<Mutex<Vec<Event<BlackholeVisitor, SpanId, TraceId>>>>,
}
impl TestTelemetry {
pub fn new(
spans: Arc<Mutex<Vec<Span<BlackholeVisitor, SpanId, TraceId>>>>,
events: Arc<Mutex<Vec<Event<BlackholeVisitor, SpanId, TraceId>>>>,
) -> Self {
TestTelemetry { spans, events }
}
}
impl Telemetry for TestTelemetry {
type Visitor = BlackholeVisitor;
type TraceId = TraceId;
type SpanId = SpanId;
fn mk_visitor(&self) -> Self::Visitor {
BlackholeVisitor
}
fn report_span(&self, span: Span<BlackholeVisitor, SpanId, TraceId>) {
// succeed or die. failure is unrecoverable (mutex poisoned)
let mut spans = self.spans.lock().unwrap();
spans.push(span);
}
fn report_event(&self, event: Event<BlackholeVisitor, SpanId, TraceId>) {
// succeed or die. failure is unrecoverable (mutex poisoned)
let mut events = self.events.lock().unwrap();
events.push(event);
}
}
#[instrument]
fn foo() {
let trace = tracing_distributed::register_dist_tracing_root(TraceId(123), Option::<Id>::None);
println!("trace value: {:?}", trace);
info!("test");
}
fn main() {
let spans = Arc::new(Mutex::new(Vec::new()));
let events = Arc::new(Mutex::new(Vec::new()));
let cap = TestTelemetry::new(spans.clone(), events.clone());
let telemetry_layer = TelemetryLayer::new("test_svc_name", cap, |x| x);
let subscriber = registry::Registry::default()
.with(tracing_subscriber::fmt::Layer::default())
.with(telemetry_layer);
// dbg!(&subscriber);
tracing::subscriber::set_global_default(subscriber).expect("setting global default failed");
foo();
dbg!(&spans);
dbg!(&events);
}
crate versions:
tracing = "0.1.32"
tracing-distributed = "0.4.0"
tracing-subscriber = "0.3.10"

Chisel3: Vec indexWhere expected Bool, actual Any

In Chisel, I have a Vec of Bools coming into a module. I would like to know the index of the first False which occurs.
To obtain this, I tried to use the following:
val faultIndex = Wire(UInt)
faultIndex := comparison.indexWhere(x:Bool => x === false.B)
When I put this in, an error was highlighted:
Unspecified value parameters: from: Int
Type mismatch, expected Bool => Bool, actual: Bool => Any
Type mismatch, expected Bool => Boolean, actual: Bool => Any
Cannot resolve symbol x
Cannot resolve symbol x
What is the proper way to use this function?
There are 2 minor syntax issues here:
val faultIndex = Wire(UInt())
Note the () after UInt. You can think about this as constructing a fresh type object rather than pointing to the static object called UInt.
There are a few ways to express the indexWhere:
faultIndex := comparison.indexWhere((x: Bool) => x === false.B) // Note parentheses
// or
faultIndex := comparison.indexWhere(x => x === false.B) // Type is inferred
// or
faultIndex := comparison.indexWhere(_ === false.B) // underscore shorthand
// alternatively
faultIndex := comparison.indexWhere(x => !x) // !x is equivalent to x === false.B
// or
faultIndex := comparison.indexWhere(!_) // More underscore shorthand
Executable example: https://scastie.scala-lang.org/uHCX5wxgSzu6wXqa9OJdRA

How to dynamically build function calls with different numbers of arguments in Rust?

How do I take a vector of function argument AST variants, extract the values, and use them to instantiate a function call?
I am writing an interpreter that evaluates certain expressions. Some of the expressions are function calls. I am having a hard time figuring out how to translate the function calls AST to the actual call. The AST gives me the function name and a vector of arguments. I can lookup the function pointer to call from the name using a map, but passing the arguments to the function pointer is problem.
Rust does not have a splat operator (argument expansion). I could pass them as a tuple and use destructuring of the arguments, but I can't figure out how to convert the vector of AST argument enum variants to a tuple of the concrete types.
I can't simply map or loop over the AST arguments to extract the values and produce a tuple.
I can use nested tuples to build a heterogenous list incrementally:
fn prepend<I,T>(i: I, t: T) -> (I,T) { (i, t) }
fn foo() {
let x = ();
let x = prepend(1, x);
let x = prepend(2.0, x);
let x = prepend(true, x);
}
But that only works because x gets shadowed and the new binding has a different type. This won't work:
fn foo() {
let mut x = ();
x = prepend(1, x);
x = prepend(2.0, x);
x = prepend(true, x);
}
Any ideas?
You don't. Rust is a statically typed language and you are attempting to do non-statically-determinable actions.
Instead, all of your functions need to take in a collection of arguments, verify that there is the right number of arguments (and type, if appropriate to your interpreter), then call the appropriate Rust function with a fixed number of arguments:
// All of the panicking can be replaced by proper error handling.
enum Arg {
Bool(bool),
Int(i32),
}
impl Arg {
fn into_bool(self) -> bool {
match self {
Arg::Bool(b) => b,
_ => panic!("Not a bool"),
}
}
fn into_int(self) -> i32 {
match self {
Arg::Int(i) => i,
_ => panic!("Not an int"),
}
}
}
fn some_fn_wrapper(mut args: Vec<Arg>) {
assert_eq!(args.len(), 3);
let c = args.pop().unwrap();
let b = args.pop().unwrap();
let a = args.pop().unwrap();
some_fn(a.into_bool(), b.into_int(), c.into_bool())
}
fn some_fn(_a: bool, _b: i32, _c: bool) {}
All of this will happen at runtime, as you want to create a highly dynamic language.
See also:
How do I pass each element of a slice as a separate argument to a variadic C function?
How to pass a dynamic amount of typed arguments to a function?
Calling a function only known at runtime
How can I create a function with a variable number of arguments?
Is Reflection possible in Rust, and if so how can I invoke an unknown function with some arguments?

Can I have an anonymous function that isn't typed as a closure in Rust?

I'm using 1.6.0 (stable), but any future/nightly feature that enables this or that I can watch/track is cool too.
what I'd like in theory (simplified for brevity):
let a:fn(&lib_plotMote::mask::Mask) -> bool = {fn(_)->true};
the closest I've gotten:
let a:fn(&lib_plotMote::mask::Mask) -> bool = { fn anon(_:&Mask)->bool{true}; anon };
No.
Closures are the "anonymous function" feature of Rust.
That said, you can slightly reduce the redundancy in what you have:
let a: fn(_) -> _ = { fn anon(_: &Mask) -> bool { true }; anon };