Last active 2 weeks ago

A language to surpass Io

Revision aa2ce7a2ce1edb4e51ced420d673fbacc1970683

StackTalkDesign.txt Raw Playground
1title[ StackTalk ]
2
3"Stack Basics" note[
4
5 An object is a collection of named stacks
6 A quotation is a malleable list of code symbols, delimited by [ and ]
7 Strings can be written two ways:
8
9 "This is a conventional string"
10 this-is-a-symbol-string:
11
12 There are 4 baseline stack operations:
13
14 `$value $stack push`
15 `$stack pop`
16 `$stack peek`
17 `$stack run`
18
19 These let you manipulate arbitrarily named stacks.
20 `run` is a bit special. It'll run top of $stack, if it is a
21 quotation, otherwise it acts like peek
22
23 There are shortcuts for these operations:
24
25 [ 1 x: push ] can be writtn as [ 1 >x ]
26 [ x: peek ] can be written as [ x. ] when you need no ambiguity
27 [ x: pop ] can be written as [ x> ]
28 [ x: run ] can be written as [ x ]
29
30]
31
32"Quotation suffix autoswap" note[
33 This one is a little inspired by https://knucklecracker.com/wiki/doku.php?id=crpl:overview#warp_notation,
34 but is ultimately a bit less generalized.
35
36 I anticipate that quotations will be modified by a lot of words. Because of this, and because
37 I think it reads better in a lot of cases, there's another rewrite
38
39 [ 1 [ me> 1 + >me ] do ] can be written as [ 1 do[ me> 1 + >me ] ]
40
41 This is how `note` has been working.
42
43 This doesn't generalize to arbitrary word movement, just for quotations.
44]
45
46
47Objects: note[
48
49 The current Object/scope is the top of the `me:` stack.
50
51 `do` executes the quotation inside the scope of object below
52 it in the stack.
53
54 `$subject $quotation do`
55
56 do single command Shorthand:
57
58 [ AnObject [ aThing ] do ] can be written as [ AnObject .aThing ]
59
60 You can use an existing object as a starting point for one of your own via `clone`
61
62 [ 0 0 Object clone do[ >y >x ] >my2dPoint ]
63]
64
65Quotations: note[
66 Quotations are a swiss-army-knife of a code structure
67
68 You can call `string` on them to get their contents.
69 [ [ a thing ] .string NB[ stack is " a thing " ] ]
70
71 `interpolate` will copy values from the containing scope based on $names
72 [ 1 >a 2 >b interpolate[ $a $b + ] NB[ stack is [ 1 2 + ] ]
73
74 Objects copied this way are copied by reference, rather than deep cloned.
75
76 You can get the list of symbols from a quotation
77 code[
78
79 [ @ @ -- @ ] symbols each[ println ]
80 NB[ print output:
81 "@"
82 "@"
83 "--"
84 "@"
85 ]
86 ]
87
88 You can supply an interpretation ruleset, on the left side, you have patterns, on the right, consequent actions
89 The patterns match against one or more symbols (as fetched by `symbols`).
90
91 [ @ @ -- @ ] obj[ 0 >numInputValues 0 >numOutputValues input: >mode ]
92 interperet[
93 @ [ input: mode ] -> [ numInputValues: inc ]
94 -- [ input: mode ] -> [ output: >mode ]
95 @ [ output: mode ] -> [ numOutputValues: inc ]
96 * -> [ [ "Unrecogized symbol" _ ] fmt error ]
97 ] >effect
98 NB[ effect do[ numInputValues numOutputValues mode ] stack is [ 2 1 output ] ]
99]
100
101Scope: note[
102
103 Stack name resolution order:
104 - Own set of stacks, where state and method definitions live
105 - Ordered list of modules. Symbol list is what is available at import time, need to explicitly refresh for updates
106 - A reference to `Lobby`, where iterpreter-level state lives.
107
108 Notably, -not- strictly lexical. `interpolate` provides a way to place values in from an outer scope.
109 Also, unless you `freeze` a quotation, a new one is allocated each time you run.
110
111 If a stack is resolved, then that should probably be cached on the current instance
112]
113
114
115Experimental: note[
116 Some code snippets that I'm noodling on.
117
118 experimental[
119 1 >x 2 >y 3 >z
120 [ x: y: z: ] from-stacks
121 ]
122]
123
124io: module[
125 load-by-default
126 println: js: [ @ -- ] ffi[ (x) => console.log(x); ]
127 readln: js: [ -- @ ] ffi[ () => ; ]
128]
129
130math: module[
131 load-by-default
132
133 +: js: [ @ @ -- @ ] ffi[ (x, y) => x+y; ]
134 +: lua: [ @ @ -- @ ] ffi[ function(x, y) return x+y end ]
135 -: js: [ @ @ -- @ ] ffi[ (x, y) => x-y; ]
136 *: js: [ @ @ -- @ ] ffi[ (x, y) => x*y; ]
137 gt: js: [ @ @ -- @] ffi[ (a, b) => a > b; ]
138 lt: js: [ @ @ -- @] ffi[ (a, b) => a < b; ]
139 div: js: [ @ @ -- @ ] ffi[ (x, y) => x/y; ]
140 [ >n n. pop + n> push ] >+=
141]
142
143Point: class[
144 usage[
145 1 2 Point .fromPair >location
146 1 1 location .move
147 location .pos NB[ stack is [ 2 3 ] ]
148 location: drop
149 ]
150
151 fromPair: [ @ @ -- @ ] fn[ clone do[ >y >x ] ]
152 init: [ -- ] method[ clone do[ 0 >x 0 >y ] ]
153 pos: [ -- @ @ ] method[ x> y> ]
154 moveByPair: [ @ @ -- ] method[ y: += x: += ]
155 move: [ x y -- ] method[ your[ x> y> ] moveByPair ]
156]
157