« first day (739 days earlier)      last day (1933 days later) » 

7:52 AM
@ktye What is the (1;2;) notation?
 
 
1 hour later…
8:54 AM
If f is one function, argument one int, result one int... What happen when that function is called to one list of ints? f 1 2 3 is the list (f 1),(f 2),(f 3)? If that is true what is the difference for f¨1 2 3?
⍞←{2+⍵}1 2 3
 
@RosLuP 3 4 5
 
@RosLuP If f is entirely defined in terms of scalar functions, then yes, f 1 2 3 will be the same as (f 1),(f 2),(f 3) and f¨1 2 3, but if the function has side-effects, then note that (f 1),(f 2),(f 3) processes 3 first, while f 1 2 3 processes all three at once, and f¨ 1 2 3 processes 1 first:
⋄ f←{⎕←'processing:',⍵ ⋄ 2+⍵} ⋄ ⎕←(f 1),(f 2),(f 3) ⋄ ⎕←f¨ 1 2 3 ⋄ ⎕←f 1 2 3
 
@Adám
processing: 3
processing: 2
processing: 1
3 4 5
processing: 1
processing: 2
processing: 3
3 4 5
processing: 1 2 3
3 4 5
 
⍞←{2+⍵}¨1 2 3
 
@RosLuP 3 4 5
 
9:09 AM
@Adám This is a nested list (similar to K). The parser needs a trailing semicolon to detect it easily.
 
@ktye Ah, so you do have nested arrays.
 
if f has argument type int and it receives one argument type list of int, why it would not return error?
 
@RosLuP What does it even mean that f has "argument type int". We generally don't declare argument types in APL.
 
@Adám Kind of. As arrays they are always rank 1, but nested. There are no n-dimensional nested arrays
@Adám In lists I can store also functions. I thought about parsing directly into a list, to be able to manipulate at runtime. But this is not done.
 
I thin APL see if the argument is one int if it is one int, than apply f to it, else if it is one list of int apply f to each element of list...
 
9:16 AM
@RosLuP Well, you can use for that, as long as the result is also a simple scalar.
@user3476430 Hi. If you want to be able to chat here, drop me an email to adam@ with the same domain as www.dyalog.com.
@ktye You could also let the function handle that by itself:
⋄ f←{0=≡⍵:⍵+7 ⋄ ⎕←'digging into',⍵ ⋄ ∇¨⍵} ⋄ ⎕←f 7 (4 3) (1 (4 5))
 
@Adám
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬───┬───────┐
│d│i│g│g│i│n│g│ │i│n│t│o│7│4 3│┌─┬───┐│
│ │ │ │ │ │ │ │ │ │ │ │ │ │   ││1│4 5││
│ │ │ │ │ │ │ │ │ │ │ │ │ │   │└─┴───┘│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴───┴───────┘
digging into 4 3
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬───┐
│d│i│g│g│i│n│g│ │i│n│t│o│1│4 5│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴───┘
digging into 4 5
┌──┬─────┬─────────┐
│14│11 10│┌─┬─────┐│
│  │     ││8│11 12││
│  │     │└─┴─────┘│
└──┴─────┴─────────┘
 
OK, that was a bit ugly, but you get the idea.
⎕←{0=≡⍵:⍵+7 ⋄ ⎕←'digging into:'⍵ ⋄ ∇¨⍵}7 (4 3) (1 (4 5))
 
@Adám
┌─────────────┬───────────────┐
│digging into:│┌─┬───┬───────┐│
│             ││7│4 3│┌─┬───┐││
│             ││ │   ││1│4 5│││
│             ││ │   │└─┴───┘││
│             │└─┴───┴───────┘│
└─────────────┴───────────────┘
┌─────────────┬───┐
│digging into:│4 3│
└─────────────┴───┘
┌─────────────┬───────┐
│digging into:│┌─┬───┐│
│             ││1│4 5││
│             │└─┴───┘│
└─────────────┴───────┘
┌─────────────┬───┐
│digging into:│4 5│
└─────────────┴───┘
┌──┬─────┬─────────┐
│14│11 10│┌─┬─────┐│
 
