« first day (854 days earlier)      last day (681 days later) » 

12:55 AM
@ngn " "?2 is segfaulting
 
ngn
1:22 AM
@Traws fixed, thanks
 
 
2 hours later…
2:56 AM
@ngn you have a Unicode version of ngn/k?
 
ngn
@Razetime no
 
@ngn I find pre simpler to use
 
ngn
@Razetime i mean, you can use single unicode characters as identifiers, but that's more like an experiment
 
Oh. No wonder
 
2:58 AM
So where is golf.k located
 
ngn
k itself doesn't understand unicode. identifiers can be only /[A-Za-z][A-Za-z0-9]*/
strings can contain utf8 sequences but indexing sees them as individual bytes
 
3:20 AM
so it's a compartmentalized special feature
 
ngn
3:34 AM
@Razetime did you see my amateur attempt to make an infobox in the wiki? :)
 
3:44 AM
not yet
need to see the recent changes
I like it
 
ngn
thanks :) it's just html, i didn't import any templates from wikipedia
 
i think leaving it borderless seems fine
maybe we can add an added in label
 
ngn
or "supported in" and "not supported in"
 
yeah that'smore comprehensive
 
ngn
@Razetime in k features are often added and removed
unlike in apl :)
 
3:52 AM
haha
alright who's adding it
 
ngn
what should it look like?
most infoboxes i've seen in wikipedia have something like a table below the image (or the big black rectangle in our case)
 
