« first day (620 days earlier)      last day (2035 days later) » 

ngn
9:01 AM
> -⍬
?
@dzaima ^ :)
⍳0 also prints "?"
 
@ngn a question mark means unknown prototype, so it can't decide between and ''. I haven't done much about prototypes still
 
ngn
@dzaima ah... i see
 
I can't decide between leaving it at its current state and just scrapping everything and throwing out prototypes
 
ngn
@dzaima depends on what you're trying to achieve with this impl
 
@ngn that I too haven't decided :p
 
ngn
9:05 AM
if you want compatibility with dyalog and other apls, you should have prototypes
if you want simplicity and performance, probably not
 
well I'm splitting / up (and making the op part different too) so no compatibility and I'm not going for performance at all. Simplicity probably applies to me here though
 
ngn
@dzaima there are many things you can do for simplicity :)
 
also maps :D m←⎕map⋄m.x←2⋄"y"(m⌸)3⋄("x"⊃m),m2 (x:2⋄y:3) (that output syntax currently is only output syntax though)
 
ngn
@dzaima did you know dyalog already has a ⎕map? but it does something else - it reads a file (or rather mmap-s it)
 
@ngn yeah, but again, no compatibility, and I haven't touched files yet
and that shouldn't that be ⎕mmap anyways?
 
ngn
9:12 AM
@dzaima well, history...
so, what you describe is very similar to ⎕ns - namespaces
except the syntax is a bit different and dyalog doesn't print the content of the namespace
 
@ngn both of the things are subject to change if anyone has better ideas
 
ngn
@dzaima well, i would recomment, of course, looking at k's dictionaries instead :)
they behave like values, unlike dyalog's namespaces
⎕←{ a←⎕ns⍬ ⋄ a.x←1 ⋄ b←a ⋄ b.x←2 ⋄ a.x }0
 
@ngn
2
 
ngn
same thing in k: a:(0#`)!(); a.x:1; b:a; b.x:2; a.x returns 1
 
@ngn it'd require way too much work to make them that while keeping setting and getting O(log n)
 
ngn
9:20 AM
@dzaima yeah, but you don't care about performance :) and the same is true about modifying arrays
 
@ngn I'm not going for raw performance, but do want at least good algorithmic performance
 
ngn
@dzaima so how do you plan to implement a[i]←? it's the same kind of problem
"a" being a normal array
 
@ngn that's O(n), so I can't do anything better than that
 
ngn
@dzaima well, theoretically you can... but my point is why is that any different from m.x← ?
"m" being a map/namespace/dict
 
@ngn because immutable arrays are useful, but immutable maps are pointless (as they're no better than a key-value array)
@ngn and I'd have to implement reference counting then, since a←b←1 2 3 makes a and b point to the same array, and that gets complicated fast
 
ngn
9:28 AM
@dzaima that's dyalog's point of view, which i think is wrong
 
@ngn which part - the immutable arrays?
 
ngn
@dzaima "immutable maps are pointless"
 
@ngn that's my point of view too. In any way, shape or form, I do want to have hashmaps in my APL
how are immutable maps different from a key-value array (well, except syntax)?
 
ngn
@dzaima exactly :)
@dzaima whatever reasoning is valid for normal arrays, should be valid for "associative arrays" too
 
@ngn immutable arrays is the base idea of APL. Hashmaps are a nice addon for those who do want performance
@ngn if I add k-ish "map-like" modification of arrays, will you be happy? :p
 
ngn
9:38 AM
@dzaima well, i don't put any ego or emotions into this :) i'm just trying to explain why k's way is more self-consistent, but ofc you're free to implement this any way you like
 
@ngn I'm more asking whether adding fancy would make arrays enough like k's dicts, hence the :p (though I'd understand if everyone just filters those out as they're at the end of like 50% of my messages)
 
ngn
@dzaima do you envision maps as something penetrated by scalar functions?
 
@ngn oh that's a good question
 
ngn
@dzaima i implemented this only a few days ago, here are some of my tests:
(`a`b!1 2)+3                  / `a`b!4 5
2*("ab"!3 4)                  / "ab"!6 8
(`a`b`c!1 2 3)-`c`d`b!4 5 6   / `a`b`c`d!1 -4 -1 -5
keys!values creates a dict
the expected result is as a comment - after the /
 
@ngn oh god that monadic - & nothing done on a scares me
 
ngn
9:45 AM
@dzaima sorry, i don't understand that. monadic what?
 
@ngn last examples d doesn't have a counterpart in the 1st map (or does that just assume a 0 left arg?)
 
ngn
@dzaima right :) and k knows that the identity element for "-" is 0, so it fills it in
 
I'd rather require both sides maps to be the same length though
 
ngn
@dzaima i was tempted to do something like that at first - require both dicts to have the same keys
but a complete impl turned out simpler than i expected
and here's another example of the beauty of k - what do you think this should return? &"abc"!2 0 1
monadic & is "where", like dyalog's
 
@ngn well yeah that's what I meant. Keeping both sides the same length means a full pass though only one maps elements O(log n)
@ngn no idea, that doesn't transpile in my brain
@ngn either way, whenever I want I could add K-like maps later (which would make my APLMap not seem so badly named :D ), and I definitely want hashmaps
 
ngn
9:56 AM
@dzaima ok, let me use different numbers in the example to avoid confusion: &"abc"!3 5 8
hint: &3 5 8 returns 0 0 0 1 1 1 1 1 2 2 2 2 2 2 2 2 (3 zeroes, 5 ones, and 8 twos)
which is exactly like &0 1 2!3 5 8
because ordinary arrays are like maps between ⍳N and their content
 
so a a a b b b b b many cs?
 
ngn
@dzaima yes :)
you may recognise that as ⍺/⍵ :)
 