@Adám you mean applying a function recursively to a nested list?
 
@ktye I'm just trying to give more answers to RosLuP.
 
9:26 AM
@Adám I still have to figure out, why the parser couldn't deal with the tacit GoL...
 
@ktye Which one?
@ktye Btw, shortest known APL GoL is 17 chars: {≢⍸⍵}⌺3 3∊¨3+0,¨⊢
 
l←3=s-⊢∧4=s←{+/,⍵}⌺3 3
One thing was, that function variables need to be lowercase in iv.
But there are more issues with this line.
 
@ktye The assignment could be problematic, especially if there is an atop on its right.
 
@Adám Yes, but also if I split it into two lines, it cannot be parsed. I think it has to do with agh forks if they are more functions on the left...
@Adám Btw, how complicated is the parser in Dyalog? Please tell me it's more than 10 lines...
 
@ktye I can ask tomorrow. I suspect it is rather complicated due to all the additional stuff Dyalog supports. Check out our binding strength table.
 
9:37 AM
⎕←{⍵=1:3⋄9}¨ 1 2 3
⎕←{⍵=1:3⋄9} 1 2 3
 
@RosLuP
LENGTH ERROR
 
@Adám Oh I did stare at it for some time... and with some bad conscience ignored most of it. I just added more test cases, compared to tryapl and patched...
 
⎕←{⍵=1:3⋄9}¨ 1 2 3
 
@RosLuP
3 9 9
 
⎕←{⍵=1:3⋄9} 1 2 3
 
9:38 AM
@RosLuP
LENGTH ERROR
 
It is always passed the array... So above it is all wrong what I said... Thank you...
 
@RosLuP A condition must evaluate to a simple Boolean singleton
@RosLuP Happy to help get clarity.
 
In the function
{2+⍵} 1 2 3 it is passed as argument the array 1 2 3
 
@RosLuP Yes, as you correctly concluded, functions are always passed their entire arguments. However, you can of course control that with ¨ or , but again, the derived function or f⍤k is of course still passed the entire argument.
@ktye I've had to ask our CTO about it a few times.
 
9:57 AM
The problem born for the function
1π that here would find the next prime...
If 1π1 2 3 here is ok it is probably because they define 1π function for list and scalar, but if one not know this it has to be
1π¨ 1 2 3
 
@RosLuP For the prime finding function it is even more important that the function handles such, so it avoids doubling work. Clearly, it has to find the largest scalar in its argument, then find only primes up to that number, and the lower ones are included there.
 
Now I found out. I have to write:
A←5 5⍴(23⍴2)⊤1215488 ⋄ s←{+/,⍵}⌺3 3 ⋄ l←{(3=s-⊢∧(4=s))⍵} ⋄ (l⍣8)A
 
@ktye Why do you need the parens around (4=s)?
 
An agh fork can only be parsed, if it is alone. Even f←1+- does not work and needs parantheses
 
@ktye How about A←5 5⍴(23⍴2)⊤1215488 ⋄ l←{(⊢(3=⊢-⊣∧(4=⊢)){+/,⍵}⌺3 3)⍵} ⋄ (l⍣8)A ?
 
10:06 AM
@Adám yes that works
 
ngn
10:39 AM
@ktye (x;y;) syntax, ranks ≤1, fns as 1st-class objects, no parsing ambiguity (you can tell apart verbs from nouns at parse time) - so, this is more k than apl :)
 
@ngn It does have ranks above 1, just not nested.
@ktye Have you implemented user defined operators?
 
yes, the K influence came later, when I read about it. Separating parsing from evaluation felt easier.
User defined operators does not exist. If I want to add it, I need special variable names. I thought about greek letters, or a prefix.
@ngn There is more from K: time/date, dicts and tables
 
ngn
@ktye why do you need special variable names? can't you infer variable kinds (array / fn / monadic operator / dyadic operator) from first assignment?
 
@ngn How do you write variadic functions in K?
 
@ngn Probably. It was my first parser ever written, I lack some theoretical background..
 
ngn
10:48 AM
@Adám what do you mean? i don't think it has such a thing
 
