A chaining with expression

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

@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.

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

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

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

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

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

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