« first day (1502 days earlier)      last day (1155 days later) » 

8:00 PM
I guess its self evident
because its working now
 
@nathanrogers is (⍺⍺∇∇⍵⍵) so if you want to invoke the same operator with the same operands, is enough. Otherwise use ∇∇ if you want to use the same operator with different operands.
 
I see
s06_1a←{                                 ⍝ 6_?
    onoff ← ⍺⍺                           ⍝ ... 6_1: 0/1 ⋄ 6_2 1/¯1
    tggle ← ⍵⍵                           ⍝ ... 6_1: ~⍵  ⋄ 6_2 2+⍵
    ind  ← {,{(⊃⍵)∘+¨⍳1+⊃|-/⍵}1↓¨⍵}      ⍝ ... The indices to set
    eval ← {                             ⍝ ... Recursive Solution
        ~×≢⍵ : 1⊥,⍺                      ⍝ ... Not any? Then sum reduce
        i←ind (n←⊃⍵)                     ⍝ ... Current update indices)
        'e'=⊃⊃⊃⍵ : (tggle@i⊢⍺) ∇ 1↓⍵     ⍝ ... Toggle? Apply ~ to i in ⍺
There's the final solution for each one that passes tests
the ind function to a while to intuit because the size was super big. even on smaller tables output looked right, but it wasn't until I did ...1+... that it produced the right answer
Why can I only edit for like 30 seconds after sending a message?
 
@nathanrogers I would personally find this easier to read if you used a naming convention to differentiate arrays/functions/mops/dops
 
mops/dops?
 
@nathanrogers So that I cannot agree with your statement, only to have you change it and make me look like I agreed with something very different. (Also, it isn't 30 s.)
@nathanrogers monadic operators, dyadic operators.
 
8:12 PM
I tend to be more slapdash until I know what things are, and then try to refactor into names that work
 
@nathanrogers Though you didn't name the operand in this case, you could have, and that might have helped you spot that you were giving an operator to @
 
Right, that wasn't something I thought about until now
 
Now you know for next time.
 
Do guards always return?
 
@nathanrogers yep, at least in Dyalog
 
8:21 PM
even with assignment
 
yep
 
@nathanrogers Yes, then the result is shy.
 
how can I map one of 2 functions to a given name
depending on conditions
I always want to call some form of an expression, but the f may be one or the other
 
@nathanrogers {cond:f⍵⋄g⍵}
 
no, I don't want to evaluate
I want the function
{cond : f ⋄ g}
I know that isn't the way to do it
but how is the way
 
8:23 PM
     solve←{
         m←0⍴⍨2⍴1000
         on←⍎⊃⍵ ⋄ off←⍎1⊃⍵ ⋄ toggle←⍎2⊃⍵
         +/,m⊣{0⊣m∘←0⌈(⍎3⊃a)@((⊂⊃⌽b)+,⍳1+⊃-/b←⍎¨0 2⊃¨⊂a←⌽' '(≠⊆⊢)⍵)⊢m}¨⊃⎕NGET'201506.txt' 1
     }
solve '10~'
solve '+∘1' '-∘1' '+∘2'
not very fast... probably a better way
 
@nathanrogers Where do the two functions come from?
 
they're the operands from ealier
 
@nathanrogers How about ⍺⍺{⍵:⍺⍺ ⍵ ⋄ ⍵⍵ ⍵}⍵⍵∘cond ?
 
(0⌈f@(inds⊃⍵)⊢⍺) ∇ 1↓⍵
this is the expresion I want
its the same in both cases
f might be ⍺⍺∘⍵ or it might be ⍵⍵
in this case onoff or toggle
f←{cond: onoff∘⍵ ⋄ toggle} doesn't work
 
(BQN, cond⊏f‿g :) )
 
8:26 PM
I need to select the function that should go there
 
@nathanrogers Right, because you need to pass the argument to the function.
 
so you're saying there is not a way to optionally bind the name of f to one of a few functions
 
⍎cond⊃'fg'
 
are there any guards that DONT exit
 
(0⌈⍺⍺∘⍵{⍵:⍺⍺ ⍺ ⋄ ⍵⍵ ⍺}⍵⍵∘cond@(inds⊃⍵)⊢⍺) ∇ 1↓⍵ should work.
 
8:28 PM
embrace the evals
 
I get that it should work, but it isn't very elegant, so I'm trying to rephrase the question ot be specific
 
@nathanrogers No, then you have to wrap in another layer of dfn. If you really need this, you seem to be doing structured imperative programming, so use a tradfn.
 
it seems like I'm doing functionally recursive programming
 
@Adám wanting to pick one of two functions is a pretty normal thing to do imo
 
Anyway, what I wrote should work.
 
8:29 PM
@Adám he's trying to do functional programming not imperative
 
@dzaima Sure, but that wasn't what I answered. I talked about diverging branches coming back together again.
 
personally I'd give up any principles and use ⍎ but that's not for everyone
 
@Adám functional programming doesn't not allow that
 
@nathanrogers Does my expression work?
@dzaima OK.
 
yes it works
but I'll go with @rak1507 suggestion
eval ← {                             ⍝ ... Recursive Solution
    f←⍎'onoff∘⍵' 'tggle'⊃⍨'e'=⊃⊃⊃⍵   ⍝ ... Select function
    ~×≢⍵     : 1⊥,⍺                  ⍝ ... Not any? Then sum reduce
    (0⌈f@(inds⊃⍵)⊢⍺) ∇ 1↓⍵           ⍝ ... Set onoff at i in a, with 0 floor
}
honestly I'd take an array of functions over trains
 
8:32 PM
If you went with mine, I'd recommend breaking up that long lin.
@nathanrogers Not sure what that means.
 
first class functions would be great but it'll never happen :(
 
(also fwiw, {cond: f ⋄ g} works in dzaima/APL :) )
 
