Skip to main content

hara_native/core/
value.rs

1#[derive(Debug, Clone, PartialEq, Eq)]
2pub struct ExceptionSite {
3    pub namespace: Option<String>,
4    pub resource: Option<String>,
5    pub line: usize,
6    pub column: usize,
7}
8
9#[derive(Debug, Clone, Default)]
10pub struct ExceptionProvenance {
11    pub created_at: Option<ExceptionSite>,
12    pub throws: Vec<ExceptionSite>,
13}
14
15#[derive(Debug, Clone)]
16pub struct ExceptionInfo {
17    pub message: String,
18    pub data: Box<Value>,
19    pub cause: Option<Box<Value>>,
20    pub provenance: Rc<RefCell<ExceptionProvenance>>,
21}
22
23/// A callable frame collected while an evaluation boundary has tracing
24/// enabled.  Keep this structured until a presentation boundary chooses how
25/// to render it: editor clients need the namespace and source site separately
26/// from the human-readable stack label.
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct TraceFrame {
29    pub name: String,
30    pub namespace: Option<String>,
31    pub site: Option<ExceptionSite>,
32}
33
34impl TraceFrame {
35    pub fn label(&self) -> String {
36        let label = self
37            .namespace
38            .as_ref()
39            .map(|namespace| format!("{namespace}/{}", self.name))
40            .unwrap_or_else(|| self.name.clone());
41        match &self.site {
42            Some(site) if site.line > 0 => format!("{label} @ {}:{}", site.line, site.column),
43            _ => label,
44        }
45    }
46}
47
48fn default_exception_class(code: &Keyword) -> Option<Keyword> {
49    if code.get_namespace() != Some("hara") {
50        return None;
51    }
52    let class = match code.get_name() {
53        "security" | "timeout" | "not-found" | "conflict" | "limit" | "syntax" | "io"
54        | "database" | "dependency" | "serialization" | "argument" | "state" | "host" => {
55            code.get_name()
56        }
57        "generic" => "internal",
58        _ => return None,
59    };
60    Keyword::parse(&format!("ex.class/{class}")).ok()
61}
62
63fn normalize_exception_code(code: &Keyword) -> Result<Keyword, String> {
64    if code.get_namespace().is_some() {
65        return Ok(code.clone());
66    }
67    let canonical = Keyword::parse(&format!("hara/{}", code.get_name()))?;
68    if default_exception_class(&canonical).is_some() {
69        Ok(canonical)
70    } else {
71        Err("ex expects a registered standard keyword or namespaced keyword code".into())
72    }
73}
74
75pub(crate) fn record_exception_throw(value: &Value, site: Option<ExceptionSite>) {
76    let (Value::ExceptionInfo(exception), Some(site)) = (value, site) else {
77        return;
78    };
79    let mut provenance = exception.provenance.borrow_mut();
80    provenance.throws.push(site);
81}
82
83pub(crate) fn record_exception_creation(value: &Value, site: Option<ExceptionSite>) {
84    let (Value::ExceptionInfo(exception), Some(site)) = (value, site) else {
85        return;
86    };
87    let mut provenance = exception.provenance.borrow_mut();
88    if provenance.created_at.is_none() {
89        provenance.created_at = Some(site);
90    }
91}
92
93pub(crate) fn exception_site_value(site: &ExceptionSite) -> Value {
94    Value::Map(
95        [
96            (
97                "namespace",
98                site.namespace
99                    .clone()
100                    .map(Value::String)
101                    .unwrap_or(Value::Nil),
102            ),
103            (
104                "resource",
105                site.resource
106                    .clone()
107                    .map(Value::String)
108                    .unwrap_or(Value::Nil),
109            ),
110            ("line", Value::Number(site.line as i64)),
111            ("column", Value::Number(site.column as i64)),
112        ]
113        .into_iter()
114        .map(|(key, value)| (Value::Keyword(key.into()), value))
115        .collect(),
116    )
117}
118
119pub(crate) fn exception_provenance_value(exception: &ExceptionInfo) -> Value {
120    let provenance = exception.provenance.borrow();
121    Value::Map(
122        [
123            (
124                Value::Keyword("ex/created-at".into()),
125                provenance
126                    .created_at
127                    .as_ref()
128                    .map(exception_site_value)
129                    .unwrap_or(Value::Nil),
130            ),
131            (
132                Value::Keyword("ex/throws".into()),
133                Value::Vector(provenance.throws.iter().map(exception_site_value).collect()),
134            ),
135        ]
136        .into_iter()
137        .collect(),
138    )
139}
140
141#[derive(Debug, Clone)]
142pub enum Value {
143    Number(i64),
144    Float(f64),
145    BigInteger(BigInt),
146    Character(char),
147    Regex(String),
148    Tagged(Box<PTaggedLiteral<Value>>),
149    Bool(bool),
150    String(String),
151    Keyword(Keyword),
152    Bytes(Vec<u8>),
153    ByteBuffer(Rc<RefCell<Vec<u8>>>),
154    Array(Rc<RefCell<Vec<Value>>>),
155    Object(Rc<RefCell<Vec<(String, Value)>>>),
156    Promise(Promise),
157    Atom(Box<RuntimeAtom>),
158    Recur(Vec<Value>),
159    Map(PMap<Value, Value>),
160    OrderedMap(Box<POrderedMap<Value, Value>>),
161    SortedMap(Box<PSortedMap<Value, Value>>),
162    Trie(Box<PTrie<Value>>),
163    Set(PSet<Value>),
164    OrderedSet(Box<POrderedSet<Value>>),
165    SortedSet(Box<PSortedSet<Value>>),
166    List(PList<Value>),
167    Cons(Box<PCons<Value>>),
168    Deque(Box<PDeque<Value>>),
169    Queue(Box<PQueue<Value>>),
170    PriorityMap(Box<PPriorityMap<Value, Value>>),
171    Symbol(Symbol),
172    Pointer(PPointer),
173    Function(Rc<Function>),
174    Tuple(Box<PTuple<Value>>),
175    Vector(PVector<Value>),
176    MapEntry(Box<PMapEntry>),
177    MutableCollection(Rc<RefCell<Option<MutableCollection>>>),
178    Seq(Box<PSeq<Result<Value, String>>>),
179    Iterator(Rc<RefCell<IteratorState>>),
180    Var(KernelVar<Value>),
181    Namespace(Rc<crate::kernel::Namespace<Value>>),
182    Extension(ExtensionValue),
183    StructType(Rc<StructType>),
184    Struct(Rc<StructValue>),
185    MutableType(Rc<MutableType>),
186    Mutable(Rc<MutableValue>),
187    Protocol(Rc<GuestProtocol>),
188    NativeType(Rc<NativeType>),
189    Schema(Rc<RuntimeSchema>),
190    Coroutine(Rc<Coroutine>),
191    Stream(Rc<RuntimeStream>),
192    Result(Rc<ResultValue>),
193    ExceptionInfo(Rc<ExceptionInfo>),
194    Nil,
195}
196
197/// Rebuilds a persistent runtime value while allowing a caller to substitute
198/// selected leaves.  Snapshot boundaries use this to turn process-local
199/// callable Vars into portable references before HTA encoding, then resolve
200/// those references in the receiving Runtime.
201///
202/// The transformer deliberately rejects lazy, mutable, and host-owned values:
203/// carrying any of those across an image boundary would make the image look
204/// valid while silently changing its runtime semantics.
205pub(crate) fn transform_persistent_value(
206    value: &Value,
207    transform: &mut impl FnMut(&Value) -> Option<Result<Value, String>>,
208) -> Result<Value, String> {
209    if let Some(result) = transform(value) {
210        return result;
211    }
212    let nested = |value: &Value, transform: &mut _| transform_persistent_value(value, transform);
213    let pair = |key: &Value, value: &Value, transform: &mut _| {
214        Ok((nested(key, transform)?, nested(value, transform)?))
215    };
216    match value {
217        Value::Tagged(value) => Ok(Value::Tagged(Box::new(PTaggedLiteral::new(
218            value.tag().clone(),
219            nested(value.form(), transform)?,
220        )))),
221        Value::Array(values) => Ok(Value::Array(Rc::new(RefCell::new(
222            values
223                .borrow()
224                .iter()
225                .map(|value| nested(value, transform))
226                .collect::<Result<Vec<_>, _>>()?,
227        )))),
228        Value::Object(values) => Ok(Value::Object(Rc::new(RefCell::new(
229            values
230                .borrow()
231                .iter()
232                .map(|(key, value)| Ok((key.clone(), nested(value, transform)?)))
233                .collect::<Result<Vec<_>, String>>()?,
234        )))),
235        Value::Atom(value) => Ok(Value::Atom(Box::new(RuntimeAtom::new(
236            nested(&value.deref_value(), transform)?,
237            value.watchable,
238        )))),
239        Value::Recur(values) => Ok(Value::Recur(
240            values
241                .iter()
242                .map(|value| nested(value, transform))
243                .collect::<Result<Vec<_>, _>>()?,
244        )),
245        Value::Map(values) => Ok(Value::Map(
246            values
247                .iter()
248                .map(|(key, value)| pair(key, value, transform))
249                .collect::<Result<Vec<_>, String>>()?
250                .into_iter()
251                .collect(),
252        )),
253        Value::OrderedMap(values) => Ok(Value::OrderedMap(Box::new(
254            values
255                .iter()
256                .map(|(key, value)| pair(key, value, transform))
257                .collect::<Result<Vec<_>, String>>()?
258                .into_iter()
259                .collect(),
260        ))),
261        Value::SortedMap(values) => Ok(Value::SortedMap(Box::new(
262            values
263                .iter()
264                .map(|(key, value)| pair(key, value, transform))
265                .collect::<Result<Vec<_>, String>>()?
266                .into_iter()
267                .collect(),
268        ))),
269        Value::Trie(values) => {
270            let entries = values
271                .entries()
272                .into_iter()
273                .map(|(key, value)| Ok((key, nested(&value, transform)?)))
274                .collect::<Result<Vec<_>, String>>()?;
275            Ok(Value::Trie(Box::new(
276                entries.into_iter().fold(PTrie::new(), |trie, (key, value)| {
277                    trie.assoc_value(key, value)
278                }),
279            )))
280        }
281        Value::Set(values) => Ok(Value::Set(
282            values
283                .iter()
284                .map(|value| nested(value, transform))
285                .collect::<Result<Vec<_>, _>>()?
286                .into_iter()
287                .collect(),
288        )),
289        Value::OrderedSet(values) => Ok(Value::OrderedSet(Box::new(
290            values
291                .iter()
292                .map(|value| nested(value, transform))
293                .collect::<Result<Vec<_>, _>>()?
294                .into_iter()
295                .collect(),
296        ))),
297        Value::SortedSet(values) => Ok(Value::SortedSet(Box::new(
298            values
299                .iter()
300                .map(|value| nested(value, transform))
301                .collect::<Result<Vec<_>, _>>()?
302                .into_iter()
303                .collect(),
304        ))),
305        Value::List(values) => Ok(Value::List(
306            values
307                .iter()
308                .map(|value| nested(value, transform))
309                .collect::<Result<Vec<_>, _>>()?
310                .into_iter()
311                .collect(),
312        )),
313        Value::Cons(values) => {
314            let values = values
315                .iter()
316                .map(|value| nested(&value, transform))
317                .collect::<Result<Vec<_>, _>>()?;
318            let Some((first, rest)) = values.split_first() else {
319                return Err("cannot transform an empty cons".into());
320            };
321            Ok(Value::Cons(Box::new(PCons::new(
322                first.clone(),
323                rest.iter().cloned().collect(),
324            ))))
325        }
326        Value::Deque(values) => Ok(Value::Deque(Box::new(
327            values
328                .iter()
329                .map(|value| nested(value, transform))
330                .collect::<Result<Vec<_>, _>>()?
331                .into_iter()
332                .collect(),
333        ))),
334        Value::Queue(values) => Ok(Value::Queue(Box::new(
335            values
336                .iter()
337                .map(|value| nested(value, transform))
338                .collect::<Result<Vec<_>, _>>()?
339                .into_iter()
340                .collect(),
341        ))),
342        Value::PriorityMap(values) => Ok(Value::PriorityMap(Box::new(
343            values
344                .iter()
345                .map(|(key, value)| pair(&key, &value, transform))
346                .collect::<Result<Vec<_>, String>>()?
347                .into_iter()
348                .collect(),
349        ))),
350        Value::Tuple(values) => Ok(Value::Tuple(Box::new(PTuple::from_values(
351            values
352                .iter()
353                .map(|value| nested(value, transform))
354                .collect::<Result<Vec<_>, _>>()?,
355        )?))),
356        Value::Vector(values) => Ok(Value::Vector(
357            values
358                .iter()
359                .map(|value| nested(value, transform))
360                .collect::<Result<Vec<_>, _>>()?
361                .into_iter()
362                .collect(),
363        )),
364        Value::MapEntry(value) => Ok(Value::MapEntry(Box::new(PMapEntry::new(
365            nested(value.key(), transform)?,
366            nested(value.value(), transform)?,
367        )))),
368        Value::Pointer(value) => Ok(Value::Pointer(PPointer::new(
369            value.context().clone(),
370            value
371                .fields()
372                .iter()
373                .map(|(key, value)| pair(key, value, transform))
374                .collect::<Result<Vec<_>, String>>()?
375                .into_iter()
376                .collect(),
377        ))),
378        Value::Struct(value) => Ok(Value::Struct(Rc::new(StructValue::from_values(
379            value.ty.clone(),
380            value
381                .ordered_values()
382                .into_iter()
383                .map(|value| nested(value, transform))
384                .collect::<Result<Vec<_>, _>>()?,
385            value.metadata.clone(),
386        )?))),
387        Value::ExceptionInfo(value) => Ok(Value::ExceptionInfo(Rc::new(ExceptionInfo {
388            message: value.message.clone(),
389            data: Box::new(nested(&value.data, transform)?),
390            cause: value
391                .cause
392                .as_deref()
393                .map(|value| nested(value, transform).map(Box::new))
394                .transpose()?,
395            provenance: value.provenance.clone(),
396        }))),
397        Value::Result(value) => {
398            let context = nested(&value.context, transform)?;
399            match value.status {
400                ResultStatus::Success => Ok(Value::Result(Rc::new(ResultValue::success(
401                    nested(&value.data, transform)?,
402                    context,
403                )?))),
404                ResultStatus::Error => Ok(Value::Result(Rc::new(ResultValue::error(
405                    nested(&value.error_value(), transform)?,
406                    context,
407                )?))),
408            }
409        }
410        Value::ByteBuffer(_) | Value::Promise(_) | Value::MutableCollection(_) | Value::Seq(_)
411        | Value::Iterator(_) | Value::Extension(_) | Value::StructType(_) | Value::MutableType(_)
412        | Value::Mutable(_) | Value::Protocol(_) | Value::NativeType(_) | Value::Schema(_)
413        | Value::Coroutine(_) | Value::Stream(_) => Err(format!(
414            "cannot transform non-persistent value: {}",
415            value.display()
416        )),
417        _ => Ok(value.clone()),
418    }
419}
420
421const UUID_TAG: &str = "uuid";
422
423fn uuid_value_from_uuid(value: uuid::Uuid) -> Value {
424    Value::Tagged(Box::new(PTaggedLiteral::new(
425        Symbol::parse(UUID_TAG),
426        Value::String(value.hyphenated().to_string()),
427    )))
428}
429
430fn uuid_from_bytes(bytes: &[u8]) -> uuid::Uuid {
431    let digest = md5::compute(bytes);
432    let mut value = digest.0;
433    value[6] = (value[6] & 0x0f) | 0x30;
434    value[8] = (value[8] & 0x3f) | 0x80;
435    uuid::Uuid::from_bytes(value)
436}
437
438fn uuid_from_parts(most: i64, least: i64) -> uuid::Uuid {
439    let value = ((most as u64 as u128) << 64) | least as u64 as u128;
440    uuid::Uuid::from_u128(value)
441}
442
443fn uuid_from_value(value: &Value) -> Result<uuid::Uuid, String> {
444    match value {
445        Value::String(value) => uuid::Uuid::parse_str(value)
446            .map_err(|_| "Base/uuid expects a valid UUID string".into()),
447        Value::Bytes(value) => Ok(uuid_from_bytes(value)),
448        Value::ByteBuffer(value) => Ok(uuid_from_bytes(&value.borrow())),
449        Value::Keyword(value) => Ok(uuid_from_parts(
450            crate::lang::hash::java_string_hash(value.as_str()) as i64,
451            crate::lang::hash::java_string_hash(value.get_name()) as i64,
452        )),
453        _ => Err("Base/uuid expects a string, bytes, or keyword".into()),
454    }
455}
456
457fn random_uuid() -> uuid::Uuid {
458    let mut bytes = [0u8; 16];
459    getrandom::getrandom(&mut bytes)
460        .unwrap_or_else(|_| panic!("could not retrieve random bytes for uuid"));
461    bytes[6] = (bytes[6] & 0x0f) | 0x40;
462    bytes[8] = (bytes[8] & 0x3f) | 0x80;
463    uuid::Uuid::from_bytes(bytes)
464}
465
466pub(crate) fn uuid_value(values: &[Value]) -> Result<Value, String> {
467    let value = match values {
468        [] => random_uuid(),
469        [value] => uuid_from_value(value)?,
470        [Value::Number(most), Value::Number(least)] => uuid_from_parts(*most, *least),
471        _ if values.len() == 2 => {
472            return Err("Base/uuid expects two integer arguments".into())
473        }
474        _ => return Err("Base/uuid expects zero, one, or two arguments".into()),
475    };
476    Ok(uuid_value_from_uuid(value))
477}
478
479pub(crate) fn uuid_tag_value(value: Value) -> Result<Value, String> {
480    let Value::String(text) = value else {
481        return Err("#uuid expects a UUID string literal".into());
482    };
483    let uuid =
484        uuid::Uuid::parse_str(&text).map_err(|_| "#uuid expects a valid UUID string literal")?;
485    Ok(uuid_value_from_uuid(uuid))
486}
487
488pub(crate) fn uuid_text_from_tagged(value: &PTaggedLiteral<Value>) -> Option<&str> {
489    if value.tag().as_str() != UUID_TAG {
490        return None;
491    }
492    let Value::String(text) = value.form() else {
493        return None;
494    };
495    uuid::Uuid::parse_str(text)
496        .ok()
497        .filter(|uuid| uuid.hyphenated().to_string() == *text)
498        .map(|_| text.as_str())
499}
500
501pub(crate) fn is_uuid_tagged(value: &PTaggedLiteral<Value>) -> bool {
502    uuid_text_from_tagged(value).is_some()
503}
504
505#[derive(Debug, Clone)]
506pub enum MutableCollection {
507    Map(MutableMap<Value, Value>),
508    OrderedMap(MutableOrderedMap<Value, Value>),
509    SortedMap(MutableSortedMap<Value, Value>),
510    Trie(MutableTrie<Value>),
511    Set(MutableSet<Value>),
512    OrderedSet(MutableOrderedSet<Value>),
513    SortedSet(MutableSortedSet<Value>),
514    List(MutableList<Value>),
515    Queue(MutableQueue<Value>),
516    Vector(MutableVector<Value>),
517}
518
519fn named_field_key(field: &str) -> Value {
520    Value::Keyword(Keyword::from(field))
521}
522
523fn named_field_name(value: &Value) -> Option<&str> {
524    match value {
525        Value::String(name) => Some(name.as_str()),
526        Value::Keyword(name) if name.get_namespace().is_none() => Some(name.get_name()),
527        Value::Symbol(name) if name.get_namespace().is_none() => Some(name.get_name()),
528        _ => None,
529    }
530}
531
532impl StructValue {
533    pub(crate) fn from_values(
534        ty: Rc<StructType>,
535        values: Vec<Value>,
536        metadata: Option<Rc<Metadata>>,
537    ) -> Result<Self, String> {
538        if values.len() != ty.fields.len() {
539            return Err(format!("{} expects {} arguments", ty.name, ty.fields.len()));
540        }
541        let values = ty
542            .fields
543            .iter()
544            .zip(values)
545            .fold(POrderedMap::new(), |values, (field, value)| {
546                values.assoc_value(named_field_key(field), value)
547            });
548        Ok(Self {
549            ty,
550            values,
551            metadata,
552        })
553    }
554
555    pub(crate) fn get(&self, field: &str) -> Option<&Value> {
556        self.values.get(&named_field_key(field))
557    }
558
559    pub(crate) fn ordered_values(&self) -> Vec<&Value> {
560        self.ty
561            .fields
562            .iter()
563            .filter_map(|field| self.get(field))
564            .collect()
565    }
566
567    pub(crate) fn ordered_entries(&self) -> Vec<(Value, Value)> {
568        self.ty
569            .fields
570            .iter()
571            .filter_map(|field| {
572                self.get(field)
573                    .cloned()
574                    .map(|value| (named_field_key(field), value))
575            })
576            .collect()
577    }
578}
579
580impl MutableValue {
581    pub(crate) fn from_values(
582        ty: Rc<MutableType>,
583        values: Vec<Value>,
584        metadata: Option<Rc<Metadata>>,
585    ) -> Result<Self, String> {
586        if values.len() != ty.fields.len() {
587            return Err(format!("{} expects {} arguments", ty.name, ty.fields.len()));
588        }
589        Ok(Self {
590            ty,
591            values: Rc::new(RefCell::new(values)),
592            metadata,
593        })
594    }
595
596    fn field_index(&self, field: &str) -> Option<usize> {
597        self.ty
598            .fields
599            .iter()
600            .position(|candidate| candidate == field)
601    }
602
603    pub(crate) fn get(&self, field: &str) -> Option<Value> {
604        let index = self.field_index(field)?;
605        self.values.borrow().get(index).cloned()
606    }
607
608    pub(crate) fn set(&self, field: &str, replacement: Value) -> Result<Value, String> {
609        let index = self
610            .field_index(field)
611            .ok_or_else(|| format!("unknown mutable field: {field}"))?;
612        self.values.borrow_mut()[index] = replacement.clone();
613        Ok(replacement)
614    }
615
616    pub(crate) fn ordered_values(&self) -> Vec<Value> {
617        self.values.borrow().clone()
618    }
619
620    pub(crate) fn ordered_entries(&self) -> Vec<(Value, Value)> {
621        self.ty
622            .fields
623            .iter()
624            .cloned()
625            .zip(self.ordered_values())
626            .map(|(field, value)| (named_field_key(&field), value))
627            .collect()
628    }
629
630    fn same_identity(&self, other: &Self) -> bool {
631        Rc::ptr_eq(&self.values, &other.values)
632    }
633
634    fn identity_address(&self) -> usize {
635        Rc::as_ptr(&self.values) as usize
636    }
637}
638
639#[derive(Clone)]
640pub struct Function {
641    params: Vec<String>,
642    variadic: Option<String>,
643    patterns: Vec<Form>,
644    variadic_pattern: Option<Form>,
645    body: Vec<Form>,
646    captured: Rc<RefCell<HashMap<String, Value>>>,
647    pub name: Option<String>,
648    /// Namespace in which the function body was defined. Lazy aliases and
649    /// qualified Vars are resolved against this namespace when invoked.
650    namespace: Option<String>,
651    native: Option<Rc<dyn Fn(Vec<Value>) -> Result<Value, String>>>,
652    fiber_native: Option<Rc<dyn Fn(Vec<Value>, Cont) -> Step>>,
653    /// Arity clauses for multi-arity `defn`/`fn` dispatchers; empty otherwise.
654    clauses: Vec<Rc<Function>>,
655    /// Runtime-neutral metadata attached through IObjType.
656    metadata: Option<Rc<Metadata>>,
657    /// Whether this function is a macro expander.
658    is_macro: bool,
659}
660
661impl Function {
662    pub(crate) fn accepts_arity(&self, argument_count: usize) -> bool {
663        if !self.clauses.is_empty() {
664            return self
665                .clauses
666                .iter()
667                .any(|clause| clause.accepts_arity(argument_count));
668        }
669        self.variadic.is_some() && argument_count >= self.params.len()
670            || self.variadic.is_none() && argument_count == self.params.len()
671    }
672
673    /// Returns the symbol that identifies this callable's definition.
674    /// Named source functions use their defining namespace as the origin;
675    /// native callables may already carry a qualified display name.
676    pub(crate) fn origin_symbol(&self) -> Option<Symbol> {
677        let name = self.name.as_deref()?;
678        if name.contains('/') {
679            Some(Symbol::parse(name))
680        } else {
681            Some(Symbol::create(self.namespace.as_deref(), name))
682        }
683    }
684}
685
686#[derive(Clone)]
687pub(crate) struct MultiMethod {
688    dispatch: Rc<Function>,
689    methods: Vec<(Value, Rc<Function>)>,
690    default: Option<Rc<Function>>,
691}
692
693impl std::fmt::Debug for Function {
694    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
695        formatter
696            .debug_struct("Function")
697            .field("params", &self.params)
698            .field("variadic", &self.variadic)
699            .field("name", &self.name)
700            .field("native", &self.native.is_some())
701            .finish()
702    }
703}
704
705/// State of a portable coroutine value.
706pub enum CoroutineState {
707    /// The body has not started yet; stores the body function.
708    New(Value),
709    /// Parked at a yield/await; stores the continuation that resumes the body.
710    Suspended(Box<dyn FnOnce(Value) -> Step>),
711    /// Currently executing on a fiber.
712    Running,
713    /// Completed, closed, or killed by an error.
714    Dead,
715}
716
717impl std::fmt::Debug for CoroutineState {
718    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
719        match self {
720            Self::New(_) => formatter.debug_tuple("New").finish(),
721            Self::Suspended(_) => formatter.debug_tuple("Suspended").finish(),
722            Self::Running => formatter.write_str("Running"),
723            Self::Dead => formatter.write_str("Dead"),
724        }
725    }
726}
727
728/// A re-entrant coroutine implemented with the fiber/CPS evaluator.
729pub struct Coroutine {
730    pub state: RefCell<CoroutineState>,
731}
732
733impl std::fmt::Debug for Coroutine {
734    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
735        formatter
736            .debug_struct("Coroutine")
737            .field("state", &self.state.borrow())
738            .finish()
739    }
740}
741
742impl Coroutine {
743    pub fn new(body: Value) -> Self {
744        Self {
745            state: RefCell::new(CoroutineState::New(body)),
746        }
747    }
748}
749
750pub struct RuntimeStream {
751    source: RuntimeStreamSource,
752    pending: Rc<Cell<bool>>,
753    closed: Rc<Cell<bool>>,
754}
755
756enum RuntimeStreamSource {
757    Coroutine {
758        coroutine: Rc<Coroutine>,
759        initial_arguments: RefCell<Option<Vec<Value>>>,
760    },
761    Guest {
762        next: Rc<Function>,
763        close: Option<Rc<Function>>,
764    },
765    Host {
766        next: Rc<dyn Fn() -> Result<Promise, String>>,
767        close: Rc<dyn Fn() -> Result<(), String>>,
768    },
769}
770
771impl std::fmt::Debug for RuntimeStream {
772    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
773        f.debug_struct("RuntimeStream")
774            .field("closed", &self.closed.get())
775            .finish()
776    }
777}
778
779impl RuntimeStream {
780    fn new(body: Value, initial_arguments: Vec<Value>) -> Self {
781        Self {
782            source: RuntimeStreamSource::Coroutine {
783                coroutine: Rc::new(Coroutine::new(body)),
784                initial_arguments: RefCell::new(Some(initial_arguments)),
785            },
786            pending: Rc::new(Cell::new(false)),
787            closed: Rc::new(Cell::new(false)),
788        }
789    }
790    fn host(
791        next: Rc<dyn Fn() -> Result<Promise, String>>,
792        close: Rc<dyn Fn() -> Result<(), String>>,
793    ) -> Self {
794        Self {
795            source: RuntimeStreamSource::Host { next, close },
796            pending: Rc::new(Cell::new(false)),
797            closed: Rc::new(Cell::new(false)),
798        }
799    }
800    fn guest(next: Rc<Function>, close: Option<Rc<Function>>) -> Self {
801        Self {
802            source: RuntimeStreamSource::Guest { next, close },
803            pending: Rc::new(Cell::new(false)),
804            closed: Rc::new(Cell::new(false)),
805        }
806    }
807}
808
809#[derive(Clone)]
810pub struct RuntimeAtom {
811    value: PAtom<Value>,
812    watches: Rc<RefCell<Vec<(Value, Rc<Function>)>>>,
813    watchable: bool,
814}
815
816impl RuntimeAtom {
817    pub(crate) fn new(value: Value, watchable: bool) -> Self {
818        Self {
819            value: PAtom::new(value),
820            watches: Rc::new(RefCell::new(Vec::new())),
821            watchable,
822        }
823    }
824    fn same_identity(&self, other: &Self) -> bool {
825        self.value.same_identity(&other.value)
826    }
827    fn identity_address(&self) -> usize {
828        self.value.identity_address()
829    }
830    pub(crate) fn deref_value(&self) -> Value {
831        self.value.deref_value()
832    }
833    pub(crate) fn reset(&self, new_value: Value) -> Result<Value, String> {
834        let old_value = self.value.deref_value();
835        let result = self.value.reset(new_value.clone())?;
836        self.notify(old_value, new_value)?;
837        Ok(result)
838    }
839    fn compare_and_set(&self, old: &Value, new_value: Value) -> Result<bool, String> {
840        let prior = self.value.deref_value();
841        let changed = self.value.compare_and_set(old, new_value.clone())?;
842        if changed {
843            self.notify(prior, new_value)?;
844        }
845        Ok(changed)
846    }
847    fn add_watch(&self, key: Value, function: Rc<Function>) -> Result<(), String> {
848        if !self.watchable {
849            return Err("watch-add expects a standard atom".into());
850        }
851        let mut watches = self.watches.borrow_mut();
852        watches.retain(|(candidate, _)| candidate != &key);
853        watches.push((key, function));
854        Ok(())
855    }
856    fn remove_watch(&self, key: &Value) -> Result<(), String> {
857        if !self.watchable {
858            return Err("watch-remove expects a standard atom".into());
859        }
860        self.watches
861            .borrow_mut()
862            .retain(|(candidate, _)| candidate != key);
863        Ok(())
864    }
865    fn watch_entries(&self) -> Result<Vec<Value>, String> {
866        if !self.watchable {
867            return Err("watch-list expects a standard atom".into());
868        }
869        self.watches
870            .borrow()
871            .iter()
872            .map(|(key, function)| {
873                vector_literal(vec![key.clone(), Value::Function(function.clone())])
874            })
875            .collect()
876    }
877    fn notify(&self, old_value: Value, new_value: Value) -> Result<(), String> {
878        let watches = self.watches.borrow().clone();
879        for (key, function) in watches {
880            call_function(
881                &function,
882                vec![
883                    key,
884                    Value::Atom(Box::new(self.clone())),
885                    old_value.clone(),
886                    new_value.clone(),
887                ],
888            )?;
889        }
890        Ok(())
891    }
892}
893
894impl std::fmt::Debug for RuntimeAtom {
895    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
896        formatter
897            .debug_struct("RuntimeAtom")
898            .finish_non_exhaustive()
899    }
900}
901
902fn function_definition_namespace() -> Option<String> {
903    namespace_registry()
904        .ok()
905        .map(|registry| registry.current().name().as_str().to_owned())
906}
907
908/// Builds a fixed-arity native callable for embedding-owned namespaces.
909pub fn native_function(
910    name: &str,
911    arity: usize,
912    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
913) -> Value {
914    let function = Rc::new(Function {
915        params: (0..arity).map(|index| format!("arg{index}")).collect(),
916        variadic: None,
917        patterns: Vec::new(),
918        variadic_pattern: None,
919        body: Vec::new(),
920        captured: Rc::new(RefCell::new(HashMap::new())),
921        name: Some(name.into()),
922        namespace: function_definition_namespace(),
923        native: Some(Rc::new(callback)),
924        fiber_native: None,
925        clauses: Vec::new(),
926        metadata: None,
927        is_macro: false,
928    });
929    debug_assert!(function.origin_symbol().is_some());
930    Value::Function(function)
931}
932
933/// A native function wrapper with an exact fixed parameter list and an
934/// optional rest marker: `params.len()` reflects the fixed arity so the
935/// multi-arity `select_clause` boundary can dispatch on it, unlike
936/// [`native_variadic_function`] whose parameter list is empty. Used by
937/// the bytecode VM for variadic closures (issue #223).
938pub(crate) fn native_fixed_variadic_function(
939    name: &str,
940    fixed_arity: usize,
941    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
942) -> Value {
943    let function = Rc::new(Function {
944        params: (0..fixed_arity)
945            .map(|index| format!("arg{index}"))
946            .collect(),
947        variadic: Some("rest".into()),
948        patterns: Vec::new(),
949        variadic_pattern: None,
950        body: Vec::new(),
951        captured: Rc::new(RefCell::new(HashMap::new())),
952        name: Some(name.into()),
953        namespace: function_definition_namespace(),
954        native: Some(Rc::new(callback)),
955        fiber_native: None,
956        clauses: Vec::new(),
957        metadata: None,
958        is_macro: false,
959    });
960    debug_assert!(function.origin_symbol().is_some());
961    Value::Function(function)
962}
963
964pub fn native_variadic_function(
965    name: &str,
966    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
967) -> Value {
968    let function = Rc::new(Function {
969        params: Vec::new(),
970        variadic: Some("arguments".into()),
971        patterns: Vec::new(),
972        variadic_pattern: None,
973        body: Vec::new(),
974        captured: Rc::new(RefCell::new(HashMap::new())),
975        name: Some(name.into()),
976        namespace: function_definition_namespace(),
977        native: Some(Rc::new(callback)),
978        fiber_native: None,
979        clauses: Vec::new(),
980        metadata: None,
981        is_macro: false,
982    });
983    debug_assert!(function.origin_symbol().is_some());
984    Value::Function(function)
985}
986
987pub(crate) fn native_fiber_function(
988    name: &str,
989    fixed_arity: usize,
990    variadic: bool,
991    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
992    fiber_callback: impl Fn(Vec<Value>, Cont) -> Step + 'static,
993) -> Value {
994    native_fiber_function_with_arity_error(
995        name,
996        fixed_arity,
997        variadic,
998        callback,
999        fiber_callback,
1000        |expectation, _received| format!("function expects {expectation} arguments"),
1001    )
1002}
1003
1004pub(crate) fn native_protocol_fiber_function(
1005    name: &str,
1006    protocol: &str,
1007    method: &str,
1008    fixed_arity: usize,
1009    variadic: bool,
1010    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
1011    fiber_callback: impl Fn(Vec<Value>, Cont) -> Step + 'static,
1012) -> Value {
1013    let display_name = format!("{protocol}/{method}");
1014    native_fiber_function_with_arity_error(
1015        name,
1016        fixed_arity,
1017        variadic,
1018        callback,
1019        fiber_callback,
1020        move |expectation, received| {
1021            format!(
1022                "protocol/arity: {display_name} expects {expectation} arguments, received {received}"
1023            )
1024        },
1025    )
1026}
1027
1028fn native_fiber_function_with_arity_error(
1029    name: &str,
1030    fixed_arity: usize,
1031    variadic: bool,
1032    callback: impl Fn(Vec<Value>) -> Result<Value, String> + 'static,
1033    fiber_callback: impl Fn(Vec<Value>, Cont) -> Step + 'static,
1034    arity_error: impl Fn(String, usize) -> String + 'static,
1035) -> Value {
1036    let fiber_callback = move |arguments: Vec<Value>, continuation: Cont| {
1037        let valid = if variadic {
1038            arguments.len() >= fixed_arity
1039        } else {
1040            arguments.len() == fixed_arity
1041        };
1042        if !valid {
1043            let expectation = if variadic {
1044                format!("at least {fixed_arity}")
1045            } else {
1046                fixed_arity.to_string()
1047            };
1048            return continuation(Err(arity_error(expectation, arguments.len())));
1049        }
1050        fiber_callback(arguments, continuation)
1051    };
1052    let function = Rc::new(Function {
1053        params: (0..fixed_arity)
1054            .map(|index| format!("arg{index}"))
1055            .collect(),
1056        variadic: variadic.then(|| "rest".into()),
1057        patterns: Vec::new(),
1058        variadic_pattern: None,
1059        body: Vec::new(),
1060        captured: Rc::new(RefCell::new(HashMap::new())),
1061        name: Some(name.into()),
1062        namespace: function_definition_namespace(),
1063        native: Some(Rc::new(callback)),
1064        fiber_native: Some(Rc::new(fiber_callback)),
1065        clauses: Vec::new(),
1066        metadata: None,
1067        is_macro: false,
1068    });
1069    debug_assert!(function.origin_symbol().is_some());
1070    Value::Function(function)
1071}
1072
1073pub(crate) fn exception_function_values() -> Vec<(&'static str, Value)> {
1074    vec![
1075        (
1076            "ex",
1077            native_variadic_function("ex", |arguments| {
1078                if arguments.len() < 2 || arguments.len() % 2 != 0 {
1079                    return Err("ex expects a code, attributes map, and key/value pairs".into());
1080                }
1081                let Value::Keyword(input_code) = &arguments[0] else {
1082                    return Err(
1083                        "ex expects a registered standard keyword or namespaced keyword code"
1084                            .into(),
1085                    );
1086                };
1087                let code = normalize_exception_code(input_code)?;
1088                let mut attributes = arguments[1].clone();
1089                for pair in arguments[2..].chunks_exact(2) {
1090                    attributes = map_assoc_value(&attributes, pair[0].clone(), pair[1].clone())?;
1091                }
1092                let Some(entries) = map_entries(&attributes) else {
1093                    return Err("ex expects an attributes map".into());
1094                };
1095                let lookup = |name: &str| {
1096                    entries.iter().find_map(|(key, value)| {
1097                        matches!(key, Value::Keyword(key_name) if key_name.as_str() == name)
1098                            .then_some(value)
1099                    })
1100                };
1101                let message = match lookup("ex/message") {
1102                    Some(Value::String(message)) => message.clone(),
1103                    Some(_) => return Err(":ex/message must be a string".into()),
1104                    None => format!(":{code}"),
1105                };
1106                if lookup("ex/code").is_some() {
1107                    return Err("ex attributes must not contain :ex/code; pass the code as the first argument".into());
1108                }
1109                if let Some(class) = lookup("ex/class") {
1110                    match class {
1111                        Value::Keyword(class) if class.get_namespace().is_some() => {
1112                            if let Some(expected) = default_exception_class(&code) {
1113                                if class != &expected {
1114                                    return Err(":ex/class conflicts with the registered class for :ex/code".into());
1115                                }
1116                            }
1117                        }
1118                        _ => return Err(":ex/class must be a namespaced keyword".into()),
1119                    }
1120                }
1121                let cause = match lookup("ex/cause") {
1122                    Some(cause @ Value::ExceptionInfo(_)) => Some(cause.clone()),
1123                    Some(_) => return Err(":ex/cause must be an Exception".into()),
1124                    None => None,
1125                };
1126                if let Some(context) = lookup("ex/context") {
1127                    if map_entries(context).is_none() {
1128                        return Err(":ex/context must be a map".into());
1129                    }
1130                }
1131                let mut data = map_assoc_value(
1132                    &attributes,
1133                    Value::Keyword("ex/code".into()),
1134                    Value::Keyword(code.clone()),
1135                )?;
1136                if lookup("ex/class").is_none() {
1137                    if let Some(class) = default_exception_class(&code) {
1138                        data = map_assoc_value(
1139                            &data,
1140                            Value::Keyword("ex/class".into()),
1141                            Value::Keyword(class),
1142                        )?;
1143                    }
1144                }
1145                if let Some(cause) = &cause {
1146                    data =
1147                        map_assoc_value(&data, Value::Keyword("ex/cause".into()), cause.clone())?;
1148                }
1149                let value = Value::ExceptionInfo(Rc::new(ExceptionInfo {
1150                    message,
1151                    cause: cause.map(Box::new),
1152                    data: Box::new(data),
1153                    provenance: Rc::new(RefCell::new(ExceptionProvenance {
1154                        created_at: None,
1155                        throws: Vec::new(),
1156                    })),
1157                }));
1158                record_exception_creation(&value, current_exception_site());
1159                Ok(value)
1160            }),
1161        ),
1162        (
1163            "ex-data",
1164            native_function("ex-data", 1, |arguments| match &arguments[0] {
1165                Value::ExceptionInfo(value) => Ok((*value.data).clone()),
1166                _ => Ok(Value::Nil),
1167            }),
1168        ),
1169        (
1170            "ex-message",
1171            native_function("ex-message", 1, |arguments| match &arguments[0] {
1172                Value::ExceptionInfo(value) => Ok(Value::String(value.message.clone())),
1173                Value::String(value) => Ok(Value::String(value.clone())),
1174                value => Ok(Value::String(value.display())),
1175            }),
1176        ),
1177        (
1178            "ex-cause",
1179            native_function("ex-cause", 1, |arguments| match &arguments[0] {
1180                Value::ExceptionInfo(value) => {
1181                    Ok(value.cause.as_deref().cloned().unwrap_or(Value::Nil))
1182                }
1183                _ => Err("ex-cause expects an Exception".into()),
1184            }),
1185        ),
1186        (
1187            "ex-provenance",
1188            native_function("ex-provenance", 1, |arguments| match &arguments[0] {
1189                Value::ExceptionInfo(value) => Ok(exception_provenance_value(value)),
1190                _ => Err("ex-provenance expects an Exception".into()),
1191            }),
1192        ),
1193        (
1194            "ex-class",
1195            native_function("ex-class", 1, |arguments| match &arguments[0] {
1196                Value::ExceptionInfo(value) => {
1197                    let Some(entries) = map_entries(&value.data) else {
1198                        return Err("Exception data must be a map".into());
1199                    };
1200                    match entries.iter().find_map(|(key, value)| {
1201                        matches!(key, Value::Keyword(name) if name.as_str() == "ex/class")
1202                            .then_some(value)
1203                    }) {
1204                        None => Ok(Value::Nil),
1205                        Some(Value::Keyword(class)) if class.get_namespace().is_some() => {
1206                            Ok(Value::Keyword(class.clone()))
1207                        }
1208                        Some(_) => Err(":ex/class must be a namespaced keyword".into()),
1209                    }
1210                }
1211                _ => Err("ex-class expects an Exception".into()),
1212            }),
1213        ),
1214        (
1215            "ex-native-type",
1216            native_function("ex-native-type", 1, |arguments| match &arguments[0] {
1217                Value::ExceptionInfo(_) => Ok(Value::Nil),
1218                _ => Err("ex-native-type expects an Exception".into()),
1219            }),
1220        ),
1221    ]
1222}
1223
1224pub(crate) fn direct_function_value(name: &str) -> Option<Value> {
1225    match name {
1226        "pair" => Some(native_function("pair", 2, |arguments| {
1227            Ok(Value::MapEntry(Box::new(PMapEntry::new(
1228                arguments[0].clone(),
1229                arguments[1].clone(),
1230            ))))
1231        })),
1232        "disj" => Some(native_variadic_function("disj", |arguments| {
1233            let (collection, values) = arguments
1234                .split_first()
1235                .ok_or_else(|| "disj expects a collection".to_string())?;
1236            let mut output = collection.clone();
1237            for value in values {
1238                if matches!(output, Value::Nil) {
1239                    break;
1240                }
1241                output = crate::core::protocol_intrinsic_call(
1242                    "std.protocol.idissoc.IDissoc/dissoc",
1243                    &[output, value.clone()],
1244                )?;
1245            }
1246            Ok(output)
1247        })),
1248        "quot" => Some(native_function("quot", 2, |arguments| {
1249            numeric::numeric_quotient(&arguments[0], &arguments[1])
1250        })),
1251        "rem" => Some(native_function("rem", 2, |arguments| {
1252            apply_binary_intrinsic(IntrinsicOp::Remainder, &arguments[0], &arguments[1])
1253        })),
1254        "mod" => Some(native_variadic_function("mod", |arguments| {
1255            if arguments.len() != 2 {
1256                return Err("mod expects arguments".into());
1257            }
1258            numeric::numeric_binary(ArithmeticOp::Modulo, &arguments[0], &arguments[1])
1259        })),
1260        _ => IntrinsicOp::from_symbol(name).map(|primitive| {
1261            native_variadic_function(name, move |arguments| {
1262                apply_intrinsic(primitive, &arguments)
1263            })
1264        }),
1265    }
1266}
1267
1268/// Creates a callable exported by a `std.native.*` namespace.
1269///
1270/// Native type methods must terminate in their Rust implementation. They must
1271/// not resolve their public HAL facade name and re-enter `eval`, because doing
1272/// so makes alias precedence part of native invocation and permits facade →
1273/// native → facade recursion.
1274pub fn native_type_function_value(native_type: &str, method: &str) -> Result<Value, String> {
1275    native_qualified_type_function_value(&format!("std.native.{native_type}"), method)
1276}
1277
1278/// Creates a callable owned by an explicitly qualified native type namespace.
1279///
1280/// Short type names deliberately continue to resolve through the closed
1281/// `std.native` compatibility surface; new host families must opt into their
1282/// full identity to avoid global alias collisions.
1283pub fn native_qualified_type_function_value(
1284    native_type: &str,
1285    method: &str,
1286) -> Result<Value, String> {
1287    let declaration = NATIVE_DECLARATIONS
1288        .iter()
1289        .find(|declaration| declaration.qualified_name() == native_type)
1290        .ok_or_else(|| {
1291            format!("missing annotated native declaration: {native_type}/{method}")
1292        })?;
1293    if !declaration.method(method) {
1294        return Err(format!("unknown annotated native method: {native_type}/{method}"));
1295    }
1296    (declaration.provider)(declaration.name, method)
1297}
1298
1299fn native_display_name(native_type: &str, method: &str) -> String {
1300    format!("std.native.{native_type}/{method}")
1301}
1302
1303fn native_base_provider(native_type: &str, method: &str) -> Result<Value, String> {
1304    let display_name = native_display_name(native_type, method);
1305    let method = method.to_owned();
1306    Ok(native_variadic_function(&display_name, move |arguments| {
1307        native_base_values(&method, &arguments)
1308    }))
1309}
1310
1311fn native_schema_provider(native_type: &str, method: &str) -> Result<Value, String> {
1312    let display_name = native_display_name(native_type, method);
1313    let method = method.to_owned();
1314    Ok(native_variadic_function(&display_name, move |arguments| {
1315        native_schema_values(&method, &arguments)
1316    }))
1317}
1318
1319fn native_string_provider(native_type: &str, method: &str) -> Result<Value, String> {
1320    let display_name = native_display_name(native_type, method);
1321    let operation = format!("str/{method}");
1322    Ok(native_variadic_function(&display_name, move |arguments| {
1323        string_operation(&operation, arguments)
1324    }))
1325}
1326
1327fn native_bytes_provider(native_type: &str, method: &str) -> Result<Value, String> {
1328    let display_name = native_display_name(native_type, method);
1329    let method = method.to_owned();
1330    Ok(native_variadic_function(&display_name, move |arguments| {
1331        native_bytes_operation(&method, arguments)
1332    }))
1333}
1334
1335fn native_iter_provider(native_type: &str, method: &str) -> Result<Value, String> {
1336    let display_name = native_display_name(native_type, method);
1337    let method = method.to_owned();
1338    Ok(native_variadic_function(&display_name, move |arguments| {
1339        native_iter_operation(&method, arguments)
1340    }))
1341}
1342
1343fn native_maths_provider(native_type: &str, method: &str) -> Result<Value, String> {
1344    let display_name = native_display_name(native_type, method);
1345    let method = method.to_owned();
1346    Ok(native_variadic_function(&display_name, move |arguments| {
1347        math_values(&method, arguments)
1348    }))
1349}
1350
1351fn native_num_provider(native_type: &str, method: &str) -> Result<Value, String> {
1352    let display_name = native_display_name(native_type, method);
1353    let method = method.to_owned();
1354    Ok(native_variadic_function(&display_name, move |arguments| {
1355        if arguments.len() != 1 {
1356            return Err(format!("{method} expects one value"));
1357        }
1358        number_conversion_value(&method, arguments.into_iter().next().unwrap())
1359    }))
1360}
1361
1362fn native_bits_provider(native_type: &str, method: &str) -> Result<Value, String> {
1363    let display_name = native_display_name(native_type, method);
1364    let method = method.to_owned();
1365    Ok(native_variadic_function(&display_name, move |arguments| {
1366        bit_values(&method, &arguments)
1367    }))
1368}
1369
1370fn native_kernel_provider(native_type: &str, method: &str) -> Result<Value, String> {
1371    let display_name = native_display_name(native_type, method);
1372    let method = method.to_owned();
1373    Ok(native_variadic_function(&display_name, move |arguments| {
1374        require_native_capability("Kernel", &method, "kernel")?;
1375        kernel_provider(&method)?(method.clone(), arguments)
1376    }))
1377}
1378
1379fn native_sandbox_provider(native_type: &str, method: &str) -> Result<Value, String> {
1380    let display_name = native_display_name(native_type, method);
1381    let operation = format!("sandbox-{method}");
1382    let method = method.to_owned();
1383    Ok(native_variadic_function(&display_name, move |arguments| {
1384        require_native_capability("Sandbox", &method, "sandbox")?;
1385        kernel_provider(&operation)?(operation.clone(), arguments)
1386    }))
1387}
1388
1389fn native_crypto_provider(native_type: &str, method: &str) -> Result<Value, String> {
1390    let display_name = native_display_name(native_type, method);
1391    let method = method.to_owned();
1392    Ok(native_variadic_function(&display_name, move |arguments| {
1393        native_crypto::operation(&method, arguments)
1394    }))
1395}
1396
1397fn native_document_provider(native_type: &str, method: &str) -> Result<Value, String> {
1398    let display_name = native_display_name(native_type, method);
1399    let method = method.to_owned();
1400    Ok(native_variadic_function(&display_name, move |arguments| {
1401        document_operation(&method, arguments)
1402    }))
1403}
1404
1405fn native_package_provider(native_type: &str, method: &str) -> Result<Value, String> {
1406    let display_name = native_display_name(native_type, method);
1407    let method = method.to_owned();
1408    Ok(native_variadic_function(&display_name, move |arguments| {
1409        require_native_capability("Package", &method, "kernel")?;
1410        native_package_values(&method, arguments, &mut HashMap::new())
1411    }))
1412}
1413
1414fn native_hbx_provider(native_type: &str, method: &str) -> Result<Value, String> {
1415    let display_name = native_display_name(native_type, method);
1416    let method = method.to_owned();
1417    Ok(native_variadic_function(&display_name, move |arguments| {
1418        hbx_operation(&method, arguments)
1419    }))
1420}
1421
1422fn native_instrument_provider(native_type: &str, method: &str) -> Result<Value, String> {
1423    let display_name = native_display_name(native_type, method);
1424    let method = method.to_owned();
1425    Ok(native_variadic_function(&display_name, move |arguments| {
1426        native_instrument_values(&method, arguments)
1427    }))
1428}
1429
1430fn native_os_provider(native_type: &str, method: &str) -> Result<Value, String> {
1431    let display_name = native_display_name(native_type, method);
1432    let native_type = native_type.to_owned();
1433    let method = method.to_owned();
1434    let operation = native_display_name(&native_type, &method);
1435    Ok(native_variadic_function(&display_name, move |arguments| {
1436        if native_type == "Process" {
1437            require_native_capability("Process", &method, "native-runtime")?;
1438        }
1439        os_values(&operation, arguments)
1440    }))
1441}
1442
1443fn native_file_provider(native_type: &str, method: &str) -> Result<Value, String> {
1444    let display_name = native_display_name(native_type, method);
1445    let method = method.to_owned();
1446    let operation = native_display_name(native_type, &method);
1447    Ok(native_variadic_function(&display_name, move |arguments| {
1448        require_native_capability("File", &method, "file")?;
1449        file_values(&operation, arguments)
1450    }))
1451}
1452
1453fn native_socket_provider(native_type: &str, method: &str) -> Result<Value, String> {
1454    let display_name = native_display_name(native_type, method);
1455    let method = method.to_owned();
1456    let operation = native_display_name(native_type, &method);
1457    Ok(native_variadic_function(&display_name, move |arguments| {
1458        require_native_capability("Socket", &method, "network")?;
1459        socket_values(&operation, arguments)
1460    }))
1461}
1462
1463fn native_promise_provider(native_type: &str, method: &str) -> Result<Value, String> {
1464    let display_name = native_display_name(native_type, method);
1465    let method = method.to_owned();
1466    Ok(native_variadic_function(&display_name, move |arguments| {
1467        native_promise_values(&method, arguments)
1468    }))
1469}
1470
1471fn native_coroutine_provider(native_type: &str, method: &str) -> Result<Value, String> {
1472    let display_name = native_display_name(native_type, method);
1473    match method {
1474        "create" => Ok(native_fiber_function(
1475            &display_name,
1476            1,
1477            false,
1478            native_coroutine_create,
1479            native_coroutine_create_fiber,
1480        )),
1481        "yield" => Ok(native_fiber_function(
1482            &display_name,
1483            1,
1484            false,
1485            native_coroutine_yield,
1486            native_coroutine_yield_fiber,
1487        )),
1488        "await" => Ok(native_fiber_function(
1489            &display_name,
1490            1,
1491            false,
1492            native_coroutine_await,
1493            native_coroutine_await_fiber,
1494        )),
1495        _ => Err(format!("unknown std.native.Coroutine operation: {method}")),
1496    }
1497}
1498
1499fn native_stream_provider(native_type: &str, method: &str) -> Result<Value, String> {
1500    let display_name = native_display_name(native_type, method);
1501    let method = method.to_owned();
1502    Ok(native_variadic_function(&display_name, move |arguments| {
1503        native_stream_values(&method, arguments)
1504    }))
1505}
1506
1507fn native_mutable_provider(native_type: &str, method: &str) -> Result<Value, String> {
1508    let display_name = native_display_name(native_type, method);
1509    let operation = native_display_name(native_type, method);
1510    Ok(native_variadic_function(&display_name, move |arguments| {
1511        native_mutable_values(&operation, arguments)
1512    }))
1513}
1514
1515fn native_runtime_provider(native_type: &str, method: &str) -> Result<Value, String> {
1516    let display_name = native_display_name(native_type, method);
1517    let method = method.to_owned();
1518    Ok(native_variadic_function(&display_name, move |arguments| {
1519        native_runtime_values(&method, arguments, &mut HashMap::new())
1520    }))
1521}
1522
1523fn native_printer_provider(native_type: &str, method: &str) -> Result<Value, String> {
1524    let display_name = native_display_name(native_type, method);
1525    let method = method.to_owned();
1526    Ok(native_variadic_function(&display_name, move |arguments| {
1527        native_printer_values(&method, arguments)
1528    }))
1529}
1530
1531fn native_edn_provider(native_type: &str, method: &str) -> Result<Value, String> {
1532    let display_name = native_display_name(native_type, method);
1533    let method = method.to_owned();
1534    Ok(native_variadic_function(&display_name, move |arguments| {
1535        native_edn_values(&method, arguments)
1536    }))
1537}
1538
1539fn native_json_provider(native_type: &str, method: &str) -> Result<Value, String> {
1540    let display_name = native_display_name(native_type, method);
1541    let method = method.to_owned();
1542    Ok(native_variadic_function(&display_name, move |arguments| {
1543        match (method.as_str(), arguments.as_slice()) {
1544            ("read", [Value::String(source)]) => crate::json::read(source),
1545            ("write", [value]) => crate::json::write(value).map(Value::String),
1546            ("pretty", [value, options]) if map_entries(options).is_some() => {
1547                crate::json::write_pretty(value).map(Value::String)
1548            }
1549            ("pretty", [_, _]) => Err("json/pretty expects an options map".into()),
1550            ("read", _) => Err("json/read expects a string".into()),
1551            ("write", _) => Err("json/write expects one value".into()),
1552            ("pretty", _) => Err("json/pretty expects a value and options map".into()),
1553            _ => Err(format!("unknown std.native.Json operation: {method}")),
1554        }
1555    }))
1556}
1557
1558fn native_host_provider(native_type: &str, method: &str) -> Result<Value, String> {
1559    let display_name = native_display_name(native_type, method);
1560    let method = method.to_owned();
1561    Ok(native_variadic_function(&display_name, move |arguments| {
1562        if !native_capability_granted("host-call") {
1563            return Ok(native_capability_denied_promise(
1564                "Host",
1565                &method,
1566                "host-call",
1567            ));
1568        }
1569        native_host_values(&method, arguments)
1570    }))
1571}
1572
1573fn native_test_provider(native_type: &str, method: &str) -> Result<Value, String> {
1574    let display_name = native_display_name(native_type, method);
1575    let method = method.to_owned();
1576    Ok(native_variadic_function(&display_name, move |arguments| {
1577        native_test_values(&method, arguments)
1578    }))
1579}
1580
1581fn native_command_provider(native_type: &str, method: &str) -> Result<Value, String> {
1582    let display_name = native_display_name(native_type, method);
1583    let method = method.to_owned();
1584    Ok(native_variadic_function(&display_name, move |arguments| {
1585        native_command_values(&method, arguments)
1586    }))
1587}
1588
1589fn native_regexp_provider(native_type: &str, method: &str) -> Result<Value, String> {
1590    let display_name = native_display_name(native_type, method);
1591    let method = method.to_owned();
1592    Ok(native_variadic_function(&display_name, move |arguments| {
1593        native_regex_values(&method, arguments)
1594    }))
1595}
1596
1597fn native_result_provider(native_type: &str, method: &str) -> Result<Value, String> {
1598    let display_name = native_display_name(native_type, method);
1599    let method = method.to_owned();
1600    Ok(native_variadic_function(&display_name, move |arguments| {
1601        native_result_values(&method, arguments)
1602    }))
1603}
1604
1605fn native_exception_provider(native_type: &str, method: &str) -> Result<Value, String> {
1606    let display_name = native_display_name(native_type, method);
1607    let method = method.to_owned();
1608    Ok(native_variadic_function(&display_name, move |arguments| {
1609        native_exception_values(&method, arguments)
1610    }))
1611}
1612
1613fn native_algo_provider(native_type: &str, method: &str) -> Result<Value, String> {
1614    let display_name = native_display_name(native_type, method);
1615    let operation = native_display_name(native_type, method);
1616    Ok(native_variadic_function(&display_name, move |arguments| {
1617        native_algo_values(&operation, arguments)
1618    }))
1619}
1620
1621fn native_work_provider(_native_type: &str, method: &str) -> Result<Value, String> {
1622    crate::work::guest::values()
1623        .into_iter()
1624        .find(|(name, _)| *name == method)
1625        .map(|(_, value)| value)
1626        .ok_or_else(|| format!("unknown std.native.Work operation: {method}"))
1627}
1628
1629fn native_lang_provider(native_type: &str, method: &str) -> Result<Value, String> {
1630    crate::lang_harness::function(native_type, method)
1631}
1632
1633fn native_coroutine_create(arguments: Vec<Value>) -> Result<Value, String> {
1634    match arguments.as_slice() {
1635        [Value::Function(function)] => Ok(Value::Coroutine(Rc::new(Coroutine::new(
1636            Value::Function(function.clone()),
1637        )))),
1638        _ => Err("Coroutine/create expects one function".into()),
1639    }
1640}
1641
1642fn native_coroutine_create_fiber(arguments: Vec<Value>, k: Cont) -> Step {
1643    match arguments.as_slice() {
1644        [Value::Function(function)] => k(Ok(Value::Coroutine(Rc::new(Coroutine::new(
1645            Value::Function(function.clone()),
1646        ))))),
1647        _ => k(Err("Coroutine/create expects one function".into())),
1648    }
1649}
1650
1651fn native_coroutine_yield(_arguments: Vec<Value>) -> Result<Value, String> {
1652    Err("Coroutine/yield requires the fiber evaluator".into())
1653}
1654
1655fn native_coroutine_yield_fiber(arguments: Vec<Value>, k: Cont) -> Step {
1656    match arguments.as_slice() {
1657        [value] => Step::Yield(value.clone(), Box::new(move |resumed| k(Ok(resumed)))),
1658        _ => k(Err("Coroutine/yield expects one value".into())),
1659    }
1660}
1661
1662fn native_coroutine_await(_arguments: Vec<Value>) -> Result<Value, String> {
1663    Err("Coroutine/await requires the fiber evaluator".into())
1664}
1665
1666fn native_coroutine_await_fiber(arguments: Vec<Value>, k: Cont) -> Step {
1667    match arguments.as_slice() {
1668        [Value::Var(reference)] => k(Ok(reference.deref_value())),
1669        [Value::Promise(promise)] => match promise.state() {
1670            PromiseState::Fulfilled(value) => k(Ok(value)),
1671            PromiseState::Rejected(error) => k(Err(crate::core::promise_rejection_error(error))),
1672            PromiseState::Pending => Step::Wait(
1673                promise.clone(),
1674                Box::new(move |state| match state {
1675                    PromiseState::Fulfilled(value) => k(Ok(value)),
1676                    PromiseState::Rejected(error) => {
1677                        k(Err(crate::core::promise_rejection_error(error)))
1678                    }
1679                    PromiseState::Pending => k(Err("Coroutine/await resumed pending".into())),
1680                }),
1681            ),
1682        },
1683        _ => k(Err("Coroutine/await expects a derefable (e.g. a promise)".into())),
1684    }
1685}
1686
1687fn native_reader_position_value(position: crate::kernel::Position) -> Value {
1688    Value::Map(PMap::from_iter([
1689        (Value::Keyword("offset".into()), Value::Number(position.offset as i64)),
1690        (Value::Keyword("line".into()), Value::Number(position.line as i64)),
1691        (
1692            Value::Keyword("column".into()),
1693            Value::Number(position.column as i64),
1694        ),
1695    ]))
1696}
1697
1698fn native_spanned_form_value(form: &crate::kernel::SpannedForm) -> Result<Value, String> {
1699    let children = form
1700        .children
1701        .iter()
1702        .map(native_spanned_form_value)
1703        .collect::<Result<Vec<_>, _>>()?;
1704    Ok(Value::Map(PMap::from_iter([
1705        (Value::Keyword("form".into()), form_to_value(&form.form)?),
1706        (
1707            Value::Keyword("start".into()),
1708            native_reader_position_value(form.span.start),
1709        ),
1710        (
1711            Value::Keyword("end".into()),
1712            native_reader_position_value(form.span.end),
1713        ),
1714        (
1715            Value::Keyword("children".into()),
1716            Value::Vector(PVector::from_iter(children)),
1717        ),
1718    ])))
1719}
1720
1721fn native_edn_values(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1722    match (method, arguments.as_slice()) {
1723        ("read", [Value::String(source)]) => read_edn(source),
1724        ("read-forms-spanned", [Value::String(source)]) => {
1725            let forms = crate::kernel::read_forms(source)
1726                .map_err(|error| format!("read-forms-spanned failed: {error}"))?;
1727            Ok(Value::Vector(PVector::from_iter(
1728                forms
1729                    .iter()
1730                    .map(native_spanned_form_value)
1731                    .collect::<Result<Vec<_>, _>>()?,
1732            )))
1733        }
1734        ("read-forms", [Value::String(path)]) => {
1735            if !(path.ends_with(".hal") || path.ends_with(".hrl")) {
1736                return Err("read-forms expects a .hal or .hrl path".into());
1737            }
1738            let promise = file_provider("read-forms")?
1739                .read(path)
1740                .map_err(|error| file_error("read-forms", error))?;
1741            let bytes = match promise.wait_state() {
1742                PromiseState::Fulfilled(Value::Bytes(bytes)) => bytes,
1743                PromiseState::Fulfilled(Value::ByteBuffer(bytes)) => bytes.borrow().clone(),
1744                PromiseState::Fulfilled(value) => {
1745                    return Err(format!(
1746                        "read-forms expected file bytes, got {}",
1747                        value.display()
1748                    ));
1749                }
1750                PromiseState::Rejected(error) => return Err(error.message()),
1751                PromiseState::Pending => return Err("read-forms file read is still pending".into()),
1752            };
1753            let source = String::from_utf8(bytes)
1754                .map_err(|_| format!("read-forms source is not UTF-8: {path}"))?;
1755            let forms = crate::kernel::parse_forms(&source)
1756                .map_err(|error| format!("read-forms failed: {error}"))?;
1757            Ok(Value::Vector(PVector::from_iter(
1758                forms
1759                    .iter()
1760                    .map(form_to_value)
1761                    .collect::<Result<Vec<_>, _>>()?,
1762            )))
1763        }
1764        ("write", [value]) => Ok(Value::String(value.display())),
1765        ("pretty", [value, options]) if map_entries(options).is_some() => {
1766            Ok(Value::String(value.display()))
1767        }
1768        ("pretty", [_, _]) => Err("edn/pretty expects an options map".into()),
1769        ("read", _) => Err("edn/read expects one string".into()),
1770        ("read-forms", _) => Err("read-forms expects a path string".into()),
1771        ("read-forms-spanned", _) => {
1772            Err("read-forms-spanned expects one source string".into())
1773        }
1774        ("write", _) => Err("std.native.Edn/write expects one value".into()),
1775        ("pretty", _) => Err("std.native.Edn/pretty expects a value and options map".into()),
1776        _ => Err(format!("unknown std.native.Edn operation: {method}")),
1777    }
1778}
1779
1780fn native_printer_values(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1781    match method {
1782        "capture" => {
1783            let [callable] = arguments.as_slice() else {
1784                return Err("Printer/capture expects one callable".into());
1785            };
1786            PRINTER_CAPTURES.with(|captures| captures.borrow_mut().push(String::new()));
1787            let result = call_value(callable.clone(), Vec::new());
1788            let output = PRINTER_CAPTURES.with(|captures| {
1789                captures
1790                    .borrow_mut()
1791                    .pop()
1792                    .expect("Printer/capture stack must contain the active capture")
1793            });
1794            result.map(|_| Value::String(output))
1795        }
1796        "p" | "println" => {
1797            let text = arguments
1798                .iter()
1799                .map(|value| match (method, value) {
1800                    ("p", Value::Nil) => String::new(),
1801                    ("p", Value::String(text)) => text.clone(),
1802                    ("p", Value::Character(character)) => character.to_string(),
1803                    (_, Value::String(text)) => text.clone(),
1804                    _ => value.display(),
1805                })
1806                .collect::<Vec<_>>()
1807                .join(if method == "println" { " " } else { "" });
1808            let output = if method == "println" {
1809                format!("{text}\n")
1810            } else {
1811                text
1812            };
1813            printer_write(&output)?;
1814            Ok(Value::Nil)
1815        }
1816        _ => Err(format!("unknown std.native.Printer operation: {method}")),
1817    }
1818}
1819
1820fn native_promise_values(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1821    match (method, arguments.as_slice()) {
1822        ("from", [value]) => Ok(Value::Promise(promise_from(value.clone()))),
1823        ("all", [values]) => Ok(Value::Promise(promise_all(iterator_values(
1824            values.clone(),
1825        )?))),
1826        ("run", [Value::Function(function)]) => {
1827            let function = function.clone();
1828            let context = crate::core::NativeCallbackContext::capture();
1829            let task = Rc::new(move || context.with(|| call_function(&function, Vec::new())));
1830            Ok(Value::Promise(promise_provider().run(task)))
1831        }
1832        ("new", [Value::Function(function)]) => {
1833            let promise = Promise::new();
1834            let resolving = promise.clone();
1835            let resolve = native_function("promise-resolve", 1, move |mut values| {
1836                let value = values.remove(0);
1837                settle_promise_result(&resolving, Ok(value.clone()));
1838                Ok(value)
1839            });
1840            let rejecting = promise.clone();
1841            let reject = native_function("promise-reject", 1, move |mut values| {
1842                let value = values.remove(0);
1843                rejecting.reject_value(value.clone());
1844                Ok(value)
1845            });
1846            if let Err(error) = call_function(function, vec![resolve, reject]) {
1847                promise.reject(error);
1848            }
1849            Ok(Value::Promise(promise))
1850        }
1851        ("delay", [millis, Value::Function(function)]) => {
1852            let millis = value_u64_integer(millis, "promise/delay")
1853                .map_err(|_| "promise/delay expects non-negative milliseconds".to_string())?;
1854            let function = function.clone();
1855            let context = crate::core::NativeCallbackContext::capture();
1856            let task = Rc::new(move || context.with(|| call_function(&function, Vec::new())));
1857            Ok(Value::Promise(
1858                promise_provider().delay(std::time::Duration::from_millis(millis), task),
1859            ))
1860        }
1861        ("run", _) => Err("promise/run expects one function".into()),
1862        ("new", [_]) => Err("promise/new expects a function".into()),
1863        ("new", _) => Err("promise/new expects one function".into()),
1864        ("from", _) => Err("promise/from expects one value".into()),
1865        ("all", _) => Err("promise/all expects one collection".into()),
1866        ("delay", _) => Err("promise/delay expects milliseconds and a function".into()),
1867        _ => Err(format!("unknown std.native.Promise operation: {method}")),
1868    }
1869}
1870
1871fn native_iter_operation(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1872    let unary = |label: &str| {
1873        arguments
1874            .first()
1875            .cloned()
1876            .filter(|_| arguments.len() == 1)
1877            .ok_or_else(|| format!("Iter/{label} expects one argument"))
1878    };
1879    let binary = |label: &str| {
1880        if arguments.len() == 2 {
1881            Ok((arguments[0].clone(), arguments[1].clone()))
1882        } else {
1883            Err(format!("Iter/{label} expects two arguments"))
1884        }
1885    };
1886    match method {
1887        "seq" => iterator_seq(unary(method)?),
1888        "iter" => make_iterator(unary(method)?),
1889        "iter-finite?" => Ok(Value::Bool(iterator_is_finite(&unary(method)?))),
1890        "iter-materialize" => Ok(Value::Vector(iterator_to_vec(unary(method)?)?.into())),
1891        "iter-next?" => iterator_has_next(&unary(method)?),
1892        "iter-next" => iterator_next(&unary(method)?),
1893        "iter-close" => iterator_close(&unary(method)?),
1894        "iter-concat" => iterator_concat(arguments),
1895        "iter-interleave" => iterator_interleave(arguments),
1896        "iter-zip" => iterator_zip(arguments),
1897        "iter-map" => {
1898            let (function, source) = binary(method)?;
1899            iterator_map(function, source)
1900        }
1901        "iter-filter" => {
1902            let (function, source) = binary(method)?;
1903            iterator_filter(function, source)
1904        }
1905        "iter-take-while" => {
1906            let (function, source) = binary(method)?;
1907            iterator_take_while(function, source)
1908        }
1909        "iter-drop-while" => {
1910            let (function, source) = binary(method)?;
1911            iterator_drop_while(function, source)
1912        }
1913        "iter-mapcat" => {
1914            let (function, source) = binary(method)?;
1915            iterator_mapcat(function, source)
1916        }
1917        "iter-keep" => {
1918            let (function, source) = binary(method)?;
1919            iterator_keep(function, source)
1920        }
1921        "iter-interpose" => {
1922            let (separator, source) = binary(method)?;
1923            iterator_interpose(separator, source)
1924        }
1925        "iter-every?" | "iter-any?" => {
1926            let (predicate, source) = binary(method)?;
1927            let iterator = make_iterator(source)?;
1928            let expect_every = method == "iter-every?";
1929            let result = (|| {
1930                while let Some(value) = iterator_try_next(&iterator)? {
1931                    let matched = call_value(predicate.clone(), vec![value])?.truthy();
1932                    if matched != expect_every {
1933                        return Ok(Value::Bool(!expect_every));
1934                    }
1935                }
1936                Ok(Value::Bool(expect_every))
1937            })();
1938            let close = iterator_close(&iterator);
1939            close?;
1940            result
1941        }
1942        "iter-take" | "iter-drop" => {
1943            let (amount, source) = binary(method)?;
1944            let amount = value_index(&amount)?;
1945            if method == "iter-take" {
1946                iterator_take(source, amount)
1947            } else {
1948                iterator_drop(source, amount)
1949            }
1950        }
1951        "iter-cycle" => iterator_cycle(unary(method)?),
1952        "iter-partition-pair" => iterator_partition(unary(method)?, 2, false),
1953        "iter-partition" | "iter-partition-all" => {
1954            let (amount, source) = binary(method)?;
1955            iterator_partition(source, value_index(&amount)?, method.ends_with("-all"))
1956        }
1957        "iter-range" => {
1958            let bounds = arguments
1959                .iter()
1960                .map(|value| {
1961                    numeric::to_i64_exact(value).map_err(|_| {
1962                        "iter-range bounds must fit signed 64-bit integers".to_string()
1963                    })
1964                })
1965                .collect::<Result<Vec<_>, _>>()?;
1966            let (start, end) = match bounds.as_slice() {
1967                [end] => (0, *end),
1968                [start, end] => (*start, *end),
1969                _ => return Err("iter-range expects an end or start and end".into()),
1970            };
1971            Ok(iterator_from_values(
1972                (start..end).map(Value::Number).collect(),
1973            ))
1974        }
1975        "iter-constantly" => Ok(iterator_constant(unary(method)?)),
1976        "iter-repeatedly" => Ok(iterator_repeated(unary(method)?)),
1977        "iter-iterate" => {
1978            let (function, seed) = binary(method)?;
1979            Ok(iterator_iterate(function, seed))
1980        }
1981        _ => Err(format!("unknown std.native.Iter operation: {method}")),
1982    }
1983}
1984
1985fn native_bytes_operation(method: &str, arguments: Vec<Value>) -> Result<Value, String> {
1986    match (method, arguments.as_slice()) {
1987        ("new", values) => native_bytes_new(values),
1988        ("count", [value]) => byte_count(value),
1989        ("get", [value, index]) => byte_get(value, index, None),
1990        ("get", [value, index, default]) => byte_get(value, index, Some(default.clone())),
1991        ("set", [value, index, item]) => byte_set(value, index, item),
1992        ("copy", [value]) => byte_copy(value),
1993        ("slice", [value, start]) => {
1994            let end = byte_count(value)?;
1995            byte_slice(value, start, &end)
1996        }
1997        ("slice", [value, start, end]) => byte_slice(value, start, end),
1998        ("u8" | "s8", [Value::Number(number)]) if (-128..=255).contains(number) => {
1999            let raw = (*number as i8) as u8;
2000            Ok(Value::Number(if method == "u8" {
2001                raw as i64
2002            } else {
2003                raw as i8 as i64
2004            }))
2005        }
2006        ("u8" | "s8", [_]) => Err(format!(
2007            "bytes/{method} expects a value in the range -128..255"
2008        )),
2009        _ => Err(format!(
2010            "std.native.Bytes/{method} received unsupported arguments"
2011        )),
2012    }
2013}
2014
2015fn native_bytes_new(values: &[Value]) -> Result<Value, String> {
2016    let values = values
2017        .iter()
2018        .map(|value| byte_input(value, "bytes"))
2019        .collect::<Result<Vec<_>, _>>()?;
2020    Ok(Value::ByteBuffer(Rc::new(RefCell::new(values))))
2021}
2022
2023/// Structural evaluator arms that are ordinary callable values.  Rust keeps
2024/// the implementations in `eval`, but exposes the names through real
2025/// `std.foundation` Vars just as the JVM runtime does.  Syntax and namespace
2026/// mutation forms deliberately remain structural and are never interned here.
2027pub(crate) fn syntax_symbol(name: &str) -> bool {
2028    const SYNTAX_FORMS: &[&str] = &[
2029        ".",
2030        "binding",
2031        "comment",
2032        "declare",
2033        "def",
2034        "defmacro",
2035        "defn",
2036        "do",
2037        "field",
2038        "fn",
2039        "if",
2040        "let",
2041        "letfn",
2042        "loop",
2043        "ns",
2044        "ns+",
2045        "quote",
2046        "read-forms",
2047        "recur",
2048        "require",
2049        "set!",
2050        "syntax-quote",
2051        "throw",
2052        "try",
2053        "var",
2054    ];
2055    SYNTAX_FORMS.contains(&name)
2056}
2057
2058pub fn with_macros<R>(
2059    macros: Rc<RefCell<HashMap<(String, String), Rc<Function>>>>,
2060    operation: impl FnOnce() -> R,
2061) -> R {
2062    ACTIVE_MACROS.with(|active| {
2063        let previous = active.replace(Some(macros));
2064        let result = operation();
2065        active.replace(previous);
2066        result
2067    })
2068}
2069
2070fn register_macro(namespace: &str, name: &str, function: Rc<Function>) -> Result<(), String> {
2071    ACTIVE_MACROS.with(|active| {
2072        active
2073            .try_borrow_mut()
2074            .map_err(|_| "macro registry is busy".into())
2075            .and_then(|opt| {
2076                if let Some(macros) = opt.as_ref() {
2077                    macros
2078                        .try_borrow_mut()
2079                        .map_err(|_| "macro registry is busy".into())
2080                        .map(|mut macros| {
2081                            macros.insert((namespace.into(), name.into()), function);
2082                        })
2083                } else {
2084                    Err("macro registry is unavailable".into())
2085                }
2086            })
2087    })
2088}
2089
2090fn resolve_macro_in(namespace: &str, name: &str) -> Option<Rc<Function>> {
2091    ACTIVE_MACROS.with(|active| {
2092        active.borrow().as_ref().and_then(|macros| {
2093            macros
2094                .borrow()
2095                .get(&(namespace.into(), name.into()))
2096                .cloned()
2097        })
2098    })
2099}
2100
2101pub(crate) fn resolve_macro(name: &str) -> Option<Rc<Function>> {
2102    if let Some((namespace, local)) = name.split_once('/') {
2103        let resolved = namespace_registry().ok().and_then(|registry| {
2104            let current = registry.current();
2105            if namespace == "-" {
2106                return Some(current.name().as_str().to_owned());
2107            }
2108            current
2109                .aliases()
2110                .into_iter()
2111                .find(|(alias, _)| alias.as_str() == namespace)
2112                .map(|(_, target)| target.name().as_str().to_owned())
2113        });
2114        return resolve_macro_in(resolved.as_deref().unwrap_or(namespace), local);
2115    }
2116    let current = namespace_registry()
2117        .map(|registry| registry.current().name().as_str().to_owned())
2118        .ok()?;
2119    resolve_macro_in(&current, name).or_else(|| resolve_macro_in("std.foundation", name))
2120}
2121
2122fn gensym(prefix: &str) -> String {
2123    let index = GENSYM_COUNTER.with(|counter| {
2124        let value = counter.get();
2125        counter.set(value + 1);
2126        value
2127    });
2128    format!("{prefix}{index}")
2129}
2130
2131pub(crate) fn form_to_value(form: &Form) -> Result<Value, String> {
2132    literal_value(form)
2133}
2134
2135fn metadata_value_to_form(value: &MetadataValue) -> Form {
2136    match value {
2137        MetadataValue::Nil => Form::Nil,
2138        MetadataValue::Boolean(value) => Form::Bool(*value),
2139        MetadataValue::Number(value) => Form::Number(*value),
2140        MetadataValue::Float(value) => Form::Float(*value),
2141        MetadataValue::BigInteger(value) => Form::BigInteger(value.clone()),
2142        MetadataValue::Character(value) => Form::Character(*value),
2143        MetadataValue::Regex(value) => Form::Regex(value.clone()),
2144        MetadataValue::Tagged(tag, value) => {
2145            Form::Tagged(tag.clone(), Box::new(metadata_value_to_form(value)))
2146        }
2147        MetadataValue::String(value) => Form::String(value.clone()),
2148        MetadataValue::Keyword(value) => Form::Keyword(value.as_str().into()),
2149        MetadataValue::Symbol(value) => Form::Symbol(value.as_str().into()),
2150        MetadataValue::Vector(values) => {
2151            Form::Vector(values.iter().map(metadata_value_to_form).collect())
2152        }
2153        MetadataValue::List(values) => {
2154            Form::List(values.iter().map(metadata_value_to_form).collect())
2155        }
2156        MetadataValue::Set(values) => {
2157            Form::Set(values.iter().map(metadata_value_to_form).collect())
2158        }
2159        MetadataValue::Map(values) => Form::Map(
2160            values
2161                .iter()
2162                .map(|(key, value)| (metadata_value_to_form(key), metadata_value_to_form(value)))
2163                .collect(),
2164        ),
2165    }
2166}
2167
2168pub(crate) fn value_to_form(value: &Value) -> Result<Form, String> {
2169    let form = match value {
2170        Value::Nil => Ok(Form::Nil),
2171        Value::Bool(value) => Ok(Form::Bool(*value)),
2172        Value::Number(value) => Ok(Form::Number(*value)),
2173        Value::Float(value) => Ok(Form::Float(*value)),
2174        Value::BigInteger(value) => Ok(Form::BigInteger(value.clone())),
2175        Value::Character(value) => Ok(Form::Character(*value)),
2176        Value::Regex(value) => Ok(Form::Regex(value.clone())),
2177        Value::String(value) => Ok(Form::String(value.clone())),
2178        Value::Keyword(value) => Ok(Form::Keyword(value.as_str().into())),
2179        Value::Symbol(value) => Ok(Form::Symbol(value.as_str().into())),
2180        Value::Tagged(value) => Ok(Form::Tagged(
2181            value.tag().get_name().into(),
2182            Box::new(value_to_form(value.form())?),
2183        )),
2184        Value::Pointer(value) => Ok(Form::Tagged(
2185            "ptr".into(),
2186            Box::new(value_to_form(&Value::Map(value.descriptor()))?),
2187        )),
2188        Value::List(values) => Ok(Form::List(
2189            values
2190                .iter()
2191                .map(|v| value_to_form(v))
2192                .collect::<Result<_, _>>()?,
2193        )),
2194        Value::Queue(values) => Ok(Form::List(
2195            values
2196                .iter()
2197                .map(|v| value_to_form(v))
2198                .collect::<Result<_, _>>()?,
2199        )),
2200        Value::Deque(values) => Ok(Form::List(
2201            values
2202                .iter()
2203                .map(|v| value_to_form(v))
2204                .collect::<Result<_, _>>()?,
2205        )),
2206        Value::Cons(values) => Ok(Form::List(
2207            values
2208                .iter()
2209                .map(|v| value_to_form(&v))
2210                .collect::<Result<_, _>>()?,
2211        )),
2212        Value::Vector(values) => Ok(Form::Vector(
2213            values
2214                .iter()
2215                .map(|v| value_to_form(v))
2216                .collect::<Result<_, _>>()?,
2217        )),
2218        Value::Tuple(values) => Ok(Form::Vector(
2219            values
2220                .iter()
2221                .map(|v| value_to_form(v))
2222                .collect::<Result<_, _>>()?,
2223        )),
2224        Value::MapEntry(entry) => Ok(Form::Vector(
2225            entry
2226                .iter()
2227                .map(value_to_form)
2228                .collect::<Result<_, _>>()?,
2229        )),
2230        Value::Set(_) | Value::OrderedSet(_) | Value::SortedSet(_) => Ok(Form::Set(
2231            set_items(value)
2232                .unwrap()
2233                .iter()
2234                .copied()
2235                .map(value_to_form)
2236                .collect::<Result<_, _>>()?,
2237        )),
2238        Value::Map(_)
2239        | Value::OrderedMap(_)
2240        | Value::SortedMap(_)
2241        | Value::Trie(_)
2242        | Value::PriorityMap(_) => Ok(Form::Map(
2243            map_entries(value)
2244                .unwrap()
2245                .into_iter()
2246                .map(|(key, value)| -> Result<(Form, Form), String> {
2247                    Ok((value_to_form(&key)?, value_to_form(&value)?))
2248                })
2249                .collect::<Result<_, _>>()?,
2250        )),
2251        value => Err(format!("cannot use {} as code", portable_type_name(value))),
2252    }?;
2253    Ok(match value_metadata(value) {
2254        Some(metadata) => Form::Metadata(
2255            Box::new(metadata_value_to_form(&MetadataValue::Map(
2256                metadata.entries().to_vec(),
2257            ))),
2258            Box::new(form),
2259        ),
2260        None => form,
2261    })
2262}
2263
2264pub(crate) fn bytecode_dynamic_bind(name: &str, value: Value) -> Result<(), String> {
2265    let registry = namespace_registry()?;
2266    let var = registry
2267        .resolve(&crate::lang::data::Symbol::parse(name))
2268        .ok_or_else(|| format!("binding expects a Var: {name}"))?;
2269    if !var.is_dynamic() {
2270        return Err(format!("binding expects a dynamic Var: {name}"));
2271    }
2272    var.bind(value);
2273    Ok(())
2274}
2275
2276pub(crate) fn bytecode_dynamic_unbind(name: &str) -> Result<(), String> {
2277    let registry = namespace_registry()?;
2278    let var = registry
2279        .resolve(&crate::lang::data::Symbol::parse(name))
2280        .ok_or_else(|| format!("binding expects a Var: {name}"))?;
2281    var.unbind().map(|_| ())
2282}
2283
2284fn macro_environment(env: &HashMap<String, Value>) -> Result<Value, String> {
2285    let namespace = namespace_registry()?.current().name().as_str().to_owned();
2286    let locals = env
2287        .iter()
2288        .filter(|(name, value)| !name.contains('/') && !matches!(value, Value::Var(_)))
2289        .map(|(name, _)| (Value::Symbol(Symbol::from(name.clone())), Value::Nil))
2290        .collect::<Vec<_>>();
2291    let entries = vec![
2292        (
2293            Value::Keyword(Keyword::from("ns")),
2294            Value::Symbol(Symbol::from(namespace)),
2295        ),
2296        (
2297            Value::Keyword(Keyword::from("locals")),
2298            Value::OrderedMap(Box::new(POrderedMap::from_iter(locals))),
2299        ),
2300        (
2301            Value::Keyword(Keyword::from("aliases")),
2302            Value::OrderedMap(Box::new(POrderedMap::new())),
2303        ),
2304    ];
2305    Ok(Value::OrderedMap(Box::new(POrderedMap::from_iter(entries))))
2306}
2307
2308fn macroexpand_call(
2309    name: &str,
2310    invocation: &[Form],
2311    env: &mut HashMap<String, Value>,
2312) -> Result<Option<Form>, String> {
2313    let function = match resolve_macro(name) {
2314        Some(function) => function,
2315        None => return Ok(None),
2316    };
2317    let mut arguments = Vec::with_capacity(invocation.len() + 1);
2318    arguments.push(form_to_value(&Form::List(invocation.to_vec()))?);
2319    arguments.push(macro_environment(env)?);
2320    for form in &invocation[1..] {
2321        arguments.push(form_to_value(form)?);
2322    }
2323    let expansion = call_function(&function, arguments)?;
2324    let expansion = value_to_form(&expansion)?;
2325    #[cfg(feature = "evaluation-journal")]
2326    evaluation_journal_macro(name, &Form::List(invocation.to_vec()), &expansion);
2327    Ok(Some(expansion))
2328}
2329
2330pub(crate) fn form_without_metadata(mut form: &Form) -> &Form {
2331    while let Form::Metadata(_, value) = form {
2332        form = value.as_ref();
2333    }
2334    form
2335}
2336
2337fn macro_clause_with_implicit_params(clause: &Form) -> Result<Form, String> {
2338    match form_without_metadata(clause) {
2339        Form::List(parts) if !parts.is_empty() => {
2340            let params = match form_without_metadata(&parts[0]) {
2341                Form::Vector(params) => params,
2342                _ => return Err("macro arity must start with a parameter vector".into()),
2343            };
2344            let mut implicit = vec![Form::Symbol("&form".into()), Form::Symbol("&env".into())];
2345            implicit.extend_from_slice(params);
2346            let mut new_parts = vec![Form::Vector(implicit)];
2347            new_parts.extend_from_slice(&parts[1..]);
2348            Ok(Form::List(new_parts))
2349        }
2350        _ => Err("macro arity must be a list".into()),
2351    }
2352}
2353
2354fn macroexpand_once(form: &Form, env: &mut HashMap<String, Value>) -> Result<Form, String> {
2355    match form {
2356        Form::List(values) if !values.is_empty() => {
2357            if let Form::Symbol(name) = &values[0] {
2358                if let Some(expanded) = macroexpand_call(name, values, env)? {
2359                    return Ok(expanded);
2360                }
2361            }
2362            Ok(form.clone())
2363        }
2364        _ => Ok(form.clone()),
2365    }
2366}
2367
2368pub(crate) fn vm_macroexpand(form: &Form) -> Result<Form, String> {
2369    let mut current = form.clone();
2370    let mut env = HashMap::new();
2371    for _ in 0..1000 {
2372        let expanded = macroexpand_once(&current, &mut env)?;
2373        if expanded == current {
2374            return Ok(current);
2375        }
2376        current = expanded;
2377    }
2378    Err("macro expansion exceeded 1000 steps".into())
2379}
2380
2381thread_local! {
2382    static TRACE_ENABLED: Cell<bool> = const { Cell::new(false) };
2383    static TRACE_STACK: RefCell<Vec<TraceFrame>> = const { RefCell::new(Vec::new()) };
2384    static TRACE_FAILURE_STACK: RefCell<Vec<TraceFrame>> = const { RefCell::new(Vec::new()) };
2385    #[cfg(feature = "evaluation-journal")]
2386    static EVALUATION_JOURNAL: RefCell<Option<crate::journal::JournalCollector>> = const { RefCell::new(None) };
2387    #[cfg(feature = "evaluation-journal")]
2388    static EVALUATION_JOURNAL_STACK: RefCell<Vec<crate::journal::OperationId>> = const { RefCell::new(Vec::new()) };
2389    static ACTIVE_MACROS: RefCell<Option<Rc<RefCell<HashMap<(String, String), Rc<Function>>>>>> =
2390        const { RefCell::new(None) };
2391    static GENSYM_COUNTER: Cell<u64> = const { Cell::new(0) };
2392}
2393
2394pub(crate) fn trace_stack_snapshot() -> Vec<TraceFrame> {
2395    TRACE_STACK.with(|stack| stack.borrow().clone())
2396}
2397
2398pub(crate) fn record_trace_failure() {
2399    if !tracing_enabled() {
2400        return;
2401    }
2402    let trace = trace_stack_snapshot();
2403    if !trace.is_empty() {
2404        TRACE_FAILURE_STACK.with(|failure| *failure.borrow_mut() = trace);
2405    }
2406}
2407
2408fn trace_failure_snapshot() -> Vec<TraceFrame> {
2409    TRACE_FAILURE_STACK.with(|stack| stack.borrow().clone())
2410}
2411
2412pub(crate) fn with_trace_stack<R>(trace: &[TraceFrame], operation: impl FnOnce() -> R) -> R {
2413    let previous = TRACE_STACK.with(|stack| {
2414        std::mem::replace(&mut *stack.borrow_mut(), trace.to_vec())
2415    });
2416    let result = operation();
2417    TRACE_STACK.with(|stack| {
2418        *stack.borrow_mut() = previous;
2419    });
2420    result
2421}
2422
2423pub(crate) fn trace_frame(
2424    name: String,
2425    namespace: Option<String>,
2426    site: Option<ExceptionSite>,
2427) -> TraceFrame {
2428    TraceFrame {
2429        name,
2430        namespace,
2431        site,
2432    }
2433}
2434
2435#[cfg(feature = "evaluation-journal")]
2436fn journal_preview(value: &Value) -> crate::journal::ValuePreview {
2437    EVALUATION_JOURNAL.with(|active| {
2438        active
2439            .borrow()
2440            .as_ref()
2441            .expect("evaluation journal must be active")
2442            .preview_value(portable_type_name(value), value.display())
2443    })
2444}
2445
2446#[cfg(feature = "evaluation-journal")]
2447fn evaluation_journal_enter(
2448    function: &Function,
2449    arguments: &[Value],
2450) -> Option<crate::journal::OperationId> {
2451    if EVALUATION_JOURNAL.with(|active| active.borrow().is_none()) {
2452        return None;
2453    }
2454    let values = arguments.iter().map(journal_preview).collect();
2455    let parent_operation = EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow().last().copied());
2456    let depth = EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow().len());
2457    EVALUATION_JOURNAL.with(|active| {
2458        let mut active = active.borrow_mut();
2459        let collector = active.as_mut()?;
2460        let operation = collector.next_operation_id();
2461        let mut event =
2462            crate::journal::JournalEvent::new(crate::journal::JournalEventKind::OperationEnter);
2463        event.operation = Some(operation);
2464        event.parent_operation = parent_operation;
2465        event.depth = depth;
2466        event.function = Some(
2467            function
2468                .name
2469                .clone()
2470                .unwrap_or_else(|| "<anonymous>".into()),
2471        );
2472        event.values = values;
2473        collector.record(event);
2474        EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow_mut().push(operation));
2475        Some(operation)
2476    })
2477}
2478
2479#[cfg(feature = "evaluation-journal")]
2480fn evaluation_journal_exit(
2481    operation: Option<crate::journal::OperationId>,
2482    function: &Function,
2483    result: Option<&Value>,
2484) {
2485    let Some(operation) = operation else { return };
2486    let value = result.map(journal_preview);
2487    EVALUATION_JOURNAL.with(|active| {
2488        if let Some(collector) = active.borrow_mut().as_mut() {
2489            let mut event = crate::journal::JournalEvent::new(
2490                crate::journal::JournalEventKind::OperationReturn,
2491            );
2492            event.operation = Some(operation);
2493            event.function = Some(
2494                function
2495                    .name
2496                    .clone()
2497                    .unwrap_or_else(|| "<anonymous>".into()),
2498            );
2499            event.values = value.into_iter().collect();
2500            collector.record(event);
2501        }
2502    });
2503    EVALUATION_JOURNAL_STACK.with(|stack| {
2504        let popped = stack.borrow_mut().pop();
2505        debug_assert_eq!(popped, Some(operation));
2506    });
2507}
2508
2509#[cfg(feature = "evaluation-journal")]
2510fn evaluation_journal_macro(name: &str, source: &Form, expansion: &Form) {
2511    let parent_operation = EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow().last().copied());
2512    let depth = EVALUATION_JOURNAL_STACK.with(|stack| stack.borrow().len());
2513    EVALUATION_JOURNAL.with(|active| {
2514        if let Some(collector) = active.borrow_mut().as_mut() {
2515            let mut event =
2516                crate::journal::JournalEvent::new(crate::journal::JournalEventKind::MacroExpand);
2517            event.parent_operation = parent_operation;
2518            event.depth = depth;
2519            event.function = Some(name.into());
2520            event.values = vec![
2521                collector.preview_value("form", source.to_string()),
2522                collector.preview_value("form", expansion.to_string()),
2523            ];
2524            collector.record(event);
2525        }
2526    });
2527}
2528
2529struct StackTraceGuard {
2530    previous: bool,
2531}
2532
2533impl StackTraceGuard {
2534    fn enable() -> Self {
2535        let previous = TRACE_ENABLED.with(|enabled| {
2536            let previous = enabled.get();
2537            enabled.set(true);
2538            previous
2539        });
2540        TRACE_STACK.with(|stack| stack.borrow_mut().clear());
2541        TRACE_FAILURE_STACK.with(|stack| stack.borrow_mut().clear());
2542        Self { previous }
2543    }
2544}
2545
2546/// Runs an execution boundary with Hara stack collection enabled.
2547///
2548/// Stack collection belongs to callable invocation, not to a second tree
2549/// evaluator. Fiber, bytecode, and other execution targets can share this
2550/// boundary while retaining the same opt-in error contract.
2551pub(crate) fn with_stack_trace<R>(operation: impl FnOnce() -> R) -> R {
2552    let _guard = StackTraceGuard::enable();
2553    operation()
2554}
2555
2556/// Runs an evaluation with trace collection and returns the frames before the
2557/// boundary resets its thread-local state.  The textual error contract remains
2558/// unchanged; embedding hosts can use this companion to build structured
2559/// diagnostics without parsing rendered stack lines.
2560pub fn with_stack_trace_snapshot<R>(operation: impl FnOnce() -> R) -> (R, Vec<TraceFrame>) {
2561    let _guard = StackTraceGuard::enable();
2562    let result = operation();
2563    let trace = {
2564        let failure = trace_failure_snapshot();
2565        if failure.is_empty() {
2566            trace_stack_snapshot()
2567        } else {
2568            failure
2569        }
2570    };
2571    (result, trace)
2572}
2573
2574impl Drop for StackTraceGuard {
2575    fn drop(&mut self) {
2576        TRACE_STACK.with(|stack| stack.borrow_mut().clear());
2577        TRACE_FAILURE_STACK.with(|stack| stack.borrow_mut().clear());
2578        TRACE_ENABLED.with(|enabled| enabled.set(self.previous));
2579    }
2580}
2581
2582fn tracing_enabled() -> bool {
2583    TRACE_ENABLED.with(Cell::get)
2584}
2585
2586pub(crate) fn append_trace(error: String) -> String {
2587    if !tracing_enabled() {
2588        return error;
2589    }
2590    record_trace_failure();
2591    let frames = TRACE_STACK.with(|stack| stack.borrow().iter().rev().cloned().collect::<Vec<_>>());
2592    if frames.is_empty() {
2593        return error;
2594    }
2595    if error.contains("\n[hara stack]") {
2596        return error;
2597    }
2598    format!(
2599        "{error}\n[hara stack]\n{}",
2600        frames
2601            .iter()
2602            .map(|frame| format!("  at {}", frame.label()))
2603            .collect::<Vec<_>>()
2604            .join("\n")
2605    )
2606}
2607
2608#[derive(Debug, Clone)]
2609enum IteratorGenerator {
2610    Seq(PSeq<Result<Value, String>>),
2611    Constant(Value),
2612    Repeated(Value),
2613    Iterate(Value, Value),
2614    Take(Value, usize),
2615    Drop(Value, usize),
2616    Cycle(Value, Vec<Value>, usize, bool),
2617    TakeWhile(Value, Value),
2618    DropWhile(Value, Value, bool),
2619    Map(Value, Value, bool),
2620    Filter(Value, Value),
2621    Mapcat(Value, Value, Option<Value>),
2622    Keep(Value, Value),
2623    Prepend(Option<Value>, Value),
2624    Concat(Vec<Value>, usize),
2625    Zip(Vec<Value>),
2626    Interleave(Vec<Value>, usize),
2627    Interpose(Value, Value, bool, Option<Value>),
2628    Partition(Value, usize, bool),
2629}
2630
2631#[derive(Debug, Clone)]
2632pub struct IteratorState {
2633    values: Vec<Value>,
2634    index: usize,
2635    closed: bool,
2636    cycle: bool,
2637    lookahead: Option<Value>,
2638    generator: Option<IteratorGenerator>,
2639}
2640
2641fn close_iterator_source(value: &Value) {
2642    if let Value::Iterator(iterator) = value {
2643        if let Ok(mut state) = iterator.try_borrow_mut() {
2644            state.close();
2645        }
2646    }
2647}
2648
2649impl IteratorState {
2650    fn new(values: Vec<Value>) -> Self {
2651        Self {
2652            values,
2653            index: 0,
2654            closed: false,
2655            cycle: false,
2656            lookahead: None,
2657            generator: None,
2658        }
2659    }
2660    fn generated(generator: IteratorGenerator) -> Self {
2661        Self {
2662            values: Vec::new(),
2663            index: 0,
2664            closed: false,
2665            cycle: false,
2666            lookahead: None,
2667            generator: Some(generator),
2668        }
2669    }
2670    pub(crate) fn is_finite(&self) -> bool {
2671        if self.closed || self.generator.is_none() {
2672            return true;
2673        }
2674        match self.generator.as_ref().unwrap() {
2675            IteratorGenerator::Seq(_) => false,
2676            IteratorGenerator::Constant(_)
2677            | IteratorGenerator::Repeated(_)
2678            | IteratorGenerator::Iterate(_, _)
2679            | IteratorGenerator::Cycle(_, _, _, _) => false,
2680            IteratorGenerator::Take(_, _) => true,
2681            IteratorGenerator::Drop(source, _)
2682            | IteratorGenerator::TakeWhile(_, source)
2683            | IteratorGenerator::DropWhile(_, source, _)
2684            | IteratorGenerator::Map(_, source, _)
2685            | IteratorGenerator::Filter(_, source)
2686            | IteratorGenerator::Keep(_, source)
2687            | IteratorGenerator::Prepend(_, source)
2688            | IteratorGenerator::Interpose(source, _, _, _)
2689            | IteratorGenerator::Partition(source, _, _) => value_iterator_is_finite(source),
2690            IteratorGenerator::Mapcat(_, _, _) => false,
2691            IteratorGenerator::Concat(sources, _) | IteratorGenerator::Interleave(sources, _) => {
2692                sources.iter().all(value_iterator_is_finite)
2693            }
2694            IteratorGenerator::Zip(sources) => sources.iter().any(value_iterator_is_finite),
2695        }
2696    }
2697    fn has_next(&mut self) -> Result<bool, String> {
2698        if self.lookahead.is_some() {
2699            return Ok(true);
2700        }
2701        match self.pull_next()? {
2702            Some(value) => {
2703                self.lookahead = Some(value);
2704                Ok(true)
2705            }
2706            None => Ok(false),
2707        }
2708    }
2709    fn try_next(&mut self) -> Result<Option<Value>, String> {
2710        if let Some(value) = self.lookahead.take() {
2711            return Ok(Some(value));
2712        }
2713        self.pull_next()
2714    }
2715    fn pull_next(&mut self) -> Result<Option<Value>, String> {
2716        if self.closed {
2717            return Ok(None);
2718        }
2719        if let Some(generator) = &mut self.generator {
2720            return match generator {
2721                IteratorGenerator::Seq(sequence) => match sequence.peek_first() {
2722                    None => {
2723                        self.closed = true;
2724                        Ok(None)
2725                    }
2726                    Some(result) => {
2727                        *sequence = sequence.pop_first();
2728                        result.map(Some)
2729                    }
2730                },
2731                IteratorGenerator::Constant(value) => Ok(Some(value.clone())),
2732                IteratorGenerator::Repeated(function) => {
2733                    call_value(function.clone(), Vec::new()).map(Some)
2734                }
2735                IteratorGenerator::Iterate(function, current) => {
2736                    let output = current.clone();
2737                    *current = call_value(function.clone(), vec![current.clone()])?;
2738                    Ok(Some(output))
2739                }
2740                IteratorGenerator::Take(source, remaining) => {
2741                    if *remaining == 0 {
2742                        close_iterator_source(source);
2743                        self.closed = true;
2744                        Ok(None)
2745                    } else {
2746                        *remaining -= 1;
2747                        let value = iterator_try_next(source)?;
2748                        if value.is_none() {
2749                            close_iterator_source(source);
2750                            self.closed = true;
2751                        }
2752                        Ok(value)
2753                    }
2754                }
2755                IteratorGenerator::Drop(source, remaining) => {
2756                    while *remaining > 0 {
2757                        if iterator_try_next(source)?.is_none() {
2758                            close_iterator_source(source);
2759                            self.closed = true;
2760                            return Ok(None);
2761                        }
2762                        *remaining -= 1;
2763                    }
2764                    let value = iterator_try_next(source)?;
2765                    if value.is_none() {
2766                        close_iterator_source(source);
2767                        self.closed = true;
2768                    }
2769                    Ok(value)
2770                }
2771                IteratorGenerator::Cycle(source, cache, index, exhausted) => {
2772                    if *index < cache.len() {
2773                        let value = cache[*index].clone();
2774                        *index += 1;
2775                        Ok(Some(value))
2776                    } else if *exhausted {
2777                        if cache.is_empty() {
2778                            self.closed = true;
2779                            Ok(None)
2780                        } else {
2781                            *index = 1;
2782                            Ok(Some(cache[0].clone()))
2783                        }
2784                    } else {
2785                        match iterator_try_next(source)? {
2786                            Some(value) => {
2787                                cache.push(value.clone());
2788                                *index += 1;
2789                                Ok(Some(value))
2790                            }
2791                            None => {
2792                                close_iterator_source(source);
2793                                *exhausted = true;
2794                                if cache.is_empty() {
2795                                    self.closed = true;
2796                                    Ok(None)
2797                                } else {
2798                                    *index = 1;
2799                                    Ok(Some(cache[0].clone()))
2800                                }
2801                            }
2802                        }
2803                    }
2804                }
2805                IteratorGenerator::TakeWhile(function, source) => {
2806                    let Some(value) = iterator_try_next(source)? else {
2807                        close_iterator_source(source);
2808                        self.closed = true;
2809                        return Ok(None);
2810                    };
2811                    if call_value(function.clone(), vec![value.clone()])?.truthy() {
2812                        Ok(Some(value))
2813                    } else {
2814                        close_iterator_source(source);
2815                        self.closed = true;
2816                        Ok(None)
2817                    }
2818                }
2819                IteratorGenerator::DropWhile(function, source, started) => loop {
2820                    let Some(value) = iterator_try_next(source)? else {
2821                        close_iterator_source(source);
2822                        self.closed = true;
2823                        break Ok(None);
2824                    };
2825                    if *started || !call_value(function.clone(), vec![value.clone()])?.truthy() {
2826                        *started = true;
2827                        break Ok(Some(value));
2828                    }
2829                },
2830                IteratorGenerator::Map(function, source, spread) => {
2831                    let Some(value) = iterator_try_next(source)? else {
2832                        close_iterator_source(source);
2833                        self.closed = true;
2834                        return Ok(None);
2835                    };
2836                    match value {
2837                        value if !*spread => call_value(function.clone(), vec![value]),
2838                        Value::Tuple(values) => {
2839                            call_value(function.clone(), values.iter().cloned().collect())
2840                        }
2841                        Value::Vector(values) => {
2842                            call_value(function.clone(), values.iter().cloned().collect())
2843                        }
2844                        value => call_value(function.clone(), vec![value]),
2845                    }
2846                    .map(Some)
2847                }
2848                IteratorGenerator::Filter(function, source) => loop {
2849                    let Some(value) = iterator_try_next(source)? else {
2850                        close_iterator_source(source);
2851                        self.closed = true;
2852                        break Ok(None);
2853                    };
2854                    if call_value(function.clone(), vec![value.clone()])?.truthy() {
2855                        break Ok(Some(value));
2856                    }
2857                },
2858                IteratorGenerator::Mapcat(function, source, pending) => loop {
2859                    if let Some(iterator) = pending {
2860                        match iterator_try_next(iterator)? {
2861                            Some(value) => break Ok(Some(value)),
2862                            None => {
2863                                close_iterator_source(iterator);
2864                                *pending = None;
2865                            }
2866                        }
2867                    }
2868                    let Some(value) = iterator_try_next(source)? else {
2869                        close_iterator_source(source);
2870                        self.closed = true;
2871                        break Ok(None);
2872                    };
2873                    *pending = Some(make_iterator(call_value(function.clone(), vec![value])?)?);
2874                },
2875                IteratorGenerator::Keep(function, source) => loop {
2876                    let Some(value) = iterator_try_next(source)? else {
2877                        close_iterator_source(source);
2878                        self.closed = true;
2879                        break Ok(None);
2880                    };
2881                    let mapped = call_value(function.clone(), vec![value])?;
2882                    if !matches!(mapped, Value::Nil) {
2883                        break Ok(Some(mapped));
2884                    }
2885                },
2886                IteratorGenerator::Prepend(head, source) => {
2887                    if let Some(value) = head.take() {
2888                        Ok(Some(value))
2889                    } else {
2890                        let value = iterator_try_next(source)?;
2891                        if value.is_none() {
2892                            close_iterator_source(source);
2893                            self.closed = true;
2894                        }
2895                        Ok(value)
2896                    }
2897                }
2898                IteratorGenerator::Concat(sources, index) => {
2899                    while *index < sources.len() {
2900                        match iterator_try_next(&sources[*index])? {
2901                            Some(value) => return Ok(Some(value)),
2902                            None => {
2903                                close_iterator_source(&sources[*index]);
2904                                *index += 1;
2905                            }
2906                        }
2907                    }
2908                    self.closed = true;
2909                    Ok(None)
2910                }
2911                IteratorGenerator::Zip(sources) => {
2912                    for source in sources.iter() {
2913                        if !matches!(iterator_has_next(source)?, Value::Bool(true)) {
2914                            for source in sources.iter() {
2915                                close_iterator_source(source);
2916                            }
2917                            self.closed = true;
2918                            return Ok(None);
2919                        }
2920                    }
2921                    let mut values = Vec::new();
2922                    for source in sources.iter() {
2923                        let Some(value) = iterator_try_next(source)? else {
2924                            for source in sources.iter() {
2925                                close_iterator_source(source);
2926                            }
2927                            self.closed = true;
2928                            return Ok(None);
2929                        };
2930                        values.push(value);
2931                    }
2932                    Ok(Some(Value::Vector(values.into())))
2933                }
2934                IteratorGenerator::Interleave(sources, index) => {
2935                    if sources.is_empty() {
2936                        self.closed = true;
2937                        return Ok(None);
2938                    }
2939                    if *index == 0 {
2940                        for source in sources.iter() {
2941                            if !matches!(iterator_has_next(source)?, Value::Bool(true)) {
2942                                for source in sources.iter() {
2943                                    close_iterator_source(source);
2944                                }
2945                                self.closed = true;
2946                                return Ok(None);
2947                            }
2948                        }
2949                    }
2950                    let source = &sources[*index];
2951                    let Some(value) = iterator_try_next(source)? else {
2952                        for source in sources.iter() {
2953                            close_iterator_source(source);
2954                        }
2955                        self.closed = true;
2956                        return Ok(None);
2957                    };
2958                    *index = (*index + 1) % sources.len();
2959                    Ok(Some(value))
2960                }
2961                IteratorGenerator::Interpose(source, separator, first, pending) => {
2962                    if let Some(value) = pending.take() {
2963                        return Ok(Some(value));
2964                    }
2965                    match iterator_try_next(source)? {
2966                        None => {
2967                            close_iterator_source(source);
2968                            self.closed = true;
2969                            Ok(None)
2970                        }
2971                        Some(value) if *first => {
2972                            *first = false;
2973                            Ok(Some(value))
2974                        }
2975                        Some(value) => {
2976                            *pending = Some(value);
2977                            Ok(Some(separator.clone()))
2978                        }
2979                    }
2980                }
2981                IteratorGenerator::Partition(source, amount, all) => {
2982                    let mut values = Vec::new();
2983                    for _ in 0..*amount {
2984                        match iterator_try_next(source)? {
2985                            Some(value) => values.push(value),
2986                            None => {
2987                                close_iterator_source(source);
2988                                self.closed = true;
2989                                if values.is_empty() || !*all {
2990                                    return Ok(None);
2991                                }
2992                                break;
2993                            }
2994                        }
2995                    }
2996                    if values.is_empty() {
2997                        self.closed = true;
2998                        Ok(None)
2999                    } else {
3000                        Ok(Some(Value::Vector(values.into())))
3001                    }
3002                }
3003            };
3004        }
3005        if self.values.is_empty() {
3006            self.closed = true;
3007            return Ok(None);
3008        }
3009        if self.cycle && self.index >= self.values.len() {
3010            self.index = 0;
3011        }
3012        if self.index >= self.values.len() {
3013            self.closed = true;
3014            return Ok(None);
3015        }
3016        let value = self.values[self.index].clone();
3017        self.index += 1;
3018        Ok(Some(value))
3019    }
3020    fn close(&mut self) {
3021        if self.closed {
3022            self.lookahead = None;
3023            return;
3024        }
3025        self.closed = true;
3026        self.lookahead = None;
3027        if let Some(generator) = &self.generator {
3028            match generator {
3029                IteratorGenerator::Constant(_)
3030                | IteratorGenerator::Repeated(_)
3031                | IteratorGenerator::Iterate(_, _)
3032                | IteratorGenerator::Seq(_) => {}
3033                IteratorGenerator::Take(source, _)
3034                | IteratorGenerator::Drop(source, _)
3035                | IteratorGenerator::Cycle(source, _, _, _)
3036                | IteratorGenerator::TakeWhile(_, source)
3037                | IteratorGenerator::DropWhile(_, source, _)
3038                | IteratorGenerator::Map(_, source, _)
3039                | IteratorGenerator::Filter(_, source)
3040                | IteratorGenerator::Keep(_, source)
3041                | IteratorGenerator::Prepend(_, source)
3042                | IteratorGenerator::Interpose(source, _, _, _)
3043                | IteratorGenerator::Partition(source, _, _) => close_iterator_source(source),
3044                IteratorGenerator::Mapcat(_, source, pending) => {
3045                    close_iterator_source(source);
3046                    if let Some(pending) = pending {
3047                        close_iterator_source(pending);
3048                    }
3049                }
3050                IteratorGenerator::Concat(sources, _)
3051                | IteratorGenerator::Zip(sources)
3052                | IteratorGenerator::Interleave(sources, _) => {
3053                    for source in sources {
3054                        close_iterator_source(source);
3055                    }
3056                }
3057            }
3058        }
3059    }
3060}
3061
3062fn value_iterator_is_finite(value: &Value) -> bool {
3063    match value {
3064        Value::Iterator(iterator) => iterator.borrow().is_finite(),
3065        Value::Seq(_) => false,
3066        _ => true,
3067    }
3068}
3069
3070#[inline(never)]
3071fn sequential_equality(left: &Value, right: &Value) -> Option<bool> {
3072    fn items(value: &Value) -> Option<Vec<Value>> {
3073        match value {
3074            Value::Seq(values) => values.iter().collect::<Result<Vec<_>, _>>().ok(),
3075            Value::List(values) => Some(values.iter().cloned().collect()),
3076            Value::Cons(values) => Some(values.iter().collect()),
3077            Value::Queue(values) => Some(values.iter().cloned().collect()),
3078            Value::Deque(values) => Some(values.iter().cloned().collect()),
3079            Value::Tuple(values) => Some(values.iter().cloned().collect()),
3080            Value::Vector(values) => Some(values.iter().cloned().collect()),
3081            _ => None,
3082        }
3083    }
3084    Some(items(left)? == items(right)?)
3085}
3086
3087/// Returns cloned entries for every map-like runtime representation.
3088/// Embedding hosts should use this instead of depending on a concrete
3089/// persistent-map implementation.
3090pub fn map_entries(value: &Value) -> Option<Vec<(Value, Value)>> {
3091    match value {
3092        Value::Map(values) => Some(values.iter().map(|(k, v)| (k.clone(), v.clone())).collect()),
3093        Value::OrderedMap(values) => {
3094            Some(values.iter().map(|(k, v)| (k.clone(), v.clone())).collect())
3095        }
3096        Value::SortedMap(values) => {
3097            Some(values.iter().map(|(k, v)| (k.clone(), v.clone())).collect())
3098        }
3099        Value::PriorityMap(values) => Some(values.iter().collect()),
3100        Value::Trie(values) => Some(
3101            values
3102                .entries()
3103                .into_iter()
3104                .map(|(k, v)| (Value::String(k), v.clone()))
3105                .collect(),
3106        ),
3107        _ => None,
3108    }
3109}
3110
3111fn pointer_from_descriptor(descriptor: Value) -> Result<Value, String> {
3112    let entries =
3113        map_entries(&descriptor).ok_or_else(|| "pointer expects one descriptor map".to_string())?;
3114    let context_key = Value::Keyword(Keyword::from("context"));
3115    let mut context = None;
3116    let mut fields = Vec::new();
3117    for (key, value) in entries {
3118        if key == context_key {
3119            if context.is_some() {
3120                return Err("pointer descriptor contains duplicate :context".into());
3121            }
3122            context = match value {
3123                Value::Keyword(context) => Some(context),
3124                _ => return Err("pointer :context must be a keyword".into()),
3125            };
3126        } else {
3127            if !matches!(key, Value::Keyword(_)) {
3128                return Err("pointer descriptor fields must use keyword keys".into());
3129            }
3130            fields.push((key, value));
3131        }
3132    }
3133    let context = context.ok_or_else(|| "pointer descriptor requires :context".to_string())?;
3134    Ok(Value::Pointer(PPointer::new(
3135        context,
3136        fields.into_iter().collect(),
3137    )))
3138}
3139
3140/// Returns whether a value may leave the evaluator session as immutable HAL data.
3141///
3142/// Session transfer is deliberately narrower than displayability. Functions,
3143/// Vars, mutable containers, iterators, asynchronous values, and native handles
3144/// all have printable representations, but those representations must not turn
3145/// a live session-owned value into an apparently successful transfer.
3146pub(crate) fn session_transferable(value: &Value) -> bool {
3147    match value {
3148        Value::Number(_)
3149        | Value::Float(_)
3150        | Value::BigInteger(_)
3151        | Value::Character(_)
3152        | Value::Regex(_)
3153        | Value::Tagged(_)
3154        | Value::Bool(_)
3155        | Value::String(_)
3156        | Value::Keyword(_)
3157        | Value::Bytes(_)
3158        | Value::Symbol(_)
3159        | Value::Nil => true,
3160        value @ (Value::Map(_)
3161        | Value::OrderedMap(_)
3162        | Value::SortedMap(_)
3163        | Value::Trie(_)
3164        | Value::PriorityMap(_)) => map_entries(value).is_some_and(|entries| {
3165            entries
3166                .iter()
3167                .all(|(key, value)| session_transferable(key) && session_transferable(value))
3168        }),
3169        value @ (Value::Set(_) | Value::OrderedSet(_) | Value::SortedSet(_)) => set_items(value)
3170            .is_some_and(|values| values.iter().all(|value| session_transferable(value))),
3171        Value::List(values) => values.iter().all(session_transferable),
3172        Value::Cons(values) => values.iter().all(|value| session_transferable(&value)),
3173        Value::Queue(values) => values.iter().all(session_transferable),
3174        Value::Deque(values) => values.iter().all(session_transferable),
3175        Value::Tuple(values) => values.iter().all(session_transferable),
3176        Value::Vector(values) => values.iter().all(session_transferable),
3177        Value::MapEntry(entry) => {
3178            session_transferable(entry.key()) && session_transferable(entry.value())
3179        }
3180        Value::Struct(value) => value.ordered_values().into_iter().all(session_transferable),
3181        Value::Pointer(value) => value
3182            .fields()
3183            .iter()
3184            .all(|(key, value)| session_transferable(key) && session_transferable(value)),
3185        Value::ExceptionInfo(value) => {
3186            session_transferable(&value.data)
3187                && value.cause.as_deref().map_or(true, session_transferable)
3188        }
3189        Value::ByteBuffer(_)
3190        | Value::Array(_)
3191        | Value::Object(_)
3192        | Value::Promise(_)
3193        | Value::Atom(_)
3194        | Value::Recur(_)
3195        | Value::Function(_)
3196        | Value::Seq(_)
3197        | Value::Iterator(_)
3198        | Value::Var(_)
3199        | Value::Namespace(_)
3200        | Value::Extension(_)
3201        | Value::StructType(_)
3202        | Value::MutableType(_)
3203        | Value::Mutable(_)
3204        | Value::Protocol(_)
3205        | Value::NativeType(_)
3206        | Value::Schema(_)
3207        | Value::Coroutine(_)
3208        | Value::Stream(_)
3209        | Value::Result(_)
3210        | Value::MutableCollection(_) => false,
3211    }
3212}
3213
3214fn map_value<'a>(value: &'a Value, key: &Value) -> Option<&'a Value> {
3215    match value {
3216        Value::Map(values) => values.get(key),
3217        Value::OrderedMap(values) => values.get(key),
3218        Value::SortedMap(values) => values.get(key),
3219        Value::PriorityMap(values) => values.get(key),
3220        Value::Trie(values) => match key {
3221            Value::String(key) => values.get(key),
3222            _ => None,
3223        },
3224        _ => None,
3225    }
3226}
3227
3228fn map_equality(left: &Value, right: &Value) -> Option<bool> {
3229    let left_entries = map_entries(left)?;
3230    let right_entries = map_entries(right)?;
3231    Some(
3232        left_entries.len() == right_entries.len()
3233            && left_entries
3234                .iter()
3235                .all(|(key, value)| map_value(right, key) == Some(value)),
3236    )
3237}
3238
3239fn set_items(value: &Value) -> Option<Vec<&Value>> {
3240    match value {
3241        Value::Set(values) => Some(values.iter().collect()),
3242        Value::OrderedSet(values) => Some(values.iter().collect()),
3243        Value::SortedSet(values) => Some(values.iter().collect()),
3244        _ => None,
3245    }
3246}
3247
3248fn set_equality(left: &Value, right: &Value) -> Option<bool> {
3249    let left_items = set_items(left)?;
3250    let right_items = set_items(right)?;
3251    Some(
3252        left_items.len() == right_items.len()
3253            && left_items.iter().all(|item| right_items.contains(item)),
3254    )
3255}
3256
3257fn map_assoc_value(collection: &Value, key: Value, value: Value) -> Result<Value, String> {
3258    Ok(match collection {
3259        Value::Map(values) => Value::Map(values.assoc_value(key, value)),
3260        Value::OrderedMap(values) => Value::OrderedMap(Box::new(values.assoc_value(key, value))),
3261        Value::SortedMap(values) => Value::SortedMap(Box::new(values.assoc_value(key, value))),
3262        Value::PriorityMap(values) => Value::PriorityMap(Box::new(values.assoc_value(key, value))),
3263        Value::Trie(values) => match key {
3264            Value::String(key) => Value::Trie(Box::new(values.assoc_value(key, value))),
3265            _ => return Err("trie expects string keys".into()),
3266        },
3267        _ => return Err("assoc expects a map".into()),
3268    })
3269}
3270
3271fn map_dissoc_value(collection: &Value, key: &Value) -> Result<Value, String> {
3272    Ok(match collection {
3273        Value::Map(values) => Value::Map(values.dissoc_value(key)),
3274        Value::OrderedMap(values) => Value::OrderedMap(Box::new(values.dissoc_value(key))),
3275        Value::SortedMap(values) => Value::SortedMap(Box::new(values.dissoc_value(key))),
3276        Value::PriorityMap(values) => Value::PriorityMap(Box::new(values.dissoc_value(key))),
3277        Value::Trie(values) => match key {
3278            Value::String(key) => Value::Trie(Box::new(values.dissoc_value(key))),
3279            _ => return Err("trie expects string keys".into()),
3280        },
3281        _ => return Err("dissoc expects a map".into()),
3282    })
3283}
3284
3285fn set_find(collection: &Value, key: &Value) -> Option<Value> {
3286    set_items(collection)?
3287        .into_iter()
3288        .find(|value| *value == key)
3289        .cloned()
3290}
3291
3292fn set_conj_value(collection: &Value, value: Value) -> Result<Value, String> {
3293    Ok(match collection {
3294        Value::Set(values) => Value::Set(values.conj_value(value)),
3295        Value::OrderedSet(values) => Value::OrderedSet(Box::new(values.conj_value(value))),
3296        Value::SortedSet(values) => Value::SortedSet(Box::new(values.conj_value(value))),
3297        _ => return Err("conj expects a set".into()),
3298    })
3299}
3300
3301fn set_dissoc_value(collection: &Value, value: &Value) -> Result<Value, String> {
3302    Ok(match collection {
3303        Value::Set(values) => Value::Set(values.dissoc_value(value)),
3304        Value::OrderedSet(values) => Value::OrderedSet(Box::new(values.dissoc_value(value))),
3305        Value::SortedSet(values) => Value::SortedSet(Box::new(values.dissoc_value(value))),
3306        _ => return Err("dissoc expects a set".into()),
3307    })
3308}
3309
3310fn collection_to_mutable(value: &Value) -> Result<Value, String> {
3311    let mutable = match value {
3312        Value::Map(values) => MutableCollection::Map(values.to_mutable()),
3313        Value::OrderedMap(values) => MutableCollection::OrderedMap(values.to_mutable()),
3314        Value::SortedMap(values) => MutableCollection::SortedMap(values.to_mutable()),
3315        Value::Trie(values) => MutableCollection::Trie(values.to_mutable()),
3316        Value::Set(values) => MutableCollection::Set(values.to_mutable()),
3317        Value::OrderedSet(values) => MutableCollection::OrderedSet(values.to_mutable()),
3318        Value::SortedSet(values) => MutableCollection::SortedSet(values.to_mutable()),
3319        Value::List(values) => MutableCollection::List(values.to_mutable()),
3320        Value::Queue(values) => MutableCollection::Queue(values.to_mutable()),
3321        Value::Vector(values) => MutableCollection::Vector(values.to_mutable()),
3322        Value::MutableCollection(_) => return Err("value is already mutable".into()),
3323        _ => return Err("to-mutable expects a persistent collection".into()),
3324    };
3325    Ok(Value::MutableCollection(Rc::new(RefCell::new(Some(
3326        mutable,
3327    )))))
3328}
3329
3330fn collection_to_persistent(value: &Value) -> Result<Value, String> {
3331    let Value::MutableCollection(collection) = value else {
3332        return Err("to-persistent expects a mutable collection".into());
3333    };
3334    let mut mutable = collection
3335        .borrow_mut()
3336        .take()
3337        .ok_or_else(|| "mutable collection used after to-persistent".to_string())?;
3338    Ok(match &mut mutable {
3339        MutableCollection::Map(values) => Value::Map(values.to_persistent()),
3340        MutableCollection::OrderedMap(values) => {
3341            Value::OrderedMap(Box::new(values.to_persistent()))
3342        }
3343        MutableCollection::SortedMap(values) => Value::SortedMap(Box::new(values.to_persistent())),
3344        MutableCollection::Trie(values) => Value::Trie(Box::new(values.to_persistent())),
3345        MutableCollection::Set(values) => Value::Set(values.to_persistent()),
3346        MutableCollection::OrderedSet(values) => {
3347            Value::OrderedSet(Box::new(values.to_persistent()))
3348        }
3349        MutableCollection::SortedSet(values) => Value::SortedSet(Box::new(values.to_persistent())),
3350        MutableCollection::List(values) => Value::List(values.to_persistent()),
3351        MutableCollection::Queue(values) => Value::Queue(Box::new(values.to_persistent())),
3352        MutableCollection::Vector(values) => Value::Vector(values.to_persistent()),
3353    })
3354}
3355
3356fn protocol_to_mutable(arguments: &[Value]) -> Result<Value, String> {
3357    match arguments {
3358        [Value::Extension(receiver)] => extension_protocol_call(
3359            receiver,
3360            "std.protocol.itomutable.IToMutable",
3361            "to-mutable",
3362            arguments,
3363        ),
3364        [value] => collection_to_mutable(value),
3365        _ => Err("IToMutable/to-mutable expects one value".into()),
3366    }
3367}
3368
3369fn protocol_to_persistent(arguments: &[Value]) -> Result<Value, String> {
3370    match arguments {
3371        [Value::Extension(receiver)] => extension_protocol_call(
3372            receiver,
3373            "std.protocol.itopersistent.IToPersistent",
3374            "to-persistent",
3375            arguments,
3376        ),
3377        [value] => collection_to_persistent(value),
3378        _ => Err("IToPersistent/to-persistent expects one value".into()),
3379    }
3380}
3381
3382impl PartialEq for Value {
3383    fn eq(&self, other: &Self) -> bool {
3384        if let Some(equal) = sequential_equality(self, other) {
3385            return equal;
3386        }
3387        if let Some(equal) = map_equality(self, other) {
3388            return equal;
3389        }
3390        if let Some(equal) = set_equality(self, other) {
3391            return equal;
3392        }
3393        if let Some(equal) = numeric::numeric_equal(self, other) {
3394            return equal;
3395        }
3396        match (self, other) {
3397            (Value::Number(a), Value::Number(b)) => a == b,
3398            (Value::Float(a), Value::Float(b)) => a.to_bits() == b.to_bits(),
3399            (Value::BigInteger(a), Value::BigInteger(b)) => a == b,
3400            (Value::Character(a), Value::Character(b)) => a == b,
3401            (Value::Regex(a), Value::Regex(b)) => a == b,
3402            (Value::Tagged(a), Value::Tagged(b)) => a == b,
3403            (Value::Bool(a), Value::Bool(b)) => a == b,
3404            (Value::String(a), Value::String(b)) => a == b,
3405            (Value::Keyword(a), Value::Keyword(b)) => a == b,
3406            (Value::Bytes(a), Value::Bytes(b)) => a == b,
3407            (Value::ByteBuffer(a), Value::ByteBuffer(b)) => *a.borrow() == *b.borrow(),
3408            (Value::Array(a), Value::Array(b)) => Rc::ptr_eq(a, b),
3409            (Value::Object(a), Value::Object(b)) => Rc::ptr_eq(a, b),
3410            (Value::Promise(a), Value::Promise(b)) => a.same_identity(b),
3411            (Value::Atom(a), Value::Atom(b)) => a.same_identity(b),
3412            (Value::Recur(a), Value::Recur(b)) => a == b,
3413            (Value::Map(a), Value::Map(b)) => a == b,
3414            (Value::Set(a), Value::Set(b)) => a == b,
3415            (Value::List(a), Value::List(b)) => a == b,
3416            (Value::Cons(a), Value::Cons(b)) => a == b,
3417            (Value::Symbol(a), Value::Symbol(b)) => a == b,
3418            (Value::Pointer(a), Value::Pointer(b)) => a == b,
3419            (Value::Function(a), Value::Function(b)) => Rc::ptr_eq(a, b),
3420            (Value::Tuple(a), Value::Tuple(b)) => a == b,
3421            (Value::Vector(a), Value::Vector(b)) => a == b,
3422            (Value::MapEntry(a), Value::MapEntry(b)) => a == b,
3423            (Value::MutableCollection(a), Value::MutableCollection(b)) => Rc::ptr_eq(a, b),
3424            (Value::Iterator(a), Value::Iterator(b)) => Rc::ptr_eq(a, b),
3425            (Value::Var(a), Value::Var(b)) => a.same_identity(b),
3426            (Value::Namespace(a), Value::Namespace(b)) => a.same_identity(b),
3427            (Value::Extension(a), Value::Extension(b)) => a == b,
3428            (Value::StructType(a), Value::StructType(b)) => Rc::ptr_eq(a, b),
3429            (Value::Struct(a), Value::Struct(b)) => {
3430                Rc::ptr_eq(&a.ty, &b.ty) && a.values == b.values
3431            }
3432            (Value::MutableType(a), Value::MutableType(b)) => Rc::ptr_eq(a, b),
3433            (Value::Mutable(a), Value::Mutable(b)) => a.same_identity(b),
3434            (Value::Protocol(a), Value::Protocol(b)) => Rc::ptr_eq(a, b),
3435            (Value::NativeType(a), Value::NativeType(b)) => a.name == b.name,
3436            (Value::Schema(a), Value::Schema(b)) => a.ast == b.ast,
3437            (Value::Coroutine(a), Value::Coroutine(b)) => Rc::ptr_eq(a, b),
3438            (Value::Stream(a), Value::Stream(b)) => Rc::ptr_eq(a, b),
3439            (Value::Result(a), Value::Result(b)) => a == b,
3440            (Value::ExceptionInfo(a), Value::ExceptionInfo(b)) => Rc::ptr_eq(a, b),
3441            (Value::Nil, Value::Nil) => true,
3442            _ => false,
3443        }
3444    }
3445}
3446
3447impl Eq for Value {}
3448impl PartialOrd for Value {
3449    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
3450        Some(self.cmp(other))
3451    }
3452}
3453impl Ord for Value {
3454    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
3455        if let Some(ordering) = numeric::numeric_total_compare(self, other) {
3456            return ordering;
3457        }
3458        if self == other {
3459            return std::cmp::Ordering::Equal;
3460        }
3461        match (self, other) {
3462            (Value::Number(left), Value::Number(right)) => return left.cmp(right),
3463            (Value::Float(left), Value::Float(right)) => return left.total_cmp(right),
3464            (Value::Character(left), Value::Character(right)) => return left.cmp(right),
3465            (Value::Bool(left), Value::Bool(right)) => return left.cmp(right),
3466            (Value::String(left), Value::String(right)) => return left.cmp(right),
3467            (Value::Keyword(left), Value::Keyword(right)) => return left.cmp(right),
3468            (Value::BigInteger(left), Value::BigInteger(right)) => return left.cmp(right),
3469            _ => {}
3470        }
3471        fn rank(value: &Value) -> u8 {
3472            match value {
3473                Value::Nil => 0,
3474                Value::Bool(_) => 1,
3475                Value::Number(_) => 2,
3476                Value::Float(_) => 3,
3477                Value::BigInteger(_) => 4,
3478                Value::Character(_) => 5,
3479                Value::String(_) => 7,
3480                Value::Keyword(_) => 8,
3481                Value::Symbol(_) => 9,
3482                Value::Pointer(_) => 9,
3483                Value::List(_)
3484                | Value::Cons(_)
3485                | Value::Queue(_)
3486                | Value::Deque(_)
3487                | Value::Tuple(_)
3488                | Value::Vector(_)
3489                | Value::MapEntry(_)
3490                | Value::Seq(_) => 10,
3491                Value::Map(_)
3492                | Value::OrderedMap(_)
3493                | Value::SortedMap(_)
3494                | Value::Trie(_)
3495                | Value::PriorityMap(_) => 11,
3496                Value::Set(_) | Value::OrderedSet(_) | Value::SortedSet(_) => 12,
3497                Value::Bytes(_) => 13,
3498                Value::ByteBuffer(_) => 14,
3499                Value::Regex(_) => 15,
3500                Value::Tagged(_) => 16,
3501                Value::Array(_) => 17,
3502                Value::Object(_) => 18,
3503                Value::Promise(_) => 19,
3504                Value::Atom(_) => 26,
3505                Value::Recur(_) => 20,
3506                Value::Function(_) => 21,
3507                Value::Iterator(_) => 22,
3508                Value::Var(_) => 23,
3509                Value::Namespace(_) => 24,
3510                Value::Extension(_) => 25,
3511                Value::StructType(_) => 27,
3512                Value::Struct(_) => 28,
3513                Value::MutableType(_) => 29,
3514                Value::Mutable(_) => 30,
3515                Value::Protocol(_) => 31,
3516                Value::NativeType(_) => 32,
3517                Value::Schema(_) => 33,
3518                Value::Coroutine(_) => 33,
3519                Value::Stream(_) => 34,
3520                Value::Result(_) => 36,
3521                Value::ExceptionInfo(_) => 37,
3522                Value::MutableCollection(_) => 38,
3523            }
3524        }
3525        rank(self)
3526            .cmp(&rank(other))
3527            .then_with(|| self.display().cmp(&other.display()))
3528            .then_with(|| self.stable_hash().cmp(&other.stable_hash()))
3529    }
3530}
3531impl Hash for Value {
3532    fn hash<H: Hasher>(&self, state: &mut H) {
3533        // CHAMP placement needs Java's scale-zero integral layout, while the
3534        // ordinary Hash contract must remain canonical across numeric types.
3535        if crate::lang::data::map::champ_placement_hashing() {
3536            if let Self::Number(value) = self {
3537                state.write_u64(crate::lang::hash::hash_long_placement(*value) as i64 as u64);
3538                return;
3539            }
3540            if let Self::Float(value) = self {
3541                if value.is_finite() && value.fract() == 0.0 {
3542                    if let Ok(integer) = (*value).to_string().parse::<i64>() {
3543                        state.write_u64(
3544                            crate::lang::hash::hash_long_placement(integer) as i64 as u64,
3545                        );
3546                        return;
3547                    }
3548                }
3549            }
3550        }
3551        if let Some(hash) = numeric::numeric_hash(self) {
3552            state.write_u64(hash as i64 as u64);
3553            return;
3554        }
3555        match self {
3556            Value::Bool(value) => state.write_u64(crate::lang::hash::hash_bool(*value) as u64),
3557            Value::Nil => state.write_u64(0),
3558            _ => state.write_u64(self.stable_hash()),
3559        }
3560    }
3561}
3562
3563impl crate::lang::hash::JavaHash for Value {
3564    /// The Java `long` hash of this value under `hash_type`, mirroring
3565    /// `G.hashFn(t).apply(o)`. See the `lang::hash` module docs for the
3566    /// parity rules and the documented deviations where Java hashes by
3567    /// object identity (keywords, pointers, SYSTEM/SIP collection hashes).
3568    fn java_hash(&self, hash_type: crate::lang::protocol::HashType) -> i64 {
3569        use crate::lang::hash as jh;
3570        use crate::lang::protocol::IHash;
3571
3572        // Opaque (non-parity) identity hash for runtime objects whose Java
3573        // counterparts hash by object identity. Follows the previous
3574        // `stable_hash` scheme.
3575        fn opaque(
3576            tag: u64,
3577            write: impl FnOnce(&mut std::collections::hash_map::DefaultHasher),
3578        ) -> i64 {
3579            let mut state = std::collections::hash_map::DefaultHasher::new();
3580            tag.hash(&mut state);
3581            write(&mut state);
3582            state.finish() as i64
3583        }
3584
3585        match self {
3586            Self::Nil => 0,
3587            Self::Bool(v) => jh::hash_bool(*v) as i64,
3588            Self::Character(v) => jh::hash_char(*v) as i64,
3589            Self::String(v) => jh::java_string_hash(v) as i64,
3590            Self::Number(value) => jh::hash_long(*value) as i64,
3591            Self::Float(value) => jh::hash_double(*value) as i64,
3592            Self::BigInteger(value) => jh::canonical_decimal_str_hash(&value.to_string()) as i64,
3593            // Java hashes java.util.regex.Pattern by identity; hash the
3594            // pattern string instead (deterministic deviation).
3595            Self::Regex(v) => jh::java_string_hash(v) as i64,
3596            Self::Keyword(v) => v.java_hash(hash_type),
3597            Self::Symbol(v) => v.java_hash(hash_type),
3598            Self::Pointer(v) => v.java_hash(hash_type),
3599            Self::Bytes(v) => jh::hash_bytes(v) as i64,
3600            Self::ByteBuffer(v) => jh::hash_bytes(v.borrow().as_slice()) as i64,
3601            // Java arrays hash by identity; composed deterministically here.
3602            Self::Array(v) => jh::compose_ordered(
3603                "SEQUENTIAL",
3604                v.borrow().iter().map(|item| item.java_hash(hash_type)),
3605            ),
3606            Self::Object(v) => jh::compose_unordered(
3607                "MAP",
3608                v.borrow().iter().map(|(key, item)| {
3609                    jh::compose_entry(jh::java_string_hash(key) as i64, item.java_hash(hash_type))
3610                }),
3611            ),
3612            Self::Recur(v) => {
3613                jh::compose_ordered("SEQUENTIAL", v.iter().map(|item| item.java_hash(hash_type)))
3614            }
3615            Self::Tagged(v) => jh::compose_ordered(
3616                "SEQUENTIAL",
3617                [v.tag().java_hash(hash_type), v.form().java_hash(hash_type)],
3618            ),
3619            Self::Map(v) => v.hash_calc(hash_type) as i64,
3620            Self::OrderedMap(v) => v.hash_calc(hash_type) as i64,
3621            Self::SortedMap(v) => v.hash_calc(hash_type) as i64,
3622            Self::PriorityMap(v) => v.hash_calc(hash_type) as i64,
3623            Self::Trie(v) => v.hash_calc(hash_type) as i64,
3624            Self::Set(v) => v.hash_calc(hash_type) as i64,
3625            Self::OrderedSet(v) => v.hash_calc(hash_type) as i64,
3626            Self::SortedSet(v) => v.hash_calc(hash_type) as i64,
3627            Self::List(v) => v.hash_calc(hash_type) as i64,
3628            Self::Cons(v) => v.hash_calc(hash_type) as i64,
3629            Self::Deque(v) => v.hash_calc(hash_type) as i64,
3630            Self::Queue(v) => v.hash_calc(hash_type) as i64,
3631            Self::Tuple(v) => v.hash_calc(hash_type) as i64,
3632            Self::Vector(v) => v.hash_calc(hash_type) as i64,
3633            Self::MapEntry(v) => v.hash_calc(hash_type) as i64,
3634            Self::Seq(v) => jh::compose_ordered(
3635                "SEQUENTIAL",
3636                v.iter().map(|item| match item {
3637                    Ok(value) => value.java_hash(hash_type),
3638                    Err(error) => jh::java_string_hash(&error) as i64,
3639                }),
3640            ),
3641            Self::MutableCollection(v) => opaque(32, |s| Rc::as_ptr(v).hash(s)),
3642            Self::Promise(v) => opaque(8, |s| v.identity_address().hash(s)),
3643            Self::Atom(v) => opaque(28, |s| v.identity_address().hash(s)),
3644            Self::Function(v) => opaque(14, |s| Rc::as_ptr(v).hash(s)),
3645            Self::Iterator(v) => opaque(16, |s| Rc::as_ptr(v).hash(s)),
3646            Self::Var(v) => opaque(17, |s| v.identity_address().hash(s)),
3647            Self::Namespace(v) => opaque(27, |s| v.identity_address().hash(s)),
3648            Self::Extension(v) => opaque(18, |s| {
3649                v.provider.hash(s);
3650                v.type_name.hash(s);
3651                v.handle.hash(s);
3652            }),
3653            Self::StructType(v) => opaque(26, |s| Rc::as_ptr(v).hash(s)),
3654            Self::Struct(v) => opaque(27, |s| {
3655                Rc::as_ptr(&v.ty).hash(s);
3656                for value in v.ordered_values() {
3657                    value.hash(s);
3658                }
3659            }),
3660            Self::MutableType(v) => opaque(28, |s| Rc::as_ptr(v).hash(s)),
3661            Self::Mutable(v) => opaque(29, |s| v.identity_address().hash(s)),
3662            Self::Protocol(v) => opaque(30, |s| v.name.hash(s)),
3663            Self::NativeType(v) => opaque(31, |s| v.name.hash(s)),
3664            Self::Schema(v) => opaque(34, |s| v.form.to_string().hash(s)),
3665            Self::Coroutine(v) => opaque(32, |s| Rc::as_ptr(v).hash(s)),
3666            Self::Stream(v) => opaque(35, |s| Rc::as_ptr(v).hash(s)),
3667            Self::Result(v) => v.java_hash(hash_type),
3668            Self::ExceptionInfo(v) => opaque(33, |s| Rc::as_ptr(v).hash(s)),
3669        }
3670    }
3671}
3672
3673impl Value {
3674    pub fn display(&self) -> String {
3675        match self {
3676            Self::Number(v) => v.to_string(),
3677            Self::Float(v) => {
3678                assert!(v.is_finite(), "non-finite number");
3679                format!("(double {v})")
3680            }
3681            Self::BigInteger(v) => v.to_string(),
3682            Self::Character('\n') => "\\newline".into(),
3683            Self::Character(' ') => "\\space".into(),
3684            Self::Character('\t') => "\\tab".into(),
3685            Self::Character('\u{0008}') => "\\backspace".into(),
3686            Self::Character('\u{000c}') => "\\formfeed".into(),
3687            Self::Character('\r') => "\\return".into(),
3688            Self::Character(v) if v.is_control() => format!("\\u{:04X}", *v as u32),
3689            Self::Character(v) => format!("\\{v}"),
3690            Self::Regex(v) => crate::kernel::form::display_regex(v),
3691            Self::Tagged(value) => uuid_text_from_tagged(value).map_or_else(
3692                || format!("#{}{}", value.tag().as_str(), value.form().display()),
3693                |text| format!("#{UUID_TAG} {}", Self::String(text.to_owned()).display()),
3694            ),
3695            Self::Bool(v) => v.to_string(),
3696            Self::String(v) => crate::kernel::form::display_string(v),
3697            Self::Keyword(v) => format!(":{}", v.as_str()),
3698            Self::Bytes(values) => format!(
3699                "#bytes[{}]",
3700                values
3701                    .iter()
3702                    .map(|v| (*v as i8).to_string())
3703                    .collect::<Vec<_>>()
3704                    .join(" ")
3705            ),
3706            Self::ByteBuffer(values) => {
3707                let body = values
3708                    .borrow()
3709                    .iter()
3710                    .map(|v| (*v as i8).to_string())
3711                    .collect::<Vec<_>>()
3712                    .join(" ");
3713                if body.is_empty() {
3714                    "(bytes)".into()
3715                } else {
3716                    format!("(bytes {body})")
3717                }
3718            }
3719            Self::Array(values) => format!(
3720                "#arr[{}]",
3721                values
3722                    .borrow()
3723                    .iter()
3724                    .map(Value::display)
3725                    .collect::<Vec<_>>()
3726                    .join(" ")
3727            ),
3728            Self::Object(values) => format!(
3729                "#obj{{{}}}",
3730                values
3731                    .borrow()
3732                    .iter()
3733                    .map(|(key, value)| format!(
3734                        "{} {}",
3735                        Value::String(key.clone()).display(),
3736                        value.display()
3737                    ))
3738                    .collect::<Vec<_>>()
3739                    .join(" ")
3740            ),
3741            Self::Promise(_) => "<promise>".into(),
3742            Self::Atom(value) => format!("#atom <{}>", value.deref_value().display()),
3743            Self::Recur(values) => format!(
3744                "<recur {}>",
3745                values
3746                    .iter()
3747                    .map(Value::display)
3748                    .collect::<Vec<_>>()
3749                    .join(" ")
3750            ),
3751            value @ (Self::Map(_)
3752            | Self::OrderedMap(_)
3753            | Self::SortedMap(_)
3754            | Self::PriorityMap(_)
3755            | Self::Trie(_)) => {
3756                format!(
3757                    "{{{}}}",
3758                    map_entries(value)
3759                        .unwrap()
3760                        .iter()
3761                        .map(|(k, v)| format!("{} {}", k.display(), v.display()))
3762                        .collect::<Vec<_>>()
3763                        .join(" ")
3764                )
3765            }
3766            value @ (Self::Set(_) | Self::OrderedSet(_) | Self::SortedSet(_)) => format!(
3767                "#{{{}}}",
3768                set_items(value)
3769                    .unwrap()
3770                    .iter()
3771                    .map(|item| item.display())
3772                    .collect::<Vec<_>>()
3773                    .join(" ")
3774            ),
3775            Self::Queue(values) => format!(
3776                "#queue[{}]",
3777                values
3778                    .iter()
3779                    .map(Value::display)
3780                    .collect::<Vec<_>>()
3781                    .join(" ")
3782            ),
3783            Self::Deque(values) => format!(
3784                "#deque[{}]",
3785                values
3786                    .iter()
3787                    .map(Value::display)
3788                    .collect::<Vec<_>>()
3789                    .join(" ")
3790            ),
3791            Self::Cons(values) => format!(
3792                "({})",
3793                values
3794                    .iter()
3795                    .map(|value| value.display())
3796                    .collect::<Vec<_>>()
3797                    .join(" ")
3798            ),
3799            Self::List(values) => format!(
3800                "({})",
3801                values
3802                    .iter()
3803                    .map(Value::display)
3804                    .collect::<Vec<_>>()
3805                    .join(" ")
3806            ),
3807            Self::Symbol(v) => v.as_str().to_owned(),
3808            Self::Pointer(v) => v.display(),
3809            Self::Function(_) => "<fn>".into(),
3810            Self::Tuple(values) => format!(
3811                "[{}]",
3812                values
3813                    .iter()
3814                    .map(Value::display)
3815                    .collect::<Vec<_>>()
3816                    .join(" ")
3817            ),
3818            Self::MapEntry(entry) => entry.display(),
3819            Self::Vector(values) => format!(
3820                "[{}]",
3821                values
3822                    .iter()
3823                    .map(Value::display)
3824                    .collect::<Vec<_>>()
3825                    .join(" ")
3826            ),
3827            Self::MutableCollection(values) => {
3828                let borrowed = values.borrow();
3829                let Some(values) = borrowed.as_ref() else {
3830                    return "#<mutable-frozen>".into();
3831                };
3832                let kind = match values {
3833                    MutableCollection::Map(_) => "map",
3834                    MutableCollection::OrderedMap(_) => "ordered-map",
3835                    MutableCollection::SortedMap(_) => "sorted-map",
3836                    MutableCollection::Trie(_) => "trie",
3837                    MutableCollection::Set(_) => "set",
3838                    MutableCollection::OrderedSet(_) => "ordered-set",
3839                    MutableCollection::SortedSet(_) => "sorted-set",
3840                    MutableCollection::List(_) => "list",
3841                    MutableCollection::Queue(_) => "queue",
3842                    MutableCollection::Vector(_) => "vector",
3843                };
3844                format!("#<mutable-{kind}>")
3845            }
3846            Self::Seq(sequence) => {
3847                let mut values = sequence.iter();
3848                let mut displayed = Vec::new();
3849                for _ in 0..10 {
3850                    match values.next() {
3851                        Some(Ok(value)) => displayed.push(value.display()),
3852                        Some(Err(error)) => {
3853                            displayed.push(format!("#error[{}]", Value::String(error).display()));
3854                            break;
3855                        }
3856                        None => break,
3857                    }
3858                }
3859                if values.next().is_some() {
3860                    displayed.push("...".into());
3861                }
3862                format!("({})", displayed.join(" "))
3863            }
3864            Self::Iterator(_) => "<iterator>".into(),
3865            Self::Var(value) => value.display(),
3866            Self::Namespace(value) => format!("#namespace[{}]", value.name().as_str()),
3867            Self::Extension(value) => format!("#ht[:handle {}]", value.handle),
3868            Self::StructType(value) => value.name.clone(),
3869            Self::Struct(value) => format!(
3870                "#{}{{{}}}",
3871                value.ty.name,
3872                value
3873                    .ty
3874                    .fields
3875                    .iter()
3876                    .filter_map(|field| value.get(field).map(|value| (field, value)))
3877                    .map(|(field, value)| format!(":{field} {}", value.display()))
3878                    .collect::<Vec<_>>()
3879                    .join(" ")
3880            ),
3881            Self::MutableType(value) => value.name.clone(),
3882            Self::Mutable(value) => format!(
3883                "#{}{{{}}}",
3884                value.ty.name,
3885                value
3886                    .ty
3887                    .fields
3888                    .iter()
3889                    .zip(value.ordered_values())
3890                    .map(|(field, value)| format!(":{field} {}", value.display()))
3891                    .collect::<Vec<_>>()
3892                    .join(" ")
3893            ),
3894            Self::Protocol(value) => format!("#protocol[{}]", value.name),
3895            Self::NativeType(value) => format!("#<native-type {}>", value.name),
3896            Self::Schema(value) => format!("(schema {})", value.form),
3897            Self::Coroutine(value) => {
3898                let status = match &*value.state.borrow() {
3899                    CoroutineState::New(_) | CoroutineState::Suspended(_) => "suspended",
3900                    CoroutineState::Running => "running",
3901                    CoroutineState::Dead => "dead",
3902                };
3903                format!("#<coroutine {status}>")
3904            }
3905            Self::Stream(value) => format!(
3906                "#<stream {}>",
3907                if value.closed.get() {
3908                    "closed"
3909                } else {
3910                    "ready"
3911                }
3912            ),
3913            Self::Result(value) => value.display(),
3914            Self::ExceptionInfo(value) => {
3915                format!(
3916                    "#ex[{} {}]",
3917                    Self::String(value.message.clone()).display(),
3918                    value.data.display()
3919                )
3920            }
3921            Self::Nil => "nil".into(),
3922        }
3923    }
3924    pub(crate) fn truthy(&self) -> bool {
3925        !matches!(self, Self::Nil | Self::Bool(false))
3926    }
3927
3928    /// Stable structural hash used by protocol and collection conformance tests.
3929    ///
3930    /// This is the Java-parity RAPID hash: the bit pattern (as `u64`) of the
3931    /// Java `long` produced by `G.hashRapid` / `hashCalc(RAPID)` on the
3932    /// equivalent Java value. Value-level hashes are Java `int` results
3933    /// sign-extended to 64 bits, matching `G.hashValue` returning `long`.
3934    /// Opaque runtime objects (functions, atoms, promises, …) keep the
3935    /// previous identity-based `DefaultHasher` scheme — their Java
3936    /// counterparts hash by object identity, so no parity exists there.
3937    pub fn stable_hash(&self) -> u64 {
3938        self.java_hash(crate::lang::hash::DEFAULT_HASH) as u64
3939    }
3940}