HackerLangs
TopNewTrendsCommentsPastAskShowJobs

dzaima

1,669 karmajoined 7 năm trước
https://github.com/dzaima/

https://codeberg.org/dzaima/

comments

dzaima
·5 giờ trước·discuss
Rather depends on definitions; GPL does contain:

> The "source code" for a work means the preferred form of the work for making modifications to it.

With that definition, there's definitely space for arguing that the AI tooling for modifying the code is necessary for the modification process to be sane therefore "preferable" for any human, if the code is "designed" (or lack of design thereof) around the idea of being AI-maintained.

Otherwise, it's not source-code, it's not meaningfully-modifiable, it's basically equivalent to just decompiling a binary. (similarly-bad quality may of course be human-produced too, though then at least you have direct proof of it being the preferred form for at least one person - the author)
dzaima
·3 ngày trước·discuss
FYI, your "8‿64 •bit._cast -⟜@ raw" in bqn/util.bqn results in passing to •bit._cast integers in the range 0..255, whereas it expects integers ¯128..127 (and does arbitrary platform-specific things on integers outside that for the int16→int8 narrow); removing the "-⟜@" makes it work properly, and 2.5-5x faster while at it from not going to intermediate int16 (allowing the bitcast to be O(1) by itself). (•FBytes → •file.MapBytes also probably improves things, at the cost of the obvious mmap problem of issues if the file changes, as BQNs arrays are immutable). This is also what caused the problem at https://github.com/ClickHouse/ClickBench/pull/939/changes/40... (there's been some discussion about what to do about invalid •bit._cast before, considering it's rather perf-sensitive; it's the only place in CBQN with such quiet very-wrong results on invalid inputs)

The default CBQN "make o3" on x86-64 also results in it only using SSE2 (utilizing function multiversioning is on the ever-infinite TODO list, though somewhat-low on it considering it's strictly-unnecessary in any specific situation; there's also AVX-512 usage on a branch, but mostly only AVX2 on mainline; and no arm SVE)

That all said, CBQN doesn't currently do any loop fusion, so being significantly-slower for sequences of operations over larger-than-cache arrays would kinda just be expected. BQN also just isn't particularly intended for database work anyway.

(didn't look much at the specific query impls, though "Pair" in utils.bqn is at least an overlong version of "Pair ← ⋈¨"; and some if not all of those Pairs would be better as "≍˘" to avoid nested arrays and ensuing pointer chasing; and, of course, if some of the columns are bools/int8/int16/int32, it'd be beneficial to store & load them as such instead of float64)
dzaima
·5 ngày trước·discuss
Perhaps some early things in the pipeline could be easier with a saner language, but I can't imagine it affecting much of the core optimizations, which'd all benefit from being ran on some messy low-level intermediate form equivalent to what C converts to anyway (if not more complex if preserving precise aliasing info). Would be curious to hear about that external visibility thing, doesn't feel like it could make optimizations (beyond inlining, perhaps?) harder.
dzaima
·5 ngày trước·discuss
Formal proofs for specific instruction sequence substitution (e.g. LLVM's instcombine) are simple-ish enough via just throwing SMT at it, ...as long as the source pattern and target replacement are in a format from which both the compiler code and verification source+target can be automatically derived from; though you'd still need manual proofs for anything with unbounded configurations that can't be exhaustively checked if you aren't satisfied with just checking some subset.

Larger-scale things operating over an unbounded amount of instructions require significant amounts of effort of verification on each pass. CompCert apparently has 1200LoC of proving DCE, one of the simplest whole-function passes - https://github.com/AbsInt/CompCert/blob/02fc017cf69210db5fd5...
dzaima
·6 ngày trước·discuss
..except, if you want to add logging/metrics/other logic, it's quite possible you'll want it to be conditional on the boolean anyway, bringing branching back, now mixed with the non-branching code.

And even if you don't need to keep an if statement in mind, you still need to keep the variable in mind anyway.
dzaima
·9 ngày trước·discuss
Note that glibc does provide a malloc_usable_size to query the size of a malloc'd block; not standard though of course.

A problem with just directly exposing such is it makes precise sanitizing impossible, as you'd have to tolerate some out-of-intended-bounds reads/writes. (and making the sanitizer always give exact-size allocations would also be bad as that'd end up not testing code paths that may break when they're not)
dzaima
·10 ngày trước·discuss
Not that I know of; and such would necessarily have false-positives (...or, rather, entirely consist of potential false-positives) because you may actually want the re-read.
dzaima
·10 ngày trước·discuss
The crappiness of shrink-wrapping in gcc and clang (but especially clang) annoys me a lot. It feels like there should be a quite decent amount of general performance to be gained from properly pushing more into slow paths (or, not necessarily even slow paths, but generally paths with high register pressure / uninlined function calls), never mind calling conventions in general.

On the push impl in the article - for non-x86 (and perhaps even on x86 for performance, though not size/instruction count) it'd be better to allow the size increment to reuse the size read done by the capacity check; with C++'s lack of suitable aliasing information, the interleaved memcpy/store prevents the compiler from deciding this itself.
dzaima
·11 ngày trước·discuss
Ampere Altra is for cloud/datacenters/servers where multithreaded throughput is approximately all that matters. Apple M series is for consumers.
dzaima
·11 ngày trước·discuss
That'd only help for one object per address space. Main thing needing relocation - shared libraries - needs arbitrarily-many segment bases.

And when you're not a library, relocation is just a mild probabalistic security improvement (...that'd be massively-more bypassable than it already is if the program was littered full of gadgets of "read register as unrelocated offset and use it with its correct base" instructions).
dzaima
·11 ngày trước·discuss
OP links you to POSIX explicitly denoting it being implementation-defined - https://pubs.opengroup.org/onlinepubs/9699919799/utilities/e..., and https://pubs.opengroup.org/onlinepubs/9699919799/utilities/e... literally says "It is not possible to use echo portably across all POSIX systems unless [specific setup]"

