From c84c38544bc6e81f0b0482e4e82b6c95848c1a0c Mon Sep 17 00:00:00 2001
From: Akshay <nerdy@peppe.rs>
Date: Tue, 6 Apr 2021 14:54:54 +0530
Subject: apply clippy lints

---
 src/lisp/eval.rs    |  55 +++++++++---------
 src/lisp/expr.rs    |  46 +++++++++++----
 src/lisp/lex.rs     |  25 ++++-----
 src/lisp/number.rs  |   6 +-
 src/lisp/parse.rs   | 159 +++++++++++++++++++++++++---------------------------
 src/lisp/prelude.rs | 122 ++++++++++++++++++++--------------------
 6 files changed, 210 insertions(+), 203 deletions(-)

(limited to 'src/lisp')

diff --git a/src/lisp/eval.rs b/src/lisp/eval.rs
index 9276ef5..329b6ab 100644
--- a/src/lisp/eval.rs
+++ b/src/lisp/eval.rs
@@ -76,7 +76,7 @@ where
                                 self.eval(&LispExpr::List(f.body.clone()))
                             };
                             self.app.lisp_env.pop();
-                            return result;
+                            result
                         }
                     }
                     LispExpr::List(_) => {
@@ -108,7 +108,7 @@ where
                     error!("Unable to create global definition");
                     return Err(EvalError::BadForm.into());
                 }
-                return Ok(LispExpr::Unit);
+                Ok(LispExpr::Unit)
             }
             [LispExpr::List(shorthand), LispExpr::List(body)] => {
                 // (define (func arg) <body>) shorthand
@@ -130,12 +130,12 @@ where
 
                 let local_env = &mut self.app.lisp_env.last_mut();
                 if let Some(env) = local_env {
-                    env.insert(id.into(), value);
+                    env.insert(id, value);
                 } else {
                     error!("Unable to create global definition");
                     return Err(EvalError::BadForm.into());
                 }
-                return Ok(LispExpr::Unit);
+                Ok(LispExpr::Unit)
             }
             _ => {
                 error!("Invalid usage of `define`");
@@ -154,17 +154,16 @@ where
                 let value = self.eval(&expr)?;
                 let local_env = self.app.lisp_env.last_mut();
                 if let Some(env) = local_env {
-                    return env
-                        .insert(id.into(), value)
-                        .ok_or(EvalError::UnboundVariable(id.into()).into());
+                    env.insert(id.into(), value)
+                        .ok_or_else(|| EvalError::UnboundVariable(id.into()).into())
                 } else {
                     error!("Unable to set in global env!");
-                    return Err(EvalError::BadForm.into());
+                    Err(EvalError::BadForm.into())
                 }
             }
             _ => {
                 error!("Invalid usage of `set!`");
-                return Err(EvalError::BadForm.into());
+                Err(EvalError::BadForm.into())
             }
         }
     }
@@ -172,15 +171,15 @@ where
     pub fn eval_if(&mut self, args: &[LispExpr]) -> Result<LispExpr, LispError> {
         let arity = Arity::Exact(3);
         if !arity.check(args) {
-            return Err(arity.to_error());
+            Err(arity.to_error())
         } else {
             match args {
                 [predicate, then, else_] => {
                     let predicate = self.eval(&predicate)?;
                     if matches!(predicate, LispExpr::BoolLit(false)) {
-                        return self.eval(&else_);
+                        self.eval(&else_)
                     } else {
-                        return self.eval(&then);
+                        self.eval(&then)
                     }
                 }
                 _ => {
@@ -194,7 +193,7 @@ where
         let arity = Arity::Atleast(1);
         let valid_cond_stmt = |expr: &LispExpr| matches!(expr, LispExpr::List(v) if v.len() == 2);
         if !arity.check(args) {
-            return Err(arity.to_error());
+            Err(arity.to_error())
         } else {
             for cond_stmt in args {
                 if valid_cond_stmt(cond_stmt) {
@@ -211,7 +210,7 @@ where
                     return Err(EvalError::BadForm.into());
                 }
             }
-            return Ok(LispExpr::Unit);
+            Ok(LispExpr::Unit)
         }
     }
 
@@ -220,7 +219,7 @@ where
         let valid_binding_stmt =
             |expr: &LispExpr| matches!(expr, LispExpr::List(v) if v.len() == 2);
         if !arity.check(args) {
-            return Err(arity.to_error());
+            Err(arity.to_error())
         } else {
             let nested_env = Environment::new();
             self.app.lisp_env.push(nested_env);
@@ -247,11 +246,11 @@ where
                     }
                     let result = self.eval(&body);
                     self.app.lisp_env.pop();
-                    return result;
+                    result
                 }
                 _ => {
                     error!("bad `let` form");
-                    return Err(EvalError::BadForm.into());
+                    Err(EvalError::BadForm.into())
                 }
             }
         }
