Stack: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 3,824: Line 3,824:
empty
empty
depth: 0</pre>
depth: 0</pre>

=={{header|jq}}==
For most purposes, jq's arrays can be used for stacks if needed, without much further ado.
However, since the present task requires the definition of special stack-oriented operations,
we shall start with the following definitions:
<syntaxhighlight lang=jq>
# create a Stack
def Stack: {stack: []};

# check an object is a Stack
def isStack:
type == "object" and has("stack") and (.stack|type) == "array";

def pop:
if .stack|length == 0 then "pop: stack is empty" | error
else {stack: .stack[1:], item: .stack[0]]
end;

def push($x):
.stack = [$x] + .stack | .item = null;

def size:
.stack | length;

def isEmpty:
size == 0;
</syntaxhighlight>

Depending on context, additional code to check for or to enforce
type discipline could be added, but is omitted for simplicity here.
If using the C implementation of jq, the function names could also
be prefixed with "Stack::" to distinguish them as stack-oriented
operations.

For some purposes, this approach may be sufficient, but it can easily
become cumbersome if a sequence of operations must be performed
while also producing outputs that reflect intermediate states.

Suppose for example that we wish to create a stack, push some value,
and then pop the stack, obtaining the popped value as the final
result. This could be accomplished by the pipe:
<syntaxhighlight lang=jq>
Stack | push(3) | pop | .item
</syntaxhighlight>

Now suppose we also wish to record the size of the stack after each of these three operations.
One way to do this would be to write:
<syntaxhighlight lang=jq>
Stack
| size, (push(3)
| size, (pop
| size, .item ))
</syntaxhighlight>

Unfortunately this approach is error-prone and can quickly become tedious, so
we introduce an "observer" function that can "observe" intermediate states following any operation.
With observer/2 as defined below, we can instead write:
<syntaxhighlight lang=jq>
null
| observe(Stack; size)
| observe(push(3); size)
| observe(pop; size)
| .emit, item
</syntaxhighlight>

The idea is that each call to `observe` updates the "emit" slot, so that
all the accumulated messages are available at any point in the pipeline.

<syntaxhighlight lang=jq>
# Input: an object
# Output: the updated object with .emit filled in from `update|emit`.
# `emit` may produce a stream of values, which need not be strings.
def observe(update; emit):
def s(stream): reduce stream as $_ (null;
if $_ == null then .
elif . == null then "\($_)"
else . + "\n\($_)"
end);
.emit as $x
| update
| .emit = s($x // null, emit);
</syntaxhighlight>



=={{header|Julia}}==
=={{header|Julia}}==