How to write a function (or a macro) to create a Vec and a reference to it? - macros

So I have something like this:
let v = vec![...];
let s = Data { vec: &v, ... };
Perhaps this is misguided, but the idea is that many data structures could share the same vector. But for the case where I don't want to share, it would be convenient to have something like this:
let (v, s) = make_data(...);
Apparently, unlike the first example, there is no way to connect the lifetime of v and s (correct me if I'm wrong). Anyway, I understand the borrow checker rejects this. So I end up doing:
let v = vec![];
let s = make_data(&v, ...);
Now, perhaps, I could make one of those work:
let (v, s) = make_data!(...);
let s = make_data!(v, ...);
let s = make_data!(...);
The problem here is that thse macros would expand to something like { let v = vec![]; ... } and v's destructor will be run in the end of this block, but what I really want is to have it expand to something like the first example.
Now, I can make this work:
make_data!(v, s, ...);
But it's odd. Is there any other way to solve this?

Rust allows you to define multiple variables with the same name in the same block.
let a = vec![...];
let a = Data { vec: &a, ... };
On the second line, the new a is not in scope yet, so you can still refer to the previous definition of a. However, on the following statements, you can no longer refer to the original a definition, since the second definition shadows the first one; nevertheless, the Vec remains alive until the end of the block, as usual.
You can take advantage of this in your macro by only taking a single identifier and using it for both the Vec and the slice.

Related

PureScript - Simple Multiline Computation

Consider the following JavaScript function, which performs a computation over several lines to clearly indicate the programmer's intent:
function computation(first, second) {
const a = first * first;
const b = second - 4;
const c = a + b;
return c;
}
computation(12, 3)
//143
computation(-3, 2.6)
//7.6
I have tried using do notation to solve this with PureScript but I seem to be just short of understanding some key concept. The do notation examples in the documentation only covers do notation when the value being bound is an array (https://book.purescript.org/chapter4.html#do-notation), but in my example I would like the values to be simple values of the Int or Number type.
While it is possible to perform this computation in one line, it makes the code harder to debug and does not scale to many operations.
How would the computation method be written correctly in PureScript so that...
If computation involved 1000 intermediate steps, instead of 3, the code would not suffer from excessive indenting but would be as readable as possible
Each step of the computation is on its own line, so that, for example, the code could be reviewed line by line by a supervisor, etc., for quality
You don't need the do notation. The do notation is intended for computations happening in a monad, whereas your computation is naked.
To define some intermediate values before returning result, use the let .. in construct:
computation first second =
let a = first * first
b = second - 4
c = a + b
in c
But if you really want to use do, you can do that as well: it also supports naked computations just to give you some choice. The difference is that within a do you can have multiple lets on the same level (and they work the same as one let with multiple definitions) and you don't need an in:
computation first second = do
let a = first * first -- first let
b = second - 4
let c = a + b -- second let
c -- no in

How to create a struct or type from a dictionary in Julia?

I have imported a bunch of data from a .mat file (MATLAB format) and they come as dictionarys, but it's kind of anoying using them, so I wanted to pass it for a struct. I know I can do this:
using MAT
struct model
trans
means
vars
end
vars = matread("data.mat")
hmm1=model(vars["hmm1"]["trans"],vars["hmm1"]["means"],vars["hmm1"]["vars"])
Is there a way to do this without typing every key of the dictionay?
There's probably no way to avoid directly accessing the relevant keys of your dictionary. However, you can simplify your life a little by making a custom Model constructor that takes in a Dict:
using MAT
struct Model
trans
means
vars
end
function Model(d::Dict)
h = d["hmm1"]
Model(h["trans"], h["means"], h["vars"])
end
d = matread("data.mat")
Model(d)
If you're only worried about the dot-access syntax à la hmm1.means, you could instead use a NamedTuple:
julia> vars = Dict("hmm1"=>Dict("trans"=>1, "means"=>2, "vars"=>3)) ;
julia> hmm1 = (; (Symbol(k) => v for (k,v) in vars["hmm1"])...)
(trans = 1, vars = 3, means = 2)
julia> hmm1.means
2
(Taken and adapted from Julia discourse: How to make a named tuple from a dictionary?.)

Implementing the map function for a Pony array

I have been playing with Pony arrays to understand Pony better, and wanted to write the map function for any arrays.
I am talking about something like the standard map function most languages have nowadays for converting elements of collections, as in Clojure:
(map #(+ 1 %) [1 2 3]) ; => [2 3 4]
But I want it to actually modify the given array, not return a new one.
My current attempt so far runs into many errors due to capabilities:
// array is "iso" so I can give it to another actor and change it
let my_array: Array[U64] iso = [1; 2; 3; 4]
// other actor tries to recover arrays as "box" just to call pairs() on it
let a = recover box my_array end // ERROR: can't recover to this capability
for (i, item) in a.pairs() do
// TODO set item at i to some other mapped value
try my_array.update(i, fun(item))? end
end
Anyone knows how this can be done
Alright, took me a while, but I was able to get things working.
Here's my basic understanding of what's going on (please correct me if I'm wrong)!
The first step was to understand that we need to use aliases to change the capabilities of a variable in Pony.
So, in order to make an iso variable useable as a box, one must alias it by basically, consuming it into another variable:
let a: Array[U64] ref = consume array // array is "iso"
for (i, item) in a.pairs() do
try a.update(i, item + n)? end
end
This works!!
One more problem I had was that I couldn't do much with the resulting Array[U64] ref. Can't pass it to anyone, for example.
So I wrapped the whole thing into a recover block in order to end up with the same array, but as a val (immutable reference to the array) which is more useful as I can send it to other actors:
let result = recover val
let a: Array[U64] ref = consume array
for (i, item) in a.pairs() do
try a.update(i, item + n)? end
end
a
end
Now I can send result to anyone!

Are Scala closures as flexible as C++ lambdas?

I know the question seems a bit heretical. Indeed, having much appreciated lambdas in C++11, I was quite thrilled to learn a language which was built to support them from the beginning rather than as a contrived addition.
However, I cannot figure out how to do with Scala all I can do with C++11 lambdas.
Suppose I want to make a function which adds to a number passed as a parameter some value contained in a variable a. In C++, I can do both
int a = 5;
auto lambdaVal = [ a](int par) { return par + a; };
auto lambdaRef = [&a](int par) { return par + a; };
Now, if I change a, the second version will change its behavior; but the first will keep adding 5.
In Scala, if I do this
var a = 5
val lambdaOnly = (par:Int) => par + a
I essentially get the lambdaRef model: changing a will immediately change what the function does.
(which seems somewhat specious to me given that this time a isn't even mentioned in the declaration of the lambda, only in its code. But let it be)
Am I missing the way to obtain lambdaVal? Or do I have to first copy a to a val to be free to modify it afterwards without side effects?
The a in the function definition refers the variable a. If you want to use the current value of a when the lambda has been created, you have to copy the value like this:
val lambdaConst = {
val aNow = a
(par:Int) => par + aNow
}

1-line try/catch equivalent in MATLAB

I have a situation in MATLAB where I want to try to assign a struct field into a new variable, like this:
swimming = fish.carp;
BUT the field carp may or may not be defined. Is there a way to specify a default value in case carp is not a valid field? For example, in Perl I would write
my $swimming = $fish{carp} or my $swimming = 0;
where 0 is the default value and or specifies the action to be performed if the assignment fails. Seems like something similar should exist in MATLAB, but I can't seem to find any documentation of it. For the sake of code readability I'd rather not use an if statement or a try/catch block, if I can help it.
You can make your own function to handle this and keep the code rather clear. Something like:
swimming = get_struct(fish, 'carp', 0);
with
function v = get_struct(s, f, d)
if isfield(s, f)
v = s.(f); % Struct value
else
v = d; % Default value
end
Best,
From what I know, you can't do it in one line in MATLAB. MATLAB logical constructs require explicit if/else statements and can't do it in one line... like in Perl or Python.
What you can do is check to see if the fish structure contains the carp field. If it isn't, then you can set the default value to be 0.
Use isfield to help you do that. Therefore:
if isfield(fish, 'carp')
swimming = fish.carp;
else
swimming = 0;
end
Also, as what Ratbert said, you can put it into one line with commas... but again, you still need that if/else construct:
if isfield(fish,'carp'), swimming = fish.carp; else, swimming = 0;
Another possible workaround is to declare a custom function yourself that takes in a structure and a field, and allow it to return the value at the field, or 0.
function [out] = get_field(S, field)
if isfield(S, field)
out = S.(field);
else
out = 0;
end
Then, you can do this:
swimming = get_field(fish, 'carp');
swimming will either by 0, or fish.carp. This way, it doesn't sacrifice code readability, but you'll need to create a custom function to do what you want.
If you don't like to define a custom function in a separate function file - which is certainly a good option - you can define two anonymous functions at the beginning of your script instead.
helper = {#(s,f) 0, #(s,f) s.(f)}
getfieldOrDefault = #(s,f) helper{ isfield(s,f) + 1 }(s,f)
With the definition
fish.carp = 42
and the function calls
a = getfieldOrDefault(fish,'carp')
b = getfieldOrDefault(fish,'codfish')
you get for the first one
a = 42
and the previous defined default value for the second case
b = 0