diff --git a/README.md b/README.md
index 613701ca712add8d861cc06f67469ceb4fc68672..edbe64fbdb8bfc990f90ea8fb4b2dd0fb4951f20 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ Syntax and feature decisions for Ion are made based upon three specific measurem
 
 While Ion's foundations are heavily influenced by POSIX shell syntax, it does offer some critical features and differentiations that you won't find in a POSIX shell. The similarities only exist because POSIX syntax already had some good ideas, but it also came with a number of bad design decisions that have lead to inflexibility, and so we have taken the good ideas and implemented even better ideas on top of them, and as a replacement to the bad parts. Hence, while syntax may look familiar, it is not, nor will it ever, be compliant with POSIX.
 
-In example, we have carried a lot of the same basic features such as strings (**$string**) and process expansions that return strings (**$(command args...)***), but we have also implemented support for first class arrays (**@array**) and array-based process expansions (**@[command args..]**), rather than compounding the string variables, and utilize the distinction between the two types to implement methods (**$join(array)**, **@split(string)**) and slicing (**$string[..5]**, **@array[..5]**). In addition, we implement better syntax for redirecting/piping stderr (**^>**, **^|**), and both stderr/stdout (**&>**, **&|**); as well as dropping the **do** keyword, and using the **end** keyword to end a block.
+In example, we have carried a lot of the same basic features such as strings (**$string**) and process expansions that return strings (**$(command args...)***), but we have also implemented support for first class arrays (**@array**) and array-based process expansions (**@(command args..)**), rather than compounding the string variables, and utilize the distinction between the two types to implement methods (**$join(array)**, **@split(string)**) and slicing (**$string[..5]**, **@array[..5]**). In addition, we implement better syntax for redirecting/piping stderr (**^>**, **^|**), and both stderr/stdout (**&>**, **&|**); as well as dropping the **do** keyword, and using the **end** keyword to end a block.
 
 # Features
 
@@ -31,7 +31,7 @@ Below is an overview of features that Ion has either already implemented, or aim
         - [x] Nested Braces
     - [x] Process Expansions
         - [x] String-based Command Substitution (**$()**)
-        - [x] Array-based Command Substitution (**@[]**)
+        - [x] Array-based Command Substitution (**@()**)
     - [ ] Arithmetic Expansions
 - [x] Flow Control
     - [x] For Loops
@@ -258,7 +258,7 @@ Whereas the standard command substitution syntax will create a single string fro
 a whitespace-delimited vector of values from the output of the command.
 
 ```ion
-let word_split_process = @[echo one two three]
+let word_split_process = @(echo one two three)
 ```
 
 ### Using Arrays
@@ -286,9 +286,9 @@ echo [ 1 2 3 ][0]
 echo [ 1 2 3 ][1]
 echo [ 1 2 3 ][2]
 
-echo @[echo 1 2 3][0]
-echo @[echo 1 2 3][1]
-echo @[echo 1 2 3][2]
+echo @(echo 1 2 3)[0]
+echo @(echo 1 2 3)[1]
+echo @(echo 1 2 3)[2]
 ```
 
 #### Slice by Range
@@ -460,7 +460,7 @@ Command substitution allows the user to execute commands within a subshell, and
 output used as the substitution for the expansion. There are two methods of performing command substitution: string and
 array-based command substitution. String-based command substitutions are the standard, and they are created by wrapping
 the external command between **$(** and **)**. Array-based command substitution is denoted by wrapping the command
-between **@[** and **]**. The first merely captures the result as a single string, precisely as it was written, while
+between **@(** and **)**. The first merely captures the result as a single string, precisely as it was written, while
 the second splits the data recieved into words delimited by whitespaces.
 
 Try comparing the following:
@@ -472,7 +472,7 @@ end
 ```
 
 ```ion
-for i in @[echo 1 2 3]
+for i in @(echo 1 2 3)
     echo $i
 end
 ```
