diff --git a/grimoire/src/lib.rs b/grimoire/src/lib.rs
index 9d2490435c120be2aa6a13805cce8dd29fe2d67f..4a319192df5b2808e4c143023a965ee54df721a0 100644
--- a/grimoire/src/lib.rs
+++ b/grimoire/src/lib.rs
@@ -7,10 +7,22 @@ pub mod parser;
 pub mod spell;
 
 pub mod prelude {
+    // Types prefixed by crate name.
     pub use crate::{
-        ast::expr::{Const as GrimoireConstant, Expression as GrimoireExpression},
+        ast::{
+            Const as GrimoireConstant, Expression as GrimoireExpression,
+            VarOrConst as GrimoireVarOrConst,
+        },
         error::Error as GrimoireError,
         state::State as GrimoireState,
         types::Type as GrimoireType,
     };
+
+    // Spell structs/traits re-exports.
+    pub use crate::spell::{BuildableSpell, Spell, SpellArguments, SpellFactory};
+
+    // Standard spells re-rexports.
+    pub mod spell {
+        pub use crate::spell::std::*;
+    }
 }
diff --git a/grimoire/src/spell/arguments.rs b/grimoire/src/spell/arguments.rs
index 35ccba3780ed33fa17853e2d0c7a2e6cd370be8e..76e9b9855c53e0bd0b324904288600f0eaaf81ff 100644
--- a/grimoire/src/spell/arguments.rs
+++ b/grimoire/src/spell/arguments.rs
@@ -1,36 +1,118 @@
-use crate::{
-    ast::expr::{Const, Expression},
-    error::Error,
-    state::State,
-    types::Type,
-};
+use crate::{ast::Const, error::Error, types::Type};
 use std::collections::HashMap;
 
 /// The arguments that may be passed to a spell for its instanciation.
 #[derive(Debug, Default)]
-pub struct SpellArguments(HashMap<String, Expression>);
+pub struct SpellArguments {
+    named: HashMap<String, Const>,
+    trailing: Vec<Const>,
+}
 
 impl SpellArguments {
     /// Set/Override the value in the [Argument] list.
-    pub fn set(&mut self, name: impl Into<String>, value: Expression) {
-        _ = self.0.insert(name.into(), value);
+    pub fn insert(&mut self, name: impl Into<String>, value: Const) {
+        _ = self.named.insert(name.into(), value);
+    }
+
+    /// Push an unamed argument to the argument list.
+    pub fn push(&mut self, value: Const) {
+        self.trailing.push(value);
+    }
+
+    /// Removes a named argument of a [SpellArguments], and try to cast it into the asked type. On
+    /// success returns [Option<Argument>::Some], otherwise [None].
+    pub fn remove_as<S>(&mut self, name: S, ty: Type) -> Result<Const, Error>
+    where
+        S: AsRef<str>,
+    {
+        self.remove(name.as_ref())
+            .ok_or_else(|| Error::Undefined(name.as_ref().to_string()))?
+            .cast_into(ty)
     }
 
-    /// Pops the value of an [Argument], and try to cast it into the asked type. On success returns
+    /// Removes a named argument of a [SpellArguments]. On success returns
     /// [Option<Argument>::Some], otherwise [None].
-    pub fn pop<S>(&mut self, state: &State, name: S, ty: Type) -> Result<Const, Error>
+    pub fn remove<S>(&mut self, name: S) -> Option<Const>
     where
         S: AsRef<str>,
     {
-        self.0
-            .remove(name.as_ref())
-            .ok_or_else(|| Error::Undefined(name.as_ref().to_string()))
-            .map(|expr| state.evaluate_as(expr, ty))?
+        self.named.remove(name.as_ref())
+    }
+
+    /// Pops an unamed argument from the argument list.
+    pub fn pop_as(&mut self, ty: Type) -> Result<Const, Error> {
+        self.pop()
+            .ok_or(Error::Empty("unamed argument list"))?
+            .cast_into(ty)
+    }
+
+    /// Pops an unamed argument from the argument list.
+    pub fn pop(&mut self) -> Option<Const> {
+        self.trailing.pop()
+    }
+
+    /// Iterate over the name of the named arguments.
+    pub fn iter_named_keys(&self) -> impl Iterator<Item = &str> {
+        self.named.keys().map(String::as_str)
+    }
+
+    /// Iterate over named arguments.
+    pub fn iter_named(&self) -> impl Iterator<Item = (&str, &Const)> {
+        self.named
+            .iter()
+            .map(|(key, constant)| (key.as_str(), constant))
+    }
+
+    /// Iterate over unnamed arguments.
+    pub fn iter_unamed(&self) -> impl Iterator<Item = &Const> {
+        self.trailing.iter()
+    }
+
+    /// Tells wether we have named arguments or not.
+    pub fn has_named(&self) -> bool {
+        self.named.is_empty()
+    }
+
+    /// Tells wether we have unamed arguments or not.
+    pub fn has_unamed(&self) -> bool {
+        self.trailing.is_empty()
+    }
+
+    /// Tells wether the argument list is empty or not. Note that at the end of the
+    /// [crate::spell::Spell] creation, the argument list must be empty!
+    pub fn is_empty(&self) -> bool {
+        !self.has_named() && !self.has_unamed()
     }
 }
 
-impl FromIterator<(String, Expression)> for SpellArguments {
-    fn from_iter<T: IntoIterator<Item = (String, Expression)>>(iter: T) -> Self {
-        Self(iter.into_iter().collect())
+/// Iterate over all the arguments. You are guarentied to have first the named arguments - in an
+/// unspecified order - then the unamed arguments in order.
+pub struct IntoIter {
+    named: <HashMap<String, Const> as IntoIterator>::IntoIter,
+    trailing: <Vec<Const> as IntoIterator>::IntoIter,
+}
+
+impl IntoIterator for SpellArguments {
+    type Item = <Self::IntoIter as Iterator>::Item;
+    type IntoIter = IntoIter;
+
+    /// Iterate over all the arguments. You are guarentied to have first the named arguments - in
+    /// an unspecified order - then the unamed arguments in order.
+    fn into_iter(self) -> Self::IntoIter {
+        IntoIter {
+            named: self.named.into_iter(),
+            trailing: self.trailing.into_iter(),
+        }
+    }
+}
+
+impl Iterator for IntoIter {
+    type Item = (Option<String>, Const);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.named
+            .next()
+            .map(|(key, constant)| (Some(key), constant))
+            .or_else(|| self.trailing.next().map(|constant| (None, constant)))
     }
 }
diff --git a/grimoire/src/spell/traits.rs b/grimoire/src/spell/traits.rs
index f9fa195ecb7c158925bc20845f86931f89422754..aa919904a2765f6e112195235424fbd5fdadb9e4 100644
--- a/grimoire/src/spell/traits.rs
+++ b/grimoire/src/spell/traits.rs
@@ -1,12 +1,9 @@
 use crate::{error::Error, spell::SpellArguments, state::State};
 
-/// A spell, can be casted or reverted if we need to.
+/// A spell, can be casted on a state to modify it.
 pub trait Spell {
     /// Cast the spell on a [State]. Returns a new [State].
-    fn cast(&mut self, state: State) -> Result<State, Error>;
-
-    /// UnCast the spell from a [State]. Returns the previous [State].
-    fn uncast(&mut self, state: State) -> Result<State, Error>;
+    fn cast(&self, state: State) -> Result<State, Error>;
 }
 
 /// A [Spell] that we can create. Is used to be able to register it into a
@@ -33,7 +30,7 @@ where
     /// Create a spell from a set of arguments. May fail.
     fn create(arguments: SpellArguments) -> Result<Box<dyn Spell>, Error> {
         Self::try_from(arguments)
-            .map(Box::new)
-            .map(|boxed| boxed as Box<dyn Spell>)
+            .map(|this| Box::new(this) as Box<dyn Spell>)
+            .map_err(|err| Error::BuildSpell(Self::name(), Box::new(err)))
     }
 }