@ngn A benefit is that any snippet of code can be analysed without context.
 
@ngn why is your K a secret? Do you use it professionally?
 
@ngn E.g. f[3;2] and f[2] are both valid calls.
 
@Adám If you need this, why not just pass a list?
 
@ktye Why have multi-arg functions at all?
 
10:52 AM
@Adám I have only 1 or 2. No niladics either. iv also lacks ⍬.
 
@ktye So f←{a←0 ⋄ ⍺-⍵} isn't valid (as a cover for -).
 
ngn
@ktye no, i'm a hobbyist, i don't make money from k. at this stage i don't see what i would gain from publishing it - most people i've talked to simply don't appreciate the significance of a small fast half-apl half-lisp. also, my source looks horrible
 
@ngn Is it in C or should I say cpp?
 
ngn
@ktye just c, and since i never learned c properly, it's whatever works in clang on x64
not any particular standard of c
 
@ngn I meant the preprocessor, not c++
f
 
ngn
10:57 AM
@ktye ah... i make heavy use of macros, yes :)
 
@ngn maybe you rethink about publishing it. if people are not interested, they won't notice anyway
@Adám you mean: f←{⍺←0 ⋄ ⍺-⍵} (with alpha), that works
 
@ktye Yes, that. But not f←{⍺←⊢ ⋄ ⍺×⍵} (as a cover for ×) I gather.
 
@Adám No alpha and omega can only be nouns
 
@ktye Any way for a dfn to detect if it has a left arg or not?
 
@Adám I dont think so, but it should not be too complicated to add. But it does have tail recursion as opposed to go.
@Adám Has it ever been considered, to add "fallthrough" to dfns? So that multiple branches can be executed like in a case expr?
 
11:13 AM
@ktye No, that's not what they are intended for. If you want structured programming, use tradfns.
@ktye … although you can of course construct it out of multiple nested dfns — it just looks strange (imho).
 fb←{
     {
         ⍝ code after case
         'Answer is: ',⍵
     }{
         0=15|⍵:'FizzBuzz'
         0=5|⍵:'Buzz'
         0=3|⍵:'Fizz'
         '(nothing)'
     }{
         ⍝ code before case
         ⊃⍵
     }⍵
 }
 
ngn
@Adám "code before case" doesn't have to be a separate dfn
 
@ngn Neither does the code after. In this case. I was just illustrating the general pattern. However, if you need several branches there too, then it does need to be.
 
ngn
@Adám for "after" you'd have to repeat it at the end of each case, so a separate dfn makes sense
 
@ngn Sure, but I maybe the before is also a multi-branch.
 
ngn
@Adám if it's multi-branch we would be in one particular branch from it :)
 
11:26 AM
@ngn No, I meant that the middle dfn takes over after all the branches of the before dfn, and the after dfn takes over after all the branches before it.
 
ngn
@Adám yeah, pity dfns have only "if-return" (guards) and no plain "if"
 
@ngn They sure would have been more versatile if they would continue after a guard if the expression after : was an assignment. But where should they continue? With the very next statement?
 
ngn
@Adám they wouldn't be called "guards" then
 
@ngn Is "guard" a well-defined word in FP or something?
 
ngn
@Adám a guard is someone who might not let you go past a certain point
 
11:32 AM
@ngn or someone who lets you in. You can also go back out to the next gate.
 
@ngn OK, you could call cond:exp a guard, and cond:name←exp a conditional or something.
 
ngn
@ktye exactly. what Adam is describing is someone who tells you to go down one of two possible paths, and then the two paths merge
@Adám an "if" :)
 
@ngn Maybe I add this, continue with the next guard if there is an assignment.
@ngn At least I don't have to worry about a large user base I could break ;)
 
@ktye Also consider continuing after an unguarded dfn expression, even if there is not assignment. E.g. {2 ⋄ 3} should return 3, not 2.
@ktye That's the reason for "big APLs"' quirks: Backwards compatibility.
I find it pretty cool that most half-century old APL code can run in modern interpreters with no modification, and if anything needs to be changed, it is trivial.
 
