-
Notifications
You must be signed in to change notification settings - Fork 310
Expand file tree
/
Copy pathllms-full.txt
More file actions
7154 lines (4393 loc) · 233 KB
/
Copy pathllms-full.txt
File metadata and controls
7154 lines (4393 loc) · 233 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Io — Full Documentation
Io is a dynamic, prototype-based language built on a few simple ideas taken from Smalltalk (all values are objects), Self (prototypes, not classes), NewtonScript (differential inheritance), Act1 (actors and futures for concurrency), Lisp (code is a runtime-inspectable message tree), and Lua (small and embeddable).
See also: /llms.txt (curated index) and /sitemap.xml.
---
<!-- Page: (root) -->
Source: /
A small, prototype-based programming language — now targeting WASM/WASI.
## About
Io is a dynamic, prototype-based language built on a few simple ideas taken from Smalltalk (all values are objects), Self (prototypes, not classes), NewtonScript (differential inheritance), Act1 (actors and futures for concurrency), Lisp (code is a runtime-inspectable message tree), and Lua (small and embeddable).
Its guiding design principle is simplicity and power through conceptual unification — a handful of primitives stand in for features most languages keep separate:
conceptunifiesscopable blocksfunctions, methods, closuresprototypesobjects, classes, namespaces, localsmessagesoperators, calls, assigns, var accessThe VM is written in portable C and now targets WebAssembly (WASI) by default. The same binary runs under wasmtime, Node.js, or directly in the browser via a bidirectional Io↔JavaScript bridge.
## Key Features
- **Minimal Syntax** — Expressions only. No keywords, no statements, no special forms. Every expression is a message send, including assignment, operators, and control flow.
- **Prototype-Based Objects** — No classes. New objects are clones of existing ones, slots are created on write, and any object can be used as a prototype for any other.
- **Differential Inheritance** — Clones inherit by reference until a slot is assigned, so most objects carry only the deltas that distinguish them from their parents.
- **Multiple Inheritance** — Every object has a list of protos; lookup is depth-first with runtime loop detection.
- **Messages as Code** — Messages form trees that can be inspected and rewritten at runtime. Argument evaluation can be deferred, so `if`, `while`, and `for` are implementable in Io itself.
- **Runtime Introspection** — Slots, protos, message trees, and block source code are all inspectable and modifiable at runtime.
- **Actors and Futures** — Any object can receive `asyncSend` or `futureSend` messages and run its own coroutine. Futures are transparent (they become their result) and detect deadlocks automatically.
- **Coroutines Everywhere** — Concurrency uses cooperative user-level coroutines rather than OS threads, scaling to thousands of active tasks without thread-level overhead.
- **First-Class Continuations** — the VM is callcc-capable: the current computation can be captured as a first-class value and later resumed, stored, or serialized.
- **Unified Sequences** — Strings, buffers, and numeric vectors share one `Sequence` primitive, with multiple item types, text encodings, and SIMD acceleration on float vectors.
- **WASM/WASI Target** — The default build produces a single WebAssembly module that runs under wasmtime, Node.js, or in browsers, with full access to the DOM when hosted in a page.
- **Io↔JS Bridge** — Host integration on the browser target is bidirectional: Io can call JavaScript functions and JavaScript can call Io methods, replacing the native-addon model of earlier Io releases.
- **Embeddable Core** — The VM ships as a single WebAssembly module under a BSD license, embeddable in any WASM host — browsers, Node.js, or native apps via wasmtime or wasmer.
- [Live Interpreter](repl/index.html) — Try Io right now — the full VM compiled to WebAssembly, running in your browser.
- [Documentation](docs/index.html) — Guides, tutorial, language reference, and design notes.
- FAQ
- [Links](Links/index.html) — Books, tutorials, articles, papers, tools, and community resources.
- Timeline
- Release Notes
- [Performance](bench/index.html) — Benchmark results tracked over time — interpreter ops, shootout programs, and SIMD throughput.
- [GitHub Repository](https://github.com/IoLanguage/io) — Source code, issues, and contributions.
For AI agents: [llms.txt](llms.txt) (curated index) and [llms-full.txt](llms-full.txt) (full content).
---
<!-- Page: docs -->
Source: /docs/
# Documentation
Guides, tutorial, language reference, and design notes.
- Guide
- Tutorial
- Book
- Reference
- Style Guide
- Implementation
- Technical Notes
- Paper
---
<!-- Page: docs/Book -->
Source: /docs/Book/
# Book
The original Io book, organized by chapter.
- Introduction
- Syntax
- Objects
- Control Flow
- Concurrency
- Primitives
- Appendix
---
<!-- Page: docs/Book/Appendix -->
Source: /docs/Book/Appendix/
---
heroImage: ../images/Appendix.png
nextSectionLink: true
---
# Appendix
Grammar reference and citations.
## Grammar
#### messages
expression ::= { message | sctpad }
message ::= [wcpad] symbol [scpad] [arguments]
arguments ::= Open [argument [ { Comma argument } ]] Close
argument ::= [wcpad] expression [wcpad]
#### symbols
symbol ::= Identifier | number | Opereator | quote
Identifier ::= { letter | digit | "_" }
Operator ::= { ":" | "." | "'" | "~" | "!" | "@" | "$" |
"%" | "^" | "&" | "*" | "-" | "+" | "/" | "=" | "{" | "}" |
"[" | "]" | "|" | "\" | "<" | ">" | "?" }
#### quotes
quote ::= MonoQuote | TriQuote
MonoQuote ::= """ [ "\"" | not(""")] """
TriQuote ::= """"" [ not(""""")] """""
#### spans
Terminator ::= { [separator] ";" | "\n" | "\r" [separator] }
separator ::= { " " | "\f" | "\t" | "\v" }
whitespace ::= { " " | "\f" | "\r" | "\t" | "\v" | "\n" }
sctpad ::= { separator | Comment | Terminator }
scpad ::= { separator | Comment }
wcpad ::= { whitespace | Comment }
#### comments
Comment ::= slashStarComment | slashSlashComment | poundComment
slashStarComment ::= "/*" [not("*/")] "*/"
slashSlashComment ::= "//" [not("\n")] "\n"
poundComment ::= "#" [not("\n")] "\n"
#### numbers
number ::= HexNumber | Decimal
HexNumber ::= "0" anyCase("x") { [ digit | hexLetter ] }
hexLetter ::= "a" | "b" | "c" | "d" | "e" | "f"
Decimal ::= digits | "." digits |
digits "." digits ["e" [-] digits]
#### characters
Comma ::= ","
Open ::= "(" | "[" | "{"
Close ::= ")" | "]" | "}"
letter ::= "a" ... "z" | "A" ... "Z"
digit ::= "0" ... "9"
digits ::= { digit }
Uppercase words designate elements the lexer treats as tokens.
## References
1. Goldberg, A et al. *Smalltalk-80: The Language and Its Implementation.* Addison-Wesley, 1983.
2. Ungar, D and Smith, RB. *Self: The Power of Simplicity.* OOPSLA, 1987.
3. Smith, W. *Class-based NewtonScript Programming.* PIE Developers magazine, Jan 1994.
4. Lieberman, H. *Concurrent Object-Oriented Programming in Act 1.* MIT AI Lab, 1987.
5. McCarthy, J et al. *LISP I programmer's manual.* MIT Press, 1960.
6. Ierusalimschy, R, et al. *Lua: an extensible extension language.*
---
<!-- Page: docs/Book/Concurrency -->
Source: /docs/Book/Concurrency/
---
heroImage: ../images/Concurrency.png
nextSectionLink: true
---
# Concurrency
Coroutines, actors, futures, and Io's concurrency model.
## Coroutines
Io uses coroutines (user level cooperative threads), instead of preemptive OS level threads to implement concurrency. This avoids the substantial costs (memory, system calls, locking, caching issues, etc) associated with native threads and allows Io to support a very high level of concurrency with thousands of active threads.
Under the stackless evaluator, a coroutine is simply a chain of heap-allocated evaluation frames. Switching coroutines is a matter of changing which frame chain the eval loop is walking — there is no platform-specific assembly, no `setjmp`/`longjmp`, and no `ucontext` or fibers. The same C code works on every host, including WebAssembly, which hides the native call stack entirely.
### Scheduler
The Scheduler object is responsible for resuming coroutines that are yielding. The current scheduling system uses a simple first-in-first-out policy with no priorities.
## Actors
An actor is an object with its own thread (in our case, its own coroutine) which it uses to process its queue of asynchronous messages. Any object in Io can be sent an asynchronous message by placing using the asyncSend() or futureSend() messages. Examples:
Synchronous:
```io
result := self foo
```
Asynchronous, immediately returns a Future:
```io
futureResult := self futureSend(foo)
```
Asynchronous, immediately returns nil:
```io
self asyncSend(foo)
```
When an object receives an asynchronous message it puts the message in its queue and, if it doesn't already have one, starts a coroutine to process the messages in its queue. Queued messages are processed sequentially in a first-in-first-out order. Control can be yielded to other coroutines by calling "yield".
Example:
```io
obj1 := Object clone
obj1 test := method(for(n, 1, 3, n print; yield))
obj2 := obj1 clone
obj1 asyncSend(test); obj2 asyncSend(test)
while(Scheduler yieldingCoros size > 1, yield)
```
This would print "112233".
Here's a more real world example:
```io
HttpServer handleRequest := method(aSocket,
HttpRequestHandler clone asyncSend(
handleRequest(aSocket)
)
)
```
## Futures
Io's futures are transparent. That is, when the result is ready, they become the result. If a message is sent to a future (besides the two methods it implements), it waits until it turns into the result before processing the message. Transparent futures are powerful because they allow programs to minimize blocking while also freeing the programmer from managing the fine details of synchronization.
### Auto Deadlock Detection
An advantage of using futures is that when a future requires a wait, it will check to see if pausing to wait for the result would cause a deadlock and if so, avoid the deadlock and raise an exception. It performs this check by traversing the list of connected futures.
### Futures and the Command Line Interface
The command line will attempt to print the result of expressions evaluated in it, so if the result is a Future, it will attempt to print it and this will wait on the result of Future. Example:
```io
Io> q := method(wait(1))
Io> futureSend(q)
[1-second delay]
==> nil
```
To avoid this, just make sure the Future isn't the result. Example:
```io
Io> futureSend(q); nil
[no delay]
==> nil
```
### Yield
An object will automatically yield between processing each of its asynchronous messages. The yield method only needs to be called if a yield is required during an asynchronous message execution.
### Pause and Resume
It's also possible to pause and resume an object. See the concurrency methods of the Object primitive for details and related methods.
## Continuations
Because evaluation state lives in heap-allocated frames rather than on the C stack, Io supports first-class continuations. `callcc` captures the current computation — its frame chain and local state — as a first-class object that can be stored, invoked later, or even serialized and resumed in another process.
The same property also makes it possible to model resumable exceptions: a handler can choose to resume the computation at the point of the raise, rather than unwinding past it, enabling Smalltalk- or Common-Lisp-style condition systems.
Because `callcc` is easy to misuse, it is not exposed in the top-level Lobby. It is available where needed through the VM's reflective interface.
---
<!-- Page: docs/Book/Control Flow -->
Source: /docs/Book/Control%20Flow/
---
heroImage: ../images/Control Flow.png
heroLayout: wide
heroAspect: 1024 / 681
nextSectionLink: true
---
# Control Flow
Branching, loops, exceptions, and scope.
## Branching
### if, then, else
The if() method can be used in the form:
```io
if(<condition>, <do message>, <else do message>)
```
Example:
```io
if(a == 10, "a is 10" print)
```
The else argument is optional. The condition is considered false if the condition expression evaluates to false or nil, and true otherwise.
The result of the evaluated message is returned, so:
```io
if(y < 10, x := y, x := 0)
```
is the same as:
```io
x := if(y < 10, y, 0)
```
Conditions can also be used in this form:
```io
if(y < 10) then(x := y) else(x := 2)
```
elseif() is supported:
```io
if(y < 10) then(x := y) elseif(
y == 11) then(x := 0) else(x := 2)
```
### ifTrue, ifFalse
Also supported are Smalltalk style ifTrue, ifFalse, ifNil and ifNonNil methods:
```io
(y < 10) ifTrue(x := y) ifFalse(x := 2)
```
Notice that the condition expression must have parenthesis surrounding it.
#### loop
The loop method can be used for "infinite" loops:
```io
loop("foo" println)
```
### repeat
The Number repeat method can be used to repeat a loop a given number of times.
```io
3 repeat("foo" print)
==> foofoofoo
```
#### while
Arguments:
```io
while(<condition>, <do message>)
```
Example:
```io
a := 1
while(a < 10,
a print
a = a + 1
)
```
### for
Arguments:
```io
for(<counter>, <start>, <end>,
<optional step>, <do message>)
```
The start and end messages are only evaluated once, when the loop starts. Example:
```io
for(a, 0, 10,
a println
)
```
Example with a step:
```io
for(x, 0, 10, 3, x println)
```
Which would print:
```io
0
3
6
9
```
To reverse the order of the loop, add a negative step:
```io
for(a, 10, 0, -1, a println)
```
Note: the first value will be the first value of the loop variable and the last will be the last value on the final pass through the loop. So a loop of 1 to 10 will loop 10 times and a loop of 0 to 10 will loop 11 times.
### break, continue
loop, repeat, while and for support the break and continue methods. Example:
```io
for(i, 1, 10,
if(i == 3, continue)
if(i == 7, break)
i print
)
```
Outputs:
```io
12456
```
### return
Any part of a block can return immediately using the return method. Example:
```io
Io> test := method(123 print;
return "abc"; 456 print)
Io> test
123
==> abc
```
Internally, `break`, `continue`, and `return` are handled by the iterative evaluator's frame state machine: each sets a non-local control signal on the current frame, and the eval loop unwinds frames until it reaches the enclosing loop or block.
## Comparison
### true, false and nil
There are singletons for true, false and nil. nil is typically used to indicate an unset or missing value.
### Comparison Methods
The comparison methods:
```io
==, !=, >=, <=, >, <
```
return either the true or false. The compare() method is used to implement the comparison methods and returns -1, 0 or 1 which mean less-than, equal-to or greater-than, respectively.
## Exceptions
### Raise
An exception can be raised by calling raise() on an exception proto.
```io
Exception raise("generic foo exception")
```
### Try and Catch
To catch an exception, the try() method of the Object proto is used. try() will catch any exceptions that occur within it and return the caught exception or nil if no exception is caught.
```io
e := try(<doMessage>)
```
To catch a particular exception, the Exception catch() method can be used. Example:
```io
e := try(
// ...
)
```
```io
e catch(Exception,
writeln(e coroutine backtraceString)
)
```
The first argument to catch indicates which types of exceptions will be caught. catch() returns the exception if it doesn't match and nil if it does.
#### Pass
To re-raise an exception caught by try(), use the pass method. This is useful to pass the exception up to the next outer exception handler, usually after all catches failed to match the type of the current exception:
```io
e := try(
// ...
)
```
```io
e catch(Error,
// ...
) catch(Exception,
// ...
) pass
```
### Custom Exceptions
Custom exception types can be implemented by simply cloning an existing Exception type:
```io
MyErrorType := Error clone
```
### Resumable Exceptions
Because evaluation state lives in heap-allocated frames, the frame that raised an exception is still a live, inspectable object when a handler runs. A handler can choose to *resume* the computation at the point of the raise — returning a value in place of the exception — instead of unwinding past it. This enables Smalltalk- or Common-Lisp-style condition handling where the handler decides whether to retry, substitute a value, or abort.
## Continuations
The iterative evaluator makes first-class continuations straightforward: `callcc` snapshots the current frame chain as an ordinary Io object. That object can be stored, invoked later, or — because it's just a graph of Io values — serialized and resumed in another process.
`callcc` is not exposed in the top-level Lobby because it's easy to misuse. Where continuations are needed, they're reachable through the VM's reflective interface.
---
<!-- Page: docs/Book/Introduction -->
Source: /docs/Book/Introduction/
---
heroImage: ../images/Introduction.png
nextSectionLink: true
---
# Introduction
The origins, philosophy, and influences behind Io.
## Overview
Io is a dynamic prototype-based programming language. The ideas in Io are mostly inspired by Smalltalk[1] (all values are objects), Self[2] (prototype-based), NewtonScript[3] (differential inheritance), Act1[4] (actors and futures for concurrency), Lisp[5] (code is a runtime inspectable / modifiable tree) and Lua[6] (small, embeddable).
## Perspective
The focus of programming language research for the last thirty years has been to combine the expressive power of high level languages like Smalltalk and the performance of low level language like C with little attention paid to advancing expressive power itself. The result has been a series of languages which are neither as fast as C or as expressive as Smalltalk. Io's purpose is to refocus attention on expressiveness by exploring higher level dynamic programming features with greater levels of runtime flexibility and simplified programming syntax and semantics.
In Io, all values are objects (of which, anything can change at runtime, including slots, methods and inheritance), all code is made up of expressions (which are runtime inspectable and modifiable) and all expressions are made up of dynamic message sends (including assignment and control structures). Execution contexts themselves are objects and activatable objects such as methods/blocks and functions are unified into blocks with assignable scope. Concurrency is made more easily manageable through actors and implemented using coroutines for scalability.
## Getting Started
Io is distributed as a single WebAssembly module (`io_static.wasm`) that runs under any WASM host — [wasmtime](https://wasmtime.dev), Node.js, or a browser. Source and build instructions live at [github.com/IoLanguage/io](https://github.com/IoLanguage/io).
### Interactive Mode
To start the REPL, run the WASM binary under wasmtime:
```io
wasmtime --dir=. build/bin/io_static
```
This opens the Io interpreter prompt.
You can evaluate code by entering it directly. Example:
```io
Io> "Hello world!" println
==> Hello world!
```
Expressions are evaluated in the context of the Lobby:
```io
Io> print
[printout of lobby contents]
```
If you have a .iorc file in your home folder, it will be evaled before the interactive prompt starts.
#### Inspecting objects
You can get a list of the slots of an object like this:
```io
Io> someObject slotNames
```
To show them in sorted order:
```io
Io> someObject slotNames sort
```
For a nicely formatted description of an object, the slotSummary method is handy:
```io
Io> slotSummary
==> Object_0x20c4e0:
Lobby = Object_0x20c4e0
Protos = Object_0x20bff0
exit = method(...)
forward = method(...)
```
Exploring further:
```io
Io> Protos
==> Object_0x20bff0:
Core = Object_0x20c4b0
```
Inspecting a method will print a decompiled version of it:
```io
Io> Lobby getSlot("forward")
==> # io/Z_Importer.io:65
method(
Importer import(call)
)
```
#### doFile and doString
A script can be run from the interactive mode using the doFile method:
```io
doFile("scriptName.io")
```
The evaluation context of doFile is the receiver, which in this case would be the lobby. To evaluate the script in the context of some other object, simply send the doFile message to it:
```io
someObject doFile("scriptName.io")
```
The doString method can be used to evaluate a string:
```io
Io> doString("1+1")
==> 2
```
And to evaluate a string in the context of a particular object:
```io
someObject doString("1 + 1")
```
### Command Line Arguments
Example of printing out command line arguments:
```io
System args foreach(k, v, write("'", v, "'\n"))
```
### launchPath
The System "launchPath" slot is set to the location of the initial source file that is executed; when the interactive prompt is started (without specifying a source file to execute), the launchPath is the current working directory:
```io
System launchPath
```
---
<!-- Page: docs/Book/Objects -->
Source: /docs/Book/Objects/
---
heroImage: ../images/Objects.png
nextSectionLink: true
---
# Objects
Slots, prototypes, cloning, and differential inheritance.
## Overview
Io's guiding design principle is simplicity and power through conceptual unification.
| concept | unifies |
|------------------|---------------------------------------|
| scopable blocks | functions, methods, closures |
| prototypes | objects, classes, namespaces, locals |
| messages | operators, calls, assigns, var access |
## Prototypes
In Io, everything is an object (including the locals storage of a block and the namespace itself) and all actions are messages (including assignment). Objects are composed of a list of key/value pairs called slots, and an internal list of objects from which it inherits called protos. A slot's key is a symbol (a unique immutable sequence) and its value can be any type of object.
### clone and init
New objects are made by cloning existing ones. A clone is an empty object that has the parent in its list of protos. A new instance's init slot will be activated which gives the object a chance to initialize itself. Like NewtonScript[3], slots in Io are create-on-write.
```io
me := Person clone
```
To add an instance variable or method, simply set it:
```io
myDog name := "rover"
myDog sit := method("I'm sitting\n" print)
```
When an object is cloned, its "init" slot will be called if it has one.
### Inheritance
When an object receives a message it looks for a matching slot, if not found, the lookup continues depth first recursively in its protos. Lookup loops are detected (at runtime) and avoided. If the matching slot contains an activatable object, such as a Block or CFunction, it is activated, if it contains any other type of value it returns the value. Io has no globals and the root object in the Io namespace is called the Lobby.
Since there are no classes, there's no difference between a subclass and an instance. Here's an example of creating the equivalent of a subclass:
```io
Io> Dog := Object clone
==> Object_0x4a7c0
```
The above code sets the Lobby slot "Dog" to a clone of the Object object; the protos list of this new object contains only a reference to Object, essentially indicating that a subclass of Object has been created.
Instance variables and methods are inherited from the objects referenced in the protos list. If a slot is set, it creates a new slot in our object instead of changing the protos:
```io
Io> Dog color := "red"
Io> Dog
==> Object_0x4a7c0:
color := "red"
```
#### Multiple Inheritance
You can add any number of protos to an object's protos list. When responding to a message, the lookup mechanism does a depth first search of the proto chain.
## Methods
A method is an anonymous function which, when called, creates an object to store its locals and sets the local's proto pointer and its self slot to the target of the message. The Object method method() can be used to create methods. Example:
```io
method((2 + 2) print)
```
An example of using a method in an object:
```io
Dog := Object clone
Dog bark := method("woof!" print)
```
The above code creates a new "subclass" of object named Dog and adds a bark slot containing a block that prints "woof!". Example of calling this method:
```io
Dog bark
```
The default return value of a block is the result of the last expression.
#### Arguments
Methods can also be defined to take arguments. Example:
```io
add := method(a, b, a + b)
```
The general form is:
```io
method(<arg name 0>, <arg name 1>, ..., <do message>)
```
### Blocks
A block is the same as a method except it is lexically scoped. That is, variable lookups continue in the context of where the block was created instead of the target of the message which activated the block. A block can be created using the Object method block(). Example of creating a block:
```io
b := block(a, a + b)
```
#### Blocks vs. Methods
This is sometimes a source of confusion so it's worth explaining in detail. Both methods and blocks create an object to hold their locals when they are called. The difference is what the "proto" and "self" slots of that locals object are set to. In a method, those slots are set to the target of the message. In a block, they're set to the locals object where the block was created. So a failed variable lookup in a block's locals continue in the locals where it was created. And a failed variable lookup in a method's locals continue in the object to which the message that activated it was sent.
#### call and self slots
When a locals object is created, its self slot is set (to the target of the message, in the case of a method, or to the creation context, in the case of a block) and its call slot is set to a Call object that can be used to access information about the block activation:
#### Variable Arguments
The "call message" slot in locals can be used to access the unevaluated argument messages. Example of implementing if() within Io:
```io
myif := method(
(call sender doMessage(call message argAt(0))) ifTrue(
call sender doMessage(call message argAt(1))) ifFalse(
call sender doMessage(call message argAt(2)))
)
```
```io
myif(foo == bar, write("true\n"), write("false\n"))
```
The doMessage() method evaluates the argument in the context of the receiver. A shorter way to express this is to use the evalArgAt() method on the call object:
```io
myif := method(
call evalArgAt(0) ifTrue(
call evalArgAt(1)) ifFalse(
call evalArgAt(2))
)
```
```io
myif(foo == bar, write("true\n"), write("false\n"))
```
#### Forward
If an object doesn't respond to a message, it will invoke its "forward" method if it has one. Here's an example of how to print the information related lookup that failed:
```io
MyObject forward := method(
write("sender = ", call sender, "\n")