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

Suggestion: Use for_ macro instead of manual while loops #17

Open
Boscop opened this issue Dec 15, 2020 · 0 comments
Open

Suggestion: Use for_ macro instead of manual while loops #17

Boscop opened this issue Dec 15, 2020 · 0 comments

Comments

@Boscop
Copy link

Boscop commented Dec 15, 2020

Suggestion: Use this for_ macro instead of manual while loops to make the intention clearer:

pub macro for_($start:expr, $end:expr, $(step: $step:expr,)? $($label:lifetime:)? |$var:pat| $body:block) {
	{
		let _step = if false { $start } else { 1 as _ }; // type inference for default step
		$(
			let _step = $step; // custom step
		)?
		let mut i = $start;
		$($label:)? while i < $end {
			let $var = i;
			i += _step; // before body, to make `continue` work
			$body;
		}
	}
}

You can use it like:

fn ray_march(ro: Vec3, rd: Vec3) -> f32 {
	let mut dist_from_origin = 0.;

	for_!(0, MAX_STEPS, |_| {
		let here = ro + rd * dist_from_origin;
		let dist_from_here = scene_dist(here);
		dist_from_origin += dist_from_here;
		if dist_from_origin > MAX_DIST || dist_from_here < SURF_DIST {
			break;
		}
	});

	dist_from_origin
}

It also works for floats and supports a custom step and label arg, e.g.:

fn ray_march(ro: Vec3, rd: Vec3) -> f32 {
	let mut dist_from_origin = 0.;

	for_!(0., MAX_STEPS as f32, step: 1., 'for_: |_| {
		let here = ro + rd * dist_from_origin;
		let dist_from_here = scene_dist(here);
		dist_from_origin += dist_from_here;
		if dist_from_origin > MAX_DIST || dist_from_here < SURF_DIST {
			break 'for_;
		}
	});

	dist_from_origin
}

I think it makes the purpose clearer (no need to declare an extra variable just for looping), it makes looping "automatic" (no need to remember to put i += 1; at the end) and reduces the number of mutable vars, thus making it easier to reason about the code / makes the purpose clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant