6 ms·
In my personal experience, "a bit more than a pointer" works best as a pair of (start, end) pointers (where "end" points to just beyond the last element.) The
by eqvinox 7y ago
In my personal experience, "a bit more than a pointer" works best as a pair of (start, end) pointers (where "end" points to just beyond the last element.) The most obvious reasons for this are:
- slices become a total non-issue since a pair of (start, end) already is a slice and you can just move start and end.
- comparing against an end pointer is generally easier than adding up a length value first, particularly if you're slicing at the same time.
- the end pointer value is independent of the array element type, so if you e.g. cast to uint8_t * (which arguably you shouldn't in most cases) it stays exactly the same. If you store a count you need to adjust a multiplier. If you store a byte length, you need to do a lot of divides or casts to deal with pointer arithmetics.
Also, this is a huge red flag to me:
https://github.com/orangeduck/Cello/blob/master/include/Cello.h#L135-L140 https://github.com/orangeduck/Cello/blob/master/include/Cell...
#define is ==
#define isnt !=
#define not !
#define and &&
#define or ||
#define in ,
P.S.: This also is a "try to invent a new programming language without inventing a new programming language" thing. Have your cake and eat it... either it's C or it isn't, and this library is leaving the space of "normal" C.
- aaron-lebo 7y agoI'll admit I've never written more than small programs in C, but the criticism that this "isn't C" isn't a fair criticism to me. He's not doing anything more than any other library can do, were he to write a compiler that mapped directly to really boring C, would it be more or less C than this? I don't feel like those questions are useful. We need experiments like this, and for me personally, cello was a revelation when it was posted here years ago. There are no rules that say you can't do it. I know he's doing a little hackiness by placing the size before the start of the object, but they also take that approach here (https://www.piumarta.com/software/cola/objmodel2.pdf https://www.piumarta.com/software/cola/objmodel2.pdf) so maybe it's not that uncommon. How would you do the dual pointer setup? Is there any overhead from that, or is it small enough to not worry about?
- eqvinox 7y agoThe "isn't C" argument is more about the library as a whole, not specifically about the fat pointer suggestions. (Please look at the github repo, IMHO it's obvious.) Placing a length "before" a pointer is perfectly fine on a _technical_ level. It's also how glibc's malloc works, it has its own data before any allocation it returns. However, hackiness is not the question here - it's whether it's the "best" approach. I simply believe, based on my own experiences, that twin pointers cover/win out in a much larger subset of applicable scenarios. As for how to implement it - declare a struct with 2 pointers in it. Or just pass 2 pointers around.
- artemonster 7y agoDo you, by chance, know where else object model of Piumarta is used? I think the Per6 VM "Potion" used it too as a base, but I am unsure
- aaron-lebo 7y agoUnfortunately, no, your info about Perl 6 is news to me. Only ran into it a few months ago, tried it in Python and Nim, but haven't seen it in the wild. It's very cool though.
- artemonster 7y agohttp://perl11.org/potion/ http://perl11.org/potion/
- vardump 7y ago> Also, this is a huge red flag to me: Puke! Who would ever want to create that kind of macro abomination.
- dgellow 7y agoBjarne Stroustrup! https://en.wikipedia.org/wiki/C_alternative_tokens https://en.wikipedia.org/wiki/C_alternative_tokens And I'm not even joking :)
- vardump 7y agoYeah, damn, just found out myself. I thought I knew C inside out, but I guess there are still bits and pieces you just don't encounter very often. That said, my opinion about those macros is unchanged.
- arcticbull 7y agoMan Bjarne Stroustrup is like the guy in college who flatly refused to conform in any way whatsoever no matter how good or bad it would have been for 'em. It's more of an oppositional personality disorder ;) That kid grew up and invented, because of course he did, C++.
- int_19h 7y agoIt might have something to do with various symbols that C uses not being convenient to type in many non-US keyboard layouts. In the standard Danish one, ~|^ all require the use of AltGr.
- arcticbull 7y agoC++ isn't exactly short on symbols haha
- garaetjjte 7y agoYou can do worse: http://oldhome.schmorp.de/marc/bournegol.html http://oldhome.schmorp.de/marc/bournegol.html
- dllu 7y agohuh. Interestingly, for "and", "or" and "not", iso646.h already defines C alternative tokens: https://en.wikipedia.org/wiki/C_alternative_tokens https://en.wikipedia.org/wiki/C_alternative_tokens
- eqvinox 7y agoI know :) ... but have you seen anyone actually use those? I'd be curious to get a pointer or two.
- dllu 7y agoI have seen people coming to C++ from Python use "and", "or", and "not" in their if-statements :)
- eqvinox 7y agoHah - I kid you not, I have the reverse problem! I work a lot with both C and Python (embedded interpreter & CPython extensions) and whenever I switch from a stretch of C coding to doing some Python, I catch myself typing "&&" and "||" instead of "and" and "or" :D (C is my "native" language, so it doesn't really happen the other way around, but that's just me) But honestly, I'm pretty sure we can call iso646.h "fringe" ;)
- aloisdg 7y agoIn programming languages, does we have something akin to a mother-tongue?
- macintux 7y agoThere’s a fair bit of debate about the impact of learning specific programming styles as your first language. Quite a few people would argue that learning functional programming first is a benefit to understanding the concept of state and how to write clean code, even if you end up using something less pure. Certainly, speaking as someone brought up on imperative and later OO code, it took a fair bit of unlearning to understand functional programming, and I still have no clue about type theory.
- shawa_a_a 7y agoI don’t think you’re too far off with ‘leaving the space of normal C’, but I think it may help to see the context from which the author was coming when writing Cello [1] and evaluating it in that context. It’s been a while since I watched the talk but I believe his intention was to do just that, to push the bounds of what could be done in a header file purely for the fun of it. The second half of the talk specifically addresses the “why are you doing this?” in quite a charming way. 1: https://youtu.be/bVxfwsgO00o https://youtu.be/bVxfwsgO00o
- hannibalhorn 7y agoStart and end pointers is the approach used by the C++ STL, too.
- kortex 7y agoThis is how Go does slices, though they are 3 fields: type slice struct { zerothElement *type len int cap int } Though I suspect under the hood the len and cap are ordered first. If it's good enough for C greybeard Ken Thompson and unix hacker Rob Pike, its good enough for me. In fact I've looked for a port of go-style slices to C and haven't found one. Maybe people think sds is good enough?
- LukeShu 7y ago> Though I suspect under the hood the len and cap are ordered first. A slice is stored in memory as a `reflect.SliceHeader` https://golang.org/pkg/reflect/#SliceHeader https://golang.org/pkg/reflect/#SliceHeader ; the pointer does come first.
- jgbaldwinbrown 7y agoI actually wrote a (sort of) Go-style slice library. It's a little heavier than Go slices because it allows for dynamic array resizing and tracking the parentage of slices: https://github.com/jgbaldwinbrown/slice https://github.com/jgbaldwinbrown/slice It's just a proof-of-concept, though, and would need a lot of work to be used in anything serious.
- int_19h 7y agoGo has a rather idiosyncratic take on arrays and how they're used, which is reflected in its slices. I can't think of any other language or framework that did it this way.
- saati 7y agoRust Vec has the same representation.
- gumby 7y ago> In my personal experience, "a bit more than a pointer" works best as a pair of (start, end) pointers (where "end" points to just beyond the last element.) There’s a PARC paper from the Cedar team benchmarking base-and bounds vs marker-terminated (e.g. null terminated) strings and base-and-bounds won hands down on a variety of use cases. Won on speed, not just the safety grounds. In those days some people actually worried about the space taken up by the extra bounds variable.
- pjmlp 7y agoWhile people did worry about the space taken up by the bounds checking information, systems 10 years older than the PDP-11 had enough hardware resources to support high level systems programming languages with bounds checking data structures, let alone the beefy PDP-11 (by comparison with those older models).
- gumby 7y agoAs I know well as a KA-10 MACLISP programmer! But most people these days have a hard time realizing what it was like to program a machine with only a few K of memory. PL/1 (the Multics implementation language) had bounded strings. C did not as it was believed the PDP-7 couldn't afford it. Of course by today's standards the GE 645 is an absurdly tiny machine.
- pjmlp 7y agoYeah, that was my point, this knowledge is getting lost, only to be re-discovered by those that love to dig into computer history. Just to think that what is now on a ESP32 die took over a complete desk at the high school computer club and was still weaker than what ESP32 is capable of, yet that mentality also persists for what 80's hardware was already capable of.