I made a mini example in C. It's awkward to do get right because you need an indirect pointer whose address remains fixed, but points to another pointer which can change (and is volatile). While it might be possible to…
I think parent was after base+offset+index rather than just base+index. Examples would be eg, `string_view` or `ArraySegment`. They hold some offset relative to a base allocation, and when we index the string_view or…
That's Fat pointers, not Far pointers. A fat pointer is a pointer with some other associated data which is stored in the pointer itself - typically by widening the number of bits used to hold a pointer value. The…
Far pointers are for accessing memory in different segments. They're basically obsolete now. They were necessary in older machines with limited sized pointers or address spaces. GCC still supports `__seg_fs` and…
The poorest in society are the lowest CO2 emitters - they don't fly often, many don't own a car and use public transport - they can't afford meat in every meal. Conversely, the wealthiest are frequent flyers, are…
The FS and GS segment selectors are still used in x86-64, typically for `thread_local` storage, but they can be repurposed. `thread_local` is an example of a "relative pointer" though. Instructions to access the thread…
That's not entirely true, but it's a valid reason to prefer using musttail. `register` is a hint if you don't specify which register you want to use - however, if you specify the register it will clobber it. noinline…
> What practical patterns are enabled by TCO in C? Continuation Passing Style - an important construction for interpreters, but which is also useful for compilers as it's a nice way to do control flow analysis, data…
That may be true, but it may also mean you utilize more memory than you need to. If you aren't shrinking the array when you no longer need previously allocated capacity then you're wasting memory. You could end up with…
I don't think it's that rare. I've been using the technique for years, and I've seen it done in other work. Bagwell's VList[1] for example uses the equivalent of `bit_ceil` to determine the size of each block without…
If you use a struct with a `void*`, you also need to specify the type on usage, where here it's done with `typeof`.
In C23 this approach is nice, but in older versions of C we end up with awful macros where we need to define the structure before we use it. #define Array(T) struct array_##T #define DEFINE_ARRAY(T) struct array_##T {…
The reason the struct is avoided here is so the array can be typed to its element type (rather than casting to and from `void*`). With a struct we would need one struct for each element type - at least prior to C23…
The concept of not storing capacity isn't silly. If you need to reserve space then it's not the appropriate structure, but it's otherwise fine. However, using an 2-element array to avoid using a struct is silly.
Really? It's been done plenty and I thought was quite common knowledge. Some of the <stdbit.h> provided functions are basically for this purpose. stdc_bit_ceil(len) gets the smallest power of 2 not less than len, which…
Bitcoin has a variable width encoding (`CompactSize`), but it doesn't prevent overlong encodings - however there are various canonicalization rules in the Bitcoin protocol to require minimal encoding.
The C charter has a rule of "no invention". Anything needs to be demonstrated and used in practice before being included in the standard. The standard is only meant to codify existing practices, not introduce new ideas.…
Lisps are expression based languages, but not pure. It's easy to mistake it as "like most other languages", but it's not quite the same - everything is an expression and returns a result. There are no "statements". They…
Operatives are based on FEXPRS from older lisps - they're basically a function-like form, but where the operands are not implicitly reduce at the time of call. (foo (+ 2 3) (* 3 4)) ($bar (+ 2 3) (* 3 4)) `foo` is a…
There's no "external representation" for environments. In klisp it will just print: [#environment] The environment type is encapsulated, so it doesn't give you very useful debug information. Perhaps having `@` produce…
I use klisp[1] and bronze-age-lisp[2] mostly for testing, as they're the closest to a feature complete implementation of the Kernel Report. I've written a number of less complete interpreters over the years. I currently…
I understand the use case, but Scheme macros never felt intuitive to me. I think it may be the quotation more than anything that I dislike - though I also dislike that they're second class (which was the key thing which…
Operatives do that for me, better than macros. Parent is correct that macros are compile time, which gives them a performance advantage over operatives - but IMO, they're not better ergonomically. I find operatives…
In Kernel I would use something like this: true #t false #f null () [...] (& ...) "k" : v (: k v) {...} (@ ...) Where &, :, @ are defined as: ($define! & ($lambda args (cons list args))) ($define! : ($vau (key value)…
When I learned Scheme, I liked the language but strongly disliked macros and quotation. I'd only been using it a short while and when I searched for solutions to a few problems these "fexpr" things kept appearing up,…
I made a mini example in C. It's awkward to do get right because you need an indirect pointer whose address remains fixed, but points to another pointer which can change (and is volatile). While it might be possible to…
I think parent was after base+offset+index rather than just base+index. Examples would be eg, `string_view` or `ArraySegment`. They hold some offset relative to a base allocation, and when we index the string_view or…
That's Fat pointers, not Far pointers. A fat pointer is a pointer with some other associated data which is stored in the pointer itself - typically by widening the number of bits used to hold a pointer value. The…
Far pointers are for accessing memory in different segments. They're basically obsolete now. They were necessary in older machines with limited sized pointers or address spaces. GCC still supports `__seg_fs` and…
The poorest in society are the lowest CO2 emitters - they don't fly often, many don't own a car and use public transport - they can't afford meat in every meal. Conversely, the wealthiest are frequent flyers, are…
The FS and GS segment selectors are still used in x86-64, typically for `thread_local` storage, but they can be repurposed. `thread_local` is an example of a "relative pointer" though. Instructions to access the thread…
That's not entirely true, but it's a valid reason to prefer using musttail. `register` is a hint if you don't specify which register you want to use - however, if you specify the register it will clobber it. noinline…
> What practical patterns are enabled by TCO in C? Continuation Passing Style - an important construction for interpreters, but which is also useful for compilers as it's a nice way to do control flow analysis, data…
That may be true, but it may also mean you utilize more memory than you need to. If you aren't shrinking the array when you no longer need previously allocated capacity then you're wasting memory. You could end up with…
I don't think it's that rare. I've been using the technique for years, and I've seen it done in other work. Bagwell's VList[1] for example uses the equivalent of `bit_ceil` to determine the size of each block without…
If you use a struct with a `void*`, you also need to specify the type on usage, where here it's done with `typeof`.
In C23 this approach is nice, but in older versions of C we end up with awful macros where we need to define the structure before we use it. #define Array(T) struct array_##T #define DEFINE_ARRAY(T) struct array_##T {…
The reason the struct is avoided here is so the array can be typed to its element type (rather than casting to and from `void*`). With a struct we would need one struct for each element type - at least prior to C23…
The concept of not storing capacity isn't silly. If you need to reserve space then it's not the appropriate structure, but it's otherwise fine. However, using an 2-element array to avoid using a struct is silly.
Really? It's been done plenty and I thought was quite common knowledge. Some of the <stdbit.h> provided functions are basically for this purpose. stdc_bit_ceil(len) gets the smallest power of 2 not less than len, which…
Bitcoin has a variable width encoding (`CompactSize`), but it doesn't prevent overlong encodings - however there are various canonicalization rules in the Bitcoin protocol to require minimal encoding.
The C charter has a rule of "no invention". Anything needs to be demonstrated and used in practice before being included in the standard. The standard is only meant to codify existing practices, not introduce new ideas.…
Lisps are expression based languages, but not pure. It's easy to mistake it as "like most other languages", but it's not quite the same - everything is an expression and returns a result. There are no "statements". They…
Operatives are based on FEXPRS from older lisps - they're basically a function-like form, but where the operands are not implicitly reduce at the time of call. (foo (+ 2 3) (* 3 4)) ($bar (+ 2 3) (* 3 4)) `foo` is a…
There's no "external representation" for environments. In klisp it will just print: [#environment] The environment type is encapsulated, so it doesn't give you very useful debug information. Perhaps having `@` produce…
I use klisp[1] and bronze-age-lisp[2] mostly for testing, as they're the closest to a feature complete implementation of the Kernel Report. I've written a number of less complete interpreters over the years. I currently…
I understand the use case, but Scheme macros never felt intuitive to me. I think it may be the quotation more than anything that I dislike - though I also dislike that they're second class (which was the key thing which…
Operatives do that for me, better than macros. Parent is correct that macros are compile time, which gives them a performance advantage over operatives - but IMO, they're not better ergonomically. I find operatives…
In Kernel I would use something like this: true #t false #f null () [...] (& ...) "k" : v (: k v) {...} (@ ...) Where &, :, @ are defined as: ($define! & ($lambda args (cons list args))) ($define! : ($vau (key value)…
When I learned Scheme, I liked the language but strongly disliked macros and quotation. I'd only been using it a short while and when I searched for solutions to a few problems these "fexpr" things kept appearing up,…