« first day (1434 days earlier)      last day (1221 days later) » 

12:02 AM
In APL′, is leading axis catenation (like , in J and in BQN) and "add leading axis", so (1⍪2⍪3) is a vector and (⍪1) is a 1-element vector.
 
@Adám there's this in A Programming Language. Though I have no clue what's going on there
 
@dzaima I think that is much like current APL, although I suspect has higher precedence than +, and the = is like in TMN.
@dzaima And so it seems indeed that he used (42) as a 1-element vector.
Now the question is if x←42 then is (x) the same as (0+x)?
CMQ: How do I PCRE match from a until the next a, not counting any as that are between quotes? E.g. (brackets indicate match): [abr'acad'a]bra?
 
a([^a]|\'[^']*\')*a maybe?
 
Ah, right, makes sense (except the escaping of 's).
 
12:17 AM
@Bubbler should be a([^a\']|\'[^']*\')*a
 
Oh right
 
@dzaima Wouldn't it be enough to put swap order on the |?
 
@Adám regex doesn't care about order of |s
 
Oh, right.
 
or maybe it does ¯\_(ツ)_/¯
 
12:19 AM
Apparently swapping works
 
ah, but it won't reject a'a
 
right
 
That's fine.
Thanks, you two.
⋄ '`(''[^'']*''|[^`])*`'⎕R{⍕⍎1↓¯1↓⍵.Match}'hello`≢''a`bc''`world'
 
@Adám
┌→──────────┐
│hello4world│
└───────────┘
 
This is going on APLcart.
 
12:27 AM
(using maximally correct one would be better for that)
 
@Bubbler What do you mean?
 
For the regex part.
 
@Bubbler Can you elaborate?
 
Hmm, I guess it would SYNTAX ERROR anyway on incorrect matches (matching odd number of quotes)
 
@Bubbler It should. I don't want it to just skip such an expression.
 
12:33 AM
Fine then
 
:-)
 
well, TIL order of alternatives in regex matters, so most pretty regex graphs are wrong as they don't indicate that
 
1:12 AM
@Marshall When you added « and », were you aware that Iverson Notation had something similar? ̥↑ and ̊↓ would shift left and right steps, padding with 0s, in parallel to and which would cyclically rotate left and right.
 
@Adám I had no idea! Pretty cool, although I guess I consider the dyadic forms to be more important.
 
@Marshall Sure, and I agree with your definitions, and ⥊⟜0⊸» is neat enough.
I kind of envy J's new Fold family. Would it make sense to make dyadic f⍀ (and f\) take a control number on the left? So 1f⍀ would be fold single forward, ¯1f⍀ would be fold single reverse, 2f⍀ would be fold multiple forward, ¯2f⍀ would be fold multiple reverse.
 
1:36 AM
@Adám I'm inclined to say that if you want that sort of control you should just switch to imperative programming. Those codes would be hard to understand if you ran across them in a program.
 
@Marshall Well, at least the ability to iterate and collect results over a list without recalculating everything for every step, would be nice to have. f⍀ really makes no sense for non-optimised fs.
 
@Adám Sure, but then all you want is BQN Scan and not J fold.
 
@Marshall Aren't the codes more mnemonic than J's Braille? 1 is single and 2 is multiple, positive is forward and negative backward?
 
@Adám Maybe? I don't care; I don't like either of them.
 
@Marshall True, and BQN>APL. No doubt about it. But APL is what it is. Adding a completely separate 2nd scan is unrealistic.
 
2:23 AM
I'm fine as long as something is there to make forward fold/scan and collecting repeat easier and faster than O(n^2)
J's Fold sounds cool but it becomes harder to grasp with the introduction of Z:
 
You don't have to use that. It is just a magic function to :Leave and :Continue
Aren't there 4 possibilities? a(a f b)((a f b) f c) and a(a f b)(a f (b f c)) and ((a f b) f c)(b f c)c and (a f (b f c))(b f c)c
The last two could optionally return their results reversed.
 
The first is what we need, the second is the current `\`, the rest can be derived from reversals (though having the last one as a built-in could help for efficiency)
 
2:50 AM
forward consumption, forward each   :  1  1 :  3
forward all                         :  1  0 :  2
forward consumption, backward each  :  1 ¯1 :  1
backward consumption, forward each  : ¯1  1 : ¯1
backward all                        : ¯1  0 : ¯2
backward consumption, backward each : ¯1 ¯1 : ¯3
Then the default would be 1, i.e. 1f⍀Y is the same as f⍀Y.
"what we need" would be 3f⍀ and "iterate", i.e. forwards f⌿ would be 2f⍀
 
Does "forward all" mean giving a single value (a f b) f c?
 
Yes.
 
Interesting idea
 
This also allows not having parentheses when needing a scan or reduce atop something in a train, because there'll always be a left argument one can give to achieve the same.
 
That, and an extension to to complement J's "unlimited fold" would be great
 
2:58 AM
@Bubbler Isn't that just ⍣{0}?
However, does need an extension to allow non-scalar right operands.
 
That is, with an ability to collect values and break when necessary
 
Now you're asking for Z:.
I don't think that's necessary, though. At that point, control structures are fine. It can't be optimised anyway.
 
I was thinking of dfns.traj
but yeah, that might be the job for control structures
 
@Bubbler has so many issues. It only looks at the previous value, and so gets stuck on things like -⍣=1 instead of checking for loops. No option of giving intermediary values (dzaima's ). No way to repeat 0 times if stop condition already applies.
Something that makes me sad is that so many of the primitives added to the original APL have issues.
In fact, very few of them don't have flaws.
But I should cheer up. A lot of issues can be fixed with relatively lightweight additions.
 
3:19 AM
I'm getting the impression that many of the proposals are just forgotten. Maybe we can write a page on APL Wiki to collect ideas?
 
In general I don't really like the use of different numbers as configs, it feels like it's just a hacky way of getting a new primitive
 
@Bubbler Extended and Prime are where I've been collecting ideas.
@rak1507 For I agree, but when multiple functionalities are clearly closely related, then I don't mind, especially if a neat scheme can be constructed to unify them. This, I find to be the case for , the 12-fold way of combinatorics, the left arguments to ⎕DT and ⎕DR, my proposal for extending , and also here.
 
But then the number doesn't mean anything, it's just a method of selection.
With ○ it makes more sense because there's not really any way of doing it differently
 
Oh no, those numbers are all very thoughtfully chosen.
 
They may well be, but to me a number and a symbol will never be as obvious and straightforward as a single symbol. It feels almost like a digram
 
3:34 AM
@rak1507 Right, but can you come up with 8 new glyphs to complement /⌿\⍀? J's recently introduced F. F: F.. F.: F:. F:: which are basically just using Braille numbers.
 
No, I don't think there should be 8 new glyphs, but the originals should be improved
 
@rak1507 How?
 
Scans should automatically save previous values
I feel like a lot of the other additional features wouldn't get all that much use, and the main thing that people would want is a more efficient scan
 
@Adám Personally I don't think they're the right place to share/discuss ideas about APL in general
 
@rak1507 In the current APL, we can't change the definition of the existing scans.
 
3:38 AM
⎕ML...?
It exists, may as well use it, and if people are relying on recalculation to perform randomness or side effects that is pretty horrible anyway
 
@rak1507 I'd rather a clean break language than more of that nightmare. Have you ever debugged code that jumps between various settings of ⎕ML and ⎕IO and ⎕WX and ⎕FR and ⎕CT?
@rak1507 Also, what would the new value be? 1j1?
 
I'd rather an improved scan and an extra ⎕ML level now, than a clean break language in a decade
 
@rak1507 1) Scan is hardly the only thing that needs fixing, but if we are to add a new value to ⎕ML for every incremental fix, it will become unbearable. 2) Some operands of scan are optimised, with really good performance, and many idiomatic APL expressions use those. Reversing scan would break a lot of code. 3) Proper consistent design takes time. If we start changing APL here and there, we'll have a mess, while additive changes can arrive fast, but incrementally.
 
Keep the optimised ones, improve the unoptimised ones?
Oh I see what you mean about it being backwards
Ah yeah I hadn't considered that
 
I don't think you've thought this through. You're suggesting ≠⍀ being different from {⍺≠⍵}⍀!
 
3:52 AM
Yeah I hadn't actually realised that f\ can't necessarily be improved because of the evaluation order
 
But if we add a left argument such that the existing behaviour becomes as if a specific left argument was the default, then it isn't a huge mess. That's what my idea was, that existing f⍀ stays, and is equivalent to 1f⍀ but with additional values to get the exact behaviour desired. Future newcomers won't notice that anything is strange, other than maybe wondering why the default is as it is.
And while we're at it, why not make 5 6 7 be the same but with "insert" rather than "reduce"?
 
How is it different?
 
It doesn't enclose, simple "inserts" a single instance of the operand between the elements/major cells of the argument.
Also, it may not be obvious that f⌿3 4⍴⍳12 calls f 8 times instead of 2 times, but it does:
      {⍞←# ⋄ ⍺+⍵}⌿3 4⍴⍳12
########
15 18 21 24
 
Wow, didn't know that
 
Again, some operands are optimised, but you cannot "insert" a custom function between the cells of the argument; there is an implied ¨.
Of course, if we were to start over, that ¨ shouldn't be implied, but rather explicit if that is what you actually want…
@Bubbler E.g. ,/'abc' 'ef' giving ⊂'abcde' is rarely what you want.
So 6,\'abc' 'ef' would give 'abcde'
 
4:11 AM
@Adám If , is inserted between cells, isn't it 'abc' 'ef' again?
 
@Bubbler Hm, yes. Maybe it needs to be 6,⍥⊃/ ― this is where I need @Marshall. I'm not very experienced with J-style reduction.
 
I guess that's why J has Raze for that
 
Yeah.
BQN's primitives are of course much more elegant when if comes to all this, but here we're discussing what we can do to help APL a bit in the stiff competition from BQN ;-)
 
4:32 AM
@Bubbler why does J have me
 
@Razetime Idk, actually I was wondering the relationship between that and your username
 
my username is shortened from a very old nickname from 6 years ago
so it's unlikely that there's any relationship :P
 
4:59 AM
the userscript is executing the starred posts lmao
 
 
2 hours later…
ngn
7:07 AM
@Razetime does j have something like \t ("time")?
 
ngn
7:18 AM
it has * ("times") of course
 
I don't use J
I wanted to try K bcause you said it was simpler
didn't have a reason to try out J yet
 
J is pretty close to ascii-only APL, except for some terminology, favoring rectangular simple arrays much more than nested (boxed) ones, and a few handy built-ins (some mathematical)
(and J has rationals and bigints)
 
ngn
@Razetime yes, it's simpler because it has fewer primitives, and it makes no distinctions between depth&rank, or cell&element
 
@Bubbler ah
 
ngn
for me j's strength is the enormous vocabulary of mathematical functions
k's "raze" is just ,/ (and yes, it is officially caled "raze")
 
7:30 AM
It's obviously named after me
 
ngn
obviously :)
 
although I'd like ≠⊆⊢ to be named raze for no good reason
 
ngn
@Bubbler would you say rectangular arrays are "simpler" (under any definition) than ragged?
from an implementer point of view, multidimensional rectangles require worrying about storing the variable-length shape somewhere. also, what should be a simple loop often turns into recursion.
with ragged arrays, you only have to worry about scalars and vectors. there's only one dimension to store. there's usually only one loop to process the data.
i think it's simpler from a user's point of view too. with apl i tend to switch back and forth between mixed (matrix) and split (vector of vectors) form because often it's not obvious which is more convenient for the particular task.
 
@ngn I meant "simple array" being an array of depth 1, containing plain numbers/chars
 
7:45 AM
<moon-child> @ngn considering that apl has both rectangular and ragged arrays, surely j is simpler than apl? (Though I do agree that k is simpler still)
 
ngn
@Bubbler understood. but still ^^^ ? (if you're not too busy right now)
 
Of course it's not really simple to use or implement. I did feel some amount of hurdle while I was trying to grasp the function rank and auto-rectifying and all
 
ngn
@DyalogAPL @ moon-child i don't know, the presence of enclosed scalars always confuses me but that may be just lack of experience with j
 
moon-child: J does have ragged arrays using "boxed arrays", though they're rarely used when not necessary
 
<moon-child> @Bubbler in j, all arrays are rectangular and of uniform type; that type may be a box, which may contain objects of varying type, but the array itself is still rectangular
 
ngn
7:54 AM
@ moon-child but you can pretend it's ragged, if it's a vector of boxed vectors
just like in k we pretend something is a matrix when it's really a vector of vectors (from the point of view of an apl/j model)
 
<moon-child> you have to explicitly unbox a box before you can use its contents, though. So you can't say 1 2 + 5 6;9, you have to say 1 2 (+&.>) 5 6;9
<moon-child> so the illusion is not really there
 
ngn
right, this is tedious and can be confusing to newbies (like myself)
akin to the in apl's ⊃,/
 
yeah, almost everything is designed to work with flat arrays
 
8:23 AM
what could it be
 
9:12 AM
@Razetime Just a misguided idea. However: apl.wiki/User:Razetime
 
 
1 hour later…
10:29 AM
@Adám oo nice domain name
 
@Razetime Yeah, I got tired of typing the long domain again and again. Problem is, I'd like the wiki itself to present such URLs, but I'm not sure how to do that.
 
10:55 AM
why my user profile?
 
@Razetime It is a redirect, so anywhere you'd normally write aplwiki.com/wiki you can now write apl.wiki
My Domain Registrar has a sale, and apl.wiki was only USD 4.60 for the first year, so…
 
late hanukkah present
@Adám I really wanna buy raze.time or razeti.me someday
 
11:46 AM
@Razetime There is no .time, but razeti.me is available at $2.47 for the first year right now, with $12.71/yr afterwards. Of course, median income in India is about a 20th of that in the UK, so that might still be out of your reach.
 
12:17 PM
any and all domains are out of my reach for now
 
 
2 hours later…
2:27 PM
Hello folks. Is there a description of what tradfn headers can do somewhere?

Particularly what the does the `;` do (eg. in `res←echo arg;context;event`). Is it a way to use multiple arguments, via some kind of pattern-matching on a vector?

Linked from some archived conversation/lesson from this chatroom was https://help.dyalog.com/18.0/#Language/Defined%20Functions%20and%20Operators/TradFns/Model%20Syntax.htm but that doesn't answer it for me.
 
ngn
@Adám @Razetime can you guess how much shakti.com cost?
 
Looking in the docs some more, I see https://help.dyalog.com/18.0/#Language/Defined%20Functions%20and%20Operators/TradFns/Locals%20Lines.htm

So the `;` is for specifying local names (do I have to do that? will all unspecified ones be made global instead?)... so I assume I have to do the `x y z←argument` myself then if I want to pass multiple arguments (3+) to a function
 
@MartinJaniczek you can do res ← leftArg name (rightArg1 rightArg2 rightArg3 …)
 
@MartinJaniczek Yes, (btw, APL Wiki is good for finding out about APL) you have to localise all names you don't want global, except those otherwise mentioned in the header (result, function name, argument names). You can force the function to take a 3-element right argument as per ^.
 
@MartinJaniczek ; - yep, they'll all be global (worse yet, they'll be using dynamic scope!)
 
2:32 PM
@ngn 1K+? .com is pretty expensive iirc
 
ngn
@rak1507 more
 
@MartinJaniczek Instead of/complementing the locals lines (you can have additional such lines after the header, e.g. categorising your local names), you can dynamically localise names using ⎕SHADOW which takes a list of names. So while you can't give it a pattern, you can generate a list of all names you want, and apply ⎕SHADOW to that.
 
10K+?
 
@Adám I'm sorry but when I looked at that APL Wiki page before it didn't help me much. But, the act of writing here and doublechecking myself on the Dyalog docs made me find it help.dyalog.com/18.0/#Language/… . Thanks @dzaima also for spelling it out explicitly
 
ngn
@rak1507 more
 
2:33 PM
jeez
20K+?!
 
ngn
@rak1507 more
 
100K+?! surely not
 
ngn
@rak1507 ok, less :)
 
40K+?
 
ngn
@rak1507 more, but you're close: $50k
 
2:34 PM
Wow, 50K for a domain name, more than most people earn in an entire year!
 
ngn
shrug. a thing costs as much as someone is willing to pay for it.
 
And shakti.com is pretty much only used as a redirect to shakti.sh
@ngn That's not always true.
 
ngn
@Adám .sh is relatively recent. .com is the "front" page.
@Adám well, at least under capitalism :)
 
@ngn Isn't one counter-example enough to disprove that claim?
 
ngn
@Adám what counter-example do you have in mind?
 
2:40 PM
@ngn Today, I bought apl.wiki at a price much lower than what I was willing to pay for it.
 
ngn
@Adám i see what you mean, but technically that's not a counter-example. if you're willing to pay, let's say $10, surely you're willing to pay $4.60 too.
 
@ngn Doesn't that make your claim meaningless?
 
ngn
no
to rephrase: if you can't find someone to pay your "ask" price, then it's not the true market price
 
@ngn that's completely different from your previous "people will pay as much as they're willing to pay"
 
ngn
@dzaima when did i say that?
 
2:46 PM
@rak1507 domain names inflate heavily based on how short they are, and based on their meaning
 
@ngn this, no? aren't those very much equivalent?
@dzaima (well, plus "and other people want to get the most out of their deal", but that's a rather obvious addition)
 
@MartinJaniczek I can see that it is a bit buried under the Dyalog extensions. I'll add some headings.
 
ngn
@dzaima i meant it from the point of view of a seller
 
@ngn holy-
 
@Adám it's a basic claim about capitalism, so yeah
 
2:50 PM
¯\_(⍨)_/¯
 
ngn
my duckduckgoing skills aren't great but just to give at least one link: domainnamewire.com/2018/08/22/…
 
AW is relatively well to-do, right?
 
ngn
maybe he was saving from pocket money at school :)
 
@MartinJaniczek Actually, allowing patterns is a great idea. We've been thinking about how to make tradfns less awkward, and the lack of auto-localisation is probably the biggest issue for most people, and a major reason for (ab)using dfns. I'll bring up your idea.
 
3:28 PM
ay it's RGS
@RGS +←1
 
@MartinJaniczek I've added JSONInputFormat to Jarvis (pull the latest commit from master).
j←⎕NEW Jarvis
j.JSONInputFormat←'M' ⍝ the default is 'D'
 
@Brian Awesome, thank you!
 
RGS
@Razetime only temporarily :P See you next year!
 
bruh
 
 
2 hours later…
5:06 PM
Is there any way to assign a variable conditionally (without evaluating the alternative value)? The easiest thing I could come up with so far was to make another dfn and use guards inside that.
 
@user Sounds like procedural programming. Use a tradfn.
If you assign from inside the inner dfn, that'll become a local assignment, and not carry over to the outer dfn.
 
I guess a tradfn might be simpler, although I'm using this for code golf
Actually, I'm assigning the result of the dfn, so it looks something like var←{cond ⍵:iftrue ⍵ ⋄ iffalse ⍵}⍵
 
So you're just choosing between applying the two functions?
 
Pretty much.
 
If so, do you mind if both functions are executed, as long as you get the right result?
 
5:11 PM
No, that was the problem with using something like or ⊣⍣, it'll blow the stack if both are evaluated
 
var←iftrue⍣c iffalse⍣(~c←cond ⍵)⊢⍵ is probably longer.
Are the two functions named?
 
Actually, one of the functions can be evaluated safely, the other is the outer function itself, with ∇.
 
ngn
@user the old-fashioned way is ⍎c⊃ 'iffalse⍵' 'iftrue⍵'
 
One of them is ∇, the other is not named, but I could turn into a train.
 
@ngn And the fun way is (⍎c⊃'iffalse' 'iftrue')⍵
 
5:14 PM
@ngn Cool, looks like it doesn't evaluate both unnecessarily
 
ngn
there used to be var←⍣c.. too :)
 
@ngn Still is, but not in dfns.
 
Unrelated: why does ⍎ work even when the string contains an operator or function?
 
@user Hm, sounds like you're recursing and then at the leaf, you do something else. Can you not phrase it like that and immediately return (on the guard) instead of having to assign the result?
@user (Correction: Monadic operator.) No idea. Tradfns can return a function result too. Dfns can't. Why? No idea.
 
@Adám Well, I have to do something else with the result (get the rest, call ∇ again, and join together)
 
ngn
5:17 PM
@Adám are you advocating the use of tradfns?
 
@Adám Huh, I didn't know that.
 
@ngn Dfns often look like a half-hearted experiment that was never properly thought through.
 
ngn
@Adám ouch
but they are mostly done right
 
As Nic says: "yeah, but"
 
ngn
tradfns' dynamic scope is a show-stopper
 
5:19 PM
To me dfns seem miles better than tradfns and a lot more modern
 
@ngn Full disclosure: Dfns are a half-hearted experiment that was never properly thought through.
@ngn Most people (other than FP wizards) probably never even notice.
@rak1507 With emphasis on seem ;-)
 
ngn
@Adám "disclosure"?? dfns have flaws but they are much closer to properly thought through than tradfns
@Adám disagree
 
Tradfns (while maybe state-of-the-art in 1960) have multiple issues: Dynamic scoping, global assignment by default, cannot be nested, know their name. But afaik, with those things in mind, they have no gotchas.
 
ngn
@Adám dynamic scoping - you can stop right there
 
@ngn You keep saying that, but show a realistic example of where that actually matters. And by realistic, I mean keeping best practices, including always passing arguments instead of relying on globals.
 
ngn
5:25 PM
i'm tired of explaining this over and over again. look it up.
 
<klg> next time you're gonna say that there's something wrong with ⎕IO←1
 
@ngn Explaining? There's no explaining to be done. I know what the difference is.
 
ngn
@Adám "global assignment by default" <- this is a give-away that you don't
 
@ngn How so?
 
ngn
@Adám assignment could happen in the caller's scope by default. it's the very definition of dynamic scope.
 
5:27 PM
@ngn That's just plain counterfactual. John Scholes basically sneaked them into the product, and if someone had actually bothered to write down the rules for how they work, they would have found obvious spec contradictions. I can't call that "well thought through".
 
ngn
seriously, i'm fed up with having to discuss this.
 
@ngn Nobody is forcing you to.
 
@ngn is is horrible that that's the case? obviously, definitely. Does it practically matter if you write out all locals in the header? not really.
 
@ngn Feel free to stick to K too. There you have just one very well thought-through functional form. With lexical scope, of course.
 
@Adám with local + global scope*
 
ngn
5:29 PM
@Adám yes, there is at least one k impl with lexical scope
 
@ngn Trust me, I know. No reason to spell it all out.
@ngn You must at least find it intriguing that not all Ks use lexical scope, no?
 
ngn
@Adám good
 
@dzaima Should I even ask what that * means?
 
ngn
@ngn small correction: s/scope/environment/
 
@Adám that was a correction marker (imo whatever that one k with actual lexical scope is, is insignificant)
 
ngn
5:34 PM
@DyalogAPL @ klg and that's how world war 3 starts :)
 
@dzaima Ah, I see. Right, I wrote that sentence fully aware that K usually doesn't have lexical scope. I should have added "/s"
 
@dzaima (it would be nice if the IDE could automatically add all locals to the header, but even that's mostly impossible with dynamic typing)
 
@dzaima It could certainly add locals on the left of as you type, and then you should be able to immediately hit Ctrl+Z if you want that global.
 
@Adám it still couldn't parse whether a f←1 is reading a function f or assigning to (a f). (even with requiring multi-assignment parentheses, (f a)←1 is still technically possible)
 
@Adám With a single anonymous, lexical, local-first, nestable functional form.
 
ngn
5:40 PM
@Adám it's lexical but locals and globals only
assignment in k, like in almost all programming languages, would never modify the caller's locals
 
@ngn fwiw that's equivalent to "it's dynamic but locals and globals only"
 
ngn
@dzaima sigh
 
@dzaima I'd be fine with it ignoring the possibility of naked multi-assignments. And (f a)←1 with f a function isn't currently permitted (though there's a bug you can exploit if you go out of your way to do so). Maybe a f⍛← would be a good thing for selective assignment, along with a(f←) for modified assignment.
@dzaima Exactly, and that's an important point. If you are strict about never relying on semi-globals, then the exact scoping rule doesn't actually matter.
 
@Adám were they really state of the art in 1960? lisp existed since 1958...
 
ngn
@rak1507 early lisps got scoping wrong too. i think scheme was the first good one. (apologies to CL fans)
 
5:46 PM
Ah
 
> The Lisp family splits over the use of dynamic or static (a.k.a. lexical) scope. Clojure, Common Lisp and Scheme make use of static scoping by default, while newLISP, Picolisp and the embedded languages in Emacs and AutoCAD use dynamic scoping. Since version 24.1, Emacs uses both dynamic and lexical scoping.
So Scheme appears to be the first Lisp with lexical scoping. It came out in '75.
 
6:03 PM
@ngn Do you know who wrote lisp and apl?
 
ngn
@Adám no. i would guess, the obvious?
 
@ngn He puts "m-expression" on the APL side. Did you know that John McCarthy saw s-expressions as an implementation step on the way to m-expressions, which were his goal. He just never got around to finish implementing Lisp. I don't know if he ever heard about K, but I imagine he would have liked it.
 
ngn
@Adám interesting. i didn't know.
 
AW must be aware, otherwise he wouldn't use that term. Afaict, it is only used about McCarthy's goal.
 
6:45 PM
@Adám lexical scope is crucial for closures and any higher-order functions not breaking when used out of where they were created. This also applies to a module system that stores functions as values. maybe these problems don't apply as much to APL, but they are important for most functional programming
 
1 hour ago, by Adám
@ngn Most people (other than FP wizards) probably never even notice.
 
@ngn scheme came first, so it would be the first good one even if CL was counted as good
 
I don't mean to criticise FPers. Not at all. I have great respect for FP. I'm just trying to be pragmatic and salvage what can be salvaged. (ngn would of course support abandoning rather than salvaging.)
I'm in the middle of reading Name scope control in APL defined functions from '78…
 
@Adám why wouldn't they notice, other than that almost no new languages come with dynamic scope. And perl, for example, added lexical scope.
 
@Wezl Because they'd never do anything where it makes a difference. From my experience, most programmers do fairly simple things when it comes to the structure of code and data. Actual data processing algorithms may be complex, but inter-function calls aren't.
 
6:56 PM
okay now we get to actual experience, which is where I have no points to defend
 
@Wezl I've run quite a few workshops for APL programmers of our actual paying customers, and I'm repeatedly surprised by their struggles with very basic problems. Almost everything they do are fancy applications of dyadic and . Things like FP and scope and closures are way over their heads.
For all our wanting to create the perfect array language, we often forget to be pragmatic, including realising that the customers don't think about the "beauty" or "consistency" of the language, or marvel at the "versatility" or "cleverness" in the design of a primitive.
 
That's interesting, I wonder what qualities make someone more likely to quickly pick up APL
 
Exposure to CS definitely causes a slow-down.
 
I'm not so sure about that, I get the reasoning behind it but practically if you already know CS, you're at an advantage
Maybe if they're stuck thinking in one particular way in CS
 
7:11 PM
Yeah, that's what happens.
CS people with even moderate code golf experience are an exception, because they've already broken out of their box.
 
That makes sense
So were the programmers you mentioned new to CS or people who already knew some? I assume the latter?
 
I don't know. Since they were professional APLers, picking up the basic ideas of APL was never the issue.
 
 
3 hours later…
9:55 PM
Can anyone help me with this answer? The challenge is to interpret lisp. To evaluate s-expressions, I'm currently passing around a context containing the names of variables and their values, but I was considering making everything a tradfn (except the function returned from LAMBDA) so that parameters to lambdas are in scope. Does that seem like a good approach, or would tradfns be too verbose (and complicated)?
 
@user Complicated, no. More verbose, but I'd say try it. Have you considered a namespace to keep the variables?
 
No, I haven't, although I should probably try that
 
@user I'm no sure if it'd help at all, but I'm curious if you've looked at the Lisp implementation in dfns.dws.
(btw, your explanation is a bit out of sync; it still has '_?[(),]_?'⎕R{⍵.Match~'_'})
 
Oops, let me update that.
@Adám Wait, you mean I did all that work when I could have just used a function out of dfns?
 
@user Maybe.
@user Are you also looking for golfing tips?
 
10:11 PM
@Adám Of course
 
@user I think ⍕'('(∇¨¯1↓⍵)')' can be 1⌽')(',∇¨¯1↓⍵
 
Thanks! First time using dyadic ⌽
 
Not a golf, just a style thing: Consider using instead of
 
@Adám ∊ Doesn't leave spaces in, unfortunately
 
Ah, I didn't realise you relied on those. Sorry.
 
10:19 PM
Thanks for suggesting it though - I can't expect you to intuit how my answer works, and anyway, it'll be useful in the future.
While the lisp in dfns looks very promising, I think I'm going to go stick with my answer for now. It'll probably be more of a headache for me to extend it anyway.
 
@user Here's a golfing tip that fails under TIO's Code field due to a bug in the interpreter mixed with the hack TIO uses to enable scripting in 17.1. It works in 18.0, and in the Input field (the session): Define r←⎕R'_' and use it to replace the two instances of ⎕R'_'⊢ (notice the trailing can be removed then).
 
Ah, nice!
How does that work exactly? Isn't ⎕R an operator?
 
Yes, a dyadic operator, and ⎕R'_' is a monadic operator.
 
So you can use trains to make new operators?
 
Not trains. However, you can create a tacit monadic operator by giving dyadic operator a right operand, yes.
 
10:28 PM
Ah, I see
 
11:06 PM
Hm, looking at how my APL data preprocessing script is maxing out only one CPU core, I suddenly have a newfound interest in isolate.llEach :)
 
@dzaima The fact that ⌊´⟨⟩ is defined to be and not a character is a decent reason not to allow on characters. Still not sure about restricting it though.
 
11:27 PM
@Marshall one could say that ⌊´⟨⟩ is an error, ⌊´↕0 is , and ⌊´"" is @+65535. But I'd prefer to just limit it to numbers.
 
11:46 PM
@dzaima 65535, not 1114111?
 
Aw yeah my first usage of Over endts {¯3↑⊃¯1⎕DT ⍺-⍵}⍥(1∘⎕DT∘⊂) startts
 
@MartinJaniczek Nice, but you know ⎕DT can take an array of tss? ¯3↑⊃¯1⎕DT-/1⎕DT endts startts
 
@Adám I was answering for dzaima/BQN mostly. is that 1114111 constant guaranteed to not change in the future?
 
@Adám That's nicer :)
 
@dzaima That's my understanding.
 
11:52 PM
@Adám ah, because UTF-16 restricts extensions
 
Exactly.
@MartinJaniczek Are you sure the time delta will never exceed an hour?
 

« first day (1434 days earlier)      last day (1221 days later) »