it should be a borderless table, 2 rows 2 cols
also pure black(#000) is unrecommended most for backgrounds, would change that to #111 or #222
 
ngn
it looks too narrow, or maybe we should shorten "(not) supported in"
@Razetime what's wrong with #000? it's my favourite shade of black
black on white is also an option
there's a "dark mode" for the whole wiki which inverts all colours for those of us who prefer that
 
@ngn it's a UX design related thing
which is why even in dark themes you rarely find pure black
it's always a colored black or saturated
 
ngn
@Razetime i think that's false. low contrast causes more strain
 
4:04 AM
very low contrast does cause strain
honestly the argument only applies to pitch black anyway
@ngn for this, probably make all cols 50% of bounding box and then increase the size of the infobox
 
ngn
better?
(the black is #111)
 
yep, better
is the width a % value
 
ngn
now how do i make a row disappear when the corresponding paramater is absent
@Razetime no, i looked at a few random infoboxes in wikipedia and they don't do that
 
mmkay
 
ngn
4:19 AM
generally the second column is supposed to contain more information
 
0
Q: Hide label if there are no parameters set in template. (Parser functions)

Michael BuiI have an infobox like this {{Infobox |name = {{{name}}} |status = {{{status}}} |- |! style="text-align:center; color:white; font-size:1.4em; line-height:1.3em; background:#827f75" colspan="2" {{!}}Contacts |- {{#if:{{{Person1|}}}| {{!}} Person1 {{!}} {{{Person1}}} |- {{#if:{{{Person2|}}}| {{!...

 
ngn
@Razetime exactly what i needed, thanks :)
 
ngn
4:35 AM
not too bad
 
does the image require a caption
ah, it's a real-life odometer.
 
if you want more material for "shape" you could include the nifty implementation I discovered a while back (with the caveat that it only works if a structure is rectangular):

-1_#:'*:\
 
ngn
@Razetime i'm not sure, maybe it would be nicer
@JohnE it's a wiki, you can edit too
 
@ngn added one
 
4:54 AM
@ngn pressing enter on an empty line in ngn/k online repl gives an error
 
ngn
@Razetime huh. thanks, i'll investigate tomorrow
 
 
2 hours later…
6:29 AM
@ngn odometer, looks like k's version of the typeball
 
 
2 hours later…
8:16 AM
@ktye is the prototype of a given value the default falsy value for it?
 
8:38 AM
It's not the value per se, though the first element of the prototype will be the default falsely value
So if we take a zero-length list of four letter chars:
 
ok whats the prototype
porbably need a definition for that in a wiki page
 
 s:0#("well";"then")
 s
0#,"    "
 *s
"    "
@Razetime different dialects have different setups
 
no general definition?
 
Afaik k7 was the first k to have multi-dimensional prototypes
In short, lists store information about the kind of elements they hold, including shape and type
This seems pretty good aplwiki.com/wiki/Prototype
 
whats 0n and 0N
i know they are falsy
but that is about it
 
8:50 AM
Null for float and int respectively
 
alright
 
Apropos of nothing: I don't like flip doing an auto-take as a padder
Would much rather 0 or nulls
@Razetime you might find some of this material useful gist.github.com/chrispsn/b1020918a83a28ab8b4442d8aff8d1b4
Using where to implement range makes me laugh
&~&7 for example
 
9:39 AM
@chrispsn good learning resource
 
10:16 AM
@ngn working on making deep where support dicts
hmm needs more work for a keytable
 
 
2 hours later…
12:38 PM
@Razetime I don't think k9 has nulls, so its prototypes are more typical "falsey" values. Most other k's (at least k4-k6) have nulls as the prototypes, which aren't strictly "falsey", but can be tested for using ^x and "filled" with x(atom)^y. There are different nulls for each datatype; if there are separate integer widths, or things like date/time formats, there can end up being a lot
@chrispsn I've come to the same conclusion. the only issue I see with having it fill with something else is the impact on initializing tables. if you have a dict, with some keys having lists of values and others just scalars (perhaps because it's shorter when typing it out), flipping it into a table will broadcast any scalars to all rows of the table
the alternative, which also exists when initializing empty string columns, is annoying (something like (#tbl)#,"")
 
1:09 PM
@ngn I've found another inconvenient ? find edge case; e.g. ()?"e" or ()?"abc". ideally it would just do a flat lookup and return a 0N for each item of y
 
@coltim yes, scalars should broadcast.
@coltim could be part of why () is empty list of strings in k7/9
 
ngn
@Razetime fixed
 
@chrispsn so something like +(1;1 2;1 2 3) would become (1 1 1;1 2 2;1 0N 3)?
 
@coltim 100%
I like k9-style null as zero but maybe 0N is more natural in k6-style dialects
 
ngn
1:24 PM
@coltim i'd rather implement prototypes than introduce such a special case
 
@chrispsn hmm, that could work. I don't think there are many "organically created" lists containing both atoms and lists (maybe from some primitives that return both atoms and scalars, but that's pretty contrived)
@ngn ok my attempt at a more sound rationale: it's a base case, especially given the ambiguity around how nested () is
 
ngn
with prototypes there would be no ambiguity
 
would all ops "pass through" the prototypes if they would be a no-op on it? some operations can change the types, given their ranges (e.g. <x(list) always returns an integer list)
 
ngn
@coltim <() returns !0 even now
 
@ngn hmm. I'm likely just missing the bigger picture here. in my experience, when there's a chain of functions and a () or other empty/edge-casey type value gets generated early on in the chain, some ops are OK with it and others aren't (error'ing out somewhere downstream)
 
ngn
1:41 PM
@coltim most primitives should work fine. the big problem is "each on empty"
if you have f'empty the interpreter would have to either just return empty with whatever prototype it already has (which may be wrong) or try to deduce it from f somehow
for instance now #'() is !0 but {#x}'() is () because the interpreter is not clever enough to figure out that {#x} always returns ints
 
would prototypes resolve that issue?
 
ngn
no
apl has the same issue and they solved it in the worst possible way
 
hmm do I want to know? =P
 
ngn
each on empty calls the operand function once, just to see what the result is
 
hum
I mean in practice I think what I'm grasping for is essentially "try this line of execution, and if stuff fails, just bubble the failing value up to the end" for empty lists
 
1:49 PM
@ngn could the interpreter do some magic rewriting of lambdas into tacit form?
 
like a (::) but as an empty list
 
ngn
@chrispsn it only needs to determine the structure of the result
but even that is hard enough..
in practice, if you're doing each-empty and want the result to be of a particular type or prototype, you can always catenate an explicit empty array
e.g. ({#x}'()),!0
 
@ngn does emptyList1 , emptyList2 always return an empty list of type emptyList2?
 
ngn
@coltim in my impl, yes
would it be better to make it the left one?
(!0), looks slightly better than ( .. ),!0
 
2:05 PM
hmm, I guess the concept of which is the "original" value is kinda vague when it's dealing with empty lists
 
2:44 PM
type inference for a k-like language wouldn't be that bad, I think, since the types are fixed and non-extensible. There's just a lot of cases where definitions are so general there aren't any constraints you can infer from the structure of expressions
at one point I pitched the idea of optional type annotations on lambda arguments, with a concise syntax, to arthur, with the idea that if you grounded a few types you could JIT hot functions quite simply, melting all the rank-agnostic stuff into specific fixed loops. K leaves a bit of performance on the table wrt. loop fusion
might be too complicated to pay for itself though
 
 
2 hours later…
5:10 PM
@coltim I think this also crops up when looking up a key in an empty dictionary (at least where the keys are () versus a typed empty list), e.g. (()!0)@`Jimmy
 
 
5 hours later…
9:52 PM
@JohnE a lower-level k is an interesting concept (e.g. some level of explicit typing, maybe some kind of vector loop syntax - iterating over chunks of a large array, etc etc)
@ngn would you be interested in test versions of my golfs?
 
ngn
@coltim of course!
 
@ngn ok well I have them, not sure how to send them over (I created a codeberg account)
 
@coltim I don't even think it would be necessary to change/extend the semantics of the language. It's just that type- and rank- polymorphism imply a fair degree of runtime complexity and dispatch that could be totally avoided if you could, in bounded contexts, provide assertions like "this argument is always a flat float vector", etc
 
ngn
@coltim i've never used it, but i think codeberg has a pull request mechanism similar to github
 
@JohnE I had a lot of fun going from python => numpy => cython => C, it was a nice/useful gradient of flexibility vs. raw performance
 
9:59 PM
if you add some constraints to the inputs of a lambda it can be enough to crystallize all the types flowing through it, and then you can perform some simple optimizations
 
@ngn on your repo the "New Pull Request" button is disabled (maybe I need to be added to it? or some setting needs to be flipped?)
@JohnE have you been following what @dzaima and @marshall have been working on with BQN? they're doing some JIT stuff I believe
 
nope; I've been busy
 
ngn
@coltim idk.. this is ticked^
i'll try adding you as collaborator to see what happens
@coltim is "new pull request" enabled now?
maybe you have to commit and push something to your cloned repo first
 
@coltim the JIT stuff currently in CBQN is just lame mostly-constant code generation for each bytecode instruction. Soon are some plans for some scalar optimizations (going the JS-like route of assuming arguments are of a certain type and falling back to interpreter on unexpected arguments). Loop fusion is something for a very far future (there are barely even any vectorized builtin impls currently!).
 
needing to fall back when you aren't on a happy path is exactly what optional types could help avoid
make a typed lambda, compile it at parse time, perform the type assertions when you call the lambda, and either it's hella fast or you get a type error at invocation time
 
10:11 PM
yeah, type markers would of course be good in general, as long as you're fine with not checking them at runtime
 
general loop fusion can get hairy, but imo you could get a lot of mileage out of just fusing across conforming applications and the eaches
 
verifying type markers at runtime is exactly as slow as verifying expected types (except with startup time i guess)
 
lift the sequence of vectorized ops into a single loop body. It's a fairly straightforward AST fold
@dzaima only on entry to the lambda, though- that's the point. you put your hot code inside the lambda and within it, no runtime dispatch would be required
 
@JohnE but then you need to dynamically compile that loop body to vectorized instructions, with correct overflow checks depending on language guarantees
 
I think you're really imagining something different than I am describing
 
10:15 PM
@JohnE still don't quite get how that's different. Manual type markers any dynamically generated type markers should be precisely the same, no?
@JohnE how I understand it, you're saying something like a×b+c{(⍵⊃a)×(⍵⊃b)+(⍵⊃c)}¨⍳n. Which isn't at all beneficial if × and + are implemented with vectorized loops, and the ¨ is not
 
explicit type markers can constrain the types sufficiently for codegen at parse time. A lambda like {x+y*z} requires dynamic dispatch for * and +. If you know x,y, and z are conformable vectors of floats, you have enough information to generate a vectorized loop without dynamic dispatch.
 
@JohnE but the runtime interpreter could see on the first call of the lambda that x,y,z are conformable float arrays, and just act like type markers were there in the first place (but instead of erroring when they don't match, you deoptimize instead)
 
but then you'd have to perform the analysis and codegen on every call!
or as you say otherwise use a fallback implementation
 
you'd "cache" the generated code of course
 
sure, you can memoize over the type signature, but then you need to track usage to decide when a path is hot enough to optimize, etc, etc
 
10:24 PM
generating loop fusion code shouldn't be too expensive, for large enough arrays you could just always do it. In practice, most type variance you'd have would just be 8/16/32-bit ints
 
explicitly "fixing" subgraphs of a program gives a programmer control over the mechanism. There'd be sharp corners, but the implementation would stay relatively simple.
 
@ngn yeh I think that was it. PR opened!
 
@JohnE if you have ideas for nice type markers, I'd be open to hearing your thoughts though. All I'm saying is that they "just" simplify the implementation and decrease the startup time by a bit, hot loops would look pretty much the same for optimistic optimization of regular code
I personally would by far prefer type markers to dynamically generated assumptions, if they were sanely actually usable.
 
ngn
@coltim merged. thanks a lot! it must have been a lot of work to collect them and convert them to the required format
 
@dzaima (hard part with type markers is that in impls that don't allow the user to distinguish 8/16/32-bit arrays you still need to dynamically dispatch anyways)
 
10:42 PM
@ngn a lot of it was mindless, and the rest was fun =P
 

« first day (854 days earlier)      last day (681 days later) »