ngn
@ktye i can relate :) but i think you should be careful - early design decisions tend to have profound consequences if/when your language becomes popular
 
11:39 AM
@Adám not sure. This could shadow errors. currently I have an "unreachable brach" error message
 
@ktye Well, if you plan to abuse dfns for non-functional stuff, then ability to have side effects without hoop-jumping is nice.
 
@Adám I have to abuse them, as I don't have tradfns
 
@ktye My point exactly.
 
ngn
@Adám backwards compatibility = perpetuating early mistakes
 
@ngn backwards compatibility = perpetuating early mistakes and paying salaries
 
ngn
11:43 AM
@Adám in dyalog's case, maybe
that's basically what you're paid to do - not break existing code
but the cost of maintaining this is enormous. a single person can't deal with it
 
@ngn I prefer the thow away and start from scratch approach
 
ngn
@ktye me too. have you watched this?
 
@ngn not yet. will do.
@ngn I think I might have considered K if it had APL symbols. I'm curious about the next version.
 
 
1 hour later…
ngn
1:24 PM
@ktye how do you compile iv? (i'm totally unfamiliar with go)
 
do you have go installed?
 
ngn
@ktye yes - go1.7.4 if that's recent enough
 
create a directory, say ~/tmp/go
set GOPATH to it, then run
go get github.com/ktye/iv/cmd/apl
@ngn It could be too old. If it complains about strings.Builder then you need at least go1.10
 
ngn
@ktye thanks. you guessed right :)
 
You can also run the test cases like that:
cd ~/tmp/go/src/github.com/ktye/iv/apl/primitives
go test
 
ngn
1:32 PM
@ktye it worked! thanks
 
@ngn There is also a not so simple version cmd/lui, that contains a graphical user interface, a sam text editor and a virtual file system. But it's very recent.
 
ngn
@ktye i'm interested in the programming language. i already have a file system and favourite text editor :)
 
That's good for you. I work on windows and at work the files have too long names. That's why I wrote the per-session file system.
In apl I mount the current working directory to root with
/m./
 
ngn
@ktye ⍉`a`b#1 2 ⍝ wow!
 
@ngn @ktye What are ` and # about?
 
1:40 PM
@Adám It's similar to K symbols (strings)
 
@ktye And #?
 
Actually I have 3 ways to parse strings:
'abc' => same as apl results in a vector containing 3 strings "a" "b" "c"
"abc" => a single string (atom)
`abc => short form
` does not end when an apl symbol starts.
I did it because I want to be able to write paths like that `/file/to/path
@Adám This creates a dict. The syntax is very similar to K's
 
@ktye And do you have a way to package a character vector into an atomic string, and unpack an atomic string into a vector?
@ktye OK.
 
@Adám to be honest, I don't know. I'm not too familiar with it.
 
@ktye With what? This is new, for APL at least.
@ngn How about in K? Can you do charvec←→symbol?
 
ngn
1:45 PM
@Adám yes, with $
 
Do any operations work on symbols, other than structural ones, of course?
 
@Adám ⊂'abc' this works as string catenation
 
ngn
@Adám what operations do you have in mind?
 
@ngn Like getting the number of characters, or concatenation.
 
ngn
@Adám a symbol is an atom, so #`abc is 1
concatenation works as usual for atoms (i.e. scalars)
 
1:49 PM
@ktye Oh, so because you don't support generalised nested arrays, you repurposed to create a symbol from a charvec (and I presume for the opposite).
 
ngn
sorry for multiple pings
 
@ngn OK, so you'd need #$`abc to get 3?
 
ngn
@Adám yes
my "wow" was more for the support for flipdicts, not symbols
 
@ktye Now I want to see Iv on TIO.
 
ngn
 `a`b
a b
 `a , `b
a b
 `a,`b
a, b
@ktye ^ this looks a bit strange
 
1:54 PM
I thought much of the need for nested arrays was, because strings are no atoms.
About TIO: is that complicated to put it there?
@ngn what do you mean?
 
ngn
@ktye the presence of a comma in the last output
 
@ngn yes, back-tick escaped strings go further than in K
 
