Skip to content
Topaz6.0 · Before release
Download

Search documentation

Specification 6.0 · Not released · Tested product 5.21.3

Use arrow keys to choose a result. Press Enter to open.

Type an API name, diagnostic number, rule, or project topic.

    Library · std.lispex

    LispexDatumView

    Construct and inspect the portable Datum kinds without host references.

    enum LispexDatumView { Boolean(bool), Number(BigInt, BigInt), Character(string), Symbol(string), EmptyList(), Pair(LispexValue, LispexValue), Text(string), Vector(Array<LispexValue>), Bytevector(Bytes) }
    Receiver
    Not applicable
    Minimum arity
    0
    Maximum arity
    0

    Declaration and parameters

    Link

    Availability

    Included by default: no

    Import std.lispex from an application package with a verified lock. Packages with [lispex] require --locked. Application profile topaz/lispex-decision-application/1 uses evaluator profile lispex/r7rs-rule-embedded-core/1. Application profile topaz/lispex-decision-application/2 uses evaluator profile lispex/r7rs-rule-current-profile-bounded/1.

    The generated-module resolver gate starts at language mode 5.18. Compatibility of this API with earlier released editions remains Pending. Target deployment conditions are native (native-only), web (web-isolated-workers), web-worker (web-isolated-workers). Runtime payload follows checker-reached rules. An empty reached-rule set includes no runtime payload. Application quotas are required. Lock-only packages do not receive these application modules.

    Source evidence

    Receiver

    Parameter constraints

    LispexValue is an immutable validated Datum handle. Its codec identity travels with the value. Guest inputs and successful results use this same representation. Equality follows the selected canonical value contract.

    valueFromCanonical accepts an admitted package, immutable bytes and complete finite host limits. Decode exactly one complete canonical Datum under the package codec. Reject malformed bytes, trailing values, unsupported versions and noncanonical representations as InvalidCanonicalValue.

    valueFromDatum accepts a LispexDatumView and creates a detached immutable snapshot. Boolean accepts a bool. Number accepts exact BigInt numerator and denominator values and normalizes their rational value. A zero denominator returns InvalidDatum. No inexact floating value is accepted.

    Character accepts exactly one Unicode scalar. Empty text, several scalars and invalid scalar representations return InvalidDatum. Symbol and Text preserve their scalar sequences without normalization or case conversion. Empty symbols follow the selected Datum codec contract.

    EmptyList is the empty list value. Pair holds two validated values. Vector copies its Array of validated values in order. Bytevector retains exact immutable bytes. Every child must use the same admitted codec contract. A mismatched child returns InvalidDatum before guest entry.

    The exposed view has no procedure, callback or host object alternative. A procedure cannot be hidden in Pair or Vector because each child must already be a validated LispexValue. Construction does not follow host reference graphs. Mutating a source Array after conversion cannot change the sealed value.

    valueView returns a detached view of the same value. Number exposes the normalized exact numerator and positive denominator. Aggregate views contain sealed child handles. Changing a returned Array changes that view and does not mutate the LispexValue.

    Conversions reserve their work, allocation, traversal frames, input and result channels under LispexHostLimits. Host conversion exhaustion returns LimitExceeded with the first axis. A failure returns no prefix or partly valid value. It creates no canonical evaluation outcome or receipt.

    canonicalBytes returns the immutable canonical bytes established when the handle was created. It does not decode, evaluate, discover a codec or perform fresh serialization. The handle retains that bounded representation, so reading it starts no new guest or host work account.

    Host conversion work is separate from evaluation work. Evaluation still charges canonical input decoding and canonical result or failure encoding under its own limits. Prevalidated bytes cannot bypass those charges.

    The same value, codec and explicit conversion limits have the same accepted canonical bytes or deterministic conversion refusal. Exact codec bytes and normalization encodings belong to the admitted versioned Lispex contract. Legacy 1.21 bytes are never relabeled as 2.0 bytes.

    Result

    Effects

    Failures

    Result and effects

    Link

    Construct and inspect the portable Datum kinds without host references.

    Why

    Link

    The values contract gives this operation one explicit input boundary and preserves the distinct result and failure cases.

    Related entries

    Link

    std.lispex

    Exchange exact immutable Datum values

    Link
    Ruletopaz.stdlib.contract.lispex-values.rule

    Exchange exact immutable Datum values

    LispexValue is an immutable validated Datum handle. Its codec identity travels with the value. Guest inputs and successful results use this same representation. Equality follows the selected canonical value contract.

    valueFromCanonical accepts an admitted package, immutable bytes and complete finite host limits. Decode exactly one complete canonical Datum under the package codec. Reject malformed bytes, trailing values, unsupported versions and noncanonical representations as InvalidCanonicalValue.

    valueFromDatum accepts a LispexDatumView and creates a detached immutable snapshot. Boolean accepts a bool. Number accepts exact BigInt numerator and denominator values and normalizes their rational value. A zero denominator returns InvalidDatum. No inexact floating value is accepted.

    Character accepts exactly one Unicode scalar. Empty text, several scalars and invalid scalar representations return InvalidDatum. Symbol and Text preserve their scalar sequences without normalization or case conversion. Empty symbols follow the selected Datum codec contract.

    EmptyList is the empty list value. Pair holds two validated values. Vector copies its Array of validated values in order. Bytevector retains exact immutable bytes. Every child must use the same admitted codec contract. A mismatched child returns InvalidDatum before guest entry.

    The exposed view has no procedure, callback or host object alternative. A procedure cannot be hidden in Pair or Vector because each child must already be a validated LispexValue. Construction does not follow host reference graphs. Mutating a source Array after conversion cannot change the sealed value.

    valueView returns a detached view of the same value. Number exposes the normalized exact numerator and positive denominator. Aggregate views contain sealed child handles. Changing a returned Array changes that view and does not mutate the LispexValue.

    Conversions reserve their work, allocation, traversal frames, input and result channels under LispexHostLimits. Host conversion exhaustion returns LimitExceeded with the first axis. A failure returns no prefix or partly valid value. It creates no canonical evaluation outcome or receipt.

    canonicalBytes returns the immutable canonical bytes established when the handle was created. It does not decode, evaluate, discover a codec or perform fresh serialization. The handle retains that bounded representation, so reading it starts no new guest or host work account.

    Host conversion work is separate from evaluation work. Evaluation still charges canonical input decoding and canonical result or failure encoding under its own limits. Prevalidated bytes cannot bypass those charges.

    The same value, codec and explicit conversion limits have the same accepted canonical bytes or deterministic conversion refusal. Exact codec bytes and normalization encodings belong to the admitted versioned Lispex contract. Legacy 1.21 bytes are never relabeled as 2.0 bytes.

    Why

    Canonical bytes serve interchange. Datum views serve typed host construction and inspection. These are different intentions even when they describe the same value. Immutable snapshots keep host mutation from changing a request after it has been identified.

    Source evidence

    Preserve an explicit Boolean input

    Link
    main.tpzPreserve an explicit Boolean inputOpen in Playground
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. import std.lispex {
    5. LispexPackage,
    6. LispexBoundaryReport,
    7. LispexLimitPreset,
    8. LispexLimits,
    9. LispexSource,
    10. LispexSourceBundle,
    11. PreparedLispexRule,
    12. LispexPreparationError,
    13. LispexDatumView,
    14. LispexValue,
    15. LispexValueError,
    16. LispexEvaluation,
    17. LispexAttemptError,
    18. LispexSettlement,
    19. applicationPackage,
    20. defaultLimits,
    21. prepare,
    22. valueFromDatum,
    23. canonicalBytes,
    24. evaluate,
    25. }
    26. export function main(args: Array<string>, stdin: string) -> Result<int, string> {
    27. let packageResult: Result<LispexPackage, LispexBoundaryReport> = applicationPackage()
    28. let application: LispexPackage = test.assertOk(packageResult)
    29. let preset: LispexLimitPreset = defaultLimits()
    30. let source: LispexSource = LispexSource {
    31. name: "source.scm",
    32. bytes: "(define rule (lambda (input) input))\n".encodeUtf8(),
    33. }
    34. let bundle: LispexSourceBundle = LispexSourceBundle {
    35. entryModule: "source.scm",
    36. entryBinding: "rule",
    37. sources: [source],
    38. }
    39. let prepared: Result<PreparedLispexRule, LispexPreparationError> = prepare(application, bundle, preset.preparation)
    40. let rule: PreparedLispexRule = test.assertOk(prepared)
    41. let converted: Result<LispexValue, LispexValueError> = valueFromDatum(application, LispexDatumView.Boolean(true), preset.host)
    42. let input: LispexValue = test.assertOk(converted)
    43. let attempt: Result<LispexEvaluation, LispexAttemptError> = evaluate(rule, input, preset.evaluation)
    44. let evaluation: LispexEvaluation = test.assertOk(attempt)
    45. match (evaluation.settlement) {
    46. case Complete(output) => {
    47. let expected: Bytes = canonicalBytes(input)
    48. let actual: Bytes = canonicalBytes(output)
    49. io.writeLine("{actual.toHex() == expected.toHex()}")
    50. }
    51. case _ => io.writeLine("unexpected outcome")
    52. }
    53. return Ok(0)
    54. }
    Expected outputexit 0
    true
    
    $ topaz run main.tpz --locked · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. true

    Run this source inside the verified Lispex application supplied through TOPAZ_LISPEX_APPLICATION. The example expects the Lispex 2.0 host contract.

    Source evidence

    Round trip exact values and isolate host mutations

    Link
    main.tpzRound trip exact values and isolate host mutationsOpen in Playground
    1. import std.bigint { BigInt }
    2. import std.bytes { Bytes }
    3. import std.io
    4. import std.test
    5. import std.lispex {
    6. LispexPackage, LispexBoundaryReport, LispexLimitPreset, LispexDatumView,
    7. LispexValue, LispexValueError, applicationPackage, defaultLimits,
    8. valueFromDatum, valueFromCanonical, valueView, canonicalBytes,
    9. }
    10. function conversionFailure(error: LispexValueError) -> string {
    11. return match (error) {
    12. case InvalidCanonicalValue(report) => report.code
    13. case InvalidDatum(report) => report.code
    14. case LimitExceeded(report) => report.code
    15. }
    16. }
    17. export function main(args: Array<string>, stdin: string) -> Result<int, string> {
    18. let packageResult: Result<LispexPackage, LispexBoundaryReport> = applicationPackage()
    19. let package: LispexPackage = test.assertOk(packageResult)
    20. let limits: LispexLimitPreset = defaultLimits()
    21. let numeratorResult: Option<BigInt> = BigInt.parse("2", 10)
    22. let denominatorResult: Option<BigInt> = BigInt.parse("4", 10)
    23. let zeroResult: Option<BigInt> = BigInt.parse("0", 10)
    24. let numerator: BigInt = test.assertSome(numeratorResult)
    25. let denominator: BigInt = test.assertSome(denominatorResult)
    26. let zero: BigInt = test.assertSome(zeroResult)
    27. let built: Result<LispexValue, LispexValueError> = valueFromDatum(package, LispexDatumView.Number(numerator, denominator), limits.host)
    28. let value: LispexValue = test.assertOk(built)
    29. let bytes: Bytes = canonicalBytes(value)
    30. let decoded: Result<LispexValue, LispexValueError> = valueFromCanonical(package, bytes, limits.host)
    31. let restored: LispexValue = test.assertOk(decoded)
    32. io.writeLine("{canonicalBytes(restored).toHex() == bytes.toHex()}")
    33. let viewed: Result<LispexDatumView, LispexValueError> = valueView(value, limits.host)
    34. let view: LispexDatumView = test.assertOk(viewed)
    35. match (view) {
    36. case Number(n, d) => io.writeLine("{n.toString(10)}/{d.toString(10)}")
    37. case _ => io.writeLine("unexpected view")
    38. }
    39. let mut items: Array<LispexValue> = [value]
    40. let vectorResult: Result<LispexValue, LispexValueError> = valueFromDatum(package, LispexDatumView.Vector(items), limits.host)
    41. let vector: LispexValue = test.assertOk(vectorResult)
    42. let emptyResult: Result<LispexValue, LispexValueError> = valueFromDatum(package, LispexDatumView.EmptyList(), limits.host)
    43. let empty: LispexValue = test.assertOk(emptyResult)
    44. items[0] = empty
    45. let vectorViewResult: Result<LispexDatumView, LispexValueError> = valueView(vector, limits.host)
    46. let vectorView: LispexDatumView = test.assertOk(vectorViewResult)
    47. match (vectorView) {
    48. case Vector(snapshot) => io.writeLine("{canonicalBytes(snapshot[0]).toHex() == bytes.toHex()}")
    49. case _ => io.writeLine("unexpected vector")
    50. }
    51. let invalid: Result<LispexValue, LispexValueError> = valueFromDatum(package, LispexDatumView.Number(numerator, zero), limits.host)
    52. match (invalid) {
    53. case Err(InvalidDatum(report)) => io.writeLine("{report.code != ""}")
    54. case _ => io.writeLine("unexpected conversion")
    55. }
    56. let otherKinds: Array<LispexDatumView> = [
    57. LispexDatumView.Character("a"),
    58. LispexDatumView.Symbol("rule"),
    59. LispexDatumView.Pair(value, empty),
    60. LispexDatumView.Bytevector("abc".encodeUtf8()),
    61. ]
    62. for datum in (otherKinds) {
    63. let convertedKind: Result<LispexValue, LispexValueError> = valueFromDatum(package, datum, limits.host)
    64. let kindValue: LispexValue = test.assertOk(convertedKind)
    65. let kindBytes: Bytes = canonicalBytes(kindValue)
    66. let decodedKind: Result<LispexValue, LispexValueError> = valueFromCanonical(package, kindBytes, limits.host)
    67. let kindCopy: LispexValue = test.assertOk(decodedKind)
    68. io.writeLine("{canonicalBytes(kindCopy).toHex() == kindBytes.toHex()}")
    69. }
    70. return Ok(0)
    71. }
    Expected outputexit 0
    true
    1/2
    true
    true
    true
    true
    true
    true
    
    $ topaz run main.tpz --locked · target product 5.21.3
    Expected result

    Expected result

    Execution completes. Exit code 0.

    Expected stdout
    1. true
    2. 1/2
    3. true
    4. true
    5. true
    6. true
    7. true
    8. true

    Use a verified Lispex application package supplied through TOPAZ_LISPEX_APPLICATION. This example specifies the Lispex 2.0 behavior. The product scope remains the public 5.21.3 observation scope.

    Source evidence

    Menu

    Download