@@ -277,32 +276,28 @@ pub fn create_lambda(cdr: &[LispExpr]) -> Result<LispExpr, LispError> {
         return Err(arity.to_error());
     }
     match cdr {
-        [LispExpr::List(params), LispExpr::List(body)] if type_match!(params, (..) => LispExpr::Ident(_)) =>
-        {
-            return Ok(LispExpr::Function(LispFunction {
-                params: params
-                    .into_iter()
-                    .map(|p| p.unwrap_ident())
-                    .collect::<Vec<_>>(),
+        [LispExpr::List(params), LispExpr::List(body)] if type_match!(params, (..) => LispExpr::Ident(_)) => {
+            Ok(LispExpr::Function(LispFunction {
+                params: params.iter().map(|p| p.unwrap_ident()).collect::<Vec<_>>(),
                 body: body.clone(),
-            }));
+            }))
         }
         _ => {
             error!("Invalid usage of `lambda`");
-            return Err(EvalError::BadForm.into());
+            Err(EvalError::BadForm.into())
         }
     }
 }
 
 pub fn lookup(env_list: &[Environment], key: &str) -> Result<LispExpr, LispError> {
     if env_list.is_empty() {
-        return Err(EvalError::UnboundVariable(key.into()).into());
+        Err(EvalError::UnboundVariable(key.into()).into())
     } else {
         let local_env = env_list.last().unwrap();
         if let Some(val) = local_env.get(key) {
-            return Ok(val.clone());
+            Ok(val.clone())
         } else {
-            return lookup(&env_list[..env_list.len() - 1], key);
+            lookup(&env_list[..env_list.len() - 1], key)
         }
     }
 }