Interestingly, that doesn't allow implementation-defined behavior for "echo -e", for which bash does have special behavior.
dzaima
·12 ngày trước·discuss
ECMAScript has a pretty massive amount of fully-specified behavior though; the things that differ between those implementations is nearly-entirely limited to fresh additions like `require` or whatever.

The echo thing would be like if ECMAScript allowed stuff like `"123" == 123` to give either false or true; and then indeed many things would probably break if moved across implementations.

C is the closer comparison, and indeed much software that could easily be portable (and might claim it is) often depends on implementation-specific things like 8-bit bytes, 32-bit int, assuming int8_t/etc in stdint.h exist, twos complement (before C23 at least), arithmetic shift right, etc.
dzaima
·12 ngày trước·discuss
That seems to be be an entirely-different question - `echo "c:\\new"` still differs in behavior between bash and dash - dash parses backslashes in both the double-quoted string, and then echo does another backslash parsing pass, still printing a newline; whereas bash prints a backslash + n.
dzaima
·tháng trước·discuss
> But this has never been a condition in the FOSS world, as far as I'm aware. I've only ever seen attribution requirements attach to redistribution of source, not usage of the software.

AGPL requires that even users using the software even across a network must be provided with a way to get the license (i.e. attribution) and source. Never mind that LLMs consume the source code instead of "using" the software anyway. (and of course things go more downhill for LLMs for licenses more restrictive than AGPL)

Otherwise, I'd say that, for many, the ideal condition for (copyleft) FOSS would be that anything that utilizes source code in any form also provides said source code and license/attribution. Sometimes that can even extend to outputs of software (and e.g. gcc takes time to explicitly state that its compiled code output does not count as being derived from gcc's code).

> whether training an LLM is redistribution of the underlying code

There's a funky side-note of whether LLM training can even be done on material with improperly-followed licensing; if you don't even have the permission to modify the material (as properly following MIT/GPL/etc would give you), it might be illegal to even tokenize it, never mind use it for training.

> That's literally all LLMs do. That's what tokenization is.

It's clearly not that simple, otherwise "split source into 10-char chunks, reverse that list, reverse it back, join this fun list we've gotten" would be enough to circumvent copyright.

> all you'll see on the LLM side is probability matrices representing correlations between decomposed units of knowledge aggregated across the entire dataset as an integrated whole.

Yeah, you need at least that, tokenization is irrelevant. But jury's out on this one - of course a good chunk is some form of "abstract knowledge", but other parts could be just encoding material in some compressed form (and surely gzipping a source code file doesn't circumvent copyright) that at the very least can apply to weights.

> The only intent ever in play is that of the user. LLMs are just software.

