« first day (266 days earlier)      last day (1269 days later) » 

7:30 PM
i implemented ksql. it turns out to be simpler than using the tetradic forms, which need dicts of expressions.
 
ngn
@ktye example?
 
as well as all the tests in k_test.go starting with :expressions at line 814 to the end
 
ngn
7:46 PM
@ktye select from t where a>2 (:b>1)#t - did you mean (:a>2)#t?
 
@ngn yes. i'll have to read through it again.
 
ngn
i don't understand why they had to introduce expr syntax in k7
 
@ngn i think its only for ksql
 
ngn
they could have been lambdas, treated in a special way by tetradic #
now there are 2 separate syntaxes for user functions, and they don't like each other at all
 
they are very similar to lambdas. there are no arguments, and the locals are predefined as the dict/table keys. you can use the key names directly.
The syntax could have been {a+b+c} as well, that's true.
But in a lambda you have to assign to a variable to make it a local. in an expression this is done outside, when applying.
 
ngn
8:02 PM
@ktye well, i had something like that in mind when i said "treated in a special way"
it's hard to reason about this without knowing the implementational details
it's much easier to criticize exprs on a syntactic level :P
so, exprs don't look like lambdas at all, they look more like assignments, but there was also that crazy json-like dict literal syntax which did look a lot more like a lambda :)
good they backed off from that experiment
 
when i call a lambda, i temporarily remove all global with the name of the locals. then the arguments are assigned and the function evaluated.
calling the expression does it very similar, but uses all dict keys as arguments.
It's line 3346 (lambda) and 3363 (env)
 
ngn
that sounds expensive for performance
 
@ngn do you do anything else?
 
ngn
@ktye yes. i compile to bytecode, so locals are not stored in a dict.
i have an instructions for getting and setting locals. a few of the instructions' bits encode the "slot"
so i never have to look up locals' names from a dict. the locals are stored on the k stack, and i've already resolved their offsets at compile time.
 
8:18 PM
@ngn the "dict" is if you apply an expression to a dict or table.
 
ngn
i don't support exprs and i have no intention of adding them
but if i had to, i'd probably compile them in a similar way
as for globals, i do the slow dict lookup - i haven't optimized them yet, it seems a bit harder
 
at compile time, you do not know if a symbol has to be resolved from the globals or the dict at which it is applied.
 
ngn
@ktye well, generally i do - i know which names are local and which global
 
@ngn but not in an expression, how would you?
 
ngn
@ktye you're right about exprs. i was talking about good old lambdas.
but to "temporarily remove all global with the name of the locals" every time an expr is called - that sounds crazy to me
maybe you can tell apart locals from globals at the beginning of an operation like tetradic #
and then lower the cost per expr calls somehow... idk
 
8:34 PM
maybe. in a group-by, the aggregation expr needs to be applied to each group sequentially, so this could matter.
 
ngn
@ktye isn't the expr applied to each record sequentially, even in a plain "select from t where ..", i.e. expr#t
and all applications are on dicts with the same set of keys
 
@ngn no its a single call with a vector
 
ngn
@ktye hm.. what's the point of # as "select" then?
(:a>2)#t could be t@&t.a>2
 
@ngn in that simple case, it's dyadic take.
https://tio.run/##y9bNS8/7/z/Ryti62kg70apCO7HW8P9/AA
Here a is a local, but predefined from the global. in k7 it's class error.
or you look them up only if uninitialized?
 
ngn
@ktye i'm a bit surprised this works at all :) so, a is read first and then it's assigned, which should make it a local
but the compiler doesn't know until it reaches the a: part, so for the first (right-to-left) a it generates bytecode for a global "get"
 
8:52 PM
@ngn you generate byte code reading right to left, before having fully parsed the lambda?
 
ngn
@ktye no, i parse it first
but it ends up like "right-to-left" while it's really top-to-bottom
top-to-bottom as in traversing the ast to produce bytecode
 

« first day (266 days earlier)      last day (1269 days later) »