Explicitly named return values? - return-value

In Go (and G++?), the following is a common idiom:
func sqr(x int) (n int, err error) {
n = x * x
err = nil
return
}
The (n int, err error) explicitly enumerates the name and type of the return values. There are in my opinion lots of advantages to this, and I like it.
In Perl 6, we can:
my sub sqr (Int:D $x) returns Int:D {
$x ** 2;
}
The return is implicit, which makes me kind of uncomfortable (we could make it explicit with return), but you may notice the return type is specified (as is the fact it's Defined).
Unsurprisingly, there's no obvious way to return a value explicitly by name, but I'm curious, since Perl (especially 6) is extensively modifiable in every way, if there's a way to implement this.1
1 However hacky it may be, but too hacky and I'd avoid using it for "real" things.

If all else fails, you can always write your own slang.
However, here are two less involved approaches I came up with, the first one using a dynamic variable of fixed name, the second one using an rw parameter of user-defined name:
multi sub trait_mod:<is>(Routine:D \r, :$dynrv!) {
r.wrap(-> | { my $*rv; callsame; $*rv })
}
multi sub trait_mod:<is>(Routine:D \r, :$pararv!) {
r.wrap(-> |c { my $rv; callwith(|c, $rv); $rv })
}
sub double($x) is dynrv {
$*rv = $x * 2;
return 666; # discarded
}
sub triple($x, $y is rw) is pararv {
$y = $x * 3;
return 666; # discarded
}
say double 42;
say triple 42;
Note that this only supports a single return value, though I have some ideas how multiple ones could be made to work...
edit: Eg this way:
multi sub trait_mod:<is>(Routine:D \r, :#dynrv!) {
r.wrap(-> | {
my #rv = Nil xx #dynrv;
my $*rv = Map.new(#dynrv Z=> #rv);
callsame;
#dynrv > 1 ?? #rv !! #rv[0];
})
}
multi sub trait_mod:<is>(Routine:D \r, Int :$pararv!) {
r.wrap(-> |c {
my #rv = Nil xx $pararv;
callwith(|c, |#rv);
$pararv > 1 ?? #rv !! #rv[0];
})
}
sub divmod($a, $b) is dynrv<d m> {
$*rv<d> = $a div $b;
$*rv<m> = $a mod $b;
}
sub plusmin($a, $b, $p is rw, $m is rw) is pararv(2) {
$p = $a + $b;
$m = $a - $b;
}
say divmod 14, 3;
say plusmin 14, 3;

While slangs can be used to get exactly what you want, I believe they're the wrong size solution to this problem. Firstly, cat's Go example is returning error information as well as an (Int). I'd suggest the PerlĀ 6 way for that is to simply return a Fail object using &fail which the caller can test for using .defined or the // operator;
if $something_wrong {
return fail "Dang! Even the squaring function isn't working today."
}
else {
return $x ** 2
}
I know this doesn't document the dual return values as requested, but do you want to use an explicit variable for exceptional out-of-band data? What if it wasn't error data but other information?
Let's assume we want to return an (Int) with an Easter-egg message. In this case, as the extra data is a different type, (Str), we can run-time mixin a role with a .Str method that returns the message if the return value is used in string context.
return $x * $x but "Suprise! Bet you weren't expecting that!"
Alternatively, if the extra data is of the same type we can explicitly mixin an anonymous role. Let's say we want to return an (Int) with a .size property;
return $x but role { has $.size = calculate_size() }
Finally, you can document your return type explicitly by declaring the role and then using a subset to define your own (Int) type that demands the role;
role Size { has UInt:D $.size = 0 }
subset MyInt of Int where Size;
sub sqr(Int:D $x, UInt:D :$size = 12) returns MyInt:D {
return $x * $x but Size($size)
}
my $square5 = sqr(5);
say "5 squared is $square5 with size $square5.size()."
# prints: 5 squared is 25 with size 12.
Details are in S14 and S12 - Anonymous mixin roles

Related

Scoping problem when trying to assign vector of strings in DOORS DXL

I want to be able to send a selector value to a function, and have the function create a string array of values for use in subsequent operations. The problem I'm running into is that the DXL rules don't "see" a declared variable inside an "if {} " block, even when I've guaranteed that in all cases my string array would get initialized. Example:
string tryme( int thechoice){
string outit
if (thechoice == 1){
outit = "you chose one"
}
else if (thechoice ==2){
outit = "you chose two"
}
else { outit = "bad choice"}
// do a bunch of stuff with "outit" values
return outit
}
// that works, but this doesn't
string trymore( int thechoice){
if (thechoice == 1){
string outit[] = {"you chose one","and one"}
}
else if (thechoice ==2){
string outit[] = {"you chose two","and two", "and three"}
}
else { string outit = "bad choice"}
// do a bunch of stuff with "outit" values
return outit
}
I could use dynamic arrays, thus allowing me to declare the array prior to the "if{}", but then I'm forced to write loops inside each case, using put to load the array.
I know DXL has a limited capability, but if anyone knows a better approach please let me know.
additional constraint
In the end, I want to be able to call the function repeatedly from a loop, changing "thechoice" each time. That is why I can't declare the string array in the parent script, because once declared ( string outit[] = {'a','b'} ) , DXL cannot delete or resize the array.
It's easier than that, tho' a bit counterintuitive . I need to declare a string vector with out assigning anything, then generate a temporary string vector, then set my desired variable equal to the temp. Like this:
string trymore( int thechoice){
string outit[]
string whatdone
if (thechoice == 1){
string foo[] = {"you chose one","and one"}
whatdone = "did one"
outit = foo
}
else if (thechoice ==2){
string foo[] = {"you chose two","and two", "and three"}
whatdone = "did two"
outit = foo
}
else {
string foo[] = "bad choice"
whatdone = "nogood"
outit = foo
}
print "outit " outit[0] "\n"
// do a bunch of stuff with "outit" values
return whatdone
}
DXL will not allow you to assign the values to outit , crying "length mismatch", but will allow you to set outit equal to the fully defined foo

How to return a variable in a function in kotlin

I created a function that recieves input and compare it to a list, when find a match it return the match, in this case this match is the attribute of a class that i created.
I understand that the problem is with the return statement, so in the beginning of the function I declare the return as "Any", further more than that I'm kinda lost.
The error is this: A 'return' expression required in a function with a block body ('{...}')
class Class1(var self: String)
var test_class = Class1("")
fun giver(){
test_class.self = "Anything"
}
class Funciones(){
fun match_finder(texto: String): Any{
var lista = listOf<String>(test_class.self)
var lista_de_listas = listOf<String>("test_class.self")
var count = -1
for (i in lista_de_listas){
count = count + 1
if (texto == i){
lista_de_listas = lista
var variable = lista_de_listas[count]
return variable
}
}
}
}
fun main(){
giver()
var x = "test_class.self"
var funcion = Funciones()
var y = funcion.match_finder(x)
println(y)
}
To explain you what the problem is, let's consider the following code:
class MyClass {
fun doSomething(): String {
val numbers = listOf(1, 2, 3)
for (number in numbers) {
if (number % 2 == 0) {
return "There is at least one even number in the list"
}
}
}
}
If you try compiling it you'll get the same error message as in your question: A 'return' expression required in a function with a block body ('{...}'). Why is that?
Well, we defined a function doSomething returning a String (it could be any other type) but we're returning a result only if the list of numbers contains at least one even number. What should it return if there's no even number? The compiler doesn't know that (how could it know?), so it prompts us that message. We can fix the code by returning a value or by throwing an exception:
class MyClass {
fun doSomething(): String {
val numbers = listOf(1, 2, 3)
for (number in numbers) {
if (number % 2 == 0) {
return "There is at least one even number in the list"
}
}
// return something if the list doesn't contain any even number
return "There is no even number in the list"
}
}
The same logic applies to your original code: what should the function return if there is no i such that texto == i?
Please also note that the solution you proposed may be syntactically correct - meaning it compiles correctly - but will probably do something unexpected. The for loop is useless since the if/else statement will always cause the function to return during the first iteration, so the value "There is no match" could be returned even if a match actually exists later in the list.
I searched online, if someone has the same problem, the correct code is as follows:
class Funciones(){
fun match_finder(texto: String): Any{
var lista = listOf<String>(test_class.self)
var lista_de_listas = listOf<String>("test_class.self")
var count = -1
var variable = " "
for (i in lista_de_listas){
count = count + 1
if (texto == i){
lista_de_listas = lista
var variable = lista_de_listas[count]
return variable
} else {
return "There is no match"
}
}
return variable
}
}

Optional function arguments with no default value possible?

In Chapel, we can set the default value of function formal arguments easily, for example,
proc test( a = 1, b = 2.0, c = "hi" ) {
...
}
and call the function by using keywords also:
test( 10 ); // a = 10, b = 2.0, c = "hi"
test( b = 3.14 ); // a = 1, b = 3.14, c = "hi"
test( c = "yo" ); // a = 1, b = 2.0, c = "yo"
Here, I am wondering if it is possible to define a keyword argument that does not require a predefined default value. More specifically, I would like to write a function that can optionally receive an array depending on cases (e.g., to save intermediate data). Here, the only requirement is that I can check whether the actual argument is passed or not, and there is no need to give the default array value. I imagined something like
proc test( ..., optional d: [] real ) {
if present( d ) then ...;
}
or
proc test( ..., d: [] real = None ) {
if present( d ) then ...;
}
but was not able to find similar things. At the moment, my workaround is to give some dummy default value and check their properties to determine whether an actual argument is passed.
proc test( arr = empty2Dreal ) { ... } // where "empty2Dreal" is a pre-defined global array
or
proc test( arr = reshape( [0.0], {1..1,1..1} ) ) { ... } // some dummy array
}
However, I am wondering whether there might be a more elegant(?) or idiomatic(?) approach...
Edit
As suggested in the comment, it is also convenient to overload several functions to get different interfaces, but at some point I guess I need to pass some "dummy" object to the final (full-fledged) routine and ask the latter to see if the passed object is "dummy" or not... MWE is something like this:
const empty1Dint: [1..0] int;
proc test( x: real, arr: [] int )
{
writeln("test() with 2 args");
writeln(( x, arr ));
// here, I need to check whether the passed object is
// an actual array or not by some predefined rule
if arr.size > 0 then writeln("got a non-empty array");
}
proc test( x: real )
{
writeln("test() with 1 arg");
test( x = x, arr = empty1Dint );
}
var work = [1,2,3,4,5];
test( x = 1.0 );
writeln();
test( x = 1.0, arr = work );
which gives
test() with 1 arg
test() with 2 args
(1.0, )
test() with 2 args
(1.0, 1 2 3 4 5)
got a non-empty array
The corresponding default-value version is
const empty1Dint: [1..0] int;
proc test( x: real, arr: [] int = empty1Dint )
{
writeln("test() with 2 args");
writeln(( x, arr ));
if arr.size > 0 then writeln("got a non-empty array");
}
var work = [1,2,3,4,5];
test( x = 1.0 );
writeln();
test( x = 1.0, arr = work );
which gives
test() with 2 args
(1.0, )
test() with 2 args
(1.0, 1 2 3 4 5)
got a non-empty array
Although the above approach works for arrays, the rule needs to change depending on the type of objects used. So, I was wondering if there is some systematic way, e.g., to pass a "null pointer" or some unique global object to tell the final routine about the presence of the actual data. (But, as noted above, the above approach works for arrays).
Edit 2
Another approach may be simply to pass an additional flag for using the passed array (then there is no need to think much about the nature of the default object, so may be overall simpler...)
const empty1Dint: [1..0] int;
proc test( x: real, arr: [] int = empty1Dint, use_arr = false )
{
writeln( "x= ", x );
if use_arr {
writeln("working with the passed array...");
for i in 1..arr.size do arr[ i ] = i * 10;
}
}
test( x = 1.0 );
writeln();
var work: [1..5] int;
test( x = 2.0, arr = work, use_arr = true );
writeln( "work = ", work );
Edit 3
Following Option 3 in the answer, here is a modified version of my code using _void and void:
proc test( x: real, arr: ?T = _void )
{
writeln( "\ntest():" );
writeln( "x = ", x );
writeln( "arr = ", arr );
writeln( "arr.type = ", arr.type:string );
writeln( "T = ", T:string );
if arr.type != void {
writeln( "doing some checks" );
assert( isArray( arr ) );
}
if arr.type != void {
writeln( "writing arr" );
for i in 1..arr.size do arr[ i ] = i * 10;
}
}
// no optional arg
test( x = 1.0 );
// use an optional arg
var work: [1..5] int;
test( x = 2.0, arr = work );
writeln( "\nmain> work = ", work );
Result:
test():
x = 1.0
arr =
arr.type = void
T = void
test():
x = 2.0
arr = 0 0 0 0 0
arr.type = [domain(1,int(64),false)] int(64)
T = [domain(1,int(64),false)] int(64)
doing some checks
writing arr
main> work = 10 20 30 40 50
This answer discusses 3 answers:
The strategy discussed in the edit of the question.
A strategy using a Box type
A strategy using a generic function with a void default value
My favorite of these options is Option 3.
Option 1
proc test( x: real, arr: [] int = empty1Dint, use_arr = false ) strategy described in the question is reasonable, if a little verbose. The main drawback here is that you'd need more overloads of test if you didn't want the call sites to have to pass use_arr=true or use_arr=false. Here is a simple program that does that:
proc test(optional, hasOptional:bool) {
writeln("in test");
writeln(" optional is ", optional);
if hasOptional == false then
writeln(" note: default was used for optional");
}
proc test(optional) {
test(optional, hasOptional=true);
}
proc test() {
var emptyArray:[1..0] int;
test(emptyArray, hasOptional=false);
}
test();
test([1, 2, 3]);
Option 2
Another alternative is to create a class to store the optional argument data, and pass nil by default.
class Box {
var contents;
}
proc makeArray() {
var A:[1..2] int;
return A;
}
proc emptyBox() {
var A:[1..0] int;
var ret: owned Box(A.type) = nil;
return ret;
}
proc test( optional=emptyBox() ) {
writeln("in test with optional=", optional);
}
test();
test(new owned Box(makeArray()));
Here the main tricky part is that the array type returned by makeArray() and emptyBox() have to match. It'd be possible to use a type alias to have them refer to the same array type, but how exactly that would fit in depends on your application. Another problem with this approach is that it causes the array to be copied in the process of passing such an argument. And, one has to think about where the Box will be destroyed. Is test to hang on to the array value (e.g. storing it in a data structure) or just going to use it temporarily? This is set by the type returned by emptyBox in my example.
It's probably reasonable for the standard library to gain such a Box type but it doesn't have one now.
Option 3
My favorite solution to this problem is a third strategy altogether.
Chapel includes a value of void type called _void. The key is the declaration proc test( optional:?t=_void ). Here test is a generic function - the syntax argument:?t indicates that the argument can have a varied type (which will be available as t within the function). This is necessary to get a generic argument that also has a default value (otherwise the argument will have only the type inferred from the default value).
If no optional argument is provided, it will instantiate with optional having type void. Which makes sense as a way to not pass something. Technically it's not the same as checking if the default value was provided, but I think a call site like test(optional=_void) is reasonably clear at communicating that the value of optional should be ignored (since it's void).
Anyway here is the code:
proc test( optional:?t=_void ) {
writeln("in test");
writeln(" optional is ", optional);
if optional.type == void then
writeln(" note: default was used for optional");
}
test();
test([1, 2, 3]);

Is there a way to count with macros?

I want to create a macro that prints "Hello" a specified number of times. It's used like:
many_greetings!(3); // expands to three `println!("Hello");` statements
The naive way to create that macro is:
macro_rules! many_greetings {
($times:expr) => {{
println!("Hello");
many_greetings!($times - 1);
}};
(0) => ();
}
However, this doesn't work because the compiler does not evaluate expressions; $times - 1 isn't calculated, but fed as a new expression into the macro.
While the ordinary macro system does not enable you to repeat the macro expansion many times, there is no problem with using a for loop in the macro:
macro_rules! many_greetings {
($times:expr) => {{
for _ in 0..$times {
println!("Hello");
}
}};
}
If you really need to repeat the macro, you have to look into procedural macros/compiler plugins (which as of 1.4 are unstable, and a bit harder to write).
Edit: There are probably better ways of implementing this, but I've spent long enough on this for today, so here goes. repeat!, a macro that actually duplicates a block of code a number of times:
main.rs
#![feature(plugin)]
#![plugin(repeat)]
fn main() {
let mut n = 0;
repeat!{ 4 {
println!("hello {}", n);
n += 1;
}};
}
lib.rs
#![feature(plugin_registrar, rustc_private)]
extern crate syntax;
extern crate rustc;
use syntax::codemap::Span;
use syntax::ast::TokenTree;
use syntax::ext::base::{ExtCtxt, MacResult, MacEager, DummyResult};
use rustc::plugin::Registry;
use syntax::util::small_vector::SmallVector;
use syntax::ast::Lit_;
use std::error::Error;
fn expand_repeat(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResult + 'static> {
let mut parser = cx.new_parser_from_tts(tts);
let times = match parser.parse_lit() {
Ok(lit) => match lit.node {
Lit_::LitInt(n, _) => n,
_ => {
cx.span_err(lit.span, "Expected literal integer");
return DummyResult::any(sp);
}
},
Err(e) => {
cx.span_err(sp, e.description());
return DummyResult::any(sp);
}
};
let res = parser.parse_block();
match res {
Ok(block) => {
let mut stmts = SmallVector::many(block.stmts.clone());
for _ in 1..times {
let rep_stmts = SmallVector::many(block.stmts.clone());
stmts.push_all(rep_stmts);
}
MacEager::stmts(stmts)
}
Err(e) => {
cx.span_err(sp, e.description());
DummyResult::any(sp)
}
}
}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_macro("repeat", expand_repeat);
}
added to Cargo.toml
[lib]
name = "repeat"
plugin = true
Note that if we really don't want to do looping, but expanding at compile-time, we have to do things like requiring literal numbers. After all, we are not able to evaluate variables and function calls that reference other parts of the program at compile time.
As the other answers already said: no, you can't count like this with declarative macros (macro_rules!).
But you can implement the many_greetings! example as a procedural macro. procedural macros were stabilized a while ago, so the definition works on stable. However, we can't yet expand macros into statements on stable -- that's what the #![feature(proc_macro_hygiene)] is for.
This looks like a lot of code, but most code is just error handling, so it's not that complicated!
examples/main.rs
#![feature(proc_macro_hygiene)]
use count_proc_macro::many_greetings;
fn main() {
many_greetings!(3);
}
Cargo.toml
[package]
name = "count-proc-macro"
version = "0.1.0"
authors = ["me"]
edition = "2018"
[lib]
proc-macro = true
[dependencies]
quote = "0.6"
src/lib.rs
extern crate proc_macro;
use std::iter;
use proc_macro::{Span, TokenStream, TokenTree};
use quote::{quote, quote_spanned};
/// Expands into multiple `println!("Hello");` statements. E.g.
/// `many_greetings!(3);` will expand into three `println`s.
#[proc_macro]
pub fn many_greetings(input: TokenStream) -> TokenStream {
let tokens = input.into_iter().collect::<Vec<_>>();
// Make sure at least one token is provided.
if tokens.is_empty() {
return err(Span::call_site(), "expected integer, found no input");
}
// Make sure we don't have too many tokens.
if tokens.len() > 1 {
return err(tokens[1].span(), "unexpected second token");
}
// Get the number from our token.
let count = match &tokens[0] {
TokenTree::Literal(lit) => {
// Unfortunately, `Literal` doesn't have nice methods right now, so
// the easiest way for us to get an integer out of it is to convert
// it into string and parse it again.
if let Ok(count) = lit.to_string().parse::<usize>() {
count
} else {
let msg = format!("expected unsigned integer, found `{}`", lit);
return err(lit.span(), msg);
}
}
other => {
let msg = format!("expected integer literal, found `{}`", other);
return err(other.span(), msg);
}
};
// Return multiple `println` statements.
iter::repeat(quote! { println!("Hello"); })
.map(TokenStream::from)
.take(count)
.collect()
}
/// Report an error with the given `span` and message.
fn err(span: Span, msg: impl Into<String>) -> TokenStream {
let msg = msg.into();
quote_spanned!(span.into()=> {
compile_error!(#msg);
}).into()
}
Running cargo run --example main prints three "Hello"s.
For those looking for a way to do this, there is also the seq_macro crate.
It is fairly easy to use and works out of the box with stable Rust.
use seq_macro::seq;
macro_rules! many_greetings {
($times:literal) => {
seq!{ N in 0..$times {
println!("Hello");
}}
};
}
fn main() {
many_greetings!(3);
many_greetings!(12);
}
As far as I know, no. The macro language is based on pattern matching and variable substitution, and only evaluates macros.
Now, you can implement counting with evaluation: it just is boring... see the playpen
macro_rules! many_greetings {
(3) => {{
println!("Hello");
many_greetings!(2);
}};
(2) => {{
println!("Hello");
many_greetings!(1);
}};
(1) => {{
println!("Hello");
many_greetings!(0);
}};
(0) => ();
}
Based on this, I am pretty sure one could invent a set of macro to "count" and invoke various operations at each step (with the count).

Closures over not yet defined variables in CoffeeScript

For the following code:
inc = -> value = (value ? 0) + 1
dec = -> value = (value ? 0) - 1
print = -> console.log value ? 0
How can you make this work properly, so inc and dec close upon value instead of creating separate function-local variables, in the way other than explicitly assigning something to value?
In plain Javascript, you would just declare var value at outer scope:
var value;
function inc() { value = (value || 0) + 1; };
function dec() { value = (value || 0) - 1; };
function print() { console.log(value || 0); };
What is CoffeeScript way for exactly the same thing?
In CoffeeScript, the way to introduce a local variable is to assign to the variable in the appropriate scope.
This is simply the way that CoffeeScript was defined and as such is similar to Python or Ruby, which do not require a "variable declaration", except CoffeeScript also allows forward access. A side-effect is that one cannot shadow a lexical variable.
Just as with the placement of var in JavaScript, where this assignment is done (as long as it is in the correct scope) does not affect the scope of the variable.
Given
x = undefined
f = -> x
// JS
var f, x;
x = void 0;
f = function() {
return x;
};
Given
f = -> x
x = undefined
// JS
var f, x;
f = function() {
return x;
};
x = void 0;