@@ -490,7 +490,7 @@ echo $(echo one two three)[..3]
 You may slice the array returned to obtained a specific set of elements:
 
 ```ion
-echo @[grep "model name" /proc/cpuinfo | head -1][3..5]
+echo @(grep "model name" /proc/cpuinfo | head -1)[3..5]
 ```
 
 ### Functions
diff --git a/examples/arrays.ion b/examples/arrays.ion
index 5a652f9daee91eb9d8f4124fa03a6af40d5499bf..82d595f13d6ae8603e10756b3b82c0e9895fc261 100644
--- a/examples/arrays.ion
+++ b/examples/arrays.ion
@@ -11,12 +11,12 @@ end
 
 # Array Command Substitution
 
-let array_process = @[echo a  b c d    e]
+let array_process = @(echo a  b c d    e)
 for i in @array_process
     echo $i
 end
 
-for i in @[echo a  b c d    e]
+for i in @(echo a  b c d    e)
     echo $i
 end
 
@@ -44,9 +44,9 @@ echo [ 1 2 3 ][0]
 echo [ 1 2 3 ][1]
 echo [ 1 2 3 ][2]
 
-echo @[echo 1 2 3][0]
-echo @[echo 1 2 3][1]
-echo @[echo 1 2 3][2]
+echo @(echo 1 2 3)[0]
+echo @(echo 1 2 3)[1]
+echo @(echo 1 2 3)[2]
 
 # Slice by Range
 
diff --git a/examples/for.ion b/examples/for.ion
index e5df5c47860e5edb791e1d7b31bb6f5fd67ea2c8..606cb506ab87b8615be1a137566a05ec064410e8 100644
--- a/examples/for.ion
+++ b/examples/for.ion
@@ -10,7 +10,7 @@ for i in 1 2 3 4 5
     echo $i
 end
 
-for i in @[echo 1 2 3 4 5]
+for i in @(echo 1 2 3 4 5)
     echo $i
 end
 
diff --git a/src/parser/pipelines.rs b/src/parser/pipelines.rs
index 27cad181f0ad97890f2c4f583ca8ce31b1894e14..9a42c00b31bb2458c85eae9d68cbd39ccd9ba2d8 100644
--- a/src/parser/pipelines.rs
+++ b/src/parser/pipelines.rs
@@ -143,17 +143,16 @@ pub fn collect(possible_error: &mut Option<&str>, args: &str) -> Pipeline {
                             index += 1;
                             continue
                         },
-                        b'[' if flags_ext.contains(ARRAY_CHAR_FOUND) => {
-                            array_process_levels += 1;
-                            flags |= ARRAY_PROCESS;
-                        },
                         b'['                      => array_levels += 1,
                         b']' if array_levels != 0 => array_levels -= 1,
-                        b']'                      => array_process_levels -= 1,
                         b'(' if flags_ext.contains(VAR_CHAR_FOUND) => {
                             flags |= PROCESS_TWO;
                             levels += 1;
                         },
