Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QOL Proposal: use(xxx) statement to reduce repeating element #1098

Closed
bheads opened this issue Jun 11, 2018 · 3 comments
Closed

QOL Proposal: use(xxx) statement to reduce repeating element #1098

bheads opened this issue Jun 11, 2018 · 3 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@bheads
Copy link

bheads commented Jun 11, 2018

I propose zig uses the use statement as a way to reduce repeating code in a given block.
idea taken from D with statement but would want to support a reduced usage set. The look up rule works as such, it first tries to look up the symbol in the use block, if that fails it follows the normal scope look up rules.

Example:

const A = struct {  i: i32 };

fn hammertime(a: *A, b: i32) void {
    a.i = b;  // normal look up, OK
    use(a) { // use in a block example
            a.i = b;  // first looks up a. in a, Fails, looks up a in scope Fails, looks up in outer scope OK
            i = b; // looks up i in a OK
    }
   a = b; // normal look up, ERROR
}

Example of possible use on struct function, lets you avoid typing self.xxxx for everything.

const Foo = struct {
    a: f64,
    b: i32,

   pub fn foo1(use self: *Foo, x: i32) void {   b = x*2; } // in the arguments list
   pub fn foo2(self: *Foo, x: i32)  void use(self) {   b = x*2; } // on the function block
   pub fn foo3(self: *Foo, x: i32)  void  { use(self) {   b = x*2; }} // in its own block
};

Can be used on enum types:

enum SOME_LONG_ENUM_NAME_MAYBE_IN_A_NAME_SPACE {
    Ok,
    NotOk,
    Tufo,
};

// later on
var x = switch(on_enum_var) use(SOME_LONG_ENUM_NAME_MAYBE_IN_A_NAME_SPACE) {
    OK => 1,
    NoOk => -1,
    Tofu => 0
};

I would think we would not want it allowed on optional? or error! types.
It would be a nice to have on function signatures like foo1 or foo2, but not necessary.
It isn't difficult to support nesting use blocks, but I found in D that it makes the code harder to read.

PROS:

  • its DRY
  • function calls look more like a method (also could be a con :) )
  • makes switching on enums nicer

CONS:

  • More to remember
  • Can be miss/over used
@phase
Copy link
Contributor

phase commented Jun 11, 2018

Kotlin also provides with but it implements it in userland.

I've been writing Kotlin code for years now, and I've never used with. Adding another control flow structure for something that isn't needed clutters up the language.

@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Jun 11, 2018
@andrewrk andrewrk added this to the 0.4.0 milestone Jun 11, 2018
@PavelVozenilek
Copy link

PavelVozenilek commented Jun 12, 2018

I'd once proposed something vaguely similar in #120. Here's another take.

The problem: people invent long names and use them over and over, making code reading hard.

some_very_very_long_name.x = ...
some_very_very_long_name.y = ...
some_very_very_long_name.z = ...

Possible solution, inspired by old typographic technique:

some_very_very_long_name.x = ...
                        .y = ... 
                        .z = ...

How does it work? Long name can omitted (replaced by spaces), if it happens on the same place at the next line. The parser is smart enough to detect this pattern and "correct" the code, checking for possible ambiguities.

It does not require new keyword, it is natural and used in practice, it improves readability.

Those with/use tricks are un-natural, prone to confusion.

Inference of fully qualified name in switch should be automatic, I am surprised it isn't.

@Hejsil
Copy link
Contributor

Hejsil commented Jun 15, 2018

I question that this actually solves anything you can't already do. What is the benefit of:

use(a.b.c.d.e.f) {
    g = 2;
    h = 4;
}

compared to:

{
    const f = &a.b.c.d.e.f;
    f.g = 2;
    f.h = 4;
}

@andrewrk andrewrk modified the milestones: 0.4.0, 0.5.0 Sep 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

5 participants