So my split-into-words-and-join-back is valid circumvention of copyright, if the user of some software doing that isn't informed that it's just effectively directly copying material. (I'll grant that perhaps, in such, the accidental-infringer might get a smaller penalty and/or get to defer punishment to whoever mismarketed the software to them,...but that wouldn't apply to anyone who knows that LLMs are very much just directly trained on copyrighted material. Don't know about legally derived, but surely mathematically derived)

Never mind that, for some things, learning some specific copyrighted code is the desired thing (humans do do this after all!), at which point at the very least the weights of the model are as copyright-infused as a gzipped source code file is.

If intent determination is on the user, and the user is aware that LLMs are very much technically capable of producing copyrighted works to some extent (which they better be), it would be on the user to ensure that any specific code they end up using is not, which is...a rather non-trivial task (a human that writes code can also reasonably-reason about whether they're infringing on whatever they learned from, but splitting into LLM writing + human checking fundamentally makes that basically infeasible).
dzaima
·tháng trước·discuss
> That's simply not correct within the applicable meaning of "derives" as understood in copyright law.

Would be rather hard to write a definition that handles it properly back when LLMs didn't exist; not that laws particularly have anything to do with intent/desires behind FOSS anyway - intent is clearly there: you get code, under the condition that if you use it for anything, I get credited; else, you get nothing.

> In fact, data per se is not even within the scope of copyright protection in the first place: specific published works are copyrighted, but the underlying ideas and facts that they convey are not.

Luckily, FOSS is specific published works, and unless LLMs actually reasonably-provably do such decomposing into ideas/facts (good luck reasoning about that), that part is also irrelevant.

> If you applied the principle you're proposing here to human developers, you'd conclude that any code written by someone who learned to program by studying techniques used in FOSS software would in turn be a derivative work of that software. No one has ever regarded this to be the case.

Depending on intent, that very much can happen, it's called plagiarism. Good luck proving an LLMs intent. (not to mention the obvious differentiating factor of LLMs having arbitrarily-good memory unlike humans)
dzaima
·tháng trước·discuss
Kinda surprised that there's no discussion on that this basically just does not solve the non-canonicality problem.

Forgetting to do the range check on the first_byte==255 case and just letting it do 64-bit wraparound is exactly as much of a plausible bug as missing range checks on LEB128. Any test suite with the goal of covering canonicality will trivially cover both properly; and a programmer that implements things by reading 7 words into the spec, saying "oh yeah I got this" and goes to implement what seems simple, will write a broken version of both.

Perhaps the biggest benefit is just not being associated with a format that tolerates non-canonicality in other places (though, if bijou64 gains traction, it'll only be a matter of time for wraparound-check-less versions to start appearing in places where the wraparound is fine); and I guess also it being less annoying to implement the canonicality check, though hopefully people writing security-sensitive software aren't ones to skip out on correctness checks due to annoyingness.

In a sense, bijou64 could perhaps even be more problematic - it invites not doing any range checks for the smaller inputs because they obviously don't need it, and so you can just forget to special-case the max length case; whereas LEB128 makes you already care about it at the first point it is actually LEB128.

(of course, the format does still have other benefits; enforced canonicality is just...not one of them)
dzaima
·2 tháng trước·discuss
How different people approach workflows is fascinating.

For example, your "not all that different from looking at all (recent) heads" implies that the number of (recent) heads isn't far off from number of (would-be-)branches (i.e. no random offshoot experiments, stashed-away debug sessions; whereas I make many of such continuously (were stashes on git (with occasional grumbles about not being able to stack stashes), regular commits now on jj (maybe with a special-format description, if I bother)));

and that you (even if subconsciously) try to ensure that the head of a branch is always identifiably-representative of the branch (i.e. don't put some random unrelated change at the tip with the idea of "I'll put this in a more proper place when I get back to this").

Effectively, using the full commit graph not as a place where anything potentially-useful can stay, but rather by itself a complete picture, with things not fitting into it going into.. idk, just being abandoned, to be found by looking through the op log? commit IDs saved in an external file? wading through evolog / scanning through `jj show -r xyz/2` etc?
dzaima
·2 tháng trước·discuss
> It is like writing out a plan for what I want to do.

I usually don't have a plan for the end; certainly not what any specific commit would be; sure, I could make one (and either make my future self have to do extra work to figure out what commits with lies in their descriptions actually do, or continuously update the commit message marking what actually exists), but as I said that's basically a waste of time. (if you like comparing with past thoughts, sure, but that's definitely not a necessity for a workflow to be reasonable)

"is/isn't an ancestor of the bookmark" is also just a pretty damn good short-hand for denoting a separation between what's been considered the best attempt at the goal, vs things with known problems or just unrelated to the task.

At the core, this if all of course just a question of workflow; if you go into a thing with a plan, meaningful outlook of a non-vague destination, and without expecting continuous switching back&forth between a dozen other things over the time span the branch is alive, caring less about branches or branch names can perhaps work.

> The first line of a commit message is already a summary of the work done.

But you can't (sanely) use it to reference the branch in a revset, can't find it anywhere other than the full log (that's interleaved and mixed with a bunch of other things that you won't ever need to search for), and actual English just gets in the way for finding it, remembering it, and identifying it in a list.

This alone means that, even if I found interest in massively-ahead-of-time-describing commits, having a sane branch reference is still simply just necessary.
dzaima
·2 tháng trước·discuss
But you probably haven't spent time writing commit messages before a branch is finished. Or, if you have, you've quite potentially just wasted time writing something that will be rewritten anyway as things change; replacing a chore with a much bigger chore.

Restricted and summarized is good - easier to find/remember, less fluff in a list. And easier to recognize a short identifier from a list of the 2-3 most recent branches, than scanning through 50 commits, when trying to remember where some work last was, and which is the proper end-point instead of some failed attempt or unrelated change.

Unnamed branches are quite neat - I certainly have a lot more of such than named ones in jj - but as such named branches are, if anything, more important as a result, for separating sequences of changes striving towards a goal, from the sea of smaller experiments.
dzaima
·2 tháng trước·discuss
In BQN, I've made https://codeberg.org/dzaima/bqn-smt/ (SMT engine bindings, plus various utilities, and a RISC-V & x86 superoptimizer of varying amounts of completeness); ~4KLoC (+1KLoC of tests). Might not fit your "real-world" as I am mostly its only user (and many things are undocumented), but it does have a good amount of non-trivial things aren't necessarily particularly array-y.

Can also look through APL github repos: http://github.com/search?q=language%3Aapl&type=repositories