Just a pure question: Is Rust allocator global? (Will all heap allocations use the same allocator?)
Just a pure question: Is Rust allocator global? (Will all heap allocations use the same allocator?)
The distinction between is one I've mentally adopted in other languages like Python as well. For personal projects I like to use single quotes for 'symbols' and double quotes for "strings", e.g.:
add_label(text="Hello World!", align='center')
Does anyone else do something similar? $ telnet devnull-as-a-service.com 9
Trying 2001:19f0:6c01:497:5400:ff:fe69:8cbf...
Connection failed: Connection refused
Trying 45.76.95.197...
telnet: Unable to connect to remote host: Connection refusedThe idea is to take some number of inputs A, B, C, ... and conceptually perform all of the possible functions simultaneously, then keep the one that's desired and throw the rest away. For any arbitrary logic. Ideally using fewer operations than all of that, but that's optional. Driven by one variable, it would look like:
// branch version
switch(var1)
{
case 1:
var4 = var2 + var3;
break;
case 2:
var4 = var2 - var3;
break;
case 3:
var4 = var2 * var3;
break;
case 4:
var4 = var2 / var3;
break;
// ...
default:
var4 = 0; // optional and arbitrary
break;
}
// branchless version
var4 = magic(var1, var2, var3);
I don't know how to do this outside of programmable hardware like an FPGA. The problem is that it's extremely challenging to write/solve the formulas that map ordinary arithmetic and bitwise functions to the larger set of functions.So for now, I may just use a switch() command in a shader and let it figure out any reusable logic internally. I don't know if shaders have come far enough to allow that performantly, or if they end up just calculating everything and throwing away the paths not taken. Which would suggest that the max speed would be O(1/N) for the number of cases.
Does anyone know? Maybe truth tables? Or a SAT solver? I'm also not sure how this would work for floating point, but that's optional too.
Edit: I updated the cases to show how var1 controls the math performed on var2, var3 and var4.
var4 = (var1==1)*(var2+var3) | (var1==2)*(var2-var3) | ...
Of course this is basically the slowest possible option, but it might work as a starting point for a general-purpose optimizer to find a faster solution. If it doesn't, this will likely compile to conditional move instructions.It might help if you replace the comparison and multiplication with an equivalent expression made from bitwise operations, but I believe most compilers already know how to do this transformation.
In a lot of logging systems, debug is one of the common levels of logging. I'm not even convinced that the term "debug" is unambiguous to clearly refer to something that's not a subset logging. Presumably the difference is intended to mean things printed that are unconditionally going to stdout rather than into some system that might change the output location and filter/annotate things, but I have to imagine that it might just make more sense not to have separate models for them at all
It already is, kinda. In my practice very often you have global singleton values that are either defined as static variables, or passed as arguments to nearly all functions in a module. Since implicit presence of `Debug` effect is already a compilation parameter, it could be generalized to support any sets of implicit effects. Thus you might design a module that has implicit Logger and Database effects in all its functions.
Logging does seem like a very similar case to debugging, only that you expect to leave it on in production. On the other hand an implicit Database effect kind of defeat the point of an effect system.
I think the key is that Debug and Logger effects don't really affect the rest of the code - if you remove all debug/log statements, the only thing that changes is the debug/log output (and slightly faster execution probably).
If you have the expression 1+2*3 you have three elements with two operands. You need to choose a rule to pick one of them first.
In mathematics, the rule is "*/ then +-" and then from left to right. This means that usually first you do 2*3, then 1+.
But what if you do want to make 1+2 first?
There is another alternative, parenthesis. Those mean "do the thing inside first" so (1+2)*3 changes the precedence and now you do 1+2 first, then *3
The post is asking: with parenthesis you can increase the precedence of operations. What if you could decrease it?
Let's use «» as another operand (the blog uses parenthesis, but that makes it really confusing) this operand means "do the thing inside last". So the expression 1+«2*3» means "do 1+ first, then 2*3.
The issue is...this doesn't make sense, what the blog is really saying is to reduce the precedence of operators. Think the expression 1+2«*»3 or 1+2(*)3 and now the rule is "the parenthesized operators have one precedence less" so 1+2(*)3=(1+2)*3
Reminds me of the '$' operator in Haskell - it lowers the precedence of function application, basically being an opening parenthesis that's implicitly closed at the end of the line.