A chaining with expression

#1

For instance, MoonScript supports a with expression.

with Person!
  .name = 'MoonScript'
  \say_name!

A with block could be the best option for Rust’s case due to commas.

// Performs field-assignments and calls
// into a anonymous value.
with TextField::autosized("! Init") {
    .stroke(n),
    .height = 69,
}

Useful when there’re non-builder methods and/or field assignments. P.S., not really worth since Rust is expression-based already, thinking well…

pass({
    let mut tf = TextField::auto_sized("! Init"));
    tf.stroke(n);
    tf.height = 69;
    tf
});
2 Likes
#2

@hydroper Could you say more about what this syntax would be used for? Perhaps a comparison between current rust and the proposed syntax might help illustrate the concept better.

#3

Any advantage the with construct would provide over the code bellow?


fn main(){
    let mut val=with(Rectangle::default(),|a|{
        a.x=100;
        a.w=200;
    });

    with_mut(&mut val,|a|{
        a.h=a.w;
        a.w*=200;
    });

    assert_eq!(
        val,
        Rectangle{
            x:100,
            y:0,
            w:40000,
            h:200,
        }
    );
    
}

pub fn with<T>(mut this:T,f:impl FnOnce(&mut T))->T{
    f(&mut this);
    this
}

pub fn with_mut<T,U>(this:&mut T,f:impl FnOnce(&mut T)->U)->U{
    f(this)
}

pub fn with_ref<T,U>(this:&T,f:impl FnOnce(&T)->U)->U{
    f(this)
}

#[derive(Debug,Default,PartialEq)]
struct Rectangle{
    x:u32,
    y:u32,
    w:u32,
    h:u32,
}


1 Like
#4

with exists in some variations of Pascal and JavaScript. IDK about Pascal, but in JavaScript it’s considered an antipattern (and, in my opinion, rightfully so). The reason: it prevents local reasoning by introducing implicit context into the source (which needs to manifest as statefulness in the reader’s mind).

From what I can tell, your examples could be solved with the struct update syntax, although I’m not sure – you didn’t really specify very clearly what exactly your variant of “with” is supposed do.

1 Like
#5

Here is a link to the Moonscript reference on with statements,this is the language in the example from the first comment.

I am not convinced that Rust needs with statements since they can be emulated very easily,both with the code in my previous comment,and using the tap crate

#6

That’s true. Also, it’s not hard to use block expressions to do the same thing anonymously, i.e., invite({ let p = Person::new(); p.rant = 300 * km; p.purple = .333; p });

1 Like
#7

In many cases lambdas are less ergonomic than blocks. One of the biggest issues is that early return on error becomes much harder.

That said, I don’t see many benefits of the proposed with expression over just using a variable and a block.

2 Likes
closed #8

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.