@ktye No, generally very easy. Just go to the TIO chat room and ask Dennis to do it.
@ktye You can have everything except a space or a backtick in a symbol?
 
ngn
@ktye ah, i see, so the , is literally part of the symbol
 
https://github.com/ktye/iv/blob/master/apl/scan/scan.go#L302
backtick strings stop at '`', '}', ']', ')', ' ', '⋄', '#':
 
ngn
1:58 PM
afaik in the original k they are parsed like identifiers but if you have a colon after the backtick, it's a `:/path/to/file
 
there is also a dyadic version of enclose for strings: L⊂R, it's join:
'x'⊂'abc'
axbxc
 
String is not atom or scalar... It is list... Scalar is 'a' only but ,'a' seems vector even if it print as scalar... There would be need one function for display the type...
for see what happens...
 
ngn
@ktye another wow for getting this right:
 
I mean above vector == array == list
 
ngn
 (`a`b#1 2)+`b`c#3 4
a: 1
b: 5
c: 4
it doesn't work properly with × though
 
2:06 PM
@RosLuP In regular APL, sure. But ktye has made his own, with some influences from Go and K.
@RosLuP Most major APLs have some incarnation of the traditional DISPLAY function, and Dyalog also ships a tool, ⎕SE.Dyalog.Utils.repObj with will give you an expression that evaluates to the argument.
 
@ngn This is strange. Does not look right.
 
@ngn Huh, that's neat. Why can't we have that for namespaces?
 
ngn
@ktye anyway, that's not really significant
i am disappointed with this, however:
 D←E←`a`b`c#1 2 3
 D[`b]←4
 D
a: 1
b: 4
c: 3
 E
a: 1
b: 4
c: 3
 
@ngn What happens if there are symbols with data outside the domain of the applied function?
 
ngn
@ktye you made the same mistake as dyalog - dictionaries (namespaces) are mutable
 
2:10 PM
Ah, Iv dictionaries are pass-by-reference instead of pass-by-value.
 
@ngn there are some open issues about copying...
 
ngn
@ktye yeah, i noticed that in the readme
 
it's not like that by design. It's just not bug-free.
There are more issues when using operators that copy anything that is not a pure number.
what should an implementation of a primitive function assume?
Can it modify it's input argument (that the caller has to copy), or should it copy if it modifies?
 
ngn
@ktye sure. it's important to get the design right. bugs are bugs and ultimately get fixed. well, unless you're locked into perpetual backwards compatibility, hehe :)
@ktye that's probably the hardest part of implementing efficient array languages - refcounting
 
@ngn is there a general agreed method? or do you just have to figure out how to do it right?
 
ngn
2:18 PM
@ktye well, if you can figure out a more efficient way to do it, that would be most awesome, but what most impls do is maintain a "reference count" for each object - a counter for how many other objects point to it
when you create a pointer to something, you increment its refcount. when you destroy a pointer, you decrement it and free() it if it's dropped to 0
 
@ngn do you mean for garbage collection?
 
