« first day (1645 days earlier)      last day (999 days later) » 

2:12 AM
@dzaima: BQN compiles on my iMac, but when I run ./BQN, it says: "Error: JIT: Refusing to run with CBQN code outside of the 32-bit address range"
 
ugh, more of this problem
@jordancurve in src/vm.h, on line 6, change the 2 to a -1, and rebuild. Should solve the issue, at the cost of a bit slower scalar code, until i figure things out tomorrow
@jordancurve (might you be on an arm architecture machine?)
 
2:33 AM
@dzaima (actually, I don't think that'd even change anything, but IIRC at least one other person has CBQN working on macOS. The JIT relies on the base code being below address 2^31 to be able to make relative calls to it, and -no-pie has so far made that be the case)
 
@dzaima: With that fix, it works great now. "About this mac" says 4 GHz Quad-Core Intel Core i7
 
so x86-64. weird.
¯\_(ツ)_/¯ guess -no-pie doesn't guarantee code location. Will try to make JIT work without that tomorrow. The problem is that x86-64 call instructions are limited to a 32-bit offset, so JIT code must be allocated within 2^31 of anything it calls, but there's not a trivial way to just request memory in a specific range (but it should be possible to request somewhere nearby (and retry if it didn't work))
 
 
1 hour later…
3:46 AM
In Dyalog, if I have a variable X which may contain some value, or ⍬, and I want to do something like y ← if(X≡⍬) Z else X
What is the typical way of expressing that?
I.e. if X is some specific value (⍬ in this case), use a different value , otherwise return X itself.
 
{⍵≡⍬:Z⋄⍵}X for laziness, ⊃(X≡⍬)⌽Z X if strict is fine (pretty sure these work in all cases)
There are simpler solutions in specific cases, e.g. ⊃X,Z if both Z and nonempty X are scalars
 
Thanks. I already did the second one, although I wrote it as (X≡⍬) ⌷ X Z but it seems to be the same in principle.
The lazy one was more interesting.
I've never used that one, but I understand it's essentially an if statement, no? A:B⋄C is equivalent to if(a) B else C
 
it's a guard, yes
 
4:02 AM
Yeah, KAP needs a better syntax for that. Currently it's if(a) {b} else {c} which is excessively wordy given how often it's used.
And : and ⋄ are not available for such syntax.
 
4:14 AM
@EliasMårtenson It works as an if statement, but there are two limitations: 1) it is allowed only inside a dfn {...}. 2) when the guard condition is met, the dfn returns right away, so it's hard to use in the scenarios like {y←if(a){b}else{c} ⋄ some computation on y ⋄ return something later}.
 
@Bubbler Oh I see. That explains why they call it a guard.
I wonder if there is some nice more concise syntax that could be adopted for a full-featured alternative to the if/else version.
 
K has a proper if-then-else built-in using its own syntax for high-adic functions $[if1;then1;if2;then2;...;else], but it isn't easily adaptable to APL.
 
april has that syntax
i'm not sure hwo well it works
 
4:30 AM
Kap can leverage the defer feature which can be used in some cases. Let's say you have a value X, and you want to call either functions F0 or F1 or argument Y depending on whether X is true or false. You can do this: X ⌷ (F0 defer Y) (F1 defer Y)
 
Actually the symbol $ is free in APL at the moment, so $[...] (or whatever delimiter) may work and not interfere with any existing syntax
 
That means the generic if/else form can be written as COND ⌷ ({THEN} defer ⍬) ({ELSE} defer ⍬)
And if defer was changed to a single symbol instead of a word, the result can be reasonably concise.
 
 
2 hours later…
6:51 AM
@EliasMårtenson I'd write y ← Z ⊣⍣(X≡⍬)⊢ X however if you allow constant operands to represent constant functions (as @ and do, and as BQN does in general) then can go away, and if you get rid of implicit stranding (as SHARP APL, J, and BQN do) then you can get rid of giving you y ← Z ⍣(X≡⍬) X which is nice imo.
@EliasMårtenson GNU APL uses this anomalous syntax:
      10 ⊢[0] 20
10
      10 ⊢[1] 20
20
 
Thanks. That's interesting.
The issue in the GNU case is that both sides are still evaluated.
 
I've long considered an "if" operator: _If_←{⍺←⊢ ⋄ ⍺ ⍵⍵ ⍵:⍺(⍺⍺⊣⊢)⍵ ⋄ ⍵}
 
Creating an IF operator was the first thing I did in GNU APL I think :-)
 
      {10}_If_{⍵>3}5
10
      {10}_If_{⍵>3}2
2
 
0
Q: Check that each adjacent pair of a list is in order (tacit programming) in APL

kotethGiven a list in APL I would like to check that each adjacent pair is in order. So, given (a0, a1, ..., an), I would like to calculate: (a0 ≤ a1) ∧ (a1 ≤ a2) ∧ .... ∧ (a[n-1] ≤ an) I don't want to compute an equivalent form and I want to use tacit programming. My solution is ((¯1↓⊢)∧.≤(1↓⊢)) but i...

 
 
2 hours later…
8:50 AM
@Adám Yes, exactly like that.
 
@EliasMårtenson Ooh, even better: _If_←{⍺←⊢ ⋄ ⍺(⍵⍵⊣⊢)⍵:⍺(⍺⍺⊣⊢)⍵ ⋄ ⍵}
 