+                        b'(' if flags_ext.contains(ARRAY_CHAR_FOUND) => {
+                            flags |= ARRAY_PROCESS;
+                            array_process_levels += 1;
+                        },
                         b'(' if flags_ext.intersects(VARIABLE | ARRAY) => {
                             flags |= METHOD;
                             flags_ext -= VARIABLE | ARRAY;
@@ -161,6 +160,7 @@ pub fn collect(possible_error: &mut Option<&str>, args: &str) -> Pipeline {
                         b')' if levels == 0 && flags.contains(METHOD) && !flags.contains(SINGLE_QUOTE) => {
                             flags -= METHOD;
                         }
+                        b')' if flags.contains(ARRAY_PROCESS) => array_process_levels -= 1,
                         b')' if flags.contains(PROCESS_TWO) => {
                             levels -= 0;
                             if levels == 0 { flags -= PROCESS_TWO; }
@@ -410,10 +410,10 @@ mod tests {
 
     #[test]
     fn nested_array_process() {
-        if let Statement::Pipeline(pipeline) = parse("echo @[echo one @[echo two] three]") {
+        if let Statement::Pipeline(pipeline) = parse("echo @(echo one @(echo two) three)") {
             let jobs = pipeline.jobs;
             assert_eq!("echo", jobs[0].args[0]);
-            assert_eq!("@[echo one @[echo two] three]", jobs[0].args[1]);
+            assert_eq!("@(echo one @(echo two) three)", jobs[0].args[1]);
         } else {
             assert!(false);
         }
@@ -445,10 +445,10 @@ mod tests {
 
     #[test]
     fn array_process() {
-        if let Statement::Pipeline(pipeline) = parse("echo @[seq 1 10 | head -1]") {
+        if let Statement::Pipeline(pipeline) = parse("echo @(seq 1 10 | head -1)") {
             let jobs = pipeline.jobs;
             assert_eq!("echo", jobs[0].args[0]);
-            assert_eq!("@[seq 1 10 | head -1]", jobs[0].args[1]);
+            assert_eq!("@(seq 1 10 | head -1)", jobs[0].args[1]);
             assert_eq!(2, jobs[0].args.len());
         } else {
             assert!(false);
@@ -755,19 +755,4 @@ mod tests {
             assert!(false);
         }
     }
-
-    // #[test]
-    // fn real_tests() {
-    //     // Real world scenarios where parsing has failed.
-    //     if let Statement::Pipeline(pipeline) = parse("awk -v x=$x '{ if (1) print $1 }' myfile") {
-    //         assert_eq!(1, pipeline.jobs.len());
-    //         assert_eq!("awk", &pipeline.clone().jobs[0].args[0]);
-    //         assert_eq!("-v", &pipeline.clone().jobs[0].args[1]);
-    //         assert_eq!("x=$x", &pipeline.clone().jobs[0].args[2]);
-    //         assert_eq!("'{ if (1) print $1 }'", &pipeline.clone().jobs[0].args[3]);
-    //         assert_eq!("myfile", &pipeline.clone().jobs[0].args[4]);
-    //     } {
-    //         assert!(false);
-    //     }
-    // }
 }
diff --git a/src/parser/shell_expand/words.rs b/src/parser/shell_expand/words.rs
index 93c8e1bc0712346c03e32a44ff8e4d480edf3884..43229fbf8e472821c62e5e09d51532d1fe28dfbc 100644
--- a/src/parser/shell_expand/words.rs
+++ b/src/parser/shell_expand/words.rs
@@ -691,11 +691,11 @@ impl<'a> WordIterator<'a> {
                 b'\'' if !self.flags.contains(DQUOTE) => self.flags ^= SQUOTE,
                 b'"'  if !self.flags.contains(SQUOTE) => self.flags ^= DQUOTE,
                 b'@'  if !self.flags.contains(SQUOTE) => {
-                    if self.data.as_bytes()[self.read+1] == b'[' {
+                    if self.data.as_bytes()[self.read+1] == b'(' {
                         level += 1;
                     }
                 },
-                b']' if !self.flags.contains(SQUOTE) => {
+                b')' if !self.flags.contains(SQUOTE) => {
                     if level == 0 {
                         let array_process_contents = &self.data[start..self.read];
                         self.read += 1;
@@ -943,7 +943,7 @@ impl<'a> Iterator for WordIterator<'a> {
                     },
                     b'@' if !self.flags.contains(SQUOTE) => {
                         match iterator.next() {
-                            Some(b'[') => {
+                            Some(b'(') => {
                                 self.read += 2;
                                 return if self.flags.contains(EXPAND_PROCESSES) {
                                     Some(self.array_process(&mut iterator))
@@ -1148,7 +1148,7 @@ mod tests {
 
     #[test]
     fn array_processes() {
-        let input = "@[echo one two three] @[echo one two three][0]";
+        let input = "@(echo one two three) @(echo one two three)[0]";
         let expected = vec![
             WordToken::ArrayProcess("echo one two three", false, Select::All),
             WordToken::Whitespace(" "),
diff --git a/src/parser/statements.rs b/src/parser/statements.rs
index a3aa8ac0c2137e779050e4f6eb3f39135b46d9dc..23f9975379f981f092f24539a11222d47ed18f60 100644
--- a/src/parser/statements.rs
+++ b/src/parser/statements.rs
@@ -170,21 +170,20 @@ impl<'a> Iterator for StatementSplitter<'a> {
                         self.process_level += 1;
                     }
                 },
+                b'(' if self.flags.contains(COMM_2) => {
+                    self.array_process_level += 1;
+                },
                 b'(' if self.flags.intersects(VARIAB | ARRAY) => {
                     self.flags -= VARIAB | ARRAY;
                     self.flags |= METHOD;
                 },
-                b'[' if self.flags.contains(COMM_2) => {
-                    self.array_process_level += 1;
-                },
                 b'[' if !self.flags.contains(SQUOTE) => self.array_level += 1,
-                b']' if self.array_process_level == 0 && self.array_level == 0 && !self.flags.contains(SQUOTE) => {
+                b']' if self.array_level == 0 && !self.flags.contains(SQUOTE) => {
                     if error.is_none() {
                         error = Some(StatementError::InvalidCharacter(character as char, self.read))
                     }
                 },
                 b']' if !self.flags.contains(SQUOTE) && self.array_level != 0 => self.array_level -= 1,
-                b']' if !self.flags.contains(SQUOTE) => self.array_process_level -= 1,
                 b')' if self.flags.contains(MATHEXPR) => {
                     if self.math_paren_level == 0 {
                         if self.data.as_bytes().len() <= self.read {
@@ -207,12 +206,13 @@ impl<'a> Iterator for StatementSplitter<'a> {
                 b')' if !self.flags.contains(SQUOTE) && self.flags.contains(METHOD) => {
                     self.flags ^= METHOD;
                 },
-                b')' if self.process_level == 0 && self.array_level == 0 && !self.flags.contains(SQUOTE) => {
+                b')' if self.process_level == 0 && self.array_process_level == 0 && !self.flags.contains(SQUOTE) => {
                     if error.is_none() && !self.flags.intersects(SQUOTE | DQUOTE) {
                         error = Some(StatementError::InvalidCharacter(character as char, self.read))
                     }
                 },
-                b')' if !self.flags.contains(SQUOTE) => self.process_level -= 1,
+                b')' if !self.flags.contains(SQUOTE) && self.process_level != 0 => self.process_level -= 1,
+                b')' if !self.flags.contains(SQUOTE) => self.array_process_level -= 1,
                 b';' if !self.flags.intersects(SQUOTE | DQUOTE) && self.process_level == 0 && self.array_process_level == 0 => {
                     return match error {
                         Some(error) => Some(Err(error)),
@@ -325,9 +325,9 @@ fn processes() {
 
 #[test]
 fn array_processes() {
-    let command = "echo @[echo one; sleep 1]; echo @[echo one; sleep 1]";
+    let command = "echo @(echo one; sleep 1); echo @(echo one; sleep 1)";
     for statement in StatementSplitter::new(command) {
-        assert_eq!(statement, Ok("echo @[echo one; sleep 1]"));
+        assert_eq!(statement, Ok("echo @(echo one; sleep 1)"));
     }
 }
 
@@ -372,12 +372,12 @@ fn nested_process() {
 
 #[test]
 fn nested_array_process() {
-    let command = "echo @[echo one @[echo two] three]";
+    let command = "echo @(echo one @(echo two) three)";
     let results = StatementSplitter::new(command).collect::<Vec<Result<&str, StatementError>>>();
     assert_eq!(results.len(), 1);
     assert_eq!(results[0], Ok(command));
 
-    let command = "echo @[echo @[echo one; echo two]; echo two]";
+    let command = "echo @(echo @(echo one; echo two); echo two)";
     let results = StatementSplitter::new(command).collect::<Vec<Result<&str, StatementError>>>();
     assert_eq!(results.len(), 1);
     assert_eq!(results[0], Ok(command));