« first day (1178 days earlier)      last day (1477 days later) » 

12:09 AM
# as "simple" seems like a bit of a stretch, but I suppose the terminology lines up. What about ⊢≡(⍴⊢)⍴∊?
 
@AntonDyudin Or simply ∊≡, or ⊂≡⊆
 
hah fair, in my mind I'm separating ⊢≡ which is "fits" and (⍴⊢)⍴∊ which is "validation function whose range is the type in question", still trying to build a type system ;)
 
@AntonDyudin Btw, what do you intend by (⍴⊢)? Isn't it just ?
 
cf earlier discussion of ⍎'⊢' as the "beyond the reach of type inference" type or ~2⊣ "this should crash, and therefore is valid as input to anything"
- indeed it is, ty
⍴⍴∊ or "whether or not you were a simple array before you'll come out as one"
 
@AntonDyudin That's basically what does.
 
12:16 AM
(again treating namespaces as "scalars" here, which I'm skeptical of but seems to be in line with all the operators)
 
@AntonDyudin Namespaces‽
@AntonDyudin ⊢≡⍴⍴∊ potentially does a lot of unnecessary work, say the first many elements are identical. ⊂≡⊆ should be really cheap: is simply memory pointer to the array, and will do the minimal amount of work to decide whether to point directly to array or create a pointer, and then it is just a matter of comparing two pointers.
 
        #.z
VALUE ERROR: Undefined name: z
      #.z
        ∧
      z←1
      #.z
1
      (⊢≡⍴⍴∊)#
1
I am perhaps missing something fundamental here
 
A namespace is a simple scalar. None of our formulations challenge that.
 
      (∊≡)#
0
perhaps they are different formulations then?
 
@AntonDyudin namespaces might contain stuff, but their "containing of stuff" is no different of the "decimal thing" numbers "conain"
 
12:20 AM
@AntonDyudin The enlisted depth of #
 
@Adám ah I see I missed the , was code not formatting ^-^
 
@AntonDyudin I skin chat so code has a different background colour.
 
@dzaima I accept this is the stance taken by the system and this will help me predict its behavior, just, I feel uneasy considering something that has nested lists or for that matter dfns in it to be "just a matrix of scalars"
 
CMC: Given an array, determine if it is a simple space (namespace/class/interface/instance).
 
@AntonDyudin what would ⊃# be, if not just #? simple scalars are the only things with the property X≡⊃X
 
12:25 AM
@Adám I was speaking theoretically, and not to code you'd want to actually run; an erroring variant of those will definitely be more practical
 
Erroring?
 
@dzaima there may even be reasons for the stance taken by the system, consistent with other properties of the system
I am nonetheless uneasy when faced with 1≡≢(a:1⋄b:2), idk how many things that contains but it's not "one"
 
@AntonDyudin does 1≡≢,⊂(1 2)(3 4 'hello') not be one? (≡(a:1⋄b:2) being zero is a more valid concern)
 
@Adám for the goal of "a "'"type"'" is a function which, when presented with any input, produces some range of output, and when given input in that range produces the same result"
which is me blatantly copying off previous type system design experience, may or may not fit
sure, I am gesturing towards "it's a hashmap it's not a scalar"
(dict? it is a thing that maps names to values)
@Adám more directly to this point: is # or is it not a namespace?
 
@AntonDyudin 3.14 is a tuple of a sign, mantissa and exponent (the latter two being lists of booleans), it's not a single thing!
 
12:32 AM
and it fits in a single machine register QQ
 
@AntonDyudin a pointer to a namespace also fits in a machine register
 
not unboundedly many of them
similarly, a simple array can be thought of as a linear chunk of memory without an allocator or external dependencies
 
it'd probably be possible to define namespaces in a way that they're not scalars, but imo it makes more sense this way
 
the whole thing. otherwise ⊂⊂1 2 3 is also a "scalar"
 
@AntonDyudin I always thought it does count as a scalar...
 
12:35 AM
(I suppose 'a'1 in fact involves pointers, but like, they could be to the end of the array or w/e it's still rather self-contained)
then perhaps my terminology is off then :)
I'm going off like, "Scalar is used for a single value, a number like 456.18 or a single letter like 'Q'." in MasteringDyalogAPL
 
@dzaima in that case, what would they be? The shape of a namespace can't be anything other than , otherwise you could get an item of it (e.g. ns[1]), and that doesn't make sense!
 
…which in fact also says "The result of Enclose is always a scalar." But then I'm confused about "scalars are the only things with the property X≡⊃X"
 
@AntonDyudin X≡⊂X and X≡⊃X are both properties of, and only of, simple scalars
 
ah, and a simple array is composed of simple scalars
 
@dzaima JS does by coercing the numeric indexes into string keys. ⍨
 
12:40 AM
like 1j2 or 'a' or apparently #
I suppose if I need terminology for "will fit serialized in like 10 bytes" I can always say "non-namespace simple scalar"
(non-Object? presumably GUI handles are also, in this sense, simple)
 
@AntonDyudin my APL has bigintegers, which are simple scalars and function exactly like regular numbers, but can be arbitrarily large. Would those be of type "fill fit serialized in like 10 bytes"?
@AntonDyudin that's probably more appropriate. Though, what's the purpose of that terminology?
 
fitsinhead :)
 
