title[ StackTalk ] "Stack Basics" note[ An object is a collection of named stacks A quotation is a malleable list of code symbols, delimited by [ and ] Strings can be written two ways: "This is a conventional string" this-is-a-symbol-string: There are 4 baseline stack operations: `$value $stack push` `$stack pop` `$stack peek` `$stack run` These let you manipulate arbitrarily named stacks. `run` is a bit special. It'll run top of $stack, if it is a quotation, otherwise it acts like peek There are shortcuts for these operations: [ 1 x: push ] can be writtn as [ 1 >x ] [ x: peek ] can be written as [ x. ] when you need no ambiguity [ x: pop ] can be written as [ x> ] [ x: run ] can be written as [ x ] ] "Quotation suffix autoswap" note[ This one is a little inspired by https://knucklecracker.com/wiki/doku.php?id=crpl:overview#warp_notation, but is ultimately a bit less generalized. I anticipate that quotations will be modified by a lot of words. Because of this, and because I think it reads better in a lot of cases, there's another rewrite [ 1 [ me> 1 + >me ] do ] can be written as [ 1 do[ me> 1 + >me ] ] This is how `note` has been working. This doesn't generalize to arbitrary word movement, just for quotations. ] Objects: note[ The current Object/scope is the top of the `me:` stack. `do` executes the quotation inside the scope of object below it in the stack. `$subject $quotation do` do single command Shorthand: [ AnObject [ aThing ] do ] can be written as [ AnObject .aThing ] You can use an existing object as a starting point for one of your own via `clone` [ 0 0 Object clone do[ >y >x ] >my2dPoint ] ] Quotations: note[ Quotations are a swiss-army-knife of a code structure You can call `string` on them to get their contents. [ [ a thing ] .string NB[ stack is " a thing " ] ] `interpolate` will copy values from the containing scope based on $names [ 1 >a 2 >b interpolate[ $a $b + ] NB[ stack is [ 1 2 + ] ] Objects copied this way are copied by reference, rather than deep cloned. You can get the list of symbols from a quotation code[ [ @ @ -- @ ] symbols each[ println ] NB[ print output: "@" "@" "--" "@" ] ] You can supply an interpretation ruleset, on the left side, you have patterns, on the right, consequent actions The patterns match against one or more symbols (as fetched by `symbols`). [ @ @ -- @ ] obj[ 0 >numInputValues 0 >numOutputValues input: >mode ] interperet[ @ [ input: mode ] -> [ numInputValues: inc ] -- [ input: mode ] -> [ output: >mode ] @ [ output: mode ] -> [ numOutputValues: inc ] * -> [ [ "Unrecogized symbol" _ ] fmt error ] ] >effect NB[ effect do[ numInputValues numOutputValues mode ] stack is [ 2 1 output ] ] ] Scope: note[ Stack name resolution order: - Own set of stacks, where state and method definitions live - Ordered list of modules. Symbol list is what is available at import time, need to explicitly refresh for updates - A reference to `Lobby`, where iterpreter-level state lives. Notably, -not- strictly lexical. `interpolate` provides a way to place values in from an outer scope. Also, unless you `freeze` a quotation, a new one is allocated each time you run. If a stack is resolved, then that should probably be cached on the current instance ] Experimental: note[ Some code snippets that I'm noodling on. experimental[ 1 >x 2 >y 3 >z [ x: y: z: ] from-stacks ] ] io: module[ load-by-default println: js: [ @ -- ] ffi[ (x) => console.log(x); ] readln: js: [ -- @ ] ffi[ () => ; ] ] math: module[ load-by-default +: js: [ @ @ -- @ ] ffi[ (x, y) => x+y; ] +: lua: [ @ @ -- @ ] ffi[ function(x, y) return x+y end ] -: js: [ @ @ -- @ ] ffi[ (x, y) => x-y; ] *: js: [ @ @ -- @ ] ffi[ (x, y) => x*y; ] gt: js: [ @ @ -- @] ffi[ (a, b) => a > b; ] lt: js: [ @ @ -- @] ffi[ (a, b) => a < b; ] div: js: [ @ @ -- @ ] ffi[ (x, y) => x/y; ] [ >n n. pop + n> push ] >+= ] Point: class[ usage[ 1 2 Point .fromPair >location 1 1 location .move location .pos NB[ stack is [ 2 3 ] ] location: drop ] fromPair: [ @ @ -- @ ] fn[ clone do[ >y >x ] ] init: [ -- ] method[ clone do[ 0 >x 0 >y ] ] pos: [ -- @ @ ] method[ x> y> ] moveByPair: [ @ @ -- ] method[ y: += x: += ] move: [ x y -- ] method[ your[ x> y> ] moveByPair ] ]