docs/docs/lips/reflection.md
---
sidebar_position: 2
description: A way to introspect and manipulate LIPS internals
---
# Reflection
You can use standard JavaScript methods to inspect LIPS objects.
* Scheme functions
* `dir` - this procedure is inspired by Python function with the same name, it return all properties
that you can access on an object. Including those from object prototype and whole chain.
* `env` - function return everything what is inside current-environment.
* JavaScript functions
* `Object.keys` - this JavaScript method will return all string keys from an object.
* `Object.values` - return the value of the object.
* `Object.entries` - this return array of `[key,value]` pairs.
* `Object.getOwnPropertySymbols` - similar to `Object.keys` but return all symbols
## Numbers
You can access internal representation of numbers as JavaScript objects
```scheme
(let ((num 1/2+10i))
(print num.__im__)
(print num.__re__)
(print num.__re__.__denom__)
(print num.__re__.__num__))
;; ==> 10
;; ==> 1/2
;; ==> 2
;; ==> 1
```
## Lists and Pairs
You can access Pairs as JavaScript objects:
```scheme
(let ((x '(1 2 3)))
x.cdr.cdr.car)
;; ==> 3
```
You can also manipulate the list with `set!`:
```scheme
(let ((x '(1 2 3)))
(set! x.cdr.cdr.cdr x)
x)
;; ==> #0=(1 2 3 . #0#)
```
Above create a cycle. When you you try to display a cycle it's printed using R7RS datum syntax.
## Strings
Same as with numbers and list you can access internals of Strings.
```scheme
(let ((str "hello"))
(str.__string__.toUpperCase)
(set! str.__string__ "world")
str)
```
`__string__` property is read only so you can't modify it's value:
```scheme
(let ((str "hello"))
(set! str.__string__ "world")
str)
;; ==> Cannot assign to read only property '__string__' of object '[object Object]'
```
## Characters
Similar to string you can access internals of Characters.
```scheme
(let ((x #\X)) (dir x))
;; ==> (__char__ constructor toUpperCase toLowerCase toString serialize valueOf)
```
the `__char__` property is a string that hold the value of the character.
```scheme
(let ((x #\X))
(write x)
(newline)
(write x.__char__)
(newline))
;; ==> #\X
;; ==> "X"
```
## Procedures
Procedures as described in [Core features](/docs/lips/intro#procedures) are JavaScript functions,
they also hold additional properties like `__code__` and `__doc__`. The first property is the live
source code of the procedure that you can modify:
```scheme
(define (repeater x)
"(repeater value)
Function prints the value 1 time and modifies itself to repeat
(+ n 1) times on the next call."
(for-each (lambda () (print x)) (range 1))
(let ((r (cadr (cdadddr (. repeater '__code__)))))
(set-cdr! r (list (+ (cadr r) 1)))))
```
This procedure modify its source code. Each time you execute this function it will run one more
times.
```scheme
(print "1")
(repeater 'hello)
;; ==> 1
;; ==> hello
(print "2")
(repeater 'hello)
;; ==> 2
;; ==> hello
;; ==> hello
(print "3")
(repeater 'hello)
;; ==> 3
;; ==> hello
;; ==> hello
;; ==> hello
```
The first expression of the procedure is a doc string, unless a string is the only expression,
in that case it's a return value. To access doc string you can use `help` or `__doc__`.
```scheme
repeater.__doc__
"(repeater value)
Function prints the value 1 time and modifies itself to repeat
(+ n 1) times on the next call."
```