@AntonDyudin Roger Hui lately came up with the term "basic" meaning "not involving objects". E.g. 3 '.' (2 2⍴1 4 1 5) ⎕NULL is a basic array.
 
@dzaima coming from a nock lang background I super appreciate bigints, and yeah I suppose they do feel like an intermediate level of "complex"
or well, a bigint is isomorphic to a vector of bytes, so yeah not a basic scalar but yes a basic array
 
Arbitrary precision base-pi rational octonions are simple too, no?
 
12:46 AM
@AntonDyudin they're exactly like regular numbers besides their implementation (and of course other big-int-y stuff), though, is my point
 
How about datetimes? Are they simple?
 
…basic simple arrays? I notice the example given is in fact nested
(also what is ⎕NULL that sounds like a maybe possibly object)
 
if i implemented doubles as an array of 1000 doubles, only the first of which is used, would then 3.14 be a "will fit serialized in like 10 bytes"? (aka if determining the type of something is implementation-dependent, determining type becomes impossible)
 
@AntonDyudin Yes, an array can be simple non-basic and basic non-simple. ⎕NULL is simply a "third" type (after numeric and character), but otherwise behaves normally.
 
not familiar with APL datetimes, the 2020 04 16 17 48 03 I've seen posted around certainly are simple vectors
 
12:49 AM
@AntonDyudin I was just thinking in general. But yeah, if you wanted a "single" ⎕TS-style datetime, you'd do ⊂2020 04 16 17 48 3 0 which is a scalar, but a non-simple one.
 
If you do not expose any operators that access the remaining 999 doubles for e.g. equality, then serialized they fit in 10 bytes certainly :)
what are non⎕TS datetimes like?
(in urbit datetimes like charvectors like actual ints are implemented as bigints; so in the terminology in this conversation, simple but nonscalars)
 
@AntonDyudin i guess with serialization (where you get to control the serialization behavior) there's no way around your shenanigans. still a useless separation imo
 
@AntonDyudin APL doesn't impose any particular representation on you. In fact, in 18.0 we're adding an all-singing all-dancing function that can convert between over 30 common (in other languages) representations. The default APL ones are ⎕TS style and days since 1899-12-31.
 
I mean I don't get to fully control serialization behavior
`?81⍴2` can't fit in 10 bytes, it's an information-theoretic bound
which is the distinction I'm trying to draw really, "one finite thing" vs "matrix of finite things" vs "arbitrarily nested list of arrays of namespaces of closures capturing etc"
 