9:18 AM
@Adám Does Dyalog support custom axis arguments? Then you could do something like {1+⍵} IF[a>b] {2+⍵} 100
 
@EliasMårtenson No. Axis is considered a syntactic anomaly.
 
@Adám That would be the else statement
 
@EliasMårtenson BQN has which is both more versatile and uses normal syntax.
It works like this: (a>b)◶⟨{2+⍵}⋄{1+⍵}⟩ 100
Has the benefit that the "condition" is actually an index into the right operand array of functions, so you can have numbers greater than 1.
The left operand can (as always in BQN) be a function or an array. If it is a function, it is applied to the argument(s) and the result is used to choose with.
And of course, the elements of the right operand can be arrays instead of functions too.
So your original statement can be written as y ← (0=≠)◶⟨z⋄⊢⟩ x but of course, BQN also has z⍟(0=≠) x
(Here I use 0=≠ which is equivalent to 0=≢ in APL because BQN doesn't have )
 
9:35 AM
Oh I see now. Thanks.
Speaking of functions, I was under the impression that Dyalog derived a function from an expression without a right argument? I.e. (2+) 3 would work. Or something like add2 ← 2+ being equivalent to add2 ← {2+⍵}
That doesn't seem to work. Was there another APL that did this?
 
Only dzaima/APL does that.
 
Ah
I knew there was one
 
K also does this.
 
I find it pretty neat. However, I don't know how often I would actually use it if I had it. Is it useful in practice?
 
@EliasMårtenson (Pedantic: They are not strictly the same. {2+⍵} is equivalent to 2+⊢ in that they both ignore their left argument. 2+ would be equivalent to 2∘+ in prohibiting a left argument.)
 
9:40 AM
@Adám Fair enough.
 
@EliasMårtenson Only for code golf. Maybe where I most often want it is for constructs like ∧/2≤/⊢ where ∧/2≤/ seems "cleaner".
I tend to use A∘f over Af⊢ because it indicates that the function is only ever intended to be used monadically. Lack of such indication is one of the things people complain about when it comes to tacit functions.
However, 2∘≤/ doesn't work as intended.
 
10:31 AM
@Adám all of this came up after I was solving advent of code part 4 in Kap, and my solution contains more if/else than I care to admit.
So I was looking at the Jay Foad solutions, and I've been staring at this for a while. I do not understand one thing about it: github.com/jayfoad/aoc2020apl/blob/main/p4.dyalog
So, lines 5 to 8 checks the rules for various fields that must have numbers between certain values. I understand that.
Like 5 defines a function byr, but this function is never called.
How does this work?
 
@EliasMårtenson It builds an APL expression and executes it. 'byr' is in the input.
 
@Adám I don't get it. Are you saying byr←... doesn't assign a new function to byr?
 
10:46 AM
@EliasMårtenson It does create a function, and byr is called on line 12.
 
11:36 AM
@EliasMårtenson Haskell does that
because everything is curried
 
Oh wait. It's the ⍎.
I'm not sure if I'm supposed to be impressed or scared of that thing :-)
As someone who works in security, that thing is scary :-)
 
@EliasMårtenson Essentially it transforms the problem into requiring a DSL, and implements that DSL in APL.
 
Yeah, it's just that it essentially executes untrusted code from the input file. That's not really safe.
 
@EliasMårtenson Unfortunately, AoC is a speed coding exercise. Tends to lead to bad code.
It'd be quite simple to add a step that verifies the validity of the input.
 
12:02 PM
@Adám Yeah. I'm trying to solve them in a more clean way.
I've come to realise that Kap does need something like Dyalogs :⋄ using similar semantics. The if/else statements in the part04 solution is really ugly.
 
@EliasMårtenson In general, dfn guards work well for what they are for. Only where you'd use inline ternaries in other languages can they be a little ugly.
 
12:33 PM
@Adám it nearly always golfs a char off of s right operand
 
> Only for code golf.
 
well, isn't used exclusively in golf
 
Same with @ of course, @ being a (silly, imo) subset of .
 
@Adám I think ⍢(A f) is way bigger of a proportion of uses, than @(A f) of @'s
 
@Adám Yeah, the guards give you a way to achieve early termination of a function (without throwing an exception).
 
12:38 PM
@EliasMårtenson Well, I'm not sure that's the best aspect. dzaima/APL gives an explicit early termination with monadic
 
@Adám Yeah, but without such a "return" facility, having expression if/else forms still gives you deep recursive conditionals.
And most uses of return in a function is for exactly the case that is covered by :⋄
 
@dzaima things like ⍢(2⊃) ⍢(arr⊇) ⍢(mask⌿) ⍢(1↓) ⍢(16 16⊥) ⍢(100×) ⍢(3 5⎕DR)
in the BQN matrix room yesterday there was a discussion about conditionals too
but that's more for getting some non-ugly conditionals, not good ones
 
 
8 hours later…
8:30 PM
@Adám competition deadline is definitely friday not saturday? (seems strange not going to the end of the month)
 
@rak1507 Good to have staff working at time of deadline, even though the system is automated.
 
people work at midnight?!
 
@rak1507 Midnight in Europe is working hours in America.
 
oh right, good point
 

« first day (1645 days earlier)      last day (999 days later) »