ngn
when amending an object, for instance with a[i]+←b you can reuse a's memory as along as its refcount is 1 (or 0, depending on how you count)
@ktye instant gc is one of the uses of refcounting
ideally, your object graph mustn't contain loops
(terminology note: by "garbage collection" many people mean "mark-and-sweep garbage collection". they don't consider "refcounting" to be "garbage collection")
 
@ngn yes, gc is done by the go runtime. If I can overwrite the memory, I have to decide.
 
ngn
@ktye does go have a way to tell how many objects point to a given object? (i expect not)
 
@ngn I think you're being way too harsh on Dyalog. Pass-by-ref is sensible for OO, and OO-based GUI. It it wasn't for ⎕WC (which grew into today's Dyalog OO), there would be no Dyalog today, and APL would probably be all dead and forgotten too.
 
2:27 PM
maybe in the runtime package. https://golang.org/pkg/runtime
But I think the implementation of the go gc is not garanteed. It was changed in the past.
 
ngn
@Adám well, it's your product, you (dyalog) have to maintain it. i'd much rather not have to deal with cycles in the object graph
 
@ngn Of course, of course. We all agree that that OO is nasty, but it saved APL's skin. You probably wouldn't even have known about APL if it wasn't for those ref cycles!
 
ngn
@Adám why would value semantics contradict OO?
 
@ngn how would you prefer GUI/user interaction to be done immutably? all quads?
 
ngn
@dzaima do you have a specific example?
 
2:31 PM
@ngn nope, i don't know anything about dyalogs OOP :P
 
ngn
you already have mutability in the variables - you can give them new values
there's no need for the values to be mutable too
 
@ngn how would variables link to the OS/whatever? do I just tell it to constantly read a specific variable?
 
ngn
@dzaima for example an input field displaying a value?
maybe i'm missing something... i just don't understand what the problem is
in any case, @Adám if your argument about OO and GUIs is true, then why not have arrays with reference semantics (like namespaces) too?
 
@ngn say I have a variable button. How would I add the button somewhere so that after button.text ← 'hi' the buttons text updates?
@ngn having options is nice
an APL with both mutable & immutable arrays & dictionaries would be interesting (though probably very hard to use and not very APLy)
 
ngn
@dzaima that sounds like a question about event handling, not reference-vs-value semantics
 
2:42 PM
@ngn ok, button.setText 'hi'
 
ngn
@dzaima so you can just do button.text←'hi' and call redraw or whatever
 
@ngn so i would tell redraw to look at the variable named button?
 
ngn
@dzaima i don't know how to argue about this. there are many ways a UI can be implemented
ultimately some ui component must know where to get its data from
 
@ngn and having pass-by-reference is a nice way to do that
completely hypothetical syntax - e.g. w ← ⎕newWindow⍬ ⋄ b ← ⎕newButton⍬ ⋄ w.add b ⋄ b.setText 'hi' ⋄ ⎕openWindow w wouldn't work, as b was modified after it's been added to the window, which imo isn't nice
if i wanted to change the buttons text later I'd either have to have told w.add some reference name just so i'd be able to do w.b.setText '...' (which feels like just trying to get around the issue of no references), or recreate the whole structure from scratch (which is horribly inefficient)
 
ngn
@dzaima i was imagining b.setTextSource 'variableName'?
where variableName could be a path like dict.key1.key2.key3
 
2:54 PM
@ngn IMO passing variables by string representation of name is just very very horrible and very much trying to force around the problem of no references, but that's just my opinion
what if I wanted to create n buttons? would I have to dynamically create n different variables?
it also allows me to delete the variable dict before it's properly used, which forces the drawing mechanism to do non-existence checks everywhere, while it could just have them at the adding time
 
ngn
@dzaima i don't want to go as far as designing a ui api to prove this point, but you could generalise this by having an expression as the text
@dzaima for what price though? mark-and-sweep gc...
 
for an immutable-dict-based GUI it'd be quite a challenge to make ⎕draw w not redraw the whole window & everything every time but just the parts that have changed too, while a ref-based one wouldn't even have to touch the whole window object when a buttons text has changed
@ngn it's all compromises everywhere
 
ngn
3:18 PM
@ktye well, if you're comfortable with mutability, you could just do nothing. if you insist on value semantics (like me), you could always make a copy of the dict for now, and worry about implementing your own refcounting later
 
For dicts and tables, the plan was value semantics. Current behaviour is a bug. But I have references also, when dealing with pointers to go structs, e.g.
The definition of the type can decide, what it should be.
 
i'm wondering, what's the general use-case of k-style dicts, if they're pretty much as good as 2 lists?
 
3:42 PM
@dzaima You have to keep them in sync. I like it how they represent a single row of a table. I plan to use dicts to build property dialogs in a user interface, and tables to keep a list of those.
 
ngn
4:17 PM
@dzaima what ktye said, and they are also used to represent the "k-tree" - a hierarchical structure of contexts in which variables/functions live. you can write a.b.c to access a path in that tree, equivalent to a[`b][`c] or a[`b;`c] or (if dicts were just pairs of lists) some complicated expression involving x?y and x@y lookups (⍺⍳⍵ and ⍵⊃⍺ in apl)
 

« first day (739 days earlier)      last day (1933 days later) »