wouldn't really make sense syntactically
 
@dzaima As did it in a conference edition of Dyalog APL.
 
@Adám I wnat to have a list of function onoff tggle and select which one
onoff tggle[cond]
for instance
 
8:33 PM
@nathanrogers Sure, I get that, but I'm not sure what the connection is to trains.
 
the syntax would be overloaded with train syntax?
you have to pick one with strand notation
 
@nathanrogers well, you still couldn't create an array of both functions and arrays
 
or at least some kind of "symbol" notation
@dzaima right you'd need some kind of lisp-style or k-style symbol reference notation
 
in k functions are first class anyway
 
or just a non-strand array notation (like BQN)
 
8:36 PM
Right. BQN is good.
 
@rak1507 yeah I like your input parsing method better
I used a regex, but yours with just splitting on space works out just fine
 
yea regex seems slightly overkill but for something more complex splitting probably wouldn't work
ironic because in AOC last year I probably overused regex if anything haha
 
i06 ← ('.? ?[0-9]+,[0-9]+'⎕S{(⊃,{⍎','⎕R' '⊢1↓⍵})⍵.Match~' '})¨2015 #.day 6
prit-tee overkill
 
@nathanrogers Isn't ⍎','⎕R' '⊢1↓⍵ the same as ⍎1↓⍵?
 
idk, is it?
let me check
I thought i needed to get rid of ,'s
 
8:49 PM
@nathanrogers Because…?
 
yeah seems to work
because ,'s are numbers
and I'm not super familiar with ⍎ spec
 
@nathanrogers ≈ APL
 
but yeah, that works
('.? ?[0-9]+,[0-9]+'⎕S{(⊃,{⍎1↓⍵})⍵.Match~' '})¨2015 #.day 6
 
@nathanrogers {⍎1↓⍵} is ⍎1↓ no?
 
sorr that's a train
 
8:51 PM
Oh, right.
So (⊃,{⍎1↓⍵}) is 1(⊃,∘⍎↓) with ⎕IO←1
Or (⊃,∘⍎1↓⊢) with any ⎕IO
@nathanrogers Any reason you use [0-9] instead of \d?
 
