One of their newer APs has thread radio. That is the best idea anyone has had since the mid 90s.
HN user
bjoli
How is the ipv6 situation these days? I left Ubiquiti 2 years ago because I needed to be able to configure the /56 I got from my isp. The unifi controller was pathetic in what it could do.
if you compile to c# you can use #line directives to get integration with debuggers. it is really simple. for debug builds you can do an ANF pass and generate debugging locations for every different expression.
why doesn't anyone just jump the gun and introduce proper parallelism primitives? SML/NJ got it right in 1991. ocaml5.0 has domains and effect handlers.
why do people still accept CSP? It is simple to do some things in it, bit please just give me concurrentML with "simple" channels for that kind of work , and proper channels for any kind of hard stuff. I have had to write things in go that took me days to get straight that would have been 20 trivial lines in any concurrentML implementation.
if the language specifies all ranges to be the same this matters very little.
if a ranges are inclusive, you get used to it. if it is arbitrary it is awful.
i have made a language that xompiles to c#. I wrote a lexer. then a parser. then a type checker (hindley milner, function local so that top level functions must have type signatures) a match compiler.
the hardest part was what came next: the code generation. despite producing c# instead of MSIL. The features I use are: static and dynamic traits, pattern matching, and a concurrentML.
It is actually quite simple when you don't have to do closure conversion yourself.
the looping facilities in most languages suck. We are at a position where iteration is either "increment or decrement numbers", or "go through this collection". Everything else means degrading performance. In some languages (Python, ruby) the choice is between the comfortable way to iterate through a collection (for a in xyz:), or the fast way (while). It is just stupid.
I would chose typescript over js, Python and perhaps ruby. but I would use Scheme over typescript. I would probably use f# or ocaml over Scheme for most projects.
it is not an either or.
Last week I am #2 in Sweden on StreetComplete, despite using veapucci for about half my edits (my neighborhood is pretty effed up).
AMA I guess
that is one of the reasons async is everywhere. proper threads are not enough. 2 threads are great at doing 2 things at once, but unless you have the hardware 1000 threads scale very badly at doing 1000 dings at once.
with CAS, making a multicore cml is not too hard.
it is like CSP but with first class events. In CSP you have to manage complex protocols yourself, whereas in cml you can compose larger even trees and then do one sync.
a classic example of something that is trivial in cml but requires a mediator in CSP or go is two fibers swapping values atomically where a fiber can pull out at any time. in cml it is about 20 lines of code that can be in a library. it composes with other events.
in csp it is a "server" that manages the swap which means you lose the sectability.
Evert time you want to have any kind of protocol, cml wins.
and you get concurrentML. People get all wet in the pants by the actor model and CSP, but my god CML is much nicer in every way.
I had a weird introduction to programming. I spent my first half year doing php, and them went all in on scheme and sml. Which is nice in many ways, but I do have a hard time accepting many of the completely braindead (subjective opinion, of course) choices of most of the popular languages.
I do think clojure is a pretty nice compromise. Rich has good taste, obviously. Clojure's core.async could be less async and more CML in my taste. Wrapping a simpler async api in cml is easy. Implementing CML on top on core.async is either very hard or full of compromises.
you can implent something like futures on top of cml and use it as async. then you get async for stuff where async is useful and a proper way to write parallel programs for when async would lead to all the bad stuff async leads to.
i rarely write gui stuff and I find async is rarely what I need. in f# I at least have the option to use hopac.
yep. writing on my phone. notoriously bad at proof reading.
It seems like we forgot about lightweight fibers for about 30 years and then collectively rediscovered it in about 2010. sure, Java did green threads, but not like m:n stuff.
I sometimes wonder where we would be now if people would have gone "Wow, mr Reppy! concurrentML is so cool!" in 1993.
instead we got pthreads and collective amnesia and later we got go's girly times and channels which are only half way there.
I administrate my home lab using podman desktop and quadlets. It is one of the few GUIs for what is mostly a cli utility that really adds value.
Edit: Sorry for repeating myself. Still thinking out loud.
I have already started. Not only is the concat faster (which means the derived operations in the rrb tree will be faster), but the derived operations can be done directly since the relaxation is going to be between 16 and 32 elements. A remove will just be a copy 16 out of 17 times.
This will mean that indexing might be slower in the b tree (it will be higher since the fill ratio is lower) part of the tree, and there might be slightly more of the relaxed nodes, but sweet jeebus this is a simplification.
A simplification that makes correctness easier and speeds up all other operations.setting the minimal amount of elements to 24 will still make concat faster, and will make memory waste almost the same (I can use c# inline arrays without feeling too bad).
I have both a fast b+tree and am Rrb tree. Why didn't I think of this before?!
Hmmm. This comment made me think. If you would do a radix tree that degrades to a b+tree, you would get a couple of things. The b+tree concat and subsequently insertions and removal, is faster than the rrb tree one, but yields more relaxed nodes.
If you have a relaxed root, you know the size of every subtree. If the the subtree is dense you can easily calculate the shift, meaning you get dense radix tree subnodes with fast lookup.
This gets you the benefits of a relaxed b tree, but no issues with accidentally having too deep shifts since they are relative to where the dense subtree starts.
This could be done to a rrb tree as well, which would mitigate the issues you are seeing, but would still lead to an arbitrarily deep tree if the concatenation isn't done properly.
The only tradeoff would be slower indexing on relaxed trees because more nodes would end up unbalanced, but at the same time concatenations, insertions and removals would probably be faster.
I will try to implement this.
Edit: no, seriously. This is a splendid idea. The b tree concat is faster than the rrb tree "full" merge. And simpler. And storing the tree subtree height in a byte somewhere means we can go from relaxed to dense and then do a proper radix tree search. (I have one of those rrb tree implementations that probably fails, btw. It has a proper concat, but the improper one is so much faster. I know. I am ashamed.)
This is a persistent ordered map on b+trees.
https://rikspucko.koketteriet.se/bjoli/PersistentMap/src/bra...
that is because many implementations bypass strict rebalancing to squeeze out extra concat performance. And because the strict rebalancing algorithm is awful to implement.
you could also compare
if (a === b && b === c && c === d && d == e)
To scheme's
(= a b c d e)
JavaScript clearly has the upper hand.
Thanks! I havet always been linking to the Collections subdir so I have missed this dumb issue. Will fix next time I use a computer. Might be some time though.
If you have any questions about the trees, feel free to ask.
As I said, i think they have been teaching long enough to have a pretty good basis for the claim that racket's syntax can be a problem.
I am firmly in the "after a while you don't see the parentheses" camp, but I have a friend who I respect a lot who works in clojure (with Emacs/cider/paredit) that just doesn't like it.
I mean, I prefer sexprs above all other syntaxes, and I have had people tell me I just need to get used to indentation syntax or whatever they fancy.
Finally someone uses the rrb tree as their main data structure! I implemented it for c# and the performance tradeoff compared to List<> was smaller than i had thought.
A lot of people hate sexprs. Even seemingly reasonable folks.
I imagined they have met students that really struggle with the syntax, while grokking the concepts easily.
I myself have heard "the parentheses are hard to balance" and "after a while you dont even see the parentheses" enough times that I think maybe both can be correct.
It is hidden by default and when you mouse over it it is so bland that it is hard to see where you are on the page.
I havent used Mac is in a while, so I am not sure about how it is today, but this seems to have been the development everywhere.
Luis Alvarez is really a fascinating character. The whole pyramid thing is not mentioned in the article, but it is also fantastic thing to read about if you are curious about Alvarez.
What has been going on with deepseek recently? I have gotten lots of replies in Chinese and even more frequently, reasoning in Chinese as well.
Is it a new silent update?
A statically typed s-expression language for dotnet (called bjolang. Because I made it), with fast Rrb vectors and champ maps. No object system, but a trait system with associated types. The looping system is inspired by my own hygienic looping system for guile scheme ( https://rikspucko.koketteriet.se/bjoli/goof-loop )
It is really really fun, but I have no idea what I am doing.
I really dislike async and will hast asyncheonisity behind coroutines (which sadly will be botched because dotnet). i will use them to implement concurrentML sometime in the future. Not unlike go, but the will be called bjoroutines and soaened with the "bjo" keyword.
Other than that, it is pretty standard hindley Milner, but with some limitations to make parallel compilation simpler.
Edit: och: and i will make comprehensions general. (summing (in-vec my-vec)) Or (folding #(+ % a b) :for a (in-list aList) :for b (in-generstor a-generator))
To continue on this: info use systemd on most of my systems. I dont mind. But despite having used it for about 14 years, I still have to read the manual of journalctl.
Systemctl is OK, but I really do not like that respect of the utilities.