@ngn oh so more like this
 
ngn
@dzaima yep, i always forget that dyalog's ⍸⍵ was restricted to booleans...
 
@ngn well mine isn't :D
 
ngn
10:03 AM
@dzaima nice :)
 
oh k dicts allow multiple equal keys?
 
ngn
@dzaima well, only the first occurrence is valid
a dict is really a pair of ordinary arrays
 
ngn
@dzaima if you have repeated keys, anything could happen :)
 
@ngn so &...! isn't /, but a strange subset?
 
ngn
10:09 AM
@dzaima it's simply not worth spending O(n^2) time when creating a dict to check that the keys are dictinct
 
@ngn well, from a map I'd expect that to be O(nlogn), or just free because of the design
 
ngn
@dzaima why a strange subset?
if you mean because of repeated indices - it's probably exactly the same as ⍺/⍵
 
@ngn I don't like "probably"
 
ngn
@dzaima my implementation is really simple, it's the c equivalent of: &keys!values ←→ keys@&values
@ is indexing
if we ignore negative numbers for ⍺/⍵, i don't see why &y!x might be incompatible
 
@ngn sure, but that feels more like abusing the languages laziness than beauty of it
 
ngn
10:18 AM
@dzaima laziness?
 
ngn
efficiency :)
 
if I'd implement k-like maps, I'd definitely have that check in, even if it means O(n^2) (though shouldn't O(nlogn) be possible?)
 
ngn
"The keys should be unique, though q does not enforce this." -kx's docs
 
@ngn "should" → &`a`b`a!1 2 3 is doing a thing that "shouldn't" be done
 
ngn
10:26 AM
@dzaima rebel code :)
 
@ngn probably not, as having map-specific functions feels useful. Probably something like (a:5⋄b:2)-¨(a:1⋄b:4)(a:4⋄b:¯2) should exist though
 
ngn
i think what they meant by should (not: must) is that if you have repeated keys, lookup by key and possibly other operations may return unexpected results, but otherwise the world will not end
@dzaima how about this: another feature of k (not yet in ngn/k) is that a.b.c:1 creates a variable "a" with key "`b" mapped to a dict with a key "`c" mapped to 1
 
@ngn I'd assume . isn't an op?
 
ngn
@dzaima when surrounded by whitespace it is a verb, but when part of a name it only separates its components
 
@ngn ah, but I definitely don't want whitespace dependency (well, except numbers)
 
ngn
10:37 AM
@dzaima sure, you have more characters to choose from
 
@ngn I do want namespace access to be . and inner product to be ., since the two should be fully compatible
 
ngn
@dzaima dyalog manages to do both somehow
 
m.s.x←5 = m.(s.x)←5, not (m.s).x←5 :| seems my lazy implementation is bad
@ngn both should be fully possible together as the left operand of . being not a function (so, a map) would result in a syntax error always
 
ngn
@dzaima parsing this can be very messy and it may depend on the runtime values of "m", "s", etc
 
@ngn sure, but much of APL already changes runtime
though m m.x = (m m).x :|
 
10:43 AM
@dzaima Yeah, I was just about to raise that example.
 
i.. think ill just leave that like that and call it a feature
also another idea that's been bugging me for a while is a statically typed APL. No idea how wrongly that could go but it'd allow much better optimization and actual compilation (to some extend, at least)
 
@dzaima One of our major customers use comments to declare types and then they have a type checker.
 
11:14 AM
@dzaima ooh for a while I've been wanting to I've making an actually efficient language but had no idea what to make, that could be a good candidate
 
 
3 hours later…
2:28 PM
So a←b←1 2 3 a and b point to different memory locations both initialized to 1 2 3 or not? possible I wrong because remember C language and assembly ...
 
@RosLuP it's up to the implementation, but generally a and b could very well be pointing to the same array in memory
 
I wrote something wrong in assembly there would be not multiple assignment....
 
this vs this tells me that the multiset indeed makes the arrays point to the same memory
 
I do not have to use that multiple assignment in APL (if I remember to do it)
Thank you
So in a←b←1 2 3 a and b I have to think as pointers not as data with type? ← is considered one operator overload seen types its Arguments?
 
2:51 PM
@RosLuP really array variables could be thought as pointers to a constant/immutable thing holding the arrays contents & its shape. Even if wanted to clone the 1 2 3, the cloning function could just return the same pointer as the array is immutable
 
ngn
@dzaima forcing the user to declare types would be against the spirit of apl, but sometimes types and/or shapes can be inferred automatically - if i remember correctly, Bob Bernecky's and Martin Elsman's impls do something like that
@RosLuP yes, they point to the same memory location, but that's transparent to the user
every apl object has a "reference counter" for the number of other objects pointing to it
 
@ngn yeah, I did think about making the compiler figure out the types, but allowing declaring types could be useful (though if your program "works" with the types of everything being wrong, it should be obvious)
 
ngn
when you try to modify an array with a refcount of 0 (or 1 in dyalog's impl), the memory can be reused; otherwise a new copy of the array is made at another memory location
 
@dzaima I'm always confused when I read your conversations to yourself ;p Unless you are 2 people and I just don't know
 
@Quintec I'm replying to my past self :p
 
ngn
3:03 PM
@dzaima the problem with static typing (inferred or declared) in array languages is that it's a lot of effort to implement and use, but there's little benefit for performance in practice :|
 
@ngn it makes many more compile-time errors, warnings & notes possible to find, though. This amused me
much of that is finals & a couple import things, but this felt awesome to do in one click
 
but if assignament is from one int, i and r are two different location else i think
this function would return one number >1e5 and in NARS Apl return something as 3.14

r←q;f;i
f←{1e8÷⍨?1e8}⋄i←r←0
A: i←i+1⋄r←r+1>(f*2)+f*2⋄→A×⍳i<1e5
r←4×r÷1e5
 
ngn
@dzaima i agree, intellij is a great java ide :)
@RosLuP the third line is literally a strange loop :)
 
@dzaima Meh, I wouldn't sacrifice simple readability for fancy streams
Maybe that's just my Backward Java 7 way of thinking :P
 
@Quintec IMO a Collectors.joining(" ") is way more readable than if (i != 0) res.append(" ");
 
3:18 PM
I'm talking more of things such as Arrays.stream(arr).map(Value::fromAPL).collect(Collectors.joining());
It takes me much longer to interpret then the simple for loop
 
The third line would have to calculate in r pi/4 using random values... but now I see it if i and r point to the same location it should return 4
 
Mostly because the fancy syntatic sugar of converting to stream and back
 
@Quintec ok sure that is strange, but it gave me the option to do that and I couldn't not :p
 
lol
 
there were many instances where I didn't take the suggestions too though
 
ngn
3:20 PM
@RosLuP they might point to the same location in memory right after "i←r←0", but once you modify one of them they will become different locations (I mean, if nars behaves as i'd expect)
 
Yeah, it definitely feels satisfying to click and write
return IntStream.range(0, 3)
.filter(i -> 1 == (0xf & (valid >> 4 * (2-i))))
.mapToObj(i -> new String[]{"niladic", "dyadic", "monadic"}[i])
.collect(Collectors.joining("/"));
Collections.joining is super nice though, mostly because I miss my python join
Fun fact: it can take 3 arguments, delimiter, start, and end
 
@ngn Thanks
 
Though I'm extremely impressed IntelliJ can process your multi line for loops with ifs and whatnot and convert them to a single stream
Netbeans only understands my single line for loops
 
ngn
ide-s solve problems that shouldn't have existed in the first place...
 
@ngn because for humans to do that would be annoying
 
3:25 PM
Num.lcm(IntStream.range(0, w.ia).mapToObj(i -> (Num) w.arr[i]).toArray(Num[]::new)); barfs
 
@Quintec ok sure
 
(also, you may or may not know this: Stream operations on primitives can be up to 16 times slower than a good old for loop)
 
@Quintec I did play around with performance testing but I got bored after a while
 
You know what feels better than having your IDE replace your code with a single-line stream? Typing the single-line stream yourself. :P
 
@Quintec sadly I can't agree since I don't know anything more about streams than what IntelliJ has already done for me :p
 
3:29 PM
You feel so accomplished, until you compile the code and realize you forgot to stream, you used the wrong type of argument in collect, your mapToObj takes a wrong argument, the types are wrong, the final product is still a stream, you always forget that stupid double colon, and you forgot the additional arguments for max/min
 
related to ^, I usually create code with strings and += and when I'm done, make intelliJ convert it to StringBuilder so I don't have to bother :p
 
More high level language one goes more slow it will be especially primitive function are not assembly function... I think 90% programming is find the right function primitives and use them in hope the language not so verbose
 
lol
@dzaima I like the part in your commit where IntelliJ removed all the spaces between the negative signs and the numbers, xd
 
@Quintec eh, I did that manually (though it did warn me about it)
 
lol
I kinda want IntelliJ now... although I hate them, those stream expressions look so smart xD
 
3:34 PM
oh im stupid
 
Readability + performance
in most cases
And since I program competitively quite often, with time limits, I can't afford to use streams
 
@Quintec when I program competitively I use C++ though I barely know it, just for speed
 
But I still love the elegance and feeling of doing it all in one line, especially in Java, which is as verbose as possible
@dzaima In most competitions the difference in speed between C++,Java,Python,etc. doesn't matter, or they have different time limits for different langauges
 
ngn
@Quintec which competitions are you competing in?
 
Mostly USACO
 
4:10 PM
@ngn you see, not everyone is ngn and we, mortals, can write buggy/bad code. If your goal is to write perfect code from the get-go, why use a C(++) compiler (as it too does a ton of optimizations) and not just write in assembly?
 
ngn
@dzaima i am a mortal too, i don't do that, but i hear arthur wrote his own compiler :)
@dzaima for instance see here
 
@ngn well if you explicitly don't want any help writing good code and don't want any error messages, the only 2 possibilities for that are either you like bad code or you already write perfect code, and I don't think it's the former
 
ngn
@dzaima actually i like good error messages, short and to the point, preferably 1 word, and the location in the code
@dzaima i prefer using a concise language rather than a verbose one + tools
@dzaima as for debugging, i use very primitive tools... printf()
 
@ngn short error messages only help really if the problem is easy to notice and you know everything about what you're using. If someone didn't know that × on a character throws an error instead of doing nothing (like +), a domain error pointing to × might be pretty confusing. Or the thing that's affected me way too much - value error to a private field
 
ngn
4:28 PM
@dzaima i think help for new users shouldn't come at the expense of comfort for other users
or at the expense of simplicity, performance, size of the executable, etc
 
@ngn how is extra text bad for you? (well, except if it overflows the error message line, in which case yeah, the error's probably too long)
 
ngn
@dzaima i don't want to deal with that and i don't want it to bloat my binary
 
@ngn "my binary" as in the interpreters binary?
 
ngn
@dzaima yes
 
@ngn if I'm making the interpreter, it shouldn't bother you though
@ngn also IMO new users >> experienced users. IMO APLs main reason for not being popular is the unfriendliness to newcomers
 
ngn
4:35 PM
@dzaima of course, i can't and i won't tell you what to do :) everything i say is just an opinion based on my experience
@dzaima i don't know... dyalog is fairly newbie-friendly
i mean the graphical ide for windows with all bells and whistles
the obscurity of apl may be due to other factors: the character set, lack of a decent libre implementation, moore's law eroding the advantages of vector languages...
 
APL was definitely much easier for me to learn.
I could master the basic functions in an hour or so... then in depth learning of what everything actually does and how it works
But then again, I still know next to nothing
 
 
2 hours later…
6:24 PM
@chrispsn He uses macOS, so to enter symbols like and π (which I have heard testimony that he uses) I suppose he presses Alt+v and ⌥+p. kOS is absolutely still in the works. In fact, he cancelled his attendance at this year's Iverson College at the last minute because he felt he was on a roll with kOS. Specifically, he was succeeding in removing the last few OS dependencies from K.
 
 
3 hours later…
9:21 PM
K7 session transcript:
 √π
1.772454
 √-1
ø
 1%0
∞
 0%0
ø
 1 2 3@10
Ø
 

« first day (620 days earlier)      last day (2035 days later) »