@@ -314,7 +309,7 @@ mod tests {
     use crate::lisp::{expr::LispExpr, lex::Lexer, number::LispNumber, parse::Parser};
 
     fn run(code: &str, app: &mut AppState) -> LispExpr {
-        let mut parser = Parser::new(Lexer::new(code, 0));
+        let mut parser = Parser::new(Lexer::new(code));
         let mut evaluator = Evaluator {
             app,
             context: Vec::new(),
diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs
index d2066e7..692f951 100644
--- a/src/lisp/expr.rs
+++ b/src/lisp/expr.rs
@@ -1,12 +1,18 @@
-use std::{cmp::PartialEq, convert::TryFrom, fmt};
+use std::{
+    cmp::PartialEq,
+    convert::{From, TryFrom},
+    fmt,
+};
 
 use crate::{
     app::AppState,
+    bitmap::Axis,
+    guide::Guide,
     lisp::{
         error::{EvalError, LispError},
         eval::lookup,
         number::LispNumber,
-        EnvList,
+        Environment,
     },
 };
 
@@ -113,7 +119,7 @@ impl LispExpr {
         }
     }
 
-    pub fn compare(&self, other: &Self, envs: &EnvList) -> Result<BoolLit, LispError> {
+    pub fn compare(&self, other: &Self, envs: &[Environment]) -> Result<BoolLit, LispError> {
         match (self, other) {
             (LispExpr::Unit, LispExpr::Unit) => Ok(true),
             (LispExpr::Number(s), LispExpr::Number(o)) => Ok(s == o),
@@ -121,8 +127,8 @@ impl LispExpr {
                 .iter()
                 .zip(o)
                 .all(|(a, b)| matches!(a.compare(b, envs), Ok(true)))),
-            (LispExpr::List(s), LispExpr::Unit) => Ok(s.len() == 0),
-            (LispExpr::Unit, LispExpr::List(s)) => Ok(s.len() == 0),
+            (LispExpr::List(s), LispExpr::Unit) => Ok(s.is_empty()),
+            (LispExpr::Unit, LispExpr::List(s)) => Ok(s.is_empty()),
             (LispExpr::StringLit(s), LispExpr::StringLit(o)) => Ok(s == o),
             (LispExpr::Char(s), LispExpr::Char(o)) => Ok(s == o),
             (LispExpr::BoolLit(s), LispExpr::BoolLit(o)) => Ok(s == o),
@@ -152,7 +158,7 @@ impl LispExpr {
     // have these be code gen'd somehow
     pub fn unwrap_number(&self) -> LispNumber {
         match &self {
-            LispExpr::Number(p) => p.clone(),
+            LispExpr::Number(p) => *p,
             _ => panic!("attempt to call `unwrap_number` on invalid type"),
         }
     }
@@ -200,10 +206,7 @@ impl LispExpr {
     }
 
     pub fn cast_bool(&self) -> bool {
-        match &self {
-            LispExpr::BoolLit(false) => false,
-            _ => true,
-        }
+        !matches!(self, LispExpr::BoolLit(false))
     }
 }
 
@@ -347,3 +350,26 @@ impl TryFrom<LispExpr> for BoolLit {
         }
     }
 }
+
+// conversion implementations
+
+impl From<Axis> for LispExpr {
+    fn from(axis: Axis) -> LispExpr {
+        LispExpr::Quote(
+            Box::new(LispExpr::Ident(match axis {
+                Axis::X => "X".into(),
+                Axis::Y => "Y".into(),
+            })),
+            1,
+        )
+    }
+}
+
+impl From<Guide> for LispExpr {
+    fn from(guide: Guide) -> LispExpr {
+        LispExpr::List(vec![
+            guide.axis.into(),
+            LispExpr::Number(LispNumber::Integer(guide.offset as i64)),
+        ])
+    }
+}
diff --git a/src/lisp/lex.rs b/src/lisp/lex.rs
index 2088421..754a23f 100644
--- a/src/lisp/lex.rs
+++ b/src/lisp/lex.rs
@@ -102,16 +102,11 @@ impl<'src, 'file> SpanDisplay<'src, 'file> {
 pub struct Lexer<'input> {
     input: &'input str,
     cur_pos: u32,
-    offset: u32,
 }
 
 impl<'a> Lexer<'a> {
-    pub fn new(input: &'a str, offset: u32) -> Self {
-        Self {
-            input,
-            cur_pos: 0,
-            offset,
-        }
+    pub fn new(input: &'a str) -> Self {
+        Self { input, cur_pos: 0 }
     }
 
     pub fn next_token(&mut self) -> Result<(Span, Token<'a>), ParseError> {
@@ -166,11 +161,11 @@ impl<'a> Lexer<'a> {
             return Ok((sp, token));
         }
         self.input = &self.input[..0];
-        return Ok((Span::empty(self.cur_pos), Token::End));
+        Ok((Span::empty(self.cur_pos), Token::End))
     }
 }
 
-fn parse_number<'a>(mut input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> {
+fn parse_number(mut input: &str) -> Result<(usize, Token<'_>), ParseErrorKind> {
     let mut dot = false;
     let mut minus = false;
     let mut size = 0;
@@ -186,7 +181,7 @@ fn parse_number<'a>(mut input: &'a str) -> Result<(usize, Token<'a>), ParseError
         }
     }
 
-    while let Some(chr) = chars.next() {
+    for chr in chars {
         if chr.is_digit(10) {
             size += 1;
         } else if chr == '.' {
@@ -210,10 +205,10 @@ fn parse_number<'a>(mut input: &'a str) -> Result<(usize, Token<'a>), ParseError
     } else {
         Token::Integer(&input[..size])
     };
-    return Ok((size, tok));
+    Ok((size, tok))
 }
 
-fn parse_string<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> {
+fn parse_string(input: &str) -> Result<(usize, Token<'_>), ParseErrorKind> {
     // count opening quote
     let mut size = 1;
     let mut closed = false;
@@ -260,7 +255,7 @@ fn consume_comment(start: usize, chars: &mut CharIndices) -> usize {
     last - start + 1
 }
 
-fn parse_name<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> {
+fn parse_name(input: &str) -> Result<(usize, Token<'_>), ParseErrorKind> {
     for (ind, chr) in input.char_indices() {
         if !is_ident(chr) {
             return Ok((ind, Token::Name(&input[..ind])));
@@ -269,7 +264,7 @@ fn parse_name<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind>
     return Ok((input.len(), Token::Name(input)));
 }
 
-fn parse_char<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> {
+fn parse_char(input: &str) -> Result<(usize, Token<'_>), ParseErrorKind> {
     // first two chars of input are '#' and '\'
     let chr = &input[..3];
     return Ok((chr.len(), Token::Char(chr)));
@@ -284,7 +279,7 @@ mod tests {
     }
 
     fn tokens(input: &str) -> Vec<(Span, Token)> {
-        let mut lexer = Lexer::new(input, 0);
+        let mut lexer = Lexer::new(input);
         let mut tokens = Vec::new();
         loop {
             match lexer.next_token().unwrap() {
diff --git a/src/lisp/number.rs b/src/lisp/number.rs
index 4ca890a..4824e21 100644
--- a/src/lisp/number.rs
+++ b/src/lisp/number.rs
@@ -16,14 +16,14 @@ impl LispNumber {
     pub fn div(self, rhs: Self) -> Result<LispNumber, LispError> {
         use LispNumber::*;
         if rhs == Integer(0) || rhs == Float(0.) {
-            return Err(EvalError::DivByZero.into());
+            Err(EvalError::DivByZero.into())
         } else {
-            return Ok(match (self, rhs) {
+            Ok(match (self, rhs) {
                 (Integer(a), Integer(b)) => Float(a as f64 / b as f64),
                 (Float(a), Integer(b)) => Float(a / b as f64),
                 (Integer(a), Float(b)) => Float(a as f64 / b),
                 (Float(a), Float(b)) => Float(a / b),
-            });
+            })
         }
     }
     pub fn unwrap_integer(self) -> i64 {
diff --git a/src/lisp/parse.rs b/src/lisp/parse.rs
index 737e7ad..8aeb672 100644
--- a/src/lisp/parse.rs
+++ b/src/lisp/parse.rs
@@ -1,5 +1,5 @@
 use crate::lisp::{
-    error::{LispError, ParseError, ParseErrorKind},
+    error::{ParseError, ParseErrorKind},
     lex::{Lexer, Span, Token},
     number::LispNumber,
     LispExpr,
@@ -30,97 +30,91 @@ impl<'lex> Parser<'lex> {
         let mut total_backticks = 0;
         loop {
             let (span, token) = self.next()?;
-            let r: Result<LispExpr, ParseError> = match token {
-                Token::LeftParen => {
-                    stack.push(Group::Parens(Vec::new()));
-                    continue;
-                }
-                Token::RightParen => {
-                    let group = stack
-                        .pop()
-                        .ok_or_else(|| (ParseError::new(span, ParseErrorKind::UnmatchedParen)))?;
-                    match group {
-                        Group::Parens(v) => {
-                            if v.len() == 0 {
-                                Ok(LispExpr::Unit)
-                            } else {
-                                Ok(LispExpr::List(v))
+            let r: Result<LispExpr, ParseError> =
+                match token {
+                    Token::LeftParen => {
+                        stack.push(Group::Parens(Vec::new()));
+                        continue;
+                    }
+                    Token::RightParen => {
+                        let group = stack
+                            .pop()
+                            .ok_or_else(|| ParseError::new(span, ParseErrorKind::UnmatchedParen))?;
+                        match group {
+                            Group::Parens(v) => {
+                                if v.is_empty() {
+                                    Ok(LispExpr::Unit)
+                                } else {
+                                    Ok(LispExpr::List(v))
+                                }
                             }
+                            _ => Err(ParseError::new(
+                                span,
+                                ParseErrorKind::UnexpectedToken {
+                                    expected: "expression",
+                                    found: "(",
+                                },
+                            )),
                         }
-                        _ => Err(From::from(ParseError::new(
-                            span,
-                            ParseErrorKind::UnexpectedToken {
-                                expected: "expression",
-                                found: "(",
-                            },
-                        ))),
                     }
-                }
-                Token::Float(f) => f
-                    .parse::<f64>()
-                    .map(|n| LispExpr::Number(LispNumber::Float(n)))
-                    .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError).into()),
-                Token::Integer(i) => i
-                    .parse::<i64>()
-                    .map(|n| LispExpr::Number(LispNumber::Integer(n)))
-                    .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError).into()),
-                Token::String(s) => Ok(LispExpr::StringLit(s[1..s.len() - 1].into())),
-                Token::Char(s) => {
-                    Ok(LispExpr::Char(s.chars().nth(2).ok_or_else(|| {
+                    Token::Float(f) => f
+                        .parse::<f64>()
+                        .map(|n| LispExpr::Number(LispNumber::Float(n)))
+                        .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError)),
+                    Token::Integer(i) => i
+                        .parse::<i64>()
+                        .map(|n| LispExpr::Number(LispNumber::Integer(n)))
+                        .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError)),
+                    Token::String(s) => Ok(LispExpr::StringLit(s[1..s.len() - 1].into())),
+                    Token::Char(s) => Ok(LispExpr::Char(s.chars().nth(2).ok_or_else(|| {
                         ParseError::new(span, ParseErrorKind::LiteralParseError)
-                    })?))
-                }
-                Token::Name(n) => Ok(name_expr(n)),
-                Token::BackQuote => {
-                    total_backticks += 1;
-                    if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() {
-                        *n += 1;
+                    })?)),
+                    Token::Name(n) => Ok(name_expr(n)),
+                    Token::BackQuote => {
+                        total_backticks += 1;
+                        if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() {
+                            *n += 1;
+                            continue;
+                        }
+                        stack.push(Group::Backticks(1));
                         continue;
                     }
-                    stack.push(Group::Backticks(1));
-                    continue;
-                }
-                Token::Comma => {
-                    if total_backticks <= 0 {
-                        return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma));
-                    }
-                    total_backticks -= 1;
-                    if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() {
-                        *n -= 1;
+                    Token::Comma => {
+                        if total_backticks <= 0 {
+                            return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma));
+                        }
+                        total_backticks -= 1;
+                        if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() {
+                            *n -= 1;
+                            continue;
+                        }
+                        stack.push(Group::Backticks(-1));
                         continue;
                     }
-                    stack.push(Group::Backticks(-1));
-                    continue;
-                }
-                Token::CommaAt => {
-                    if total_backticks <= 0 {
-                        return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma));
+                    Token::CommaAt => {
+                        if total_backticks <= 0 {
+                            return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma));
+                        }
+                        total_backticks -= 1;
+                        stack.push(Group::CommaAt);
+                        continue;
                     }
-                    total_backticks -= 1;
-                    stack.push(Group::CommaAt);
-                    continue;
-                }
-                Token::Quote => {
-                    if let Some(&mut Group::Quotes(ref mut n)) = stack.last_mut() {
-                        *n += 1;
+                    Token::Quote => {
+                        if let Some(&mut Group::Quotes(ref mut n)) = stack.last_mut() {
+                            *n += 1;
+                            continue;
+                        }
+                        stack.push(Group::Quotes(1));
                         continue;
                     }
-                    stack.push(Group::Quotes(1));
-                    continue;
-                }
-                Token::End => {
-                    let any_paren = stack.iter().any(|group| match *group {
-                        Group::Parens(_) => true,
-                        _ => false,
-                    });
-
-                    if any_paren {
-                        Err(ParseError::new(span, ParseErrorKind::MissingCloseParen))
-                    } else {
-                        Err(ParseError::new(span, ParseErrorKind::UnexpectedEof))
+                    Token::End => {
+                        if stack.iter().any(|group| matches!(*group, Group::Parens(_))) {
+                            Err(ParseError::new(span, ParseErrorKind::MissingCloseParen))
+                        } else {
+                            Err(ParseError::new(span, ParseErrorKind::UnexpectedEof))
+                        }
                     }
-                }
-            };
+                };
             let mut v = r?;
             loop {
                 match stack.last_mut() {
@@ -181,8 +175,7 @@ impl<'lex> Parser<'lex> {
                     expected: "EOF",
                     found: token.name(),
                 },
-            )
-            .into()),
+            )),
         }
     }
 
@@ -210,7 +203,7 @@ fn name_expr(input: &str) -> LispExpr {
 mod tests {
     use super::*;
     fn parse(input: &str) -> Result<LispExpr, ParseError> {
-        let mut parser = Parser::new(Lexer::new(input, 0));
+        let mut parser = Parser::new(Lexer::new(input));
 
         parser.parse_single_expr()
     }
diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs
index aebff98..fee787e 100644
--- a/src/lisp/prelude.rs
+++ b/src/lisp/prelude.rs
@@ -66,7 +66,7 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Atleast(2), "+", |args, _| {
         let nums = args
-            .into_iter()
+            .iter()
             .map(|arg| arg.try_into())
             .collect::<Result<Vec<&LispNumber>, LispError>>()?;
         return Ok(LispExpr::Number(
@@ -76,10 +76,10 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Atleast(2), "-", |args, _| {
         let nums = args
-            .into_iter()
+            .iter()
             .map(|arg| arg.try_into())
             .collect::<Result<Vec<&LispNumber>, LispError>>()?;
-        let mut acc = nums[0].clone();
+        let mut acc = *nums[0];
         for arg in nums.into_iter().skip(1) {
             acc = acc - *arg;
         }
@@ -88,7 +88,7 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Atleast(2), "*", |args, _| {
         let nums = args
-            .into_iter()
+            .iter()
             .map(|arg| arg.try_into())
             .collect::<Result<Vec<&LispNumber>, LispError>>()?;
         return Ok(LispExpr::Number(
@@ -98,10 +98,10 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Atleast(2), "/", |args, _| {
         let nums = args
-            .into_iter()
+            .iter()
             .map(|arg| arg.try_into())
             .collect::<Result<Vec<&LispNumber>, LispError>>()?;
-        let mut acc = nums[0].clone();
+        let mut acc = *nums[0];
         for arg in nums.into_iter().skip(1) {
             acc = acc.div(*arg)?;
         }
@@ -139,7 +139,7 @@ pub fn new_env() -> Result<Environment, LispError> {
     });
 
     primitive!(env, Arity::Atleast(1), "begin", |args, _| {
-        Ok(args.into_iter().last().unwrap().clone())
+        Ok(args.iter().last().unwrap().clone())
     });
 
     primitive!(env, Arity::Exact(0), "quit", |_, app| {
@@ -157,8 +157,8 @@ pub fn new_env() -> Result<Environment, LispError> {
             (LispExpr::DottedList(s), LispExpr::DottedList(o)) => {
                 Ok(s.iter().zip(o).all(|(a, b)| a == b))
             }
-            (LispExpr::List(s), LispExpr::Unit) => Ok(s.len() == 0),
-            (LispExpr::Unit, LispExpr::List(s)) => Ok(s.len() == 0),
+            (LispExpr::List(s), LispExpr::Unit) => Ok(s.is_empty()),
+            (LispExpr::Unit, LispExpr::List(s)) => Ok(s.is_empty()),
             (LispExpr::DottedList(_), LispExpr::Unit) => Ok(false),
             (LispExpr::Unit, LispExpr::DottedList(_)) => Ok(false),
             (LispExpr::StringLit(s), LispExpr::StringLit(o)) => Ok(s == o),
@@ -176,10 +176,10 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Atleast(2), ">", |args, _| {
         let nums = args
-            .into_iter()
+            .iter()
             .map(|arg| arg.try_into())
             .collect::<Result<Vec<&LispNumber>, LispError>>()?;
-        let acc = nums[0].clone();
+        let acc = *nums[0];
         Ok(LispExpr::BoolLit(
             nums.into_iter().skip(1).all(|&arg| acc > arg),
         ))
@@ -187,10 +187,10 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Atleast(2), ">=", |args, _| {
         let nums = args
-            .into_iter()
+            .iter()
             .map(|arg| arg.try_into())
             .collect::<Result<Vec<&LispNumber>, LispError>>()?;
-        let acc = nums[0].clone();
+        let acc = *nums[0];
         Ok(LispExpr::BoolLit(
             nums.into_iter().skip(1).all(|&arg| acc >= arg),
         ))
@@ -198,10 +198,10 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Atleast(2), "<", |args, _| {
         let nums = args
-            .into_iter()
+            .iter()
             .map(|arg| arg.try_into())
             .collect::<Result<Vec<&LispNumber>, LispError>>()?;
-        let acc = nums[0].clone();
+        let acc = *nums[0];
         Ok(LispExpr::BoolLit(
             nums.into_iter().skip(1).all(|&arg| acc < arg),
         ))
@@ -209,10 +209,10 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Atleast(2), "<=", |args, _| {
         let nums = args
-            .into_iter()
+            .iter()
             .map(|arg| arg.try_into())
             .collect::<Result<Vec<&LispNumber>, LispError>>()?;
-        let acc = nums[0].clone();
+        let acc = *nums[0];
         Ok(LispExpr::BoolLit(
             nums.into_iter().skip(1).all(|&arg| acc <= arg),
         ))
@@ -235,18 +235,16 @@ pub fn new_env() -> Result<Environment, LispError> {
                 .map_err(|e| LispError::Stringified(e.to_string()))
                 .map(|_| LispExpr::Unit);
         }
-        return Err(EvalError::NoFileName.into());
+        Err(EvalError::NoFileName.into())
     });
 
     primitive!(env, Arity::Exact(1), "save-as", |args, app| {
         match &args[0] {
-            LispExpr::StringLit(s) => {
-                return app
-                    .save_as(&s)
-                    .map_err(|e| LispError::Stringified(e.to_string()))
-                    .map(|_| LispExpr::Unit);
-            }
-            _ => return Err(EvalError::TypeMismatch.into()),
+            LispExpr::StringLit(s) => app
+                .save_as(&s)
+                .map_err(|e| LispError::Stringified(e.to_string()))
+                .map(|_| LispExpr::Unit),
+            _ => Err(EvalError::TypeMismatch.into()),
         }
     });
 
@@ -261,52 +259,52 @@ pub fn new_env() -> Result<Environment, LispError> {
 
     primitive!(env, Arity::Exact(0), "brush-fill", |_, app| {
         app.brush = Brush::Fill;
-        return Ok(LispExpr::Unit);
+        Ok(LispExpr::Unit)
     });
 
     primitive!(env, Arity::Exact(0), "brush-circle", |_, app| {
         app.brush = Brush::new(0);
-        return Ok(LispExpr::Unit);
+        Ok(LispExpr::Unit)
     });
 
     primitive!(env, Arity::Exact(0), "brush-line", |_, app| {
         app.brush = Brush::line(0, false);
-        return Ok(LispExpr::Unit);
+        Ok(LispExpr::Unit)
     });
 
     primitive!(env, Arity::Exact(0), "brush-line-extend", |_, app| {
         app.brush = Brush::line(0, true);
-        return Ok(LispExpr::Unit);
+        Ok(LispExpr::Unit)
     });
 
     primitive!(env, Arity::Exact(2), "cons", |args, _| {
         if type_match!(args, 1 => LispExpr::Unit) {
-            return Ok(LispExpr::List(vec![args[0].clone()]));
+            Ok(LispExpr::List(vec![args[0].clone()]))
         } else if type_match!(args, 1 => LispExpr::DottedList(_)) {
             // cons of anything to an improper list is an improper list
             let mut rest = args[1].unwrap_dotted_list();
             rest.insert(0, args[0].clone());
-            return Ok(LispExpr::DottedList(rest));
+            Ok(LispExpr::DottedList(rest))
         } else if type_match!(args, 1 => LispExpr::List(_)) {
             // cons of anything to a proper list is a proper list
             let mut rest = args[1].unwrap_list();
             rest.insert(0, args[0].clone());
-            return Ok(LispExpr::List(rest));
+            Ok(LispExpr::List(rest))
         } else {
             // attempt to cons non-lists
-            return Ok(LispExpr::DottedList(vec![args[0].clone(), args[1].clone()]));
+            Ok(LispExpr::DottedList(vec![args[0].clone(), args[1].clone()]))
         }
     });
 
     primitive!(env, Arity::Exact(1), "car", |args, _| {
         if type_match!(args, 0 => LispExpr::List(_)) {
-            return Ok(args[0].unwrap_list().swap_remove(0));
+            Ok(args[0].unwrap_list().swap_remove(0))
         } else if type_match!(args, 0 => LispExpr::DottedList(_)) {
-            return Ok(args[0].unwrap_dotted_list().swap_remove(0));
+            Ok(args[0].unwrap_dotted_list().swap_remove(0))
         } else if type_match!(args, 0 => LispExpr::Unit) {
-            return Err(EvalError::AccessEmptyList.into());
+            Err(EvalError::AccessEmptyList.into())
         } else {
-            return Err(EvalError::TypeMismatch.into());
+            Err(EvalError::TypeMismatch.into())
         }
     });
 
@@ -314,32 +312,32 @@ pub fn new_env() -> Result<Environment, LispError> {
         if type_match!(args, 0 => LispExpr::List(_)) {
             // cdr of a proper list is a proper list
             let mut ls = args[0].unwrap_list();
-            if ls.len() == 0 {
-                return Err(EvalError::AccessEmptyList.into());
+            if ls.is_empty() {
+                Err(EvalError::AccessEmptyList.into())
             } else if ls.len() == 1 {
-                return Ok(LispExpr::Unit);
+                Ok(LispExpr::Unit)
             } else {
                 ls.remove(0);
-                return Ok(LispExpr::List(ls));
+                Ok(LispExpr::List(ls))
             }
         } else if type_match!(args, 0 => LispExpr::DottedList(_)) {
             // cdr of an improper list is an improper list or an atom
             let ls = args[0].unwrap_dotted_list();
             if ls.len() == 2 {
-                return Ok(ls.into_iter().last().unwrap());
+                Ok(ls.into_iter().last().unwrap())
             } else {
                 // should be unreachable
-                return Err(EvalError::AccessEmptyList.into());
+                Err(EvalError::AccessEmptyList.into())
             }
         } else if type_match!(args, 0 => LispExpr::Unit) {
-            return Err(EvalError::AccessEmptyList.into());
+            Err(EvalError::AccessEmptyList.into())
         } else {
-            return Err(EvalError::TypeMismatch.into());
+            Err(EvalError::TypeMismatch.into())
         }
     });
 
     primitive!(env, Arity::Atleast(1), "list", |args, _| {
-        return Ok(LispExpr::List(args.to_vec()));
+        Ok(LispExpr::List(args.to_vec()))
     });
 
     primitive!(env, Arity::Exact(1), "load-script", |args, app| {
@@ -347,40 +345,40 @@ pub fn new_env() -> Result<Environment, LispError> {
             let path = args[0].unwrap_stringlit();
             load_script(&path, app).map(|_| LispExpr::Unit)
         } else {
-            return Err(EvalError::TypeMismatch.into());
+            Err(EvalError::TypeMismatch.into())
         }
     });
 
     primitive!(env, Arity::Atleast(1), "error", |args, _| {
         if type_match!(args, 0 => LispExpr::StringLit(_)) {
-            let mut s = String::from(args[0].unwrap_stringlit());
-            for arg in args.into_iter().skip(1) {
+            let mut s = args[0].unwrap_stringlit();
+            for arg in args.iter().skip(1) {
                 s.push_str(&format!(" {}", arg));
             }
-            return Err(EvalError::Custom(s).into());
+            Err(EvalError::Custom(s).into())
         } else {
-            return Err(EvalError::TypeMismatch.into());
+            Err(EvalError::TypeMismatch.into())
         }
     });
 
     primitive!(env, Arity::Exact(2), "assert-eq", |args, app| {
         if args[0].compare(&args[1], &app.lisp_env)? {
-            return Ok(LispExpr::Unit);
+            Ok(LispExpr::Unit)
         } else {
-            return Err(EvalError::AssertionError {
+            Err(EvalError::AssertionError {
                 expected: args[0].clone(),
                 got: args[1].clone(),
             }
-            .into());
+            .into())
         }
     });
 
     primitive!(env, Arity::Exact(0), "canvas-width", |_, app| {
-        return Ok(LispExpr::Number(LispNumber::Integer(app.width() as i64)));
+        Ok(LispExpr::Number(LispNumber::Integer(app.width() as i64)))
     });
 
     primitive!(env, Arity::Exact(0), "canvas-height", |_, app| {
-        return Ok(LispExpr::Number(LispNumber::Integer(app.height() as i64)));
+        Ok(LispExpr::Number(LispNumber::Integer(app.height() as i64)))
     });
 
     primitive!(env, Arity::Exact(3), "set-pixel!", |args, app| {
@@ -397,21 +395,21 @@ pub fn new_env() -> Result<Environment, LispError> {
                 .try_into()
                 .map_err(|_| -> LispError { EvalError::InvalidCoordinates((x, y)).into() })?;
             if !app.pixmap.contains(set_loc) {
-                return Err(EvalError::InvalidCoordinates((x, y)).into());
+                Err(EvalError::InvalidCoordinates((x, y)).into())
             } else {
                 let old_val = app.pixmap.set(set_loc, val);
                 app.current_operation
                     .push(PaintRecord::new(set_loc, old_val, val));
-                return Ok(LispExpr::Unit);
+                Ok(LispExpr::Unit)
             }
         } else {
-            return Err(EvalError::TypeMismatch.into());
+            Err(EvalError::TypeMismatch.into())
         }
     });
 
     primitive!(env, Arity::Exact(0), "commit", |_, app| {
         app.commit_operation();
-        return Ok(LispExpr::Unit);
+        Ok(LispExpr::Unit)
     });
 
     primitive!(env, Arity::Exact(2), "add-guide!", |args, app| {
@@ -422,9 +420,9 @@ pub fn new_env() -> Result<Environment, LispError> {
                     offset: *offset as u32,
                 };
                 app.guides.insert(guide, true);
-                return Ok(LispExpr::Unit);
+                Ok(LispExpr::Unit)
             }
-            _ => return Err(EvalError::TypeMismatch.into()),
+            _ => Err(EvalError::TypeMismatch.into()),
         }
     });
 
-- 
cgit v1.2.3