6.25. kink/VAL

Provides funs for vals in general.

6.25.1. type val

`val` is the universal supertype, or the supertype of all other types. Every value is an instance of `val` type.

`val` type has only one method: `repr`. It means that every value of Kink has `repr` method.

6.25.1.1. Val.repr

`repr` returns a `str` which describes `Val` for debugging purpose.

The format of the result differs for each type:

:BIN.require_from('kink/')

stdout.print_line(new_val.repr)         # => (val id_hash=123)
stdout.print_line([1 2 3].repr)         # => [1 2 3]
stdout.print_line(BIN.of(1 2 3).repr)   # => (bin 0x01 0x02 0x03)
stdout.print_line("hello world\n".repr) # => "hello world\n"

For example, the result of `repr` can be used to construct an error message:

:NUM.require_from('kink/')

:to_int <- {(:N)
  NUM.is?(N) || raise(
    'to_int(N): N must be a num, but was {}'.format(N.repr))
  N // 1
}

to_int('foo')
# Output:
#   -- main exception
#   ...
#   {(stdin) L4 C17 raise} NUM.is?(N) || -->raise(
#   to_int(N): N must be a num, but was "foo"

The runtime also uses the result of `repr` to construct an error message:

'foo'.bar
# Output:
#   -- main exception
#   ...
#   [(stdin) L1 C7] 'foo'.-->bar
#   no such var: bar not found in "foo"

Apart from error messages, `repr` might be used to construct log messages.

There are some requirements for implementations of `repr`.

`repr` must return a `str` value

As described above, `repr` is used to construct error messages, and callers expect that `repr` returns a `str` value. If `repr` returns a non-str value, hence it breaks the expectation, things can get really messy.

`repr` must return a finite length `str` for data of infinite length or depth

If you implement a container type, probably your `repr` implementation calls `repr` method of elements. Make sure that `repr` properly returns a finite length `str` for data of infinite length or depth.

:Y <- [4 5 6]
:X <- [1 2 3 Y]
Y.push_back(X)
stdout.print_line(X.repr) # => [1 2 3 [4 5 6 [,,,]]]

Recursion check can be done using `dyn` val. Check the implementation of kink/container/FLAT_SET for example.

Keep the result short enough

If the result of `repr` is too long, it can mess up the debug output. So make sure that the result is short enough.

6.25.2. VAL.id_hash(Val)

`id_hash` returns an int `num` appointed for `Val`. Invocations of `id_hash` for the same value always return the same integer.

The result can be used as a hash code of the identity of the value.

6.25.3. VAL.same?(X Y)

`same?` returns whether two args, `X` and ``Y`, are the same value.

Example

:VAL.require_from('kink/')

:test_identity <- {(:X :Y)
  if(VAL.same?(X Y)
    { stdout.print_line('same') }
    { stdout.print_line('different') }
  )
}
:V <- new_val
test_identity(V V)        # => same
test_identity(V new_val)  # => different

6.25.4. VAL.var_syms(Val)

`var_syms` does variable-symbols operation, and returns the set of syms of the vars of `Val`.

The result is a `set` of `str` values.

Example

:VAL.require_from('kink/')

:V <- new_val('Data' 42 'fun' {})
stdout.print_line(VAL.var_syms(V).repr) # => (flat_set "Data" "fun" "repr")

6.25.5. VAL.identity(Val)

`identity` returns `Val`.

Example

:VAL.require_from('kink/')

stdout.print_line(VAL.identity('foo').repr) # => "foo"