@AntonDyudin Would you not distinguish between self-contained and not?
E.g. (a:42) is self-contained, but (a:#) isn't.
 
12:56 AM
and yeah "expects there to be a windowing environment or open network sockets and will generally die if salted and unsalted" would be a fourth tier
oh hm not that kind of self-contained
I try to avoid pointer-level cyclic references in my code, but tentatively I'd put that in the same bucket as recursive functions?
((also where can I get a REPL which will actually execute (a:42), tio.run/#apl-dyalog-extended doesn't seem to at least))
 
@AntonDyudin there's none for Dyalog
 
@AntonDyudin ⎕SE.Link.Deserialise '(a:42)' for now. We're considering this for 19.0 or 20.0.
 
oh I see you were pointing me towards https://tio.run/##SyzI0U2pSszMTfz//1Hf1EdtEzQSrQwfdbckWRlp/v8PAA
less :(
@Adám yeah I've done that some, not a repl proper though
also I will note
      ⎕SE.Link.Deserialise '(a:#)'
  NONCE ERROR
<<a debugger pops up>>
 
@AntonDyudin Yeah, it isn't intended to handle namespaces that are not self-contained. And there are other limitations too. But I should catch that one. Thanks.
 
1:04 AM
which tempts me to classify "not self-contained" as "unserializable through official channels and therefore of limited utility"
…and dzaima/APL doesn't know the token "#"
so my actual classification is "I have no way to run it" XD
(though I suppose it would be virtuous of me to practice desugaring to an explicit ⎕NS constructor)
 
i wanted to say it does now (tio's still outdated), ...but:
https://tio.run/##7dFRa9NQFAfwZ/MpAu6heYnrpnPrpKAwUFA22Ltw16Zb5m0SkrTip6827WCDiQo@/t7uufzPPYffnYVqHbrNZpqOwuRllnxaNrFYFlUf@rKuLtq2bidptYrxPM26Psy@pYu6TYdT34ZZkeza0jT9mkz3keQ@rEMeQ3WbX2/ry3XRLmL9fXgteRH6dAjchK549TjaltXth1UZ50Wbvyursp@Onl5uw5Px0etseOT91ee8/9EU3bb1S2jyvt7FR/t6iJ@9zf4wMl@HuCouF/thu7ajszfj7C93DU1TVPNndz05/c2uMSxv5uHgYeWD8ZOlx4eHzw5f9WXMP4bubpv89REXYXY3eqh3ncfHJ//Ec4oHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYMHDx48ePDgwYM
 
@AntonDyudin Ah, I see. I try to disconnect the generated namespace from the location it was generated in by making a deep copy, but I can't deep copy a namespace that isn't self-contained.
 
"impolite to throw at a runtime" is also a contender
 
@AntonDyudin there you go
 
Ah, gotta love Java error messages.
 
@AntonDyudin Manage what exactly?
 
@Adám i mean, there's not much way around it. You either give all the info, or none, and none is never better
 
I suppose that bottoms out in grabbing everything the objects contain, however
 
@AntonDyudin But I can't take a copy of the workspace. That simple doesn't make sense. There can only be one workspace active at any given time.
 
@dzaima information-theoretically again, "these 5 lines repeated 20 times" would be a more pleasant display without precisely losing anything
@Adám one of the first things I do in CLEAR WS is )copy dfns! but yeah point taken
 
1:12 AM
At least Dyalog's debugger will ask you if you want all the levels shown if there are a lot of them.
@AntonDyudin )copy dfns only copies the members, not the workspace itself.
 
@Adám that's not an option in a non-interactive environment
 
ah hm, # = workspace, #.whatever = namespace, and those are profoundly architecturally different?
(I am to an extent getting "PID 1 init is responsible for reaping all zombie processes" vibes here, if I'm at all on the right track)
 
@AntonDyudin right, a question - in (a:#) do you expect # to refer to the namespace getting created right now, or the surrounding scope?
 
@AntonDyudin Yes, they even have different name classes. # is an instance (9.2) of the root class. Normal namespaces are 9.1.
@dzaima How could it be the new namespace? That'd be ⎕THIS
Whoa, ⎕SE.Link.Deserialise '(a:⎕THIS)' crashed APL.
 
@Adám indeed i don't know how it could be the new namespace, but it nevertheless might be what was expected
 
1:17 AM
how does ## come into all of this?
 
@AntonDyudin ## is a ref to the parent namespace, like .. in a file system. # is like / while ⎕THIS is like .
 
@Adám ah so Dyalog really is dynamically scoped - s←# ⋄ {x←2 ⋄ s.x}⍬
 
ah so then a workspace is a namespace, just also other things
whoa
I recuse all claims of being able to type-inference code in the presence of #
 
@AntonDyudin I'd say a "space". "Namespace" kind of means two things in Dyalog, a container object that can have members, and specifically a non-class, non-instance, non-interface object.
 
@AntonDyudin yeah, namespaces are horrible
 
1:22 AM
a side of with with your wat ;)
 
@AntonDyudin Just wait until you hear about :With
 
if all of them can have members though, perhaps the more specific term should be "basic namespace"
which continues to be a scalar
(c.f. POJO for "javascript object, but like literally, one you could have gotten from JSON")
I mean if you can s←# surely you can #←s
 
@AntonDyudin No, because # isn't a valid user-assignable name.
 
lowkey trying to crash @Adám's APL again
 
@AntonDyudin I managed to cut it down to executing a←⎕THIS ⋄ ⎕NS'a' in ⎕SE.
 
1:27 AM
I suppose :With would be more of a )copy than a )load
(except scoping and possibly capturing assignments)
 
Yeah, and then only for some members… it is ugly.
 
1:48 AM
aw 1⊃⊂1 doesn't work
I guess makes sense with the scalar unenclosability
 
@AntonDyudin Wouldn't work anyway. Even 1⊃⊂1 2 doesn't.
 
ah right it's a pure box
(⊢⊣÷⊂≡⊆) is certainly a Construction
 
@AntonDyudin (⊢÷⊂≡⊆) you mean?
 
nope, apparently (⊢⊣(÷⊂≡⊆))
 
@AntonDyudin Ah, that makes more sense. Error on non-simple, no-op on simple. Alternative coding: (⊢⊣1÷⊂≡⊆)
 
1:59 AM
indeed, if you don't want to be a ⍵ provide one
 
@AntonDyudin Doesn't it bother you that it throws a div-by-zero error if nested? How about (⊢⊣'NESTED'⎕SIGNAL 11/⍨⊂≢⊆)?
 
no bc that runs into @arcifde's "annotations are longer than the code" complaint in the talk you link
the idea is it ~doesn't~ bc the typechecker advises you not to ~run the workspace~
 
oh
 
(the current formulation also does, honestly, but it's a plausible start without introducing anything - obviously operator ⊢⊣1÷ would want to be one glyph in theory)
in which case you can reintroduce ('expected type ',⍎⍺⍺)⎕SIGNAL 11 conveniences!
 
@AntonDyudin I'd appreciate :Assert (⊂≡⊆)var which would display:
ASSERTION ERROR
      :Assert (⊂≡⊆)var
              ^
 
 
13 hours later…
2:41 PM
i believe i've fully implemented ↑ & ↓ :D
 
@dzaima What about the extension where has more elements than has dimensions. Really useful for say 0 0↓x normalises scalar/vector x to a matrix.
 
@Adám that feels special-casey/abuse-y. and imo no code should ever need to normalize arguments anyway - i'd rather have it error on non-matrices and tell the caller to normalize (and the caller should either know whether the argument is or isn't a matrix, or if it doesn't, pass the normalizing request to its caller, and recurse until someone to blame is found)
 
@dzaima But it is just a generalisation of the existing behaviour for vector↓scalar
 
the current behavior has the property result ≡⍥(≢⍴) ⍵ or it errors
 
3:48 PM
1
Q: What is the IBM Monitor I'm thinking of?

TZFanBACKGROUND: In 1985, I took an evening class in APL at the local IBM as part of a high school Explorer Post (which was really cool, these guys giving up their time to teach us programming). Other than this, I am woefully inexperienced in computing on IBM machines. Now, this was 1985, so the mo...

 
 
2 hours later…
5:49 PM
gosh, was the text-mode logic part of the monitor at the time?
I guess by "monitor" they may be referring metonymically to "teletype terminal, i.e. not the machine proper"
 
6:07 PM
@AntonDyudin - In some cases, I think it was - for example, there were two incarnations of the IBM3270 terminal, one which supported APL and one which didn't. When I was taking my survey of computing languages course «mumble» years ago, we were specifically told to use the terminals in room such-and-such of the computing center when we started the APL unit, as those were the only terminals with the APL option.
 
6:22 PM
OK, I know I've seen discussion of this before... If I have a function f ⍵ that produces a boolean vector, and I want to select the items of ⍵ where f ⍵ is true, I can use (f ⍵)/⍵
BUT, I don't want the elements of ⍵, I want their positions - IOW, (f⍵)/⍳⍴⍵
There's another way to get that. Clue, please?
(Actually, I want 1↑(f⍵)/⍳⍴⍵)
 
@JeffZeitlin ⍸f⍵
Or ⊃⍸f⍵ if you just want the first element
 
@voidhawk - Thank you. I knew I'd seen it, but I still end up trying to solve things using TradAPL instead of modern APL.
 
Never even written a tradfn so I guess I have it easier :)
 
Well, in this case, it's less a question of tradfn vs dfn or train than it is TradAPL misses a good chunk of the primitives in modern APL - like, for example, ⍸
 
 
2 hours later…
8:42 PM
using gnu apl (which doesnt support multiple statement lambdas or guards), I tend to use dfns for shorter functions, and trad fns with dfns in them for more complex functions
its stylistically a little weird but jurgen has made it clear he doesnt intend to extend dfns and its not that much of a hindrance for me to care after a certain point.
if there was an "apl3" i think dropping tradfns might be worthwhile for simplifying the implementation
would also open up ∇ for unambiguously being a self fn reference
 
@cannadayr - I think this is a bad idea; if nothing else, TradFns would be appropriate for complex framework 'functions' that may not actually return a value (but do have side-effects).
 
reasonable
i try to avoid side effects except for return values but it does sometimes complicate code
 
Sometimes side-effects are appropriate - for example, reading or writing files.
 
i personally find tightly integrated apl with mutating values hard to read but im not strict or anything about it. big tent sortve deal
yea thats a good point. mutating a pointer in a lambda could be needlessly confusing
 
Also, programmatically, putting data into a GUI is a side effect, regardless of how the data was obtained.
 
8:58 PM
dzaima/APL doesn't have tradfns, and i'm using it just fine. Granted, i'm not writing production software, but i do often use mutating dfns and have made some non-small things i've made in it
 
@dzaima - I'm not saying that it can't be done, just that there may be times when a dfn may impose constraints that may not be entirely appropriate.
 
@JeffZeitlin i'm pretty sure there's a way to extend dfns to cover everything that tradfns can if that's really wanted. (i'm not sure there are many differences though)
 
@dzaima - As I understand it, dfns can't have null returns - I don't mean returning ⍬, I mean terminating without returning any value, just executing for any side-effects.
 
@JeffZeitlin huh, Dyalog doesn't allow this. i do, but of course the syntax is a bit weird as it wasn't designed for this
 
Umm... Yours seems to give a syntax error.
SyntaxError: trying to use result of function which returned nothing
f ← {
     ^^^^^^^^^^^^^^^^^
 
9:13 PM
@JeffZeitlin yeah, cause i'm trying to output the result of a function which isn't supposed to return anything!
(the error messages carets are a bit messed up, i'll look into that though)
 
Yes, but that's the kind of thing I mean about dfns not being able to not return a value. You're not explicitly trying to return the value, but dfns presumptively return values.
 
@JeffZeitlin i mean, if you want to have two different function syntaxes just so one would have implicit return and the other - not, sure..
(also, i could remove dfns implicitly returning as i do have syntax for explicit return (leading in a line), but that feels rather pointless)
 
9:57 PM
guess i should probably learn what a monad is...
i personally try to avoid changing state inside lambdas, to the point where im not opposed to the language providing guarantees
but also the unambiguous apl symbols make it easier to identify where its happening
 
10:09 PM
@cannadayr Using mutation-free code wherever reasonably possible is of course good, but there are cases when the hassle to remove mutation is gonna have severe impact on program readability and/or performance
 
10:39 PM
yep. im writing a linear algebra toolkit for gnu apl (was gonna post to mailing list tmrw). and altho im writing it w pure fns it def increases the complexity at first (altho imo it makes it more flexible)
lots more recursive fns and use of power operator vs branching
getting simpler tho
 

« first day (1178 days earlier)      last day (1477 days later) »