(dzaima/APL, ⍎⍢(1↓) because of course i'll choose to mention under)
 
not specifically
 
@dzaima Oh, I so wish for structural under…
 
@Adám (though this isn't purely structural under since can change the item amount)
oh :/
 
I was just about to ask "Won't under fail then?"
 
8:57 PM
@Adám it fails only on a single item. 'a' 1 2 34≡(⍎⍢(1↓))'a1 2 34' works fine
the problem is that ⍎,'1' creates a scalar, whereas wants back a vector
 
@dzaima So ,⍤⍎ works?
Shouldn't a scalar distribute?
 
@Adám yep
@Adám if ⍎⍢(1↓)'a1' was 'a' 1, it'd break the single under rule, i.e. 1↓'a' 1 isn't the result of
 
9:13 PM
man this is getting obnoxious
@Adám I've got some kind of weird stateful problem. When I clear the workspace and link in the directory again, the function doesn't work... until I modify it, then save it and run it twice, THEN it works
any idea where to begin with troubleshooting?
 
@nathanrogers Trace through runs until right before it works, then look at what changes when it starts working.
 
ok no, just modifying the file does it
um... do assigning operators in a namespace file count as "evaluating code" in a namespace...
myop ← f dfn g
@Adám
 
@nathanrogers That doesn't look right. What are f and dfn and g? (Again, a naming convention would help.)
 
that doesn't matter I'm asking if that's legal to do in a namespace file
or is that tantamount of "evaluating code" in a namespace
 
@nathanrogers is dfn a function? an operator?
 
9:28 PM
I cannot parse the statement without context info. APL is not statically parseable.
@nathanrogers I assumed myop is an operator, is this correct?
 
ok fine
myfn ← f op g
harga garga
is that legal in a namespace file
 
Oh, now that makes more sense.
 
or not
 
I think it is technically legal, but I wouldn't do it, because it depends on the order in which things are declared.
 
⋄ ∊'your code ',('is' 'is not'[?2]),' valid'
 
9:30 PM
look I'm completely stuck
 
Nominally, namespace scripts are considered ordered, but when you edit a single function, the system can "patch" that back into the namespace without evaluating everything. I think.
 
I do a fresh link
run code
unexpected errors
make any arbitrary edit to the namespace file
run twice
it works
@Adám the point to clarify is I'm not making an edit to a single function, but I can make any arbitrary edit to anywhere in the file
 
@nathanrogers Please cut it down to a minimal repro and log an issue against Link.
 
run the same expression twice and it works
i minimal repro involves an entire library
I'll just create a repository for the whole thing I guess
 
@nathanrogers something that should've been asked way earlier: what exactly are your "unexpected errors"?
 
9:32 PM
@nathanrogers That sounds unlikely.
 
LENGTH ERROR
run[32] ∨/~passed:((⊂⍵),error passMSG passed),(⊂⍉,/↑failMSG¨failed) ⍝ any failed
 
There's missing one line from that message.
Could if be that you mutate some state when you run, and only after two mutations are the arrays conformant?
 
      )clear
clear ws
      ]link.create # 'c:\d\aoc'
Linked: # ←→ c:\d\aoc
      aoc2015 t.test's06_1'
LENGTH ERROR
run[32] ∨/~passed:((⊂⍵),error passMSG passed),(⊂⍉,/↑failMSG¨failed) ⍝ any failed
                                                 ∧
 
@nathanrogers Still missing a critical last line of that error, no?
 
9:35 PM
@nathanrogers no yes. TFTFY.
 
@nathanrogers did you do printf-debugging (i.e. add a ⎕← after ,/ to see what input it doesn't like?)
 
OK, again, we're missing the context.
 
I've taken a look at all of the inputs
 
So on runs where it works, and on runs where it doesn't work, are the inputs the same?
 
9:36 PM
@nathanrogers and did you understand why ,/ was failing?
 
and to make it work, all I need to do is add a new line anywhere in the namespace file I've been working in
 
@nathanrogers OK, and what change do you see to the intermediary values when you do that?
 
1) replace ,/ with {⎕←⎕SE.Dyalog.Utils.repObj⍵⋄,/⍵}
2) reload the namespace
3) run the function twice, see if the outputs differed
 
so values is meant to be the output of a function, and somehow its collecting something that isn't the output of a function, its collected the internal data of the function
 
@nathanrogers "values"?
 
9:39 PM
values ← (⍺ trap ⍵)¨inputs ⍝ collect results
passed ← expected≡¨values ⍝ 1 for pass 0 for fail
error ← (⊂,⊂⎕THIS.config.error)⍷values ⍝ which tests crashed ?
∘∘∘
failed ← (~passed)/↓inputs,expected,⍪values ⍝ select failing cases
these are the lines that preceed the failing one
 
Can you please just follow dzaima's 1-2-3 guide?
 
the first 2 times, values is a giant matrix, which is the ⍺ in the function causing the failure
yes, I did that
and that isn't the issue
the isue is that values is something entirely unexpected
s06a←{                                   ⍝ 6_? ⍵ ←→ The range to modify
    ~×≢⍵  : 1⊥,⍺                         ⍝ ... Not any? Then sum reduce
    onoff ← ⍺⍺ ⋄ toggle ← ⍵⍵             ⍝ ... Functions for each case
    range ← {,{(⊃⍵)∘+¨⍳1+⊃|-/⍵}1↓¨⍵}     ⍝ ... The range of inds to modify
    ⍺     ← 1000 1000⍴0                  ⍝ ... A light matrix
    f     ← ⍎'onoff∘⍵' 'toggle'⊃⍨'e'=⊃⊃⊃⍵⍝ ... Which action for this range?
    (0⌈f@(range⊃⍵)⊢⍺) ∇ 1↓⍵              ⍝ ... Set value at indices, 0 floor
 
OK. So go put ⎕← or that special dfn dzaima wrote here and there until you identify the exact point where two consecutive runs differ. Then report back to us.
 
listen
 
so work backwards and see where something differs
 
9:41 PM
this is the function I was working on
 
Good for you. Now can you follow the sound advise that we're giving you?
 
let me finish
 
Why? We answered your question:
26 mins ago, by nathan rogers
any idea where to begin with troubleshooting?
 
1. link the workspace
2. run the test on this functiON
3. fail, values ←→ ⍺ in this dfn
4. edit the namespace containing this dfn anywhere not in the dfn
5. run it again
6. 1st run :: values ←→ ⍺ in this dfn
7. 2nd run :: values ←→ the expected result
yes, and I'm trying to answer
this is the thing that is wrong
values, used to formulate the failing line
is the wrong "value"
that is the thing that is wrong, how does editing a namespace file change that?
i mean, arbitrarily, just adding blank lines anywhere in the file fixes it
 
We're missing the context (again!)
Where does the line values ← (⍺ trap ⍵)¨inputs appear?
 
9:45 PM
right, because there's an entire testing framework that lays behind this
 
@nathanrogers I assume that code is within some other function that we know nothing about?
 
inside a testing tool
like I said
minimum repro involves a testing library
 
We gave you a universal method for figuring this out on your own.
If you want us to figure it out for you, you've got to give us the whole story.
 
yes and I answered the question
 
Did you remember the answers, though?
 
9:46 PM
yes
 
@nathanrogers what is "this dfn" there? the test function, s06a or something else?
 
first 2 runs a 1000 x 1000 matrix
last run an integer
 
@nathanrogers Great, then work backwards from there.
 
what's backwards? the inputs are identical
the function is identical
the output is different
 
Sure, but clearly, at some point, the two runs diverge.
 
9:48 PM
yea, and that newline sure has a lot to do with how its being evaluated
 
We want to know the point where the same code gives two different results with the same input.
 
@nathanrogers you've found that values changes. Have you looked at the reason values changes?
 
So, your homework is: Identify the earliest expression that can give two different results depending on how many times it is run or depending on if you've edited in a trivial change.
 
right, I have looked and the inputs and expected outputs look exactly the same
this is the earliest
that's what I'm saying
this line is the result of calling the function on the same inputs
 
btw, when you made the trivial change, did you try altering a comment rather than inserting a line?
 
9:50 PM
how about a ⎕← for values both after it is just defined, and in the place it's used?
 
yes that works
modifying a comment
 
@nathanrogers Works, as in triggers the change?
 
yes
(,⊂(('e' 461 550) ('h' 564 900)) (('f' 370 39) ('h' 425 839)) (('f' 464 858) ('h' 833 915)) (('f' 812 389) ('h' 865 874)) (('n' 599 989) ('h' 806 993)) (('n' 376 415) ('h' 768 548)) (('n' 606 361) ('h' 892 600)) (('f' 448 208) ('h' 645 684)) (('e' 50 472) ('h' 452 788)) (('e' 205 417) ('h' 703 826)) (('e' 533 331) ('h' 906 873)) (('e' 857 493) ('h' 989 970)) (('f' 631 950) ('h' 894 975)) (('f' 387 19) ('h' 720 700)) (('f' 511 843) ('h' 581 945)) (('e' 514 557) ('h' 662 883)) (('f' 269 809) ('h' 876 847)) (('f' 149 517) ('h' 716 777)) (('f' 994 939) ('h' 998 988)) (('e' 467 662) ('h' 555 957
look at the last result
the final elemnt
(,⊂(('e' 461 550) ('h' 564 900)) (('f' 370 39) ('h' 425 839)) (('f' 464 858) ('h' 833 915)) (('f' 812 389) ('h' 865 874)) (('n' 599 989) ('h' 806 993)) (('n' 376 415) ('h' 768 548)) (('n' 606 361) ('h' 892 600)) (('f' 448 208) ('h' 645 684)) (('e' 50 472) ('h' 452 788)) (('e' 205 417) ('h' 703 826)) (('e' 533 331) ('h' 906 873)) (('e' 857 493) ('h' 989 970)) (('f' 631 950) ('h' 894 975)) (('f' 387 19) ('h' 720 700)) (('f' 511 843) ('h' 581 945)) (('e' 514 557) ('h' 662 883)) (('f' 269 809) ('h' 876 847)) (('f' 149 517) ('h' 716 777)) (('f' 994 939) ('h' 998 988)) (('e' 467 662) ('h' 555 957
contrast that with the last element here
which is an integer
not a 1000x1000 matrix
same input
 
Well, a 1-element vector, but OK.
At which primitive do runs diverge?
 
values ← (⍺ trap ⍵)¨inputs
 r←(namespace trap fn)args
 :Trap 0
    ⍝ Attempt to run fn inside namespace with args
     r←(namespace⍎fn) args
 :Else
    ⍝ Report if error occurs
     r←,⊂⎕THIS.config.error
 :EndTrap
 
9:56 PM
@nathanrogers Last I checked, that's not a primitive.
 
At which primitive do runs diverge?
 
r←namespace⍎fn args then
 
fn is a character vector?
 
9:57 PM
@Adám i assume nathan verified that ⍺ ⍵ trap inputs there are all the same, but it ends up differing. the trap definition given is the faulty thing here
 
's06_1'
 
@nathanrogers Hold on, that doesn't appear in your code!
 
:C I don't follow
 
@nathanrogers What don't you follow? What I said or what dzaima said?
 
@nathanrogers (you mean with the parentheses, right)
 
9:59 PM
oh yes
sorry
r←(namespace⍎fn) args
 
That's not a primitive!
 
@Adám is definitely a primitive
 
@dzaima Sure, but NR didn't say that.
 
you're asking where inside the evaluation of fn it differs?
 
@nathanrogers So, if you split the line into two:
temp←namespace⍎fn
r←temp args
Does temp differ between runs?
 
10:00 PM
ok
 
ok? It was a yes/no question.
 
@Adám (just r←(⎕←namespace⍎fn) args would also work)
 
@dzaima There are cases where that ⎕← might mess up things.
 
i mean ok I'm gonna go do it
 
@Adám how so?
 
10:03 PM
@nathanrogers Great. Take your time. I'll check in tomorrow morning.
@dzaima A bug in the interpreter.
 
@Adám yaaaaay
 
oh hey
something new happened
I put ∘∘∘ after temp and r in this example, continued execution first time it exited correctly
the run errored
@Adám WHOAH
THIS is really wierd
      aoc2015 t.test's06_1'
 T IS:  ,  #.aoc2015 .  s06_1←{
                            lights←1000 1000⍴0
                            eval←{
                                ~×≢⍵:⍺
                                'e'=⊃⊃⊃⍵:~⍺
                                onoff←'o'=⊃⊃⊃⍵
                                a←onoff@,({(⊃⍵)∘+¨⍳⊃|-/⍵}1↓¨⊃⍵)⊢⍺
                                ⍺ ∇ 1↓⍵
                            }
                            lights eval ⍵
                        }
LENGTH ERROR
run[34] ∨/~passed:((⊂⍵),error passMSG passed),(⊂⍉,/↑failMSG¨failed) ⍝ any failed
I don't have this version defined ANYWHERE
this is an OLD version
before I got part 2 of the problem
even after closing and reopening Dyalog
 
maybe you have it in another file?
 
I don't have the word "lights" anywhere in my source code, nor "eval"
nope
I SEE
its been defined inside a directory for some reason
it created a directory for my namespace with this dfn in it
 
yay
 
10:13 PM
I didn't define that
manually or automatically. I probably opened the )ed on this dfn at some point
yeah ok, problem solved
 
yay
 
thanks a ton @Adám for walking through... I never would have thought to print the namespace⍎fn, I would have expected it to give me back some kind of reference to a namespace, not the text of the function
 
10:36 PM
@rak1507 I really like that
 
thanks
 
and how you made the arguemtns uniform
in both cases, that's slick
s06a←{                                   ⍝ 6_A Generalize both solutions
    ~×≢⍵  : 1⊥,⍺                         ⍝ ... Not any? Then sum reduce
    onoff ← ⍺⍺ ⋄ togl ← ⍵⍵               ⍝ ... Name functions for each case
    range ← {,{(⊃⍵)∘+¨⍳1+⊃|-/⍵}1↓¨⍵}     ⍝ ... The range of inds to modify
    ⍺     ← 1000 1000⍴0                  ⍝ ... A light matrix default value
    f     ← ⍎'onoff∘⍵' 'togl'⊃⍨'e'=⊃⊃⊃⍵  ⍝ ... Which action for this range?
    (0⌈f@(range⊃⍵)⊢⍺) ∇ 1↓⍵              ⍝ ... Set value at indices, 0 floor
That's what I'm calling my final version
I tried to copy your +∘2 for part 2
but it causes errors without ()
and (+∘2) is the same length as {2+⍵} so, meh
 
yep
I would guess yours is faster than mine but I haven't tested
 
idk, I can test yours quick
 
just from not having to store a bunch of stuff
I reckon there's probably a cleverer way to do it though
 
10:39 PM
nah
 
like, if you know a certain region is on, it's obviously easy to calculate the area, so maybe it's still doable to calculate the total area even with different overlapping rectangles
 
I like the way you handled inputs
yeah, like collapsing multiple in a row of the same type
 
really my inner dfn should've been two or three lines to make it clearer, inline assignment isn't great
 
um
can I load one thing from dfns without eliminating the entire workspace?
 
@nathanrogers eliminating?
 
10:45 PM
yeah when I )load dfns the entire workspace is replaced
 
@nathanrogers ⎕cy'dfns' (and 'specificThingFromDfns'⎕cy'dfns' if you only want a specific thing)
 
* Benchmarking "solve '01~'"
             (ms)
 CPU (avg):  2219
 Elapsed:    2217
      ]runtime "#.aoc2015.s06_1  ('.? ?\d+,\d+'⎕S{(⊃,∘⍎1↓⊢)⍵.Match~' '})¨2015 #.day 6"

* Benchmarking "#.aoc2015.s06_1  ('.? ?\d+,\d+'⎕S{(⊃,∘⍎1↓⊢)⍵.Match~' '})¨2015 #.day 6"
             (ms)
 CPU (avg):  2516
 Elapsed:    2522
@rak1507 yours gooder
 
I imagine the regex takes some time
 
yeah I can try without loading in the file
CPU (avg):  2485
 Elapsed:    2484
oof
@dzaima so when adam says "BQN Is Good"
what does that mean
 
@nathanrogers presumably, that BQN is good (it has first-class functions and syntax for arbitrary type arrays)
 
10:55 PM
how do you convince yourself that the literal notation is good? Because I don't see myself getting past that
1_2_3_4_
 
@nathanrogers that's not talking about the 1‿2‿3‿4 notation, but ⟨1,2,3,4⟩
 
I mean the former
@Marshall how is not simply inverting the case where 1 is a 1 element vector 1 2 is a 2 element vector but having some kind of prefix for scalars like .1 is a scalar or something
 
yesterday, by dzaima
@ngn I'm not exactly a fan of -notation, but the alternatives aren't good (always using ⟨⟩-or-whatever-notation is a lot of overhead, and k-style array tokens and APL strands both make for weird syntactic things)
 
how does that not solve the problem
or why not strand notation inside of those brackers?
brackets
1 is 1, ⟨1⟩ is a 1 element vector
⟨1 2 3 4 5⟩
why are those not valid alternatives
 
@nathanrogers how about ⟨2+2,3+3⟩?
 
10:58 PM
2 + (2, (3 + 3)) ?
 
@nathanrogers , in BQN is equivalent to
 
er no
 
so ⟨2+2,3+3⟩ is ⟨2+2⋄3+3⟩, and both evaluate to JSON [4,6]
 

« first day (1502 days earlier)      last day (1155 days later) »