Struct lexpr::Cons

source ·
pub struct Cons { /* private fields */ }
Expand description

A Lisp “cons cell”.

A cons cell is similiar to a two-element tuple in Rust. Its fields are traditionally called car and cdr, for obscure historical reasons. Both the car and the cdr field can hold any Value, including other cons cells.

This data type is used to represent singly-linked lists, by forming a chain of cons cells where the list element is kept in the car field, and the cdr field either points to the next cons cell, or terminates the list with any other value. Usually, that terminator value is Value::Null, also referred to as the empty list. If any other terminating value is used, the resulting linked list is referred to as “dotted”, or “improper” list.

The Cons data type provides some utility function for the singly-linked list use case, such as iterating through the list or converting the list to a vector. To account for the possibility of dotted lists, the iterators and vector conversion functions have slightly unusual types.

The most natural way to traverse a singly linked list is probably by using the list_iter method.

Implementations§

source§

impl Cons

source

pub fn new<T, U>(car: T, cdr: U) -> Selfwhere T: Into<Value>, U: Into<Value>,

Constructs a new cons cell from two values.

source

pub fn car(&self) -> &Value

Returns a reference to the value in the car field.

source

pub fn car_mut(&mut self) -> &mut Value

Returns a mutable reference to the value in the car field.

source

pub fn set_car(&mut self, car: impl Into<Value>)

Sets the car field.

source

pub fn cdr(&self) -> &Value

Returns a reference to the value in the cdr field.

source

pub fn cdr_mut(&mut self) -> &mut Value

Returns a mutable reference to the value in the cdr field.

source

pub fn set_cdr(&mut self, cdr: impl Into<Value>)

Sets the cdr field.

source

pub fn as_pair(&self) -> (&Value, &Value)

Returns references to the values in the car and cdr fields.

let cell = Cons::new(1, 2);
assert_eq!(cell.as_pair(), (&Value::from(1), &Value::from(2)));
source

pub fn into_pair(self) -> (Value, Value)

Converts self into a pair of values without cloning.

let cell = Cons::new("a", 42);
assert_eq!(cell.car(), "a");
assert_eq!(cell.cdr(), 42);
let (car, cdr) = cell.into_pair();
assert_eq!(car, "a");
assert_eq!(cdr, 42);
source

pub fn iter(&self) -> Iter<'_>

Obtains an iterator yielding references to all the cons cells in this linked list.

for cell in Cons::new(1, Cons::new(2, Value::Null)).iter() {
   println!("list element: {}", cell.car());
}
source

pub fn into_vec(self) -> (Vec<Value>, Value)

Converts self into a vector without cloning the elements.

Returns the accumulated items of the list and the cdr of the last list element. For proper lists, this will always be Value::Null.

let list = Cons::new(1, Cons::new(2, Cons::new(3, Value::Null)));
assert_eq!(list.into_vec(), (vec![Value::from(1), Value::from(2), Value::from(3)], Value::Null));
source

pub fn to_vec(&self) -> (Vec<Value>, Value)

Retrieves a vector, cloning the values.

Returns the accumulated items of the list and the cdr of the last list element. For proper lists, this will always be Value::Null.

let list = Cons::new(1, Cons::new(2, Cons::new(3, Value::Null)));
assert_eq!(list.to_vec(), (vec![Value::from(1), Value::from(2), Value::from(3)], Value::Null));
source

pub fn to_ref_vec(&self) -> (Vec<&Value>, &Value)

Retrieves a vector, taking references to the values.

Returns the accumulated items of the list and the cdr of the last list element. For proper lists, this will always be Value::Null.

let list = Cons::new(1, Cons::new(2, Cons::new(3, Value::Null)));
assert_eq!(list.to_ref_vec(), (vec![&Value::from(1), &Value::from(2), &Value::from(3)], &Value::Null));
source

pub fn list_iter(&self) -> ListIter<'_>

Returns an iterator that returns each element (car field) of a singly-linked list.

The iterator returns None if a terminating value is encountered. For a dotted list, the iterator is not yet exhausted at that point, and produces the non-Null terminating value next.

Trait Implementations§

source§

impl Clone for Cons

source§

fn clone(&self) -> Cons

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Cons

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<Cons> for Value

source§

fn from(pair: Cons) -> Self

Converts to this type from the input type.
source§

impl<'a> IntoIterator for &'a Cons

§

type Item = &'a Cons

The type of the elements being iterated over.
§

type IntoIter = Iter<'a>

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Iter<'a>

Creates an iterator from a value. Read more
source§

impl IntoIterator for Cons

source§

fn into_iter(self) -> IntoIter

Obtains an iterator yielding the contents of the elements of this linked list.

The returned iterator transfers ownership of the values contained in the list to the consumer of the iterator. For each cons cell but the last, the iterator yields a pair containing the value in the cell’s car field and None. For the last cell, the yielded pair will contain the value of car and Some(cdr).

let vec: Vec<_> = Cons::new(1, Cons::new(2, 3)).into_iter().collect();
assert_eq!(vec, vec![(Value::from(1), None), (Value::from(2), Some(Value::from(3)))]);
§

type Item = (Value, Option<Value>)

The type of the elements being iterated over.
§

type IntoIter = IntoIter

Which kind of iterator are we turning this into?
source§

impl PartialEq<Cons> for Cons

source§

fn eq(&self, other: &Cons) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl StructuralPartialEq for Cons

Auto Trait Implementations§

§

impl RefUnwindSafe for Cons

§

impl Send for Cons

§

impl Sync for Cons

§

impl Unpin for Cons

§

impl